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