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  return 0;
384 
385  if( pMap == aVParaHtmlMap )
386  return SAL_N_ELEMENTS(aVParaHtmlMap);
387  if( pMap == aVAsCharHtmlMap )
388  return SAL_N_ELEMENTS( aVAsCharHtmlMap );
389  if( pMap == aHParaHtmlMap )
390  return SAL_N_ELEMENTS( aHParaHtmlMap );
391  if( pMap == aHParaHtmlAbsMap )
392  return SAL_N_ELEMENTS( aHParaHtmlAbsMap );
393  if( pMap == aVPageMap )
394  return SAL_N_ELEMENTS( aVPageMap );
395  if( pMap == aVPageHtmlMap )
396  return SAL_N_ELEMENTS( aVPageHtmlMap );
397  if( pMap == aVAsCharMap )
398  return SAL_N_ELEMENTS( aVAsCharMap );
399  if( pMap == aVParaMap )
400  return SAL_N_ELEMENTS( aVParaMap );
401  if( pMap == aHParaMap )
402  return SAL_N_ELEMENTS( aHParaMap );
403  if( pMap == aHFrameMap )
404  return SAL_N_ELEMENTS( aHFrameMap );
405  if( pMap == aVFrameMap )
406  return SAL_N_ELEMENTS( aVFrameMap );
407  if( pMap == aHCharMap )
408  return SAL_N_ELEMENTS( aHCharMap );
409  if( pMap == aHCharHtmlMap )
410  return SAL_N_ELEMENTS( aHCharHtmlMap );
411  if( pMap == aHCharHtmlAbsMap )
412  return SAL_N_ELEMENTS( aHCharHtmlAbsMap );
413  if( pMap == aVCharMap )
414  return SAL_N_ELEMENTS( aVCharMap );
415  if( pMap == aVCharHtmlMap )
416  return SAL_N_ELEMENTS( aVCharHtmlMap );
417  if( pMap == aVCharHtmlAbsMap )
418  return SAL_N_ELEMENTS( aVCharHtmlAbsMap );
419  if( pMap == aHPageHtmlMap )
420  return SAL_N_ELEMENTS( aHPageHtmlMap );
421  if( pMap == aHFlyHtmlMap )
422  return SAL_N_ELEMENTS( aHFlyHtmlMap );
423  if( pMap == aVFlyHtmlMap )
424  return SAL_N_ELEMENTS( aVFlyHtmlMap );
425  if( pMap == aVMultiSelectionMap )
426  return SAL_N_ELEMENTS( aVMultiSelectionMap );
427  if( pMap == aHMultiSelectionMap )
428  return SAL_N_ELEMENTS( aHMultiSelectionMap );
429  return SAL_N_ELEMENTS(aHPageMap);
430 }
431 
433  SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
434 {
435  //special handling of STR_FROMLEFT
436  if(SvxSwFramePosString::FROMLEFT == eStringId)
437  {
438  eStringId = bVertical ?
441  return eStringId;
442  }
443  if(bVertical)
444  {
445  //exchange horizontal strings with vertical strings and vice versa
446  static const StringIdPair_Impl aHoriIds[] =
447  {
456  };
457  static const StringIdPair_Impl aVertIds[] =
458  {
467  };
468  for(const auto &a : aHoriIds)
469  {
470  if(a.eHori == eStringId)
471  {
472  eStringId = a.eVert;
473  return eStringId;
474  }
475  }
476  for(const auto &a : aVertIds)
477  {
478  if(a.eHori == eStringId)
479  {
480  eStringId = a.eVert;
481  break;
482  }
483  }
484  }
485  return eStringId;
486 }
487 // #i22341# - helper method in order to determine all possible
488 // listbox relations in a relation map for a given relation
489 static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
490 {
491  LB nLBRelations = LB::NONE;
492 
493  for (RelationMap const & nRelMapPos : aRelationMap)
494  {
495  if ( nRelMapPos.nRelation == _nRel )
496  {
497  nLBRelations |= nRelMapPos.nLBRelation;
498  }
499  }
500 
501  return nLBRelations;
502 }
503 
504 // #i22341# - helper method on order to determine all possible
505 // listbox relations in a relation map for a given string ID
507  const SvxSwFramePosString::StringId _eStrId,
508  const bool _bUseMirrorStr )
509 {
510  LB nLBRelations = LB::NONE;
511 
512  std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
513  for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
514  {
515  if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
516  ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
517  {
518  nLBRelations |= _pMap[nRelMapPos].nLBRelations;
519  }
520  }
521 
522  return nLBRelations;
523 }
524 
526  : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
527  , m_pVMap(nullptr)
528  , m_pHMap(nullptr)
529  , m_pSdrView(nullptr)
530  , m_nOldH(HoriOrientation::CENTER)
531  , m_nOldHRel(RelOrientation::FRAME)
532  , m_nOldV(VertOrientation::TOP)
533  , m_nOldVRel(RelOrientation::PRINT_AREA)
534  , m_fWidthHeightRatio(1.0)
535  , m_bHtmlMode(false)
536  , m_bIsVerticalFrame(false)
537  , m_bPositioningDisabled(false)
538  , m_bIsMultiSelection(false)
539  , m_bIsInRightToLeft(false)
540  , m_nProtectSizeState(TRISTATE_FALSE)
541  , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
542  , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
543  , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
544  , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
545  , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
546  , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
547  , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
548  , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
549  , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
550  , m_xSizeCB(m_xBuilder->weld_check_button("size"))
551  , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
552  , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
553  , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
554  , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
555  , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
556  , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
557  , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
558  , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
559  , m_xVertFT(m_xBuilder->weld_label("vertposft"))
560  , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
561  , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
562  , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
563  , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
564  , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
565  , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
566  , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
567 {
570 
571  FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
572  SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
573  SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
574  SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
575  SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
576 
578 
579  Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
580  m_xWidthMF->connect_focus_out(aLk3);
581  m_xHeightMF->connect_focus_out(aLk3);
582  m_xHoriByMF->connect_focus_out(aLk3);
583  m_xVertByMF->connect_focus_out(aLk3);
584  m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
585 
587  m_xWidthMF->connect_value_changed( aLk );
588  m_xHeightMF->connect_value_changed( aLk );
589  m_xHoriByMF->connect_value_changed( aLk );
590  m_xVertByMF->connect_value_changed( aLk );
591 
592  Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
593  m_xToPageRB->connect_toggled( aLk2 );
594  m_xToParaRB->connect_toggled( aLk2 );
595  m_xToCharRB->connect_toggled( aLk2 );
596  m_xAsCharRB->connect_toggled( aLk2 );
597  m_xToFrameRB->connect_toggled( aLk2 );
598 
599  m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
600  m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
601 
602  m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
603  m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
604 
605  m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
606  m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
607 }
608 
610 {
611  m_xWidthMF.reset();
612  m_xHeightMF.reset();
613  m_xHoriByMF.reset();
614  m_xVertByMF.reset();
615 }
616 
617 namespace
618 {
619  struct FrmMaps
620  {
621  FrmMap const *pMap;
622  size_t nCount;
623  };
624 }
625 
627 {
628  static const FrmMaps aMaps[] = {
629  { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
630  { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
631  { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
632  { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
633  { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
634  { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
635  { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
636  { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
637  { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
638  { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
639  { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
640  { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
641  { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
642  { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
643  { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
644  { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
645  { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
646  { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
647  { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
648  { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
649  { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
650  };
651 
652  std::vector<SvxSwFramePosString::StringId> aFrames;
653  for (const FrmMaps& aMap : aMaps)
654  {
655  for (size_t j = 0; j < aMap.nCount; ++j)
656  {
657  aFrames.push_back(aMap.pMap[j].eStrId);
658  aFrames.push_back(aMap.pMap[j].eMirrorStrId);
659  }
660  }
661 
662  std::sort(aFrames.begin(), aFrames.end());
663  aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
664 
665  for (auto const& frame : aFrames)
666  {
668  }
669 
670  Size aBiggest(m_xHoriLB->get_preferred_size());
671  m_xHoriLB->set_size_request(aBiggest.Width(), -1);
672  m_xVertLB->set_size_request(aBiggest.Width(), -1);
673  m_xHoriLB->clear();
674 }
675 
676 namespace
677 {
678  struct RelationMaps
679  {
680  RelationMap const *pMap;
681  size_t nCount;
682  };
683 }
684 
686 {
687  static const RelationMaps aMaps[] = {
688  { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
689  { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
690  };
691 
692  std::vector<SvxSwFramePosString::StringId> aRels;
693  for (const RelationMaps& aMap : aMaps)
694  {
695  for (size_t j = 0; j < aMap.nCount; ++j)
696  {
697  aRels.push_back(aMap.pMap[j].eStrId);
698  aRels.push_back(aMap.pMap[j].eMirrorStrId);
699  }
700  }
701 
702  std::sort(aRels.begin(), aRels.end());
703  aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
704 
705  for (auto const& elem : aRels)
706  {
707  m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
708  }
709 
710  Size aBiggest(m_xHoriLB->get_preferred_size());
711  m_xHoriLB->set_size_request(aBiggest.Width(), -1);
712  m_xVertLB->set_size_request(aBiggest.Width(), -1);
713  m_xHoriLB->clear();
714 }
715 
716 std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
717 {
718  return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
719 }
720 
722 {
723  static const WhichRangesContainer ranges(svl::Items<
724  SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
725  SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
726  SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
727  SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
728  SID_HTML_MODE, SID_HTML_MODE,
729  SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
730  SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
731  >);
732  return ranges;
733 }
734 
736 {
737  bool bAnchorChanged = false;
738  RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
739  bool bModified = false;
740  if(bAnchorChanged)
741  {
742  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
743  bModified = true;
744  }
745  if (m_xPositionCB->get_state_changed_from_saved())
746  {
747  if (m_xPositionCB->get_inconsistent())
748  rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
749  else
750  rSet->Put(
751  SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
752  m_xPositionCB->get_state() == TRISTATE_TRUE ) );
753  bModified = true;
754  }
755 
756  if (m_xSizeCB->get_state_changed_from_saved())
757  {
758  if (m_xSizeCB->get_inconsistent())
759  rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
760  else
761  rSet->Put(
762  SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
763  m_xSizeCB->get_state() == TRISTATE_TRUE ) );
764  bModified = true;
765  }
766 
767  const SfxItemSet& rOldSet = GetItemSet();
768 
770  {
771  //on multiple selections the positioning is set via SdrView
773  {
774  if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
775  {
776  auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
777  auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
778 
779  // old rectangle with CoreUnit
782 
783  nHoriByPos += m_aAnchorPos.X();
784  nVertByPos += m_aAnchorPos.Y();
785 
786  rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
787  rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
788 
789  bModified = true;
790  }
791  }
792  else
793  {
794  if ( m_pHMap )
795  {
796  const SfxInt16Item& rHoriOrient =
797  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
798  const SfxInt16Item& rHoriRelation =
799  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
800  const SfxInt32Item& rHoriPosition =
801  static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
802 
803  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
804  short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
805  short nRel = GetRelation(*m_xHoriToLB);
806  const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
807  if (
808  nAlign != rHoriOrient.GetValue() ||
809  nRel != rHoriRelation.GetValue() ||
810  (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
811  )
812  {
813  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
814  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
815  if(m_xHoriByMF->get_sensitive())
816  rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
817  bModified = true;
818  }
819  }
820  if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
821  bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
822 
823  if ( m_pVMap )
824  {
825  const SfxInt16Item& rVertOrient =
826  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
827  const SfxInt16Item& rVertRelation =
828  static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
829  const SfxInt32Item& rVertPosition =
830  static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
831 
832  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
833  short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
834  short nRel = GetRelation(*m_xVertToLB);
835  // #i34055# - convert vertical position for
836  // as-character anchored objects
837  auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
838  if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
839  {
840  nVertByPos *= -1;
841  }
842  if ( nAlign != rVertOrient.GetValue() ||
843  nRel != rVertRelation.GetValue() ||
844  ( m_xVertByMF->get_sensitive() &&
845  nVertByPos != rVertPosition.GetValue() ) )
846  {
847  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
848  rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
849  if(m_xVertByMF->get_sensitive())
850  rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
851  bModified = true;
852  }
853  }
854 
855  // #i18732#
856  if (m_xFollowCB->get_state_changed_from_saved())
857  {
858  //Writer internal type - based on SfxBoolItem
859  const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
860  if(pItem)
861  {
862  std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
863  pFollow->SetValue(m_xFollowCB->get_active());
864  bModified |= nullptr != rSet->Put(*pFollow);
865  }
866  }
867  }
868  }
869  if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
870  {
871  sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
872  sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
873  rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
874  rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
875  //this item is required by SdrEditView::SetGeoAttrToMarked()
876  rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
877 
878  bModified = true;
879  }
880 
881  return bModified;
882 }
883 
885 {
886  const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
887  bool bInvalidateAnchor = false;
888  RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
889  if(pItem)
890  {
891  nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
892  switch(nAnchorType)
893  {
894  case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
895  case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
896  case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
897  case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
898  case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
899  default : bInvalidateAnchor = true;
900  }
901  m_xToPageRB->save_state();
902  m_xToParaRB->save_state();
903  m_xToCharRB->save_state();
904  m_xAsCharRB->save_state();
905  m_xToFrameRB->save_state();
906  }
907  if (bInvalidateAnchor)
908  {
909  m_xToPageRB->set_sensitive( false );
910  m_xToParaRB->set_sensitive( false );
911  m_xToCharRB->set_sensitive( false );
912  m_xAsCharRB->set_sensitive( false );
913  m_xToFrameRB->set_sensitive( false );
914  }
915 
916  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
917  if (pItem)
918  {
919  bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
920  m_xPositionCB->set_active(bProtected);
921  m_xSizeCB->set_sensitive(!bProtected);
922  }
923  else
924  {
925  m_xPositionCB->set_inconsistent(true);
926  }
927 
928  m_xPositionCB->save_state();
929 
930  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
931 
932  if (pItem)
933  {
934  m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
935  }
936  else
937  m_xSizeCB->set_inconsistent(true);
938  m_xSizeCB->save_state();
939 
940  pItem = GetItem( *rSet, SID_HTML_MODE );
941  if(pItem)
942  {
943  m_bHtmlMode =
944  (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
945  != 0;
946  }
947 
948  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
949  if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
950  {
951  OUString sHLabel = m_xHoriFT->get_label();
952  m_xHoriFT->set_label(m_xVertFT->get_label());
953  m_xVertFT->set_label(sHLabel);
954  m_bIsVerticalFrame = true;
955  }
956  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
957  if(pItem)
958  m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
959 
960  pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
961  if(pItem)
962  {
963  const bool bFollowTextFlow =
964  static_cast<const SfxBoolItem*>(pItem)->GetValue();
965  m_xFollowCB->set_active(bFollowTextFlow);
966  }
967  m_xFollowCB->save_state();
968 
969  if(m_bHtmlMode)
970  {
971  m_xHoriMirrorCB->hide();
972  m_xKeepRatioCB->set_sensitive(false);
973  // #i18732# - hide checkbox in HTML mode
974  m_xFollowCB->hide();
975  }
976  else
977  {
978  // #i18732# correct enable/disable of check box 'Mirror on..'
979  m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
980 
981  // #i18732# - enable/disable check box 'Follow text flow'.
982  m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
983  m_xToCharRB->get_active());
984  }
985 
986  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
987  sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
988 
989  m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
990  m_xWidthMF->save_value();
991 
992  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
993  sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
994  m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
995  m_xHeightMF->save_value();
996  m_fWidthHeightRatio = double(nWidth) / double(nHeight);
997 
999  return;
1000 
1001  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
1002  if(pItem)
1003  {
1004  short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1005  m_nOldH = nHoriOrientation;
1006  }
1007  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
1008  if(pItem)
1009  {
1010  short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1011  m_nOldV = nVertOrientation;
1012  }
1013  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
1014  if(pItem)
1015  {
1016  m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1017  }
1018 
1019  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
1020  if(pItem)
1021  {
1022  m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1023  }
1024  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
1025  if(pItem)
1026  m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1027  m_xHoriMirrorCB->save_state();
1028 
1029  sal_Int32 nHoriPos = 0;
1030  sal_Int32 nVertPos = 0;
1031  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
1032  if(pItem)
1033  nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1034  pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
1035  if(pItem)
1036  nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1037 
1038  InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
1039 
1040  m_xVertByMF->save_value();
1041  m_xHoriByMF->save_value();
1042  // #i18732#
1043  m_xFollowCB->save_state();
1044 
1045  RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
1046 }
1047 
1049 {
1050  if( _pSet )
1051  {
1052  _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
1053  m_xPositionCB->get_active()));
1054  _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
1055  m_xSizeCB->get_active()));
1056  FillItemSet( _pSet );
1057  }
1058  return DeactivateRC::LeavePage;
1059 }
1060 
1062 {
1063  if (nAnchorEnable & SvxAnchorIds::Fly)
1064  m_xToFrameRB->show();
1065  if (!(nAnchorEnable & SvxAnchorIds::Page))
1066  m_xToPageRB->set_sensitive(false);
1067 }
1068 
1070 {
1071  RndStdIds nRet = RndStdIds::UNKNOWN;
1072  weld::RadioButton* pCheckedButton = nullptr;
1073  if(m_xToParaRB->get_sensitive())
1074  {
1075  if(m_xToPageRB->get_active())
1076  {
1077  nRet = RndStdIds::FLY_AT_PAGE;
1078  pCheckedButton = m_xToPageRB.get();
1079  }
1080  else if(m_xToParaRB->get_active())
1081  {
1082  nRet = RndStdIds::FLY_AT_PARA;
1083  pCheckedButton = m_xToParaRB.get();
1084  }
1085  else if(m_xToCharRB->get_active())
1086  {
1087  nRet = RndStdIds::FLY_AT_CHAR;
1088  pCheckedButton = m_xToCharRB.get();
1089  }
1090  else if(m_xAsCharRB->get_active())
1091  {
1092  nRet = RndStdIds::FLY_AS_CHAR;
1093  pCheckedButton = m_xAsCharRB.get();
1094  }
1095  else if(m_xToFrameRB->get_active())
1096  {
1097  nRet = RndStdIds::FLY_AT_FLY;
1098  pCheckedButton = m_xToFrameRB.get();
1099  }
1100  }
1101  if(pbHasChanged)
1102  {
1103  if(pCheckedButton)
1104  *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
1105  else
1106  *pbHasChanged = false;
1107  }
1108  return nRet;
1109 }
1110 
1112 {
1113  RangeModifyHdl(m_xWidthMF->get_widget());
1114 }
1115 
1117 {
1118  if (m_bPositioningDisabled)
1119  return;
1120  SvxSwFrameValidation aVal;
1121 
1122  aVal.nAnchorType = GetAnchorType();
1123  aVal.bAutoHeight = false;
1124  aVal.bMirror = m_xHoriMirrorCB->get_active();
1125  // #i18732#
1126  aVal.bFollowTextFlow = m_xFollowCB->get_active();
1127 
1128  if ( m_pHMap )
1129  {
1130  // horizontal alignment
1131  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
1132  sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1133  sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1134 
1135  aVal.nHoriOrient = static_cast<short>(nAlign);
1136  aVal.nHRelOrient = static_cast<short>(nRel);
1137  }
1138  else
1139  aVal.nHoriOrient = HoriOrientation::NONE;
1140 
1141  if ( m_pVMap )
1142  {
1143  // vertical alignment
1144  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1145  sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1146  sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1147 
1148  aVal.nVertOrient = static_cast<short>(nAlign);
1149  aVal.nVRelOrient = static_cast<short>(nRel);
1150  }
1151  else
1152  aVal.nVertOrient = VertOrientation::NONE;
1153 
1154  const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1155  const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1156 
1157  aVal.nHPos = nAtHorzPosVal;
1158  aVal.nVPos = nAtVertPosVal;
1159 
1160  sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
1161  sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
1162  aVal.nWidth = nWidth;
1163  aVal.nHeight = nHeight;
1164 
1165  m_aValidateLink.Call(aVal);
1166 
1167  // minimum width also for style
1168  m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
1169  m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
1170 
1171  sal_Int32 nMaxWidth(aVal.nMaxWidth);
1172  sal_Int32 nMaxHeight(aVal.nMaxHeight);
1173 
1174  sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
1175  m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
1176 
1177  nTmp = m_xWidthMF->normalize(nMaxWidth);
1178  m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
1179 
1180  m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
1181  m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
1182  if ( aVal.nHPos != nAtHorzPosVal )
1183  m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
1184 
1185  m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
1186  m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
1187  if ( aVal.nVPos != nAtVertPosVal )
1188  m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
1189 }
1190 
1192 {
1193  m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
1194 
1195  // #i18732# - enable check box 'Follow text flow' for anchor
1196  // type to-paragraph' and to-character
1197  m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
1198 
1199  RndStdIds nId = GetAnchorType();
1200 
1201  InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1202  RangeModifyHdl(m_xWidthMF->get_widget());
1203 
1204  if(m_bHtmlMode)
1205  {
1206  PosHdl(*m_xHoriLB);
1207  PosHdl(*m_xVertLB);
1208  }
1209 }
1210 
1212 {
1213  RndStdIds nId = GetAnchorType();
1214  InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1215 }
1216 
1218 {
1219  bool bHori = &rLB == m_xHoriToLB.get();
1220 
1221  UpdateExample();
1222 
1223  if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
1224  {
1225  if(bHori)
1226  {
1227  sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1228  if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
1229  {
1230  m_xVertLB->set_active(1);
1231  }
1232  else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
1233  {
1234  m_xVertLB->set_active(0);
1235  }
1236  }
1237  }
1238  RangeModifyHdl(m_xWidthMF->get_widget());
1239 }
1240 
1242 {
1243  bool bHori = &rLB == m_xHoriLB.get();
1244  weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
1245  weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
1246  FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
1247 
1248 
1249  sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
1250  sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1251 
1252  if (bHori)
1253  {
1254  bool bEnable = HoriOrientation::NONE == nAlign;
1255  m_xHoriByMF->set_sensitive( bEnable );
1256  m_xHoriByFT->set_sensitive( bEnable );
1257  }
1258  else
1259  {
1260  bool bEnable = VertOrientation::NONE == nAlign;
1261  m_xVertByMF->set_sensitive( bEnable );
1262  m_xVertByFT->set_sensitive( bEnable );
1263  }
1264 
1265  RangeModifyHdl(m_xWidthMF->get_widget());
1266 
1267  short nRel = 0;
1268  if (rLB.get_active() != -1)
1269  {
1270  if (pRelLB->get_active() != -1)
1271  nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
1272 
1273  FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1274  }
1275  else
1276  pRelLB->clear();
1277 
1278  UpdateExample();
1279 
1280  // special treatment for HTML-Mode with horz-vert-dependencies
1281  if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
1282  return;
1283 
1284  bool bSet = false;
1285  if(bHori)
1286  {
1287  // on the right only below is allowed - from the left only at the top
1288  // from the left at the character -> below
1289  if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
1290  0 == m_xVertLB->get_active())
1291  {
1292  if(RelOrientation::FRAME == nRel)
1293  m_xVertLB->set_active(1);
1294  else
1295  m_xVertLB->set_active(0);
1296  bSet = true;
1297  }
1298  else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
1299  {
1300  m_xVertLB->set_active(0);
1301  bSet = true;
1302  }
1303  else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
1304  {
1305  m_xVertLB->set_active(0);
1306  bSet = true;
1307  }
1308  if(bSet)
1309  PosHdl(*m_xVertLB);
1310  }
1311  else
1312  {
1313  if(VertOrientation::TOP == nAlign)
1314  {
1315  if(1 == m_xHoriLB->get_active())
1316  {
1317  m_xHoriLB->set_active(0);
1318  bSet = true;
1319  }
1320  m_xHoriToLB->set_active(1);
1321  }
1322  else if(VertOrientation::CHAR_BOTTOM == nAlign)
1323  {
1324  if(2 == m_xHoriLB->get_active())
1325  {
1326  m_xHoriLB->set_active(0);
1327  bSet = true;
1328  }
1329  m_xHoriToLB->set_active(0) ;
1330  }
1331  if(bSet)
1332  PosHdl(*m_xHoriLB);
1333  }
1334 }
1335 
1337 {
1338  auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
1339  auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
1340  if (m_xKeepRatioCB->get_active())
1341  {
1342  if ( &rEdit == m_xWidthMF.get() )
1343  {
1344  nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
1345  m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1346  }
1347  else if(&rEdit == m_xHeightMF.get())
1348  {
1349  nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
1350  m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1351  }
1352  }
1353  m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1354  UpdateExample();
1355 }
1356 
1358 {
1359  if (m_xSizeCB->get_sensitive())
1360  {
1361  m_nProtectSizeState = m_xSizeCB->get_state();
1362  }
1363 
1364  m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
1365  m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
1366 }
1367 
1369 {
1370  short nRel = 0;
1371  int nPos = rRelationLB.get_active();
1372  if (nPos != -1)
1373  {
1374  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
1375  nRel = pEntry->nRelation;
1376  }
1377 
1378  return nRel;
1379 }
1380 
1381 short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
1382 {
1383  short nAlign = 0;
1384 
1385  // #i22341# - special handling also for map <aVCharMap>,
1386  // because it contains ambiguous items for alignment
1387  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
1388  pMap == aVCharMap )
1389  {
1390  if (rRelationLB.get_active() != -1)
1391  {
1392  LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
1393  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1394  SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1395 
1396  for (std::size_t i = 0; i < nMapCount; i++)
1397  {
1398  if (pMap[i].eStrId == eStrId)
1399  {
1400  LB nLBRelations = pMap[i].nLBRelations;
1401  if (nLBRelations & nRel)
1402  {
1403  nAlign = pMap[i].nAlign;
1404  break;
1405  }
1406  }
1407  }
1408  }
1409  }
1410  else if (pMap)
1411  nAlign = pMap[nMapPos].nAlign;
1412 
1413  return nAlign;
1414 }
1415 
1416 sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
1417 {
1418  sal_uInt16 nMapPos = 0;
1419  int nLBSelPos = rAlignLB.get_active();
1420 
1421  if (nLBSelPos != -1)
1422  {
1423  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1424  {
1425  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1426  OUString sSelEntry(rAlignLB.get_active_text());
1427 
1428  for (std::size_t i = 0; i < nMapCount; i++)
1429  {
1430  SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1431 
1432  OUString sEntry = SvxSwFramePosString::GetString(eResId);
1433 
1434  if (sEntry == sSelEntry)
1435  {
1436  nMapPos = sal::static_int_cast< sal_uInt16 >(i);
1437  break;
1438  }
1439  }
1440  }
1441  else
1442  nMapPos = nLBSelPos;
1443  }
1444 
1445  return nMapPos;
1446 }
1447 
1449  sal_uInt16 nH,
1450  sal_uInt16 nHRel,
1451  sal_uInt16 nV,
1452  sal_uInt16 nVRel,
1453  tools::Long nX,
1454  tools::Long nY)
1455 {
1456  int nPos = m_xVertLB->get_active();
1457  if (nPos != -1 && m_pVMap)
1458  {
1459  m_nOldV = m_pVMap[nPos].nAlign;
1460  nPos = m_xVertToLB->get_active();
1461  if (nPos != -1)
1462  m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
1463  }
1464 
1465  nPos = m_xHoriLB->get_active();
1466  if (nPos != -1 && m_pHMap)
1467  {
1468  m_nOldH = m_pHMap[nPos].nAlign;
1469 
1470  nPos = m_xHoriToLB->get_active();
1471  if (nPos != -1)
1472  m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
1473  }
1474 
1475  bool bEnable = true;
1476  if( m_bIsMultiSelection )
1477  {
1480  }
1481  else if (nAnchor == RndStdIds::FLY_AT_PAGE)
1482  {
1483  m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1484  m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1485  }
1486  else if (nAnchor == RndStdIds::FLY_AT_FLY)
1487  {
1488  // #i18732# - own vertical alignment map for to frame
1489  // anchored objects.
1490  m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1491  m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1492  }
1493  else if (nAnchor == RndStdIds::FLY_AT_PARA)
1494  {
1495  if(m_bHtmlMode)
1496  {
1499  }
1500  else
1501  {
1502  m_pVMap = aVParaMap;
1503  m_pHMap = aHParaMap;
1504  }
1505  }
1506  else if (nAnchor == RndStdIds::FLY_AT_CHAR)
1507  {
1508  if(m_bHtmlMode)
1509  {
1512  }
1513  else
1514  {
1515  m_pVMap = aVCharMap;
1516  m_pHMap = aHCharMap;
1517  }
1518  }
1519  else if (nAnchor == RndStdIds::FLY_AS_CHAR)
1520  {
1521  m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
1522  m_pHMap = nullptr;
1523  bEnable = false;
1524  }
1525  m_xHoriLB->set_sensitive(bEnable);
1526  m_xHoriFT->set_sensitive(bEnable);
1527 
1528  // select current Pos
1529  // horizontal
1530  if ( nH == USHRT_MAX )
1531  {
1532  nH = m_nOldH;
1533  nHRel = m_nOldHRel;
1534  }
1535  // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
1536  sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
1537  FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
1538 
1539  // vertical
1540  if ( nV == USHRT_MAX )
1541  {
1542  nV = m_nOldV;
1543  nVRel = m_nOldVRel;
1544  }
1545  // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
1546  nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
1547  FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
1548 
1549  // Edits init
1550  bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
1551  if (!bEnable)
1552  {
1553  m_xHoriByMF->set_value(0, FieldUnit::TWIP);
1554  }
1555  else if(m_bIsMultiSelection)
1556  {
1557  m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
1558  }
1559  else
1560  {
1561  if (nX != LONG_MAX)
1562  m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
1563  }
1564  m_xHoriByFT->set_sensitive(bEnable);
1565  m_xHoriByMF->set_sensitive(bEnable);
1566 
1567  bEnable = nV == VertOrientation::NONE;
1568  if ( !bEnable )
1569  {
1570  m_xVertByMF->set_value( 0, FieldUnit::TWIP );
1571  }
1572  else if(m_bIsMultiSelection)
1573  {
1574  m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
1575  }
1576  else
1577  {
1578  if (nAnchor == RndStdIds::FLY_AS_CHAR)
1579  {
1580  if ( nY == LONG_MAX )
1581  nY = 0;
1582  else
1583  nY *= -1;
1584  }
1585  if ( nY != LONG_MAX )
1586  m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
1587  }
1588  m_xVertByFT->set_sensitive( bEnable );
1589  m_xVertByMF->set_sensitive( bEnable );
1590  UpdateExample();
1591 }
1592 
1594 {
1595  int nPos = m_xHoriLB->get_active();
1596  if (m_pHMap && nPos != -1)
1597  {
1598  sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
1599  short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1600  short nRel = GetRelation(*m_xHoriToLB);
1601 
1602  m_aExampleWN.SetHAlign(nAlign);
1603  m_aExampleWN.SetHoriRel(nRel);
1604  }
1605 
1606  nPos = m_xVertLB->get_active();
1607  if (m_pVMap && nPos != -1)
1608  {
1609  sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1610  sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1611  sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1612 
1613  m_aExampleWN.SetVAlign(nAlign);
1614  m_aExampleWN.SetVertRel(nRel);
1615  }
1616 
1617  // Size
1618  auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1619  auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1620  m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
1621 
1623  m_aExampleWN.Invalidate();
1624 }
1625 
1626 void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
1627  sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
1628 {
1629  OUString sSelEntry;
1630  LB nLBRelations = LB::NONE;
1631  std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1632 
1633  rLB.clear();
1634 
1635  if (nMapPos < nMapCount)
1636  {
1637  if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1638  {
1639  OUString sOldEntry(rLB.get_active_text());
1640  SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1641 
1642  for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
1643  {
1644  if (pMap[_nMapPos].eStrId == eStrId)
1645  {
1646  nLBRelations = pMap[_nMapPos].nLBRelations;
1647  for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
1648  {
1649  if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
1650  {
1651  SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
1652 
1654  OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1655  rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
1656  if (pMap[_nMapPos].nAlign == nAlign)
1657  sSelEntry = sEntry;
1658  break;
1659  }
1660  }
1661  }
1662  }
1663  if (!sSelEntry.isEmpty())
1664  rLB.set_active_text(sSelEntry);
1665  else
1666  {
1667  rLB.set_active_text(sOldEntry);
1668  if (rLB.get_active() == -1)
1669  {
1670  for (int i = 0; i < rLB.get_count(); i++)
1671  {
1672  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1673  if (pEntry->nLBRelation == LB::RelChar) // Default
1674  {
1675  rLB.set_active(i);
1676  break;
1677  }
1678  }
1679  }
1680  }
1681  }
1682  else
1683  {
1684  // #i22341# - special handling for map <aVCharMap>,
1685  // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1686  if ( pMap == aVCharMap )
1687  {
1688  nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
1689  ( m_xHoriMirrorCB->get_active()
1690  ? pMap[nMapPos].eMirrorStrId
1691  : pMap[nMapPos].eStrId ),
1692  m_xHoriMirrorCB->get_active() );
1693  }
1694  else
1695  {
1696  nLBRelations = pMap[nMapPos].nLBRelations;
1697  }
1698 
1699  for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
1700  {
1701  if (nLBRelations & static_cast<LB>(nBit))
1702  {
1703  for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
1704  {
1705  if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
1706  {
1707  SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
1709  OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1710  rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
1711  if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
1712  sSelEntry = sEntry;
1713  }
1714  }
1715  }
1716  }
1717  if (!sSelEntry.isEmpty())
1718  rLB.set_active_text(sSelEntry);
1719  else
1720  {
1721  // Probably anchor change. So look for a similar relation.
1722  switch (nRel)
1723  {
1724  case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
1725  case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
1726  case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
1727  case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
1728  case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
1729  case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
1730  case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
1731  case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
1732 
1733  default:
1734  if (rLB.get_count())
1735  {
1736  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
1737  nRel = pEntry->nRelation;
1738  }
1739  break;
1740  }
1741 
1742  for (int i = 0; i < rLB.get_count(); ++i)
1743  {
1744  RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1745  if (pEntry->nRelation == nRel)
1746  {
1747  rLB.set_active(i);
1748  break;
1749  }
1750  }
1751 
1752  if (rLB.get_active() == -1)
1753  rLB.set_active(0);
1754  }
1755  }
1756  }
1757 
1758  rLB.set_sensitive(rLB.get_count() != 0);
1759  rFT.set_sensitive(rLB.get_count() != 0);
1760 
1761  RelHdl(rLB);
1762 }
1763 
1764 sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
1765  sal_uInt16 _nAlign,
1766  const sal_uInt16 _nRel,
1767  weld::ComboBox& _rLB)
1768 {
1769  OUString sSelEntry, sOldEntry;
1770  sOldEntry = _rLB.get_active_text();
1771 
1772  _rLB.clear();
1773 
1774  // #i22341# - determine all possible listbox relations for
1775  // given relation for map <aVCharMap>
1776  const LB nLBRelations = (_pMap != aVCharMap)
1777  ? LB::NONE
1778  : ::lcl_GetLBRelationsForRelations( _nRel );
1779 
1780  // fill listbox
1781  std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
1782  for (std::size_t i = 0; _pMap && i < nCount; ++i)
1783  {
1784  SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1786  OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1787  if (_rLB.find_text(sEntry) == -1)
1788  {
1789  // don't insert duplicate entries at character wrapped borders
1790  _rLB.append_text(sEntry);
1791  }
1792  // #i22341# - add condition to handle map <aVCharMap>
1793  // that is ambiguous in the alignment.
1794  if ( _pMap[i].nAlign == _nAlign &&
1795  ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
1796  {
1797  sSelEntry = sEntry;
1798  }
1799  }
1800 
1801  _rLB.set_active_text(sSelEntry);
1802  if (_rLB.get_active() == -1)
1803  _rLB.set_active_text(sOldEntry);
1804 
1805  if (_rLB.get_active() == -1)
1806  _rLB.set_active(0);
1807 
1808  PosHdl(_rLB);
1809 
1810  return GetMapPos(_pMap, _rLB);
1811 }
1812 
1813 void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
1814 {
1815  m_pSdrView = pSdrView;
1816  if(!m_pSdrView)
1817  {
1818  OSL_FAIL("No SdrView* set");
1819  return;
1820  }
1821 
1822  // setting of the rectangle and the working area
1825 
1826  // get WorkArea
1828 
1829  // consider anchor position (for Writer)
1830  const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
1831  if( rMarkList.GetMarkCount() > 0 )
1832  {
1833  const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1834  m_aAnchorPos = pObj->GetAnchorPos();
1835 
1836  if( m_aAnchorPos != Point(0,0) ) // -> Writer
1837  {
1838  for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
1839  {
1840  pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
1841  if( m_aAnchorPos != pObj->GetAnchorPos() )
1842  {
1843  // different anchor positions -> disable positioning
1844  m_xPosFrame->set_sensitive(false);
1845  m_bPositioningDisabled = true;
1846  return;
1847  }
1848  }
1849  }
1850  Point aPt = m_aAnchorPos * -1;
1851  Point aPt2 = aPt;
1852 
1853  aPt += m_aWorkArea.TopLeft();
1854  m_aWorkArea.SetPos( aPt );
1855 
1856  aPt2 += m_aRect.TopLeft();
1857  m_aRect.SetPos( aPt2 );
1858  }
1859 
1860  // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
1861  if( rMarkList.GetMarkCount() != 1 )
1862  m_bIsMultiSelection = true;
1863 #if OSL_DEBUG_LEVEL > 1
1864  else
1865  {
1866  const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1867  SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
1868  if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
1869  ( eKind==SdrObjKind::Text || eKind==SdrObjKind::TitleText || eKind==SdrObjKind::OutlineText) &&
1870  pObj->HasText() )
1871  {
1872  OSL_FAIL("AutoWidth/AutoHeight should be enabled");
1873  }
1874  }
1875 #endif
1876 }
1877 
1878 /* 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
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
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
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
SdrObjKind
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
virtual tools::Long GetValue() const override
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
uno_Any a
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
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)
FrmMap const aVFlyHtmlMap[]
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[]