LibreOffice Module cui (master)  1
swpossizetabpage.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <memory>
21 #include <cstddef>
22 #include <swpossizetabpage.hxx>
23 #include <svx/dlgutil.hxx>
24 #include <svx/anchorid.hxx>
25 #include <svl/intitem.hxx>
27 #include <sfx2/htmlmode.hxx>
28 #include <svx/svdview.hxx>
29 #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/svxids.hrc>
37 #include <svtools/unitconv.hxx>
38 #include <osl/diagnose.h>
39 
40 using namespace ::com::sun::star::text;
41 
42 namespace {
43 
44 enum class LB;
45 
46 }
47 
48 struct FrmMap
49 {
52  short nAlign;
54 };
55 
56 namespace {
57 
58 struct RelationMap
59 {
61  SvxSwFramePosString::StringId eMirrorStrId;
62  LB nLBRelation;
63  short nRelation;
64 };
65 struct StringIdPair_Impl
66 {
69 };
70 
71 enum class LB {
72  NONE = 0x000000,
73  Frame = 0x000001, // paragraph text area
74  PrintArea = 0x000002, // paragraph text area + indents
75  VertFrame = 0x000004, // vertical paragraph text area
76  VertPrintArea = 0x000008, // vertical paragraph text area + indents
77  RelFrameLeft = 0x000010, // left paragraph margin
78  RelFrameRight = 0x000020, // right paragraph margin
79 
80  RelPageLeft = 0x000040, // left page margin
81  RelPageRight = 0x000080, // right page margin
82  RelPageFrame = 0x000100, // complete page
83  RelPagePrintArea = 0x000200, // text area of page
84 
85  FlyRelPageLeft = 0x000400, // left frame margin
86  FlyRelPageRight = 0x000800, // right frame margin
87  FlyRelPageFrame = 0x001000, // complete frame
88  FlyRelPagePrintArea = 0x002000, // frame interior
89 
90  RelBase = 0x004000, // as char, relative to baseline
91  RelChar = 0x008000, // as char, relative to character
92  RelRow = 0x010000, // as char, relative to line
93 
94 // #i22305#
95  FlyVertFrame = 0x020000, // vertical entire frame
96  FlyVertPrintArea = 0x040000, // vertical frame text area
97 
98 // #i22341#
99  VertLine = 0x080000, // vertical text line
100 
101  RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
102  RelPagePrintAreaTop = 0x200000,
103 
104  LAST = 0x400000
105 };
106 
107 }
108 
109 namespace o3tl {
110  template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
111 }
112 
113 RelationMap const aRelationMap[] =
114 {
115  {SvxSwFramePosString::FRAME, SvxSwFramePosString::FRAME, LB::Frame, RelOrientation::FRAME},
116  {SvxSwFramePosString::PRTAREA, SvxSwFramePosString::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
117  {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
118  {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
119  {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
120  {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
121  {SvxSwFramePosString::REL_PG_FRAME, SvxSwFramePosString::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
122  {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
123  {SvxSwFramePosString::REL_PG_PRTAREA_TOP,SvxSwFramePosString::REL_PG_PRTAREA_TOP, LB::RelPagePrintAreaTop, RelOrientation::PAGE_PRINT_AREA_TOP},
124  {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM, LB::RelPagePrintAreaBottom, RelOrientation::PAGE_PRINT_AREA_BOTTOM},
125  {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
126 
127  {SvxSwFramePosString::FLY_REL_PG_LEFT, SvxSwFramePosString::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
128  {SvxSwFramePosString::FLY_REL_PG_RIGHT, SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
129  {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
130  {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
131 
132  {SvxSwFramePosString::REL_BORDER, SvxSwFramePosString::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
133  {SvxSwFramePosString::REL_PRTAREA, SvxSwFramePosString::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
134 
135  // #i22305#
136  {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
137  {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
138 
139  // #i22341#
140  {SvxSwFramePosString::REL_LINE, SvxSwFramePosString::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
141 };
142 
143 RelationMap const aAsCharRelationMap[] =
144 {
145  {SvxSwFramePosString::REL_BASE, SvxSwFramePosString::REL_BASE, LB::RelBase, RelOrientation::FRAME},
146  {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
147  {SvxSwFramePosString::REL_ROW, SvxSwFramePosString::REL_ROW, LB::RelRow, RelOrientation::FRAME}
148 };
149 
150 /*--------------------------------------------------------------------
151  Anchored at page
152  --------------------------------------------------------------------*/
153 
154 constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
155  LB::RelPageRight;
156 
157 FrmMap const aHPageMap[] =
158 {
163 };
164 
166 {
167  {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
168 };
169 
170 #define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
171 
172 FrmMap const aVPageMap[] =
173 {
178 };
179 
181 {
182  {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
183 };
184 
185 /*--------------------------------------------------------------------
186  Anchored at frame
187  --------------------------------------------------------------------*/
188 
189 constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
190  LB::FlyRelPageLeft|LB::FlyRelPageRight;
191 
193 {
198 };
199 
201 {
202  {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
203  {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
204 };
205 
206 // #i18732# - own vertical alignment map for to frame anchored objects
207 // #i22305#
208 #define VERT_FRAME_REL (LB::VertFrame|LB::FlyVertPrintArea)
209 
211 {
216 };
217 
219 {
220  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::FlyVertFrame},
221  {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
222 };
223 
225 {
226  {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::NONE}
227 };
229 {
230  {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::FROMLEFT, HoriOrientation::NONE, LB::NONE}
231 };
232 
233 /*--------------------------------------------------------------------
234  Anchored at paragraph
235  --------------------------------------------------------------------*/
236 
237 constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
238  LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
239  LB::RelFrameRight;
240 
241 FrmMap const aHParaMap[] =
242 {
247 };
248 
249 #define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
250 
252 {
255 };
256 
258 {
261 };
262 
263 
264 constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
265  LB::RelPageFrame|LB::RelPagePrintArea| LB::RelPagePrintAreaTop |LB::RelPagePrintAreaBottom;
266 
267 FrmMap const aVParaMap[] =
268 {
273 };
274 
276 {
277  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::VertPrintArea}
278 };
279 
280 /*--------------------------------------------------------------------
281  Anchored at character
282  --------------------------------------------------------------------*/
283 
284 constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
285  LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
286  LB::RelFrameRight|LB::RelChar;
287 
288 static FrmMap aHCharMap[] =
289 {
294 };
295 
296 #define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
297 
299 {
302 };
303 
305 {
306  {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
307  {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
308  {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
309 };
310 
311 // #i18732# - allow vertical alignment at page areas
312 // #i22341# - handle <LB::RelChar> on its own
313 constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
314  LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPagePrintAreaBottom;
315 
316 static FrmMap aVCharMap[] =
317 {
318  // #i22341#
319  // introduce mappings for new vertical alignment at top of line <LB::VertLine>
320  // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
321  // Note: because of these adjustments the map becomes ambiguous in its values
322  // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
323  // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
324  // and <SwFrmPage::FillPosLB(..)>
325  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
326  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
327  {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
330  {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
331  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::VertLine},
332  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
333  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
334 };
335 
336 
338 {
339  {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
340 };
341 
343 {
344  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelChar},
345  {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
346 };
347 /*--------------------------------------------------------------------
348  anchored as character
349  --------------------------------------------------------------------*/
350 
352 {
353  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
354  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
355  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
356 
357  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
358  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
359  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
360 
361  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
362  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
363  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
364 
365  {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
366 };
367 
369 {
370  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
371  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
372 
373  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
374 
375  {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
376  {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
377  {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
378 };
379 
380 static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
381 {
382  if( pMap )
383  {
384  if( pMap == aVParaHtmlMap )
385  return SAL_N_ELEMENTS(aVParaHtmlMap);
386  if( pMap == aVAsCharHtmlMap )
387  return SAL_N_ELEMENTS( aVAsCharHtmlMap );
388  if( pMap == aHParaHtmlMap )
389  return SAL_N_ELEMENTS( aHParaHtmlMap );
390  if( pMap == aHParaHtmlAbsMap )
391  return SAL_N_ELEMENTS( aHParaHtmlAbsMap );
392  if( pMap == aVPageMap )
393  return SAL_N_ELEMENTS( aVPageMap );
394  if( pMap == aVPageHtmlMap )
395  return SAL_N_ELEMENTS( aVPageHtmlMap );
396  if( pMap == aVAsCharMap )
397  return SAL_N_ELEMENTS( aVAsCharMap );
398  if( pMap == aVParaMap )
399  return SAL_N_ELEMENTS( aVParaMap );
400  if( pMap == aHParaMap )
401  return SAL_N_ELEMENTS( aHParaMap );
402  if( pMap == aHFrameMap )
403  return SAL_N_ELEMENTS( aHFrameMap );
404  if( pMap == aVFrameMap )
405  return SAL_N_ELEMENTS( aVFrameMap );
406  if( pMap == aHCharMap )
407  return SAL_N_ELEMENTS( aHCharMap );
408  if( pMap == aHCharHtmlMap )
409  return SAL_N_ELEMENTS( aHCharHtmlMap );
410  if( pMap == aHCharHtmlAbsMap )
411  return SAL_N_ELEMENTS( aHCharHtmlAbsMap );
412  if( pMap == aVCharMap )
413  return SAL_N_ELEMENTS( aVCharMap );
414  if( pMap == aVCharHtmlMap )
415  return SAL_N_ELEMENTS( aVCharHtmlMap );
416  if( pMap == aVCharHtmlAbsMap )
417  return SAL_N_ELEMENTS( aVCharHtmlAbsMap );
418  if( pMap == aHPageHtmlMap )
419  return SAL_N_ELEMENTS( aHPageHtmlMap );
420  if( pMap == aHFlyHtmlMap )
421  return SAL_N_ELEMENTS( aHFlyHtmlMap );
422  if( pMap == aVFlyHtmlMap )
423  return SAL_N_ELEMENTS( aVFlyHtmlMap );
424  if( pMap == aVMultiSelectionMap )
425  return SAL_N_ELEMENTS( aVMultiSelectionMap );
426  if( pMap == aHMultiSelectionMap )
427  return SAL_N_ELEMENTS( aHMultiSelectionMap );
428  return SAL_N_ELEMENTS(aHPageMap);
429  }
430  return 0;
431 }
432 
434  SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
435 {
436  //special handling of STR_FROMLEFT
437  if(SvxSwFramePosString::FROMLEFT == eStringId)
438  {
439  eStringId = bVertical ?
442  return eStringId;
443  }
444  if(bVertical)
445  {
446  //exchange horizontal strings with vertical strings and vice versa
447  static const StringIdPair_Impl aHoriIds[] =
448  {
457  };
458  static const StringIdPair_Impl aVertIds[] =
459  {
468  };
469  for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aHoriIds); ++nIndex)
470  {
471  if(aHoriIds[nIndex].eHori == eStringId)
472  {
473  eStringId = aHoriIds[nIndex].eVert;
474  return eStringId;
475  }
476  }
477  for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
478  {
479  if(aVertIds[nIndex].eHori == eStringId)
480  {
481  eStringId = aVertIds[nIndex].eVert;
482  break;
483  }
484  }
485  }
486  return eStringId;
487 }
488 // #i22341# - helper method in order to determine all possible
489 // listbox relations in a relation map for a given relation
490 static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
491 {
492  LB nLBRelations = LB::NONE;
493 
494  for (RelationMap const & nRelMapPos : aRelationMap)
495  {
496  if ( nRelMapPos.nRelation == _nRel )
497  {
498  nLBRelations |= nRelMapPos.nLBRelation;
499  }
500  }
501 
502  return nLBRelations;
503 }
504 
505 // #i22341# - helper method on order to determine all possible
506 // listbox relations in a relation map for a given string ID
508  const SvxSwFramePosString::StringId _eStrId,
509  const bool _bUseMirrorStr )
510 {
511  LB nLBRelations = LB::NONE;
512 
513  std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
514  for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
515  {
516  if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
517  ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
518  {
519  nLBRelations |= _pMap[nRelMapPos].nLBRelations;
520  }
521  }
522 
523  return nLBRelations;
524 }
525 
527  : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
528  , m_pVMap(nullptr)
529  , m_pHMap(nullptr)
530  , m_pSdrView(nullptr)
531  , m_nOldH(HoriOrientation::CENTER)
532  , m_nOldHRel(RelOrientation::FRAME)
533  , m_nOldV(VertOrientation::TOP)
534  , m_nOldVRel(RelOrientation::PRINT_AREA)
535  , m_fWidthHeightRatio(1.0)
536  , m_bHtmlMode(false)
537  , m_bIsVerticalFrame(false)
538  , m_bPositioningDisabled(false)
539  , m_bIsMultiSelection(false)
540  , m_bIsInRightToLeft(false)
541  , m_nProtectSizeState(TRISTATE_FALSE)
542  , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
543  , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
544  , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
545  , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
546  , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
547  , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
548  , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
549  , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
550  , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
551  , m_xSizeCB(m_xBuilder->weld_check_button("size"))
552  , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
553  , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
554  , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
555  , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
556  , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
557  , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
558  , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
559  , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
560  , m_xVertFT(m_xBuilder->weld_label("vertposft"))
561  , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
562  , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
563  , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
564  , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
565  , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
566  , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
567  , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
568 {
571 
572  FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
573  SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
574  SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
575  SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
576  SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
577 
579 
580  Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
581  m_xWidthMF->connect_focus_out(aLk3);
582  m_xHeightMF->connect_focus_out(aLk3);
583  m_xHoriByMF->connect_focus_out(aLk3);
584  m_xVertByMF->connect_focus_out(aLk3);
585  m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
586 
588  m_xWidthMF->connect_value_changed( aLk );
589  m_xHeightMF->connect_value_changed( aLk );
590  m_xHoriByMF->connect_value_changed( aLk );
591  m_xVertByMF->connect_value_changed( aLk );
592 
593  Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
594  m_xToPageRB->connect_toggled( aLk2 );
595  m_xToParaRB->connect_toggled( aLk2 );
596  m_xToCharRB->connect_toggled( aLk2 );
597  m_xAsCharRB->connect_toggled( aLk2 );
598  m_xToFrameRB->connect_toggled( aLk2 );
599 
600  m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
601  m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
602 
603  m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
604  m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
605 
606  m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
607  m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
608 }
609 
611 {
612  m_xWidthMF.reset();
613  m_xHeightMF.reset();
614  m_xHoriByMF.reset();
615  m_xVertByMF.reset();
616 }
617 
618 namespace
619 {
620  struct FrmMaps
621  {
622  FrmMap const *pMap;
623  size_t nCount;
624  };
625 }
626 
628 {
629  static const FrmMaps aMaps[] = {
630  { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
631  { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
632  { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
633  { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
634  { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
635  { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
636  { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
637  { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
638  { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
639  { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
640  { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
641  { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
642  { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
643  { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
644  { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
645  { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
646  { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
647  { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
648  { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
649  { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
650  { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
651  };
652 
653  std::vector<SvxSwFramePosString::StringId> aFrames;
654  for (const FrmMaps& aMap : aMaps)
655  {
656  for (size_t j = 0; j < aMap.nCount; ++j)
657  {
658  aFrames.push_back(aMap.pMap[j].eStrId);
659  aFrames.push_back(aMap.pMap[j].eMirrorStrId);
660  }
661  }
662 
663  std::sort(aFrames.begin(), aFrames.end());
664  aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
665 
666  for (auto const& frame : aFrames)
667  {
669  }
670 
671  Size aBiggest(m_xHoriLB->get_preferred_size());
672  m_xHoriLB->set_size_request(aBiggest.Width(), -1);
673  m_xVertLB->set_size_request(aBiggest.Width(), -1);
674  m_xHoriLB->clear();
675 }
676 
677 namespace
678 {
679  struct RelationMaps
680  {
681  RelationMap const *pMap;
682  size_t nCount;
683  };
684 }
685 
687 {
688  static const RelationMaps aMaps[] = {
689  { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
690  { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
691  };
692 
693  std::vector<SvxSwFramePosString::StringId> aRels;
694  for (const RelationMaps& aMap : aMaps)
695  {
696  for (size_t j = 0; j < aMap.nCount; ++j)
697  {
698  aRels.push_back(aMap.pMap[j].eStrId);
699  aRels.push_back(aMap.pMap[j].eMirrorStrId);
700  }
701  }
702 
703  std::sort(aRels.begin(), aRels.end());
704  aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
705 
706  for (auto const& elem : aRels)
707  {
708  m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
709  }
710 
711  Size aBiggest(m_xHoriLB->get_preferred_size());
712  m_xHoriLB->set_size_request(aBiggest.Width(), -1);
713  m_xVertLB->set_size_request(aBiggest.Width(), -1);
714  m_xHoriLB->clear();
715 }
716 
717 std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
718 {
719  return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
720 }
721 
723 {
724  static const WhichRangesContainer ranges(svl::Items<
725  SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
726  SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
727  SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
728  SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
729  SID_HTML_MODE, SID_HTML_MODE,
730  SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
731  SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
732  >);
733  return ranges;
734 }
735 
737 {
738  bool bAnchorChanged = false;
739  RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
740  bool bModified = false;
741  if(bAnchorChanged)
742  {
743  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
744  bModified = true;
745  }
746  if (m_xPositionCB->get_state_changed_from_saved())
747  {
748  if (m_xPositionCB->get_inconsistent())
749  rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
750  else
751  rSet->Put(
752  SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
753  m_xPositionCB->get_state() == TRISTATE_TRUE ) );
754  bModified = true;
755  }
756 
757  if (m_xSizeCB->get_state_changed_from_saved())
758  {
759  if (m_xSizeCB->get_inconsistent())
760  rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
761  else
762  rSet->Put(
763  SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
764  m_xSizeCB->get_state() == TRISTATE_TRUE ) );
765  bModified = true;
766  }
767 
768  const SfxItemSet& rOldSet = GetItemSet();
769 
771  {
772  //on multiple selections the positioning is set via SdrView
774  {
775  if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
776  {
777  auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
778  auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
779 
780  // old rectangle with CoreUnit
783 
784  nHoriByPos += m_aAnchorPos.X();
785  nVertByPos += m_aAnchorPos.Y();
786 
787  rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
788  rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
789 
790  bModified = true;
791  }
792  }
793  else
794  {
795  if ( m_pHMap )
796  {
797  const SfxInt16Item& rHoriOrient =
798  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
799  const SfxInt16Item& rHoriRelation =
800  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
801  const SfxInt32Item& rHoriPosition =
802  static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
803 
804  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
805  short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
806  short nRel = GetRelation(*m_xHoriToLB);
807  const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
808  if (
809  nAlign != rHoriOrient.GetValue() ||
810  nRel != rHoriRelation.GetValue() ||
811  (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
812  )
813  {
814  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
815  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
816  if(m_xHoriByMF->get_sensitive())
817  rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
818  bModified = true;
819  }
820  }
821  if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
822  bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
823 
824  if ( m_pVMap )
825  {
826  const SfxInt16Item& rVertOrient =
827  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
828  const SfxInt16Item& rVertRelation =
829  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
830  const SfxInt32Item& rVertPosition =
831  static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
832 
833  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
834  short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
835  short nRel = GetRelation(*m_xVertToLB);
836  // #i34055# - convert vertical position for
837  // as-character anchored objects
838  auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
839  if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
840  {
841  nVertByPos *= -1;
842  }
843  if ( nAlign != rVertOrient.GetValue() ||
844  nRel != rVertRelation.GetValue() ||
845  ( m_xVertByMF->get_sensitive() &&
846  nVertByPos != rVertPosition.GetValue() ) )
847  {
848  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
849  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
850  if(m_xVertByMF->get_sensitive())
851  rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
852  bModified = true;
853  }
854  }
855 
856  // #i18732#
857  if (m_xFollowCB->get_state_changed_from_saved())
858  {
859  //Writer internal type - based on SfxBoolItem
860  const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
861  if(pItem)
862  {
863  std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
864  pFollow->SetValue(m_xFollowCB->get_active());
865  bModified |= nullptr != rSet->Put(*pFollow);
866  }
867  }
868  }
869  }
870  if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
871  {
872  sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
873  sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
874  rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
875  rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
876  //this item is required by SdrEditView::SetGeoAttrToMarked()
877  rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
878 
879  bModified = true;
880  }
881 
882  return bModified;
883 }
884 
886 {
887  const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
888  bool bInvalidateAnchor = false;
889  RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
890  if(pItem)
891  {
892  nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
893  switch(nAnchorType)
894  {
895  case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
896  case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
897  case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
898  case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
899  case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
900  default : bInvalidateAnchor = true;
901  }
902  m_xToPageRB->save_state();
903  m_xToParaRB->save_state();
904  m_xToCharRB->save_state();
905  m_xAsCharRB->save_state();
906  m_xToFrameRB->save_state();
907  }
908  if (bInvalidateAnchor)
909  {
910  m_xToPageRB->set_sensitive( false );
911  m_xToParaRB->set_sensitive( false );
912  m_xToCharRB->set_sensitive( false );
913  m_xAsCharRB->set_sensitive( false );
914  m_xToFrameRB->set_sensitive( false );
915  }
916 
917  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
918  if (pItem)
919  {
920  bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
921  m_xPositionCB->set_active(bProtected);
922  m_xSizeCB->set_sensitive(!bProtected);
923  }
924  else
925  {
926  m_xPositionCB->set_inconsistent(true);
927  }
928 
929  m_xPositionCB->save_state();
930 
931  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
932 
933  if (pItem)
934  {
935  m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
936  }
937  else
938  m_xSizeCB->set_inconsistent(true);
939  m_xSizeCB->save_state();
940 
941  pItem = GetItem( *rSet, SID_HTML_MODE );
942  if(pItem)
943  {
944  m_bHtmlMode =
945  (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
946  != 0;
947  }
948 
949  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
950  if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
951  {
952  OUString sHLabel = m_xHoriFT->get_label();
953  m_xHoriFT->set_label(m_xVertFT->get_label());
954  m_xVertFT->set_label(sHLabel);
955  m_bIsVerticalFrame = true;
956  }
957  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
958  if(pItem)
959  m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
960 
961  pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
962  if(pItem)
963  {
964  const bool bFollowTextFlow =
965  static_cast<const SfxBoolItem*>(pItem)->GetValue();
966  m_xFollowCB->set_active(bFollowTextFlow);
967  }
968  m_xFollowCB->save_state();
969 
970  if(m_bHtmlMode)
971  {
972  m_xHoriMirrorCB->hide();
973  m_xKeepRatioCB->set_sensitive(false);
974  // #i18732# - hide checkbox in HTML mode
975  m_xFollowCB->hide();
976  }
977  else
978  {
979  // #i18732# correct enable/disable of check box 'Mirror on..'
980  m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
981 
982  // #i18732# - enable/disable check box 'Follow text flow'.
983  m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
984  m_xToCharRB->get_active());
985  }
986 
987  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
988  sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
989 
990  m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
991  m_xWidthMF->save_value();
992 
993  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
994  sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
995  m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
996  m_xHeightMF->save_value();
997  m_fWidthHeightRatio = double(nWidth) / double(nHeight);
998 
1000  return;
1001 
1002  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
1003  if(pItem)
1004  {
1005  short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1006  m_nOldH = nHoriOrientation;
1007  }
1008  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
1009  if(pItem)
1010  {
1011  short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1012  m_nOldV = nVertOrientation;
1013  }
1014  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
1015  if(pItem)
1016  {
1017  m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1018  }
1019 
1020  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
1021  if(pItem)
1022  {
1023  m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1024  }
1025  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
1026  if(pItem)
1027  m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1028  m_xHoriMirrorCB->save_state();
1029 
1030  sal_Int32 nHoriPos = 0;
1031  sal_Int32 nVertPos = 0;
1032  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
1033  if(pItem)
1034  nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1035  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
1036  if(pItem)
1037  nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1038 
1039  InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
1040 
1041  m_xVertByMF->save_value();
1042  m_xHoriByMF->save_value();
1043  // #i18732#
1044  m_xFollowCB->save_state();
1045 
1046  RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
1047 }
1048 
1050 {
1051  if( _pSet )
1052  {
1053  _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
1054  m_xPositionCB->get_active()));
1055  _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
1056  m_xSizeCB->get_active()));
1057  FillItemSet( _pSet );
1058  }
1059  return DeactivateRC::LeavePage;
1060 }
1061 
1063 {
1064  if (nAnchorEnable & SvxAnchorIds::Fly)
1065  m_xToFrameRB->show();
1066  if (!(nAnchorEnable & SvxAnchorIds::Page))
1067  m_xToPageRB->set_sensitive(false);
1068 }
1069 
1071 {
1072  RndStdIds nRet = RndStdIds::UNKNOWN;
1073  weld::RadioButton* pCheckedButton = nullptr;
1074  if(m_xToParaRB->get_sensitive())
1075  {
1076  if(m_xToPageRB->get_active())
1077  {
1078  nRet = RndStdIds::FLY_AT_PAGE;
1079  pCheckedButton = m_xToPageRB.get();
1080  }
1081  else if(m_xToParaRB->get_active())
1082  {
1083  nRet = RndStdIds::FLY_AT_PARA;
1084  pCheckedButton = m_xToParaRB.get();
1085  }
1086  else if(m_xToCharRB->get_active())
1087  {
1088  nRet = RndStdIds::FLY_AT_CHAR;
1089  pCheckedButton = m_xToCharRB.get();
1090  }
1091  else if(m_xAsCharRB->get_active())
1092  {
1093  nRet = RndStdIds::FLY_AS_CHAR;
1094  pCheckedButton = m_xAsCharRB.get();
1095  }
1096  else if(m_xToFrameRB->get_active())
1097  {
1098  nRet = RndStdIds::FLY_AT_FLY;
1099  pCheckedButton = m_xToFrameRB.get();
1100  }
1101  }
1102  if(pbHasChanged)
1103  {
1104  if(pCheckedButton)
1105  *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
1106  else
1107  *pbHasChanged = false;
1108  }
1109  return nRet;
1110 }
1111 
1113 {
1114  RangeModifyHdl(m_xWidthMF->get_widget());
1115 }
1116 
1118 {
1119  if (m_bPositioningDisabled)
1120  return;
1121  SvxSwFrameValidation aVal;
1122 
1123  aVal.nAnchorType = GetAnchorType();
1124  aVal.bAutoHeight = false;
1125  aVal.bMirror = m_xHoriMirrorCB->get_active();
1126  // #i18732#
1127  aVal.bFollowTextFlow = m_xFollowCB->get_active();
1128 
1129  if ( m_pHMap )
1130  {
1131  // horizontal alignment
1132  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
1133  sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1134  sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1135 
1136  aVal.nHoriOrient = static_cast<short>(nAlign);
1137  aVal.nHRelOrient = static_cast<short>(nRel);
1138  }
1139  else
1140  aVal.nHoriOrient = HoriOrientation::NONE;
1141 
1142  if ( m_pVMap )
1143  {
1144  // vertical alignment
1145  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1146  sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1147  sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1148 
1149  aVal.nVertOrient = static_cast<short>(nAlign);
1150  aVal.nVRelOrient = static_cast<short>(nRel);
1151  }
1152  else
1153  aVal.nVertOrient = VertOrientation::NONE;
1154 
1155  const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1156  const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1157 
1158  aVal.nHPos = nAtHorzPosVal;
1159  aVal.nVPos = nAtVertPosVal;
1160 
1161  sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
1162  sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
1163  aVal.nWidth = nWidth;
1164  aVal.nHeight = nHeight;
1165 
1166  m_aValidateLink.Call(aVal);
1167 
1168  // minimum width also for style
1169  m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
1170  m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
1171 
1172  sal_Int32 nMaxWidth(aVal.nMaxWidth);
1173  sal_Int32 nMaxHeight(aVal.nMaxHeight);
1174 
1175  sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
1176  m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
1177 
1178  nTmp = m_xWidthMF->normalize(nMaxWidth);
1179  m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
1180 
1181  m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
1182  m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
1183  if ( aVal.nHPos != nAtHorzPosVal )
1184  m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
1185 
1186  m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
1187  m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
1188  if ( aVal.nVPos != nAtVertPosVal )
1189  m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
1190 }
1191 
1193 {
1194  m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
1195 
1196  // #i18732# - enable check box 'Follow text flow' for anchor
1197  // type to-paragraph' and to-character
1198  m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
1199 
1200  RndStdIds nId = GetAnchorType();
1201 
1202  InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1203  RangeModifyHdl(m_xWidthMF->get_widget());
1204 
1205  if(m_bHtmlMode)
1206  {
1207  PosHdl(*m_xHoriLB);
1208  PosHdl(*m_xVertLB);
1209  }
1210 }
1211 
1213 {
1214  RndStdIds nId = GetAnchorType();
1215  InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1216 }
1217 
1219 {
1220  bool bHori = &rLB == m_xHoriToLB.get();
1221 
1222  UpdateExample();
1223 
1224  if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
1225  {
1226  if(bHori)
1227  {
1228  sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1229  if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
1230  {
1231  m_xVertLB->set_active(1);
1232  }
1233  else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
1234  {
1235  m_xVertLB->set_active(0);
1236  }
1237  }
1238  }
1239  RangeModifyHdl(m_xWidthMF->get_widget());
1240 }
1241 
1243 {
1244  bool bHori = &rLB == m_xHoriLB.get();
1245  weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
1246  weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
1247  FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
1248 
1249 
1250  sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
1251  sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1252 
1253  if (bHori)
1254  {
1255  bool bEnable = HoriOrientation::NONE == nAlign;
1256  m_xHoriByMF->set_sensitive( bEnable );
1257  m_xHoriByFT->set_sensitive( bEnable );
1258  }
1259  else
1260  {
1261  bool bEnable = VertOrientation::NONE == nAlign;
1262  m_xVertByMF->set_sensitive( bEnable );
1263  m_xVertByFT->set_sensitive( bEnable );
1264  }
1265 
1266  RangeModifyHdl(m_xWidthMF->get_widget());
1267 
1268  short nRel = 0;
1269  if (rLB.get_active() != -1)
1270  {
1271  if (pRelLB->get_active() != -1)
1272  nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
1273 
1274  FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1275  }
1276  else
1277  pRelLB->clear();
1278 
1279  UpdateExample();
1280 
1281  // special treatment for HTML-Mode with horz-vert-dependencies
1282  if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
1283  return;
1284 
1285  bool bSet = false;
1286  if(bHori)
1287  {
1288  // on the right only below is allowed - from the left only at the top
1289  // from the left at the character -> below
1290  if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
1291  0 == m_xVertLB->get_active())
1292  {
1293  if(RelOrientation::FRAME == nRel)
1294  m_xVertLB->set_active(1);
1295  else
1296  m_xVertLB->set_active(0);
1297  bSet = true;
1298  }
1299  else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
1300  {
1301  m_xVertLB->set_active(0);
1302  bSet = true;
1303  }
1304  else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
1305  {
1306  m_xVertLB->set_active(0);
1307  bSet = true;
1308  }
1309  if(bSet)
1310  PosHdl(*m_xVertLB);
1311  }
1312  else
1313  {
1314  if(VertOrientation::TOP == nAlign)
1315  {
1316  if(1 == m_xHoriLB->get_active())
1317  {
1318  m_xHoriLB->set_active(0);
1319  bSet = true;
1320  }
1321  m_xHoriToLB->set_active(1);
1322  }
1323  else if(VertOrientation::CHAR_BOTTOM == nAlign)
1324  {
1325  if(2 == m_xHoriLB->get_active())
1326  {
1327  m_xHoriLB->set_active(0);
1328  bSet = true;
1329  }
1330  m_xHoriToLB->set_active(0) ;
1331  }
1332  if(bSet)
1333  PosHdl(*m_xHoriLB);
1334  }
1335 }
1336 
1338 {
1339  auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
1340  auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
1341  if (m_xKeepRatioCB->get_active())
1342  {
1343  if ( &rEdit == m_xWidthMF.get() )
1344  {
1345  nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
1346  m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1347  }
1348  else if(&rEdit == m_xHeightMF.get())
1349  {
1350  nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
1351  m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1352  }
1353  }
1354  m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1355  UpdateExample();
1356 }
1357 
1359 {
1360  if (m_xSizeCB->get_sensitive())
1361  {
1362  m_nProtectSizeState = m_xSizeCB->get_state();
1363  }
1364 
1365  m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
1366  m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
1367 }
1368 
1370 {
1371  short nRel = 0;
1372  int nPos = rRelationLB.get_active();
1373  if (nPos != -1)
1374  {
1375  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
1376  nRel = pEntry->nRelation;
1377  }
1378 
1379  return nRel;
1380 }
1381 
1382 short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
1383 {
1384  short nAlign = 0;
1385 
1386  // #i22341# - special handling also for map <aVCharMap>,
1387  // because it contains ambiguous items for alignment
1388  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
1389  pMap == aVCharMap )
1390  {
1391  if (rRelationLB.get_active() != -1)
1392  {
1393  LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
1394  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1395  SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1396 
1397  for (std::size_t i = 0; i < nMapCount; i++)
1398  {
1399  if (pMap[i].eStrId == eStrId)
1400  {
1401  LB nLBRelations = pMap[i].nLBRelations;
1402  if (nLBRelations & nRel)
1403  {
1404  nAlign = pMap[i].nAlign;
1405  break;
1406  }
1407  }
1408  }
1409  }
1410  }
1411  else if (pMap)
1412  nAlign = pMap[nMapPos].nAlign;
1413 
1414  return nAlign;
1415 }
1416 
1417 sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
1418 {
1419  sal_uInt16 nMapPos = 0;
1420  int nLBSelPos = rAlignLB.get_active();
1421 
1422  if (nLBSelPos != -1)
1423  {
1424  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1425  {
1426  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1427  OUString sSelEntry(rAlignLB.get_active_text());
1428 
1429  for (std::size_t i = 0; i < nMapCount; i++)
1430  {
1431  SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1432 
1433  OUString sEntry = SvxSwFramePosString::GetString(eResId);
1434 
1435  if (sEntry == sSelEntry)
1436  {
1437  nMapPos = sal::static_int_cast< sal_uInt16 >(i);
1438  break;
1439  }
1440  }
1441  }
1442  else
1443  nMapPos = nLBSelPos;
1444  }
1445 
1446  return nMapPos;
1447 }
1448 
1450  sal_uInt16 nH,
1451  sal_uInt16 nHRel,
1452  sal_uInt16 nV,
1453  sal_uInt16 nVRel,
1454  tools::Long nX,
1455  tools::Long nY)
1456 {
1457  int nPos = m_xVertLB->get_active();
1458  if (nPos != -1 && m_pVMap)
1459  {
1460  m_nOldV = m_pVMap[nPos].nAlign;
1461  nPos = m_xVertToLB->get_active();
1462  if (nPos != -1)
1463  m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
1464  }
1465 
1466  nPos = m_xHoriLB->get_active();
1467  if (nPos != -1 && m_pHMap)
1468  {
1469  m_nOldH = m_pHMap[nPos].nAlign;
1470 
1471  nPos = m_xHoriToLB->get_active();
1472  if (nPos != -1)
1473  m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
1474  }
1475 
1476  bool bEnable = true;
1477  if( m_bIsMultiSelection )
1478  {
1481  }
1482  else if (nAnchor == RndStdIds::FLY_AT_PAGE)
1483  {
1484  m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1485  m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1486  }
1487  else if (nAnchor == RndStdIds::FLY_AT_FLY)
1488  {
1489  // #i18732# - own vertical alignment map for to frame
1490  // anchored objects.
1491  m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1492  m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1493  }
1494  else if (nAnchor == RndStdIds::FLY_AT_PARA)
1495  {
1496  if(m_bHtmlMode)
1497  {
1500  }
1501  else
1502  {
1503  m_pVMap = aVParaMap;
1504  m_pHMap = aHParaMap;
1505  }
1506  }
1507  else if (nAnchor == RndStdIds::FLY_AT_CHAR)
1508  {
1509  if(m_bHtmlMode)
1510  {
1513  }
1514  else
1515  {
1516  m_pVMap = aVCharMap;
1517  m_pHMap = aHCharMap;
1518  }
1519  }
1520  else if (nAnchor == RndStdIds::FLY_AS_CHAR)
1521  {
1522  m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
1523  m_pHMap = nullptr;
1524  bEnable = false;
1525  }
1526  m_xHoriLB->set_sensitive(bEnable);
1527  m_xHoriFT->set_sensitive(bEnable);
1528 
1529  // select current Pos
1530  // horizontal
1531  if ( nH == USHRT_MAX )
1532  {
1533  nH = m_nOldH;
1534  nHRel = m_nOldHRel;
1535  }
1536  // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
1537  sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
1538  FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
1539 
1540  // vertical
1541  if ( nV == USHRT_MAX )
1542  {
1543  nV = m_nOldV;
1544  nVRel = m_nOldVRel;
1545  }
1546  // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
1547  nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
1548  FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
1549 
1550  // Edits init
1551  bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
1552  if (!bEnable)
1553  {
1554  m_xHoriByMF->set_value(0, FieldUnit::TWIP);
1555  }
1556  else if(m_bIsMultiSelection)
1557  {
1558  m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
1559  }
1560  else
1561  {
1562  if (nX != LONG_MAX)
1563  m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
1564  }
1565  m_xHoriByFT->set_sensitive(bEnable);
1566  m_xHoriByMF->set_sensitive(bEnable);
1567 
1568  bEnable = nV == VertOrientation::NONE;
1569  if ( !bEnable )
1570  {
1571  m_xVertByMF->set_value( 0, FieldUnit::TWIP );
1572  }
1573  else if(m_bIsMultiSelection)
1574  {
1575  m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
1576  }
1577  else
1578  {
1579  if (nAnchor == RndStdIds::FLY_AS_CHAR)
1580  {
1581  if ( nY == LONG_MAX )
1582  nY = 0;
1583  else
1584  nY *= -1;
1585  }
1586  if ( nY != LONG_MAX )
1587  m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
1588  }
1589  m_xVertByFT->set_sensitive( bEnable );
1590  m_xVertByMF->set_sensitive( bEnable );
1591  UpdateExample();
1592 }
1593 
1595 {
1596  int nPos = m_xHoriLB->get_active();
1597  if (m_pHMap && nPos != -1)
1598  {
1599  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
1600  short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1601  short nRel = GetRelation(*m_xHoriToLB);
1602 
1603  m_aExampleWN.SetHAlign(nAlign);
1604  m_aExampleWN.SetHoriRel(nRel);
1605  }
1606 
1607  nPos = m_xVertLB->get_active();
1608  if (m_pVMap && nPos != -1)
1609  {
1610  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1611  sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1612  sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1613 
1614  m_aExampleWN.SetVAlign(nAlign);
1615  m_aExampleWN.SetVertRel(nRel);
1616  }
1617 
1618  // Size
1619  auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1620  auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1621  m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
1622 
1624  m_aExampleWN.Invalidate();
1625 }
1626 
1627 void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
1628  sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
1629 {
1630  OUString sSelEntry;
1631  LB nLBRelations = LB::NONE;
1632  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1633 
1634  rLB.clear();
1635 
1636  if (nMapPos < nMapCount)
1637  {
1638  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1639  {
1640  OUString sOldEntry(rLB.get_active_text());
1641  SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1642 
1643  for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
1644  {
1645  if (pMap[_nMapPos].eStrId == eStrId)
1646  {
1647  nLBRelations = pMap[_nMapPos].nLBRelations;
1648  for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
1649  {
1650  if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
1651  {
1652  SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
1653 
1655  OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1656  rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
1657  if (pMap[_nMapPos].nAlign == nAlign)
1658  sSelEntry = sEntry;
1659  break;
1660  }
1661  }
1662  }
1663  }
1664  if (!sSelEntry.isEmpty())
1665  rLB.set_active_text(sSelEntry);
1666  else
1667  {
1668  rLB.set_active_text(sOldEntry);
1669  if (rLB.get_active() == -1)
1670  {
1671  for (int i = 0; i < rLB.get_count(); i++)
1672  {
1673  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1674  if (pEntry->nLBRelation == LB::RelChar) // Default
1675  {
1676  rLB.set_active(i);
1677  break;
1678  }
1679  }
1680  }
1681  }
1682  }
1683  else
1684  {
1685  // #i22341# - special handling for map <aVCharMap>,
1686  // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1687  if ( pMap == aVCharMap )
1688  {
1689  nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
1690  ( m_xHoriMirrorCB->get_active()
1691  ? pMap[nMapPos].eMirrorStrId
1692  : pMap[nMapPos].eStrId ),
1693  m_xHoriMirrorCB->get_active() );
1694  }
1695  else
1696  {
1697  nLBRelations = pMap[nMapPos].nLBRelations;
1698  }
1699 
1700  for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
1701  {
1702  if (nLBRelations & static_cast<LB>(nBit))
1703  {
1704  for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
1705  {
1706  if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
1707  {
1708  SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
1710  OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1711  rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
1712  if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
1713  sSelEntry = sEntry;
1714  }
1715  }
1716  }
1717  }
1718  if (!sSelEntry.isEmpty())
1719  rLB.set_active_text(sSelEntry);
1720  else
1721  {
1722  // Probably anchor change. So look for a similar relation.
1723  switch (nRel)
1724  {
1725  case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
1726  case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
1727  case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
1728  case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
1729  case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
1730  case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
1731  case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
1732  case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
1733 
1734  default:
1735  if (rLB.get_count())
1736  {
1737  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
1738  nRel = pEntry->nRelation;
1739  }
1740  break;
1741  }
1742 
1743  for (int i = 0; i < rLB.get_count(); ++i)
1744  {
1745  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1746  if (pEntry->nRelation == nRel)
1747  {
1748  rLB.set_active(i);
1749  break;
1750  }
1751  }
1752 
1753  if (rLB.get_active() == -1)
1754  rLB.set_active(0);
1755  }
1756  }
1757  }
1758 
1759  rLB.set_sensitive(rLB.get_count() != 0);
1760  rFT.set_sensitive(rLB.get_count() != 0);
1761 
1762  RelHdl(rLB);
1763 }
1764 
1765 sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
1766  sal_uInt16 _nAlign,
1767  const sal_uInt16 _nRel,
1768  weld::ComboBox& _rLB)
1769 {
1770  OUString sSelEntry, sOldEntry;
1771  sOldEntry = _rLB.get_active_text();
1772 
1773  _rLB.clear();
1774 
1775  // #i22341# - determine all possible listbox relations for
1776  // given relation for map <aVCharMap>
1777  const LB nLBRelations = (_pMap != aVCharMap)
1778  ? LB::NONE
1779  : ::lcl_GetLBRelationsForRelations( _nRel );
1780 
1781  // fill listbox
1782  std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
1783  for (std::size_t i = 0; _pMap && i < nCount; ++i)
1784  {
1785  SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1787  OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1788  if (_rLB.find_text(sEntry) == -1)
1789  {
1790  // don't insert duplicate entries at character wrapped borders
1791  _rLB.append_text(sEntry);
1792  }
1793  // #i22341# - add condition to handle map <aVCharMap>
1794  // that is ambiguous in the alignment.
1795  if ( _pMap[i].nAlign == _nAlign &&
1796  ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
1797  {
1798  sSelEntry = sEntry;
1799  }
1800  }
1801 
1802  _rLB.set_active_text(sSelEntry);
1803  if (_rLB.get_active() == -1)
1804  _rLB.set_active_text(sOldEntry);
1805 
1806  if (_rLB.get_active() == -1)
1807  _rLB.set_active(0);
1808 
1809  PosHdl(_rLB);
1810 
1811  return GetMapPos(_pMap, _rLB);
1812 }
1813 
1814 void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
1815 {
1816  m_pSdrView = pSdrView;
1817  if(!m_pSdrView)
1818  {
1819  OSL_FAIL("No SdrView* set");
1820  return;
1821  }
1822 
1823  // setting of the rectangle and the working area
1826 
1827  // get WorkArea
1829 
1830  // consider anchor position (for Writer)
1831  const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
1832  if( rMarkList.GetMarkCount() > 0 )
1833  {
1834  const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1835  m_aAnchorPos = pObj->GetAnchorPos();
1836 
1837  if( m_aAnchorPos != Point(0,0) ) // -> Writer
1838  {
1839  for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
1840  {
1841  pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
1842  if( m_aAnchorPos != pObj->GetAnchorPos() )
1843  {
1844  // different anchor positions -> disable positioning
1845  m_xPosFrame->set_sensitive(false);
1846  m_bPositioningDisabled = true;
1847  return;
1848  }
1849  }
1850  }
1851  Point aPt = m_aAnchorPos * -1;
1852  Point aPt2 = aPt;
1853 
1854  aPt += m_aWorkArea.TopLeft();
1855  m_aWorkArea.SetPos( aPt );
1856 
1857  aPt2 += m_aRect.TopLeft();
1858  m_aRect.SetPos( aPt2 );
1859  }
1860 
1861  // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
1862  if( rMarkList.GetMarkCount() != 1 )
1863  m_bIsMultiSelection = true;
1864 #if OSL_DEBUG_LEVEL > 1
1865  else
1866  {
1867  const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1868  SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
1869  if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
1870  ( eKind==OBJ_TEXT || eKind==OBJ_TITLETEXT || eKind==OBJ_OUTLINETEXT) &&
1871  pObj->HasText() )
1872  {
1873  OSL_FAIL("AutoWidth/AutoHeight should be enabled");
1874  }
1875  }
1876 #endif
1877 }
1878 
1879 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool FillItemSet(SfxItemSet *) override
SvxSwFramePosString::StringId eMirrorStrId
void SetPos(const Point &rPoint)
void SetFieldUnit(weld::MetricSpinButton &rField, FieldUnit eUnit, bool bAll)
sal_Int32 GetValue() const
FieldUnit
sal_Int32 nIndex
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *)
std::unique_ptr< weld::Label > m_xVertByFT
size_t GetMarkCount() const
::tools::Rectangle m_aWorkArea
static sal_uInt16 GetMapPos(FrmMap const *pMap, const weld::ComboBox &rAlignLB)
static FrmMap aHCharHtmlAbsMap[]
static constexpr auto Items
std::string GetValue
FrmMap const aHMultiSelectionMap[]
FrmMap const aHFlyHtmlMap[]
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
constexpr tools::Long Left() const
RelationMap const aRelationMap[]
sal_uIntPtr sal_uLong
long Long
FrmMap const aHPageHtmlMap[]
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
virtual bool HasText() const
virtual int find_text(const OUString &rStr) const =0
void InvalidateItem(sal_uInt16 nWhich)
sal_Int16 nId
static LB lcl_GetLBRelationsForStrID(const FrmMap *_pMap, const SvxSwFramePosString::StringId _eStrId, const bool _bUseMirrorStr)
std::unique_ptr< weld::CheckButton > m_xPositionCB
SdrMark * GetMark(size_t nNum) const
std::unique_ptr< weld::RadioButton > m_xToFrameRB
void append(const OUString &rId, const OUString &rStr)
sal_uInt16 FillPosLB(FrmMap const *pMap, sal_uInt16 nAlign, const sal_uInt16 _nRel, weld::ComboBox &rLB)
virtual OUString get_active_id() const =0
FrmMap const aVCharHtmlAbsMap[]
virtual SdrObjKind GetObjIdentifier() const
std::unique_ptr< weld::CheckButton > m_xKeepRatioCB
virtual int get_active() const =0
FrmMap const aVParaMap[]
TRISTATE_TRUE
SdrObjKind
static const SfxPoolItem * GetItem(const SfxItemSet &rSet, sal_uInt16 nSlot, bool bDeep=true)
virtual int get_count() const =0
FrmMap const aHParaHtmlMap[]
std::unique_ptr< weld::Widget > m_xPosFrame
FieldUnit GetModuleFieldUnit(const SfxItemSet &rSet)
static WhichRangesContainer GetRanges()
NONE
std::unique_ptr< weld::Label > m_xVertFT
std::unique_ptr< weld::Label > m_xHoriByFT
HashMap_OWString_Interface aMap
void LogicToPagePos(Point &rPnt) const
void SetVertRel(short nR)
LB
std::unique_ptr< weld::MetricSpinButton > m_xVertByMF
#define VERT_FRAME_REL
std::unique_ptr< weld::CheckButton > m_xHoriMirrorCB
std::unique_ptr< weld::RadioButton > m_xToPageRB
void SetExchangeSupport()
int nCount
std::unique_ptr< weld::ComboBox > m_xHoriToLB
static OUString GetString(StringId eId)
constexpr auto HORI_PAGE_REL
void SetVAlign(short nV)
std::unique_ptr< weld::ComboBox > m_xVertToLB
const SfxItemSet & GetItemSet() const
#define SAL_N_ELEMENTS(arr)
SvxSwFramePosString::StringId eStrId
SdrObject * GetMarkedSdrObj() const
static std::size_t lcl_GetFrmMapCount(const FrmMap *pMap)
SwFrameExample m_aExampleWN
FrmMap const aVMultiSelectionMap[]
constexpr auto VERT_PARA_REL
void set_active_text(const OUString &rStr)
FrmMap const * m_pVMap
FrmMap const aVPageHtmlMap[]
sal_Int16 GetValue() const
std::unique_ptr< weld::CheckButton > m_xSizeCB
static FrmMap aVCharMap[]
int i
static LB lcl_GetLBRelationsForRelations(const sal_uInt16 _nRel)
std::unique_ptr< weld::CheckButton > m_xFollowCB
constexpr auto HORI_CHAR_REL
static FrmMap aHCharMap[]
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
TRISTATE_FALSE
const SdrMarkList & GetMarkedObjectList() const
FrmMap const aHParaHtmlAbsMap[]
HTMLMODE_ON
virtual void Reset(const SfxItemSet *) override
RelationMap const aAsCharRelationMap[]
std::unique_ptr< weld::Label > m_xHoriToFT
constexpr tools::Long Top() const
void SetHAlign(short nH)
std::unique_ptr< weld::ComboBox > m_xVertLB
FrmMap const aHParaMap[]
virtual void set_active(int pos)=0
std::unique_ptr< weld::RadioButton > m_xAsCharRB
virtual void clear()=0
std::unique_ptr< weld::MetricSpinButton > m_xWidthMF
constexpr auto HORI_PARA_REL
std::unique_ptr< weld::MetricSpinButton > m_xHoriByMF
void SetAnchor(RndStdIds nA)
const tools::Rectangle & GetAllMarkedRect() const
const long LONG_MAX
virtual SdrInventor GetObjInventor() const
constexpr Point TopLeft() const
std::unique_ptr< weld::Label > m_xVertToFT
::tools::Rectangle m_aRect
FrmMap const aHFrameMap[]
std::unique_ptr< weld::ComboBox > m_xHoriLB
static short GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox &rRelationLB)
RndStdIds GetAnchorType(bool *pbHasChanged=nullptr)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
FrmMap const aVCharHtmlMap[]
IMPL_LINK(SvxSwPosSizeTabPage, RelHdl, weld::ComboBox &, rLB, void)
weld::Entry & rEdit
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
FrmMap const aVPageMap[]
static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
const SdrView * m_pSdrView
FRAME
SvxAnchorIds
FrmMap const aVAsCharMap[]
#define HTML_HORI_PARA_REL
bool get_state_changed_from_saved() const
void SetHoriRel(short nR)
FrmMap const aVParaHtmlMap[]
#define HTML_HORI_CHAR_REL
virtual OUString get_id(int pos) const =0
static short GetRelation(const weld::ComboBox &rRelationLB)
const Point & GetAnchorPos() const
OBJ_TITLETEXT
SvxSwPosSizeTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rInAttrs)
void SetRelPos(const Point &rP)
SdrPageView * GetSdrPageView() const
std::unique_ptr< weld::MetricSpinButton > m_xHeightMF
void InitPos(RndStdIds nAnchorType, sal_uInt16 nH, sal_uInt16 nHRel, sal_uInt16 nV, sal_uInt16 nVRel, tools::Long nX, tools::Long nY)
DeactivateRC
constexpr auto VERT_CHAR_REL
std::unique_ptr< weld::RadioButton > m_xToCharRB
FrmMap const * m_pHMap
void append_text(const OUString &rStr)
RndStdIds
FrmMap const aVAsCharHtmlMap[]
static FrmMap aHCharHtmlMap[]
std::unique_ptr< weld::RadioButton > m_xToParaRB
constexpr auto HORI_FRAME_REL
void EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
OBJ_OUTLINETEXT
FrmMap const aVFlyHtmlMap[]
OBJ_TEXT
const tools::Rectangle & GetWorkArea() const
void FillRelLB(FrmMap const *pMap, sal_uInt16 nLBSelPos, sal_uInt16 nAlign, sal_uInt16 nRel, weld::ComboBox &rLB, weld::Label &rFT)
#define VERT_PAGE_REL
virtual ~SvxSwPosSizeTabPage() override
FrmMap const aVFrameMap[]
std::unique_ptr< weld::Label > m_xHoriFT
sal_uInt16 nPos
virtual void set_sensitive(bool sensitive)=0
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
const sal_uInt32 TOP
virtual OUString get_active_text() const =0
IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::Toggleable &, void)
void SetView(const SdrView *pSdrView)
FrmMap const aHPageMap[]