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