connectiviy: fix to detect column data type
[LibreOffice.git] / cui / source / tabpages / swpossizetabpage.cxx
blob5e5352aff4007ef6776c001466b4592130fd9a9d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <cstddef>
22 #include <swpossizetabpage.hxx>
23 #include <svx/dlgutil.hxx>
24 #include <svx/anchorid.hxx>
25 #include <svl/intitem.hxx>
26 #include <svx/swframevalidation.hxx>
27 #include <sfx2/htmlmode.hxx>
28 #include <svx/svdview.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/swframeposstrings.hxx>
31 #include <svx/rectenum.hxx>
32 #include <sal/macros.h>
33 #include <com/sun/star/text/HoriOrientation.hpp>
34 #include <com/sun/star/text/VertOrientation.hpp>
35 #include <com/sun/star/text/RelOrientation.hpp>
36 #include <svx/svxids.hrc>
37 #include <svtools/unitconv.hxx>
38 #include <osl/diagnose.h>
40 using namespace ::com::sun::star::text;
42 namespace {
44 enum class LB;
48 struct FrmMap
50 SvxSwFramePosString::StringId eStrId;
51 SvxSwFramePosString::StringId eMirrorStrId;
52 short nAlign;
53 LB nLBRelations;
56 namespace {
58 struct RelationMap
60 SvxSwFramePosString::StringId eStrId;
61 SvxSwFramePosString::StringId eMirrorStrId;
62 LB nLBRelation;
63 short nRelation;
65 struct StringIdPair_Impl
67 SvxSwFramePosString::StringId eHori;
68 SvxSwFramePosString::StringId eVert;
71 enum class LB {
72 NONE = 0x000000,
73 Frame = 0x000001, // paragraph text area
74 PrintArea = 0x000002, // paragraph text area + indents
75 VertFrame = 0x000004, // vertical paragraph text area
76 VertPrintArea = 0x000008, // vertical paragraph text area + indents
77 RelFrameLeft = 0x000010, // left paragraph margin
78 RelFrameRight = 0x000020, // right paragraph margin
80 RelPageLeft = 0x000040, // left page margin
81 RelPageRight = 0x000080, // right page margin
82 RelPageFrame = 0x000100, // complete page
83 RelPagePrintArea = 0x000200, // text area of page
85 FlyRelPageLeft = 0x000400, // left frame margin
86 FlyRelPageRight = 0x000800, // right frame margin
87 FlyRelPageFrame = 0x001000, // complete frame
88 FlyRelPagePrintArea = 0x002000, // frame interior
90 RelBase = 0x004000, // as char, relative to baseline
91 RelChar = 0x008000, // as char, relative to character
92 RelRow = 0x010000, // as char, relative to line
94 // #i22305#
95 FlyVertFrame = 0x020000, // vertical entire frame
96 FlyVertPrintArea = 0x040000, // vertical frame text area
98 // #i22341#
99 VertLine = 0x080000, // vertical text line
101 RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
102 RelPagePrintAreaTop = 0x200000,
104 LAST = 0x400000
109 namespace o3tl {
110 template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
113 RelationMap const aRelationMap[] =
115 {SvxSwFramePosString::FRAME, SvxSwFramePosString::FRAME, LB::Frame, RelOrientation::FRAME},
116 {SvxSwFramePosString::PRTAREA, SvxSwFramePosString::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
117 {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
118 {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
119 {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
120 {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
121 {SvxSwFramePosString::REL_PG_FRAME, SvxSwFramePosString::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
122 {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
123 {SvxSwFramePosString::REL_PG_PRTAREA_TOP,SvxSwFramePosString::REL_PG_PRTAREA_TOP, LB::RelPagePrintAreaTop, RelOrientation::PAGE_PRINT_AREA_TOP},
124 {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM, LB::RelPagePrintAreaBottom, RelOrientation::PAGE_PRINT_AREA_BOTTOM},
125 {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
127 {SvxSwFramePosString::FLY_REL_PG_LEFT, SvxSwFramePosString::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
128 {SvxSwFramePosString::FLY_REL_PG_RIGHT, SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
129 {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
130 {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
132 {SvxSwFramePosString::REL_BORDER, SvxSwFramePosString::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
133 {SvxSwFramePosString::REL_PRTAREA, SvxSwFramePosString::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
135 // #i22305#
136 {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
137 {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
139 // #i22341#
140 {SvxSwFramePosString::REL_LINE, SvxSwFramePosString::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
143 RelationMap const aAsCharRelationMap[] =
145 {SvxSwFramePosString::REL_BASE, SvxSwFramePosString::REL_BASE, LB::RelBase, RelOrientation::FRAME},
146 {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
147 {SvxSwFramePosString::REL_ROW, SvxSwFramePosString::REL_ROW, LB::RelRow, RelOrientation::FRAME}
150 /*--------------------------------------------------------------------
151 Anchored at page
152 --------------------------------------------------------------------*/
154 constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
155 LB::RelPageRight;
157 FrmMap const aHPageMap[] =
159 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PAGE_REL},
160 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PAGE_REL},
161 {SvxSwFramePosString::CENTER_HORI,SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PAGE_REL},
162 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PAGE_REL}
165 FrmMap const aHPageHtmlMap[] =
167 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
170 #define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
172 FrmMap const aVPageMap[] =
174 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PAGE_REL},
175 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PAGE_REL},
176 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PAGE_REL},
177 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PAGE_REL}
180 FrmMap const aVPageHtmlMap[] =
182 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
185 /*--------------------------------------------------------------------
186 Anchored at frame
187 --------------------------------------------------------------------*/
189 constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
190 LB::FlyRelPageLeft|LB::FlyRelPageRight;
192 FrmMap const aHFrameMap[] =
194 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_FRAME_REL},
195 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_FRAME_REL},
196 {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_FRAME_REL},
197 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_FRAME_REL}
200 FrmMap const aHFlyHtmlMap[] =
202 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
203 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
206 // #i18732# - own vertical alignment map for to frame anchored objects
207 // #i22305#
208 #define VERT_FRAME_REL (LB::VertFrame|LB::FlyVertPrintArea)
210 FrmMap const aVFrameMap[] =
212 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_FRAME_REL},
213 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_FRAME_REL},
214 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_FRAME_REL},
215 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_FRAME_REL}
218 FrmMap const aVFlyHtmlMap[] =
220 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::FlyVertFrame},
221 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
224 FrmMap const aVMultiSelectionMap[] =
226 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::NONE}
228 FrmMap const aHMultiSelectionMap[] =
230 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::FROMLEFT, HoriOrientation::NONE, LB::NONE}
233 /*--------------------------------------------------------------------
234 Anchored at paragraph
235 --------------------------------------------------------------------*/
237 constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
238 LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
239 LB::RelFrameRight;
241 FrmMap const aHParaMap[] =
243 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PARA_REL},
244 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PARA_REL},
245 {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PARA_REL},
246 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PARA_REL}
249 #define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
251 FrmMap const aHParaHtmlMap[] =
253 {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
254 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
257 FrmMap const aHParaHtmlAbsMap[] =
259 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
260 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
264 constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
265 LB::RelPageFrame|LB::RelPagePrintArea| LB::RelPagePrintAreaTop |LB::RelPagePrintAreaBottom;
267 FrmMap const aVParaMap[] =
269 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PARA_REL},
270 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PARA_REL},
271 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PARA_REL},
272 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PARA_REL}
275 FrmMap const aVParaHtmlMap[] =
277 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::VertPrintArea}
280 /*--------------------------------------------------------------------
281 Anchored at character
282 --------------------------------------------------------------------*/
284 constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
285 LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
286 LB::RelFrameRight|LB::RelChar;
288 static FrmMap aHCharMap[] =
290 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_CHAR_REL},
291 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_CHAR_REL},
292 {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_CHAR_REL},
293 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_CHAR_REL}
296 #define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
298 static FrmMap aHCharHtmlMap[] =
300 {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
301 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
304 static FrmMap aHCharHtmlAbsMap[] =
306 {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
307 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
308 {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
311 // #i18732# - allow vertical alignment at page areas
312 // #i22341# - handle <LB::RelChar> on its own
313 constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
314 LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPagePrintAreaBottom;
316 static FrmMap aVCharMap[] =
318 // #i22341#
319 // introduce mappings for new vertical alignment at top of line <LB::VertLine>
320 // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
321 // Note: because of these adjustments the map becomes ambiguous in its values
322 // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
323 // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
324 // and <SwFrmPage::FillPosLB(..)>
325 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
326 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
327 {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
328 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
329 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_CHAR_REL},
330 {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
331 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::VertLine},
332 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
333 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
337 FrmMap const aVCharHtmlMap[] =
339 {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
342 FrmMap const aVCharHtmlAbsMap[] =
344 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelChar},
345 {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
347 /*--------------------------------------------------------------------
348 anchored as character
349 --------------------------------------------------------------------*/
351 FrmMap const aVAsCharMap[] =
353 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
354 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
355 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
357 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
358 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
359 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
361 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
362 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
363 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
365 {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
368 FrmMap const aVAsCharHtmlMap[] =
370 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
371 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
373 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
375 {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
376 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
377 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
380 static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
382 if( pMap )
384 if( pMap == aVParaHtmlMap )
385 return SAL_N_ELEMENTS(aVParaHtmlMap);
386 if( pMap == aVAsCharHtmlMap )
387 return SAL_N_ELEMENTS( aVAsCharHtmlMap );
388 if( pMap == aHParaHtmlMap )
389 return SAL_N_ELEMENTS( aHParaHtmlMap );
390 if( pMap == aHParaHtmlAbsMap )
391 return SAL_N_ELEMENTS( aHParaHtmlAbsMap );
392 if( pMap == aVPageMap )
393 return SAL_N_ELEMENTS( aVPageMap );
394 if( pMap == aVPageHtmlMap )
395 return SAL_N_ELEMENTS( aVPageHtmlMap );
396 if( pMap == aVAsCharMap )
397 return SAL_N_ELEMENTS( aVAsCharMap );
398 if( pMap == aVParaMap )
399 return SAL_N_ELEMENTS( aVParaMap );
400 if( pMap == aHParaMap )
401 return SAL_N_ELEMENTS( aHParaMap );
402 if( pMap == aHFrameMap )
403 return SAL_N_ELEMENTS( aHFrameMap );
404 if( pMap == aVFrameMap )
405 return SAL_N_ELEMENTS( aVFrameMap );
406 if( pMap == aHCharMap )
407 return SAL_N_ELEMENTS( aHCharMap );
408 if( pMap == aHCharHtmlMap )
409 return SAL_N_ELEMENTS( aHCharHtmlMap );
410 if( pMap == aHCharHtmlAbsMap )
411 return SAL_N_ELEMENTS( aHCharHtmlAbsMap );
412 if( pMap == aVCharMap )
413 return SAL_N_ELEMENTS( aVCharMap );
414 if( pMap == aVCharHtmlMap )
415 return SAL_N_ELEMENTS( aVCharHtmlMap );
416 if( pMap == aVCharHtmlAbsMap )
417 return SAL_N_ELEMENTS( aVCharHtmlAbsMap );
418 if( pMap == aHPageHtmlMap )
419 return SAL_N_ELEMENTS( aHPageHtmlMap );
420 if( pMap == aHFlyHtmlMap )
421 return SAL_N_ELEMENTS( aHFlyHtmlMap );
422 if( pMap == aVFlyHtmlMap )
423 return SAL_N_ELEMENTS( aVFlyHtmlMap );
424 if( pMap == aVMultiSelectionMap )
425 return SAL_N_ELEMENTS( aVMultiSelectionMap );
426 if( pMap == aHMultiSelectionMap )
427 return SAL_N_ELEMENTS( aHMultiSelectionMap );
428 return SAL_N_ELEMENTS(aHPageMap);
430 return 0;
433 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
434 SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
436 //special handling of STR_FROMLEFT
437 if(SvxSwFramePosString::FROMLEFT == eStringId)
439 eStringId = bVertical ?
440 bRTL ? SvxSwFramePosString::FROMBOTTOM : SvxSwFramePosString::FROMTOP :
441 bRTL ? SvxSwFramePosString::FROMRIGHT : SvxSwFramePosString::FROMLEFT;
442 return eStringId;
444 if(bVertical)
446 //exchange horizontal strings with vertical strings and vice versa
447 static const StringIdPair_Impl aHoriIds[] =
449 {SvxSwFramePosString::LEFT, SvxSwFramePosString::TOP},
450 {SvxSwFramePosString::RIGHT, SvxSwFramePosString::BOTTOM},
451 {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_VERT},
452 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT},
453 {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::REL_PG_TOP},
454 {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::REL_PG_BOTTOM} ,
455 {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::REL_FRM_TOP},
456 {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::REL_FRM_BOTTOM}
458 static const StringIdPair_Impl aVertIds[] =
460 {SvxSwFramePosString::TOP, SvxSwFramePosString::RIGHT},
461 {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::LEFT },
462 {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_HORI},
463 {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT },
464 {SvxSwFramePosString::REL_PG_TOP, SvxSwFramePosString::REL_PG_LEFT },
465 {SvxSwFramePosString::REL_PG_BOTTOM, SvxSwFramePosString::REL_PG_RIGHT } ,
466 {SvxSwFramePosString::REL_FRM_TOP, SvxSwFramePosString::REL_FRM_LEFT },
467 {SvxSwFramePosString::REL_FRM_BOTTOM, SvxSwFramePosString::REL_FRM_RIGHT }
469 for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aHoriIds); ++nIndex)
471 if(aHoriIds[nIndex].eHori == eStringId)
473 eStringId = aHoriIds[nIndex].eVert;
474 return eStringId;
477 for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
479 if(aVertIds[nIndex].eHori == eStringId)
481 eStringId = aVertIds[nIndex].eVert;
482 break;
486 return eStringId;
488 // #i22341# - helper method in order to determine all possible
489 // listbox relations in a relation map for a given relation
490 static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
492 LB nLBRelations = LB::NONE;
494 for (RelationMap const & nRelMapPos : aRelationMap)
496 if ( nRelMapPos.nRelation == _nRel )
498 nLBRelations |= nRelMapPos.nLBRelation;
502 return nLBRelations;
505 // #i22341# - helper method on order to determine all possible
506 // listbox relations in a relation map for a given string ID
507 static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
508 const SvxSwFramePosString::StringId _eStrId,
509 const bool _bUseMirrorStr )
511 LB nLBRelations = LB::NONE;
513 std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
514 for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
516 if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
517 ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
519 nLBRelations |= _pMap[nRelMapPos].nLBRelations;
523 return nLBRelations;
526 SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
527 : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
528 , m_pVMap(nullptr)
529 , m_pHMap(nullptr)
530 , m_pSdrView(nullptr)
531 , m_nOldH(HoriOrientation::CENTER)
532 , m_nOldHRel(RelOrientation::FRAME)
533 , m_nOldV(VertOrientation::TOP)
534 , m_nOldVRel(RelOrientation::PRINT_AREA)
535 , m_fWidthHeightRatio(1.0)
536 , m_bHtmlMode(false)
537 , m_bIsVerticalFrame(false)
538 , m_bPositioningDisabled(false)
539 , m_bIsMultiSelection(false)
540 , m_bIsInRightToLeft(false)
541 , m_nProtectSizeState(TRISTATE_FALSE)
542 , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
543 , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
544 , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
545 , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
546 , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
547 , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
548 , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
549 , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
550 , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
551 , m_xSizeCB(m_xBuilder->weld_check_button("size"))
552 , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
553 , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
554 , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
555 , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
556 , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
557 , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
558 , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
559 , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
560 , m_xVertFT(m_xBuilder->weld_label("vertposft"))
561 , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
562 , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
563 , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
564 , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
565 , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
566 , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
567 , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
569 setOptimalFrmWidth();
570 setOptimalRelWidth();
572 FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
573 SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
574 SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
575 SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
576 SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
578 SetExchangeSupport();
580 Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
581 m_xWidthMF->connect_focus_out(aLk3);
582 m_xHeightMF->connect_focus_out(aLk3);
583 m_xHoriByMF->connect_focus_out(aLk3);
584 m_xVertByMF->connect_focus_out(aLk3);
585 m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
587 Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
588 m_xWidthMF->connect_value_changed( aLk );
589 m_xHeightMF->connect_value_changed( aLk );
590 m_xHoriByMF->connect_value_changed( aLk );
591 m_xVertByMF->connect_value_changed( aLk );
593 Link<weld::Toggleable&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
594 m_xToPageRB->connect_toggled( aLk2 );
595 m_xToParaRB->connect_toggled( aLk2 );
596 m_xToCharRB->connect_toggled( aLk2 );
597 m_xAsCharRB->connect_toggled( aLk2 );
598 m_xToFrameRB->connect_toggled( aLk2 );
600 m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
601 m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
603 m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
604 m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
606 m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
607 m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
610 SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
612 m_xWidthMF.reset();
613 m_xHeightMF.reset();
614 m_xHoriByMF.reset();
615 m_xVertByMF.reset();
618 namespace
620 struct FrmMaps
622 FrmMap const *pMap;
623 size_t nCount;
627 void SvxSwPosSizeTabPage::setOptimalFrmWidth()
629 static const FrmMaps aMaps[] = {
630 { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
631 { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
632 { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
633 { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
634 { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
635 { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
636 { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
637 { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
638 { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
639 { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
640 { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
641 { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
642 { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
643 { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
644 { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
645 { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
646 { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
647 { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
648 { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
649 { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
650 { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
653 std::vector<SvxSwFramePosString::StringId> aFrames;
654 for (const FrmMaps& aMap : aMaps)
656 for (size_t j = 0; j < aMap.nCount; ++j)
658 aFrames.push_back(aMap.pMap[j].eStrId);
659 aFrames.push_back(aMap.pMap[j].eMirrorStrId);
663 std::sort(aFrames.begin(), aFrames.end());
664 aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
666 for (auto const& frame : aFrames)
668 m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
671 Size aBiggest(m_xHoriLB->get_preferred_size());
672 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
673 m_xVertLB->set_size_request(aBiggest.Width(), -1);
674 m_xHoriLB->clear();
677 namespace
679 struct RelationMaps
681 RelationMap const *pMap;
682 size_t nCount;
686 void SvxSwPosSizeTabPage::setOptimalRelWidth()
688 static const RelationMaps aMaps[] = {
689 { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
690 { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
693 std::vector<SvxSwFramePosString::StringId> aRels;
694 for (const RelationMaps& aMap : aMaps)
696 for (size_t j = 0; j < aMap.nCount; ++j)
698 aRels.push_back(aMap.pMap[j].eStrId);
699 aRels.push_back(aMap.pMap[j].eMirrorStrId);
703 std::sort(aRels.begin(), aRels.end());
704 aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
706 for (auto const& elem : aRels)
708 m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
711 Size aBiggest(m_xHoriLB->get_preferred_size());
712 m_xHoriLB->set_size_request(aBiggest.Width(), -1);
713 m_xVertLB->set_size_request(aBiggest.Width(), -1);
714 m_xHoriLB->clear();
717 std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
719 return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
722 WhichRangesContainer SvxSwPosSizeTabPage::GetRanges()
724 static const WhichRangesContainer ranges(svl::Items<
725 SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_POS_Y,
726 SID_ATTR_TRANSFORM_WIDTH, SID_ATTR_TRANSFORM_SIZE_POINT,
727 SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_INTERN,
728 SID_ATTR_TRANSFORM_AUTOWIDTH, SID_ATTR_TRANSFORM_VERT_ORIENT,
729 SID_HTML_MODE, SID_HTML_MODE,
730 SID_SW_FOLLOW_TEXT_FLOW, SID_SW_FOLLOW_TEXT_FLOW,
731 SID_ATTR_TRANSFORM_HORI_POSITION, SID_ATTR_TRANSFORM_VERT_POSITION
733 return ranges;
736 bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
738 bool bAnchorChanged = false;
739 RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
740 bool bModified = false;
741 if(bAnchorChanged)
743 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
744 bModified = true;
746 if (m_xPositionCB->get_state_changed_from_saved())
748 if (m_xPositionCB->get_inconsistent())
749 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
750 else
751 rSet->Put(
752 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
753 m_xPositionCB->get_state() == TRISTATE_TRUE ) );
754 bModified = true;
757 if (m_xSizeCB->get_state_changed_from_saved())
759 if (m_xSizeCB->get_inconsistent())
760 rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
761 else
762 rSet->Put(
763 SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
764 m_xSizeCB->get_state() == TRISTATE_TRUE ) );
765 bModified = true;
768 const SfxItemSet& rOldSet = GetItemSet();
770 if(!m_bPositioningDisabled)
772 //on multiple selections the positioning is set via SdrView
773 if (m_bIsMultiSelection)
775 if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
777 auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
778 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
780 // old rectangle with CoreUnit
781 m_aRect = m_pSdrView->GetAllMarkedRect();
782 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
784 nHoriByPos += m_aAnchorPos.X();
785 nVertByPos += m_aAnchorPos.Y();
787 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
788 rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
790 bModified = true;
793 else
795 if ( m_pHMap )
797 const SfxInt16Item& rHoriOrient =
798 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
799 const SfxInt16Item& rHoriRelation =
800 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
801 const SfxInt32Item& rHoriPosition =
802 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
804 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
805 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
806 short nRel = GetRelation(*m_xHoriToLB);
807 const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
808 if (
809 nAlign != rHoriOrient.GetValue() ||
810 nRel != rHoriRelation.GetValue() ||
811 (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
814 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
815 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
816 if(m_xHoriByMF->get_sensitive())
817 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
818 bModified = true;
821 if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
822 bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
824 if ( m_pVMap )
826 const SfxInt16Item& rVertOrient =
827 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
828 const SfxInt16Item& rVertRelation =
829 static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
830 const SfxInt32Item& rVertPosition =
831 static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
833 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
834 short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
835 short nRel = GetRelation(*m_xVertToLB);
836 // #i34055# - convert vertical position for
837 // as-character anchored objects
838 auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
839 if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
841 nVertByPos *= -1;
843 if ( nAlign != rVertOrient.GetValue() ||
844 nRel != rVertRelation.GetValue() ||
845 ( m_xVertByMF->get_sensitive() &&
846 nVertByPos != rVertPosition.GetValue() ) )
848 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
849 rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
850 if(m_xVertByMF->get_sensitive())
851 rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
852 bModified = true;
856 // #i18732#
857 if (m_xFollowCB->get_state_changed_from_saved())
859 //Writer internal type - based on SfxBoolItem
860 const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
861 if(pItem)
863 std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
864 pFollow->SetValue(m_xFollowCB->get_active());
865 bModified |= nullptr != rSet->Put(*pFollow);
870 if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
872 sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
873 sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
874 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
875 rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
876 //this item is required by SdrEditView::SetGeoAttrToMarked()
877 rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
879 bModified = true;
882 return bModified;
885 void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
887 const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
888 bool bInvalidateAnchor = false;
889 RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
890 if(pItem)
892 nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
893 switch(nAnchorType)
895 case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
896 case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
897 case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
898 case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
899 case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
900 default : bInvalidateAnchor = true;
902 m_xToPageRB->save_state();
903 m_xToParaRB->save_state();
904 m_xToCharRB->save_state();
905 m_xAsCharRB->save_state();
906 m_xToFrameRB->save_state();
908 if (bInvalidateAnchor)
910 m_xToPageRB->set_sensitive( false );
911 m_xToParaRB->set_sensitive( false );
912 m_xToCharRB->set_sensitive( false );
913 m_xAsCharRB->set_sensitive( false );
914 m_xToFrameRB->set_sensitive( false );
917 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
918 if (pItem)
920 bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
921 m_xPositionCB->set_active(bProtected);
922 m_xSizeCB->set_sensitive(!bProtected);
924 else
926 m_xPositionCB->set_inconsistent(true);
929 m_xPositionCB->save_state();
931 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
933 if (pItem)
935 m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
937 else
938 m_xSizeCB->set_inconsistent(true);
939 m_xSizeCB->save_state();
941 pItem = GetItem( *rSet, SID_HTML_MODE );
942 if(pItem)
944 m_bHtmlMode =
945 (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
946 != 0;
949 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
950 if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
952 OUString sHLabel = m_xHoriFT->get_label();
953 m_xHoriFT->set_label(m_xVertFT->get_label());
954 m_xVertFT->set_label(sHLabel);
955 m_bIsVerticalFrame = true;
957 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
958 if(pItem)
959 m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
961 pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
962 if(pItem)
964 const bool bFollowTextFlow =
965 static_cast<const SfxBoolItem*>(pItem)->GetValue();
966 m_xFollowCB->set_active(bFollowTextFlow);
968 m_xFollowCB->save_state();
970 if(m_bHtmlMode)
972 m_xHoriMirrorCB->hide();
973 m_xKeepRatioCB->set_sensitive(false);
974 // #i18732# - hide checkbox in HTML mode
975 m_xFollowCB->hide();
977 else
979 // #i18732# correct enable/disable of check box 'Mirror on..'
980 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
982 // #i18732# - enable/disable check box 'Follow text flow'.
983 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
984 m_xToCharRB->get_active());
987 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
988 sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
990 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
991 m_xWidthMF->save_value();
993 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
994 sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
995 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
996 m_xHeightMF->save_value();
997 m_fWidthHeightRatio = double(nWidth) / double(nHeight);
999 if(m_bPositioningDisabled)
1000 return;
1002 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
1003 if(pItem)
1005 short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1006 m_nOldH = nHoriOrientation;
1008 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
1009 if(pItem)
1011 short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1012 m_nOldV = nVertOrientation;
1014 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
1015 if(pItem)
1017 m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1020 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
1021 if(pItem)
1023 m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
1025 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
1026 if(pItem)
1027 m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
1028 m_xHoriMirrorCB->save_state();
1030 sal_Int32 nHoriPos = 0;
1031 sal_Int32 nVertPos = 0;
1032 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
1033 if(pItem)
1034 nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1035 pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
1036 if(pItem)
1037 nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
1039 InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
1041 m_xVertByMF->save_value();
1042 m_xHoriByMF->save_value();
1043 // #i18732#
1044 m_xFollowCB->save_state();
1046 RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
1049 DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
1051 if( _pSet )
1053 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
1054 m_xPositionCB->get_active()));
1055 _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
1056 m_xSizeCB->get_active()));
1057 FillItemSet( _pSet );
1059 return DeactivateRC::LeavePage;
1062 void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
1064 if (nAnchorEnable & SvxAnchorIds::Fly)
1065 m_xToFrameRB->show();
1066 if (!(nAnchorEnable & SvxAnchorIds::Page))
1067 m_xToPageRB->set_sensitive(false);
1070 RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
1072 RndStdIds nRet = RndStdIds::UNKNOWN;
1073 weld::RadioButton* pCheckedButton = nullptr;
1074 if(m_xToParaRB->get_sensitive())
1076 if(m_xToPageRB->get_active())
1078 nRet = RndStdIds::FLY_AT_PAGE;
1079 pCheckedButton = m_xToPageRB.get();
1081 else if(m_xToParaRB->get_active())
1083 nRet = RndStdIds::FLY_AT_PARA;
1084 pCheckedButton = m_xToParaRB.get();
1086 else if(m_xToCharRB->get_active())
1088 nRet = RndStdIds::FLY_AT_CHAR;
1089 pCheckedButton = m_xToCharRB.get();
1091 else if(m_xAsCharRB->get_active())
1093 nRet = RndStdIds::FLY_AS_CHAR;
1094 pCheckedButton = m_xAsCharRB.get();
1096 else if(m_xToFrameRB->get_active())
1098 nRet = RndStdIds::FLY_AT_FLY;
1099 pCheckedButton = m_xToFrameRB.get();
1102 if(pbHasChanged)
1104 if(pCheckedButton)
1105 *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
1106 else
1107 *pbHasChanged = false;
1109 return nRet;
1112 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::Toggleable&, void)
1114 RangeModifyHdl(m_xWidthMF->get_widget());
1117 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
1119 if (m_bPositioningDisabled)
1120 return;
1121 SvxSwFrameValidation aVal;
1123 aVal.nAnchorType = GetAnchorType();
1124 aVal.bAutoHeight = false;
1125 aVal.bMirror = m_xHoriMirrorCB->get_active();
1126 // #i18732#
1127 aVal.bFollowTextFlow = m_xFollowCB->get_active();
1129 if ( m_pHMap )
1131 // horizontal alignment
1132 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
1133 sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1134 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1136 aVal.nHoriOrient = static_cast<short>(nAlign);
1137 aVal.nHRelOrient = static_cast<short>(nRel);
1139 else
1140 aVal.nHoriOrient = HoriOrientation::NONE;
1142 if ( m_pVMap )
1144 // vertical alignment
1145 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1146 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1147 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1149 aVal.nVertOrient = static_cast<short>(nAlign);
1150 aVal.nVRelOrient = static_cast<short>(nRel);
1152 else
1153 aVal.nVertOrient = VertOrientation::NONE;
1155 const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1156 const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1158 aVal.nHPos = nAtHorzPosVal;
1159 aVal.nVPos = nAtVertPosVal;
1161 sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
1162 sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
1163 aVal.nWidth = nWidth;
1164 aVal.nHeight = nHeight;
1166 m_aValidateLink.Call(aVal);
1168 // minimum width also for style
1169 m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
1170 m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
1172 sal_Int32 nMaxWidth(aVal.nMaxWidth);
1173 sal_Int32 nMaxHeight(aVal.nMaxHeight);
1175 sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
1176 m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
1178 nTmp = m_xWidthMF->normalize(nMaxWidth);
1179 m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
1181 m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
1182 m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
1183 if ( aVal.nHPos != nAtHorzPosVal )
1184 m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
1186 m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
1187 m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
1188 if ( aVal.nVPos != nAtVertPosVal )
1189 m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
1192 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::Toggleable&, void)
1194 m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
1196 // #i18732# - enable check box 'Follow text flow' for anchor
1197 // type to-paragraph' and to-character
1198 m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
1200 RndStdIds nId = GetAnchorType();
1202 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1203 RangeModifyHdl(m_xWidthMF->get_widget());
1205 if(m_bHtmlMode)
1207 PosHdl(*m_xHoriLB);
1208 PosHdl(*m_xVertLB);
1212 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::Toggleable&, void)
1214 RndStdIds nId = GetAnchorType();
1215 InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
1218 IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
1220 bool bHori = &rLB == m_xHoriToLB.get();
1222 UpdateExample();
1224 if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
1226 if(bHori)
1228 sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
1229 if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
1231 m_xVertLB->set_active(1);
1233 else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
1235 m_xVertLB->set_active(0);
1239 RangeModifyHdl(m_xWidthMF->get_widget());
1242 IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
1244 bool bHori = &rLB == m_xHoriLB.get();
1245 weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
1246 weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
1247 FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
1250 sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
1251 sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1253 if (bHori)
1255 bool bEnable = HoriOrientation::NONE == nAlign;
1256 m_xHoriByMF->set_sensitive( bEnable );
1257 m_xHoriByFT->set_sensitive( bEnable );
1259 else
1261 bool bEnable = VertOrientation::NONE == nAlign;
1262 m_xVertByMF->set_sensitive( bEnable );
1263 m_xVertByFT->set_sensitive( bEnable );
1266 RangeModifyHdl(m_xWidthMF->get_widget());
1268 short nRel = 0;
1269 if (rLB.get_active() != -1)
1271 if (pRelLB->get_active() != -1)
1272 nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
1274 FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1276 else
1277 pRelLB->clear();
1279 UpdateExample();
1281 // special treatment for HTML-Mode with horz-vert-dependencies
1282 if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
1283 return;
1285 bool bSet = false;
1286 if(bHori)
1288 // on the right only below is allowed - from the left only at the top
1289 // from the left at the character -> below
1290 if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
1291 0 == m_xVertLB->get_active())
1293 if(RelOrientation::FRAME == nRel)
1294 m_xVertLB->set_active(1);
1295 else
1296 m_xVertLB->set_active(0);
1297 bSet = true;
1299 else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
1301 m_xVertLB->set_active(0);
1302 bSet = true;
1304 else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
1306 m_xVertLB->set_active(0);
1307 bSet = true;
1309 if(bSet)
1310 PosHdl(*m_xVertLB);
1312 else
1314 if(VertOrientation::TOP == nAlign)
1316 if(1 == m_xHoriLB->get_active())
1318 m_xHoriLB->set_active(0);
1319 bSet = true;
1321 m_xHoriToLB->set_active(1);
1323 else if(VertOrientation::CHAR_BOTTOM == nAlign)
1325 if(2 == m_xHoriLB->get_active())
1327 m_xHoriLB->set_active(0);
1328 bSet = true;
1330 m_xHoriToLB->set_active(0) ;
1332 if(bSet)
1333 PosHdl(*m_xHoriLB);
1337 IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
1339 auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
1340 auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
1341 if (m_xKeepRatioCB->get_active())
1343 if ( &rEdit == m_xWidthMF.get() )
1345 nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
1346 m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
1348 else if(&rEdit == m_xHeightMF.get())
1350 nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
1351 m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
1354 m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1355 UpdateExample();
1358 IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::Toggleable&, void)
1360 if (m_xSizeCB->get_sensitive())
1362 m_nProtectSizeState = m_xSizeCB->get_state();
1365 m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
1366 m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
1369 short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
1371 short nRel = 0;
1372 int nPos = rRelationLB.get_active();
1373 if (nPos != -1)
1375 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
1376 nRel = pEntry->nRelation;
1379 return nRel;
1382 short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
1384 short nAlign = 0;
1386 // #i22341# - special handling also for map <aVCharMap>,
1387 // because it contains ambiguous items for alignment
1388 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
1389 pMap == aVCharMap )
1391 if (rRelationLB.get_active() != -1)
1393 LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
1394 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1395 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1397 for (std::size_t i = 0; i < nMapCount; i++)
1399 if (pMap[i].eStrId == eStrId)
1401 LB nLBRelations = pMap[i].nLBRelations;
1402 if (nLBRelations & nRel)
1404 nAlign = pMap[i].nAlign;
1405 break;
1411 else if (pMap)
1412 nAlign = pMap[nMapPos].nAlign;
1414 return nAlign;
1417 sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
1419 sal_uInt16 nMapPos = 0;
1420 int nLBSelPos = rAlignLB.get_active();
1422 if (nLBSelPos != -1)
1424 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1426 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1427 OUString sSelEntry(rAlignLB.get_active_text());
1429 for (std::size_t i = 0; i < nMapCount; i++)
1431 SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1433 OUString sEntry = SvxSwFramePosString::GetString(eResId);
1435 if (sEntry == sSelEntry)
1437 nMapPos = sal::static_int_cast< sal_uInt16 >(i);
1438 break;
1442 else
1443 nMapPos = nLBSelPos;
1446 return nMapPos;
1449 void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
1450 sal_uInt16 nH,
1451 sal_uInt16 nHRel,
1452 sal_uInt16 nV,
1453 sal_uInt16 nVRel,
1454 tools::Long nX,
1455 tools::Long nY)
1457 int nPos = m_xVertLB->get_active();
1458 if (nPos != -1 && m_pVMap)
1460 m_nOldV = m_pVMap[nPos].nAlign;
1461 nPos = m_xVertToLB->get_active();
1462 if (nPos != -1)
1463 m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
1466 nPos = m_xHoriLB->get_active();
1467 if (nPos != -1 && m_pHMap)
1469 m_nOldH = m_pHMap[nPos].nAlign;
1471 nPos = m_xHoriToLB->get_active();
1472 if (nPos != -1)
1473 m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
1476 bool bEnable = true;
1477 if( m_bIsMultiSelection )
1479 m_pVMap = aVMultiSelectionMap;
1480 m_pHMap = aHMultiSelectionMap;
1482 else if (nAnchor == RndStdIds::FLY_AT_PAGE)
1484 m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1485 m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1487 else if (nAnchor == RndStdIds::FLY_AT_FLY)
1489 // #i18732# - own vertical alignment map for to frame
1490 // anchored objects.
1491 m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1492 m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1494 else if (nAnchor == RndStdIds::FLY_AT_PARA)
1496 if(m_bHtmlMode)
1498 m_pVMap = aVParaHtmlMap;
1499 m_pHMap = aHParaHtmlAbsMap;
1501 else
1503 m_pVMap = aVParaMap;
1504 m_pHMap = aHParaMap;
1507 else if (nAnchor == RndStdIds::FLY_AT_CHAR)
1509 if(m_bHtmlMode)
1511 m_pVMap = aVCharHtmlAbsMap;
1512 m_pHMap = aHCharHtmlAbsMap;
1514 else
1516 m_pVMap = aVCharMap;
1517 m_pHMap = aHCharMap;
1520 else if (nAnchor == RndStdIds::FLY_AS_CHAR)
1522 m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
1523 m_pHMap = nullptr;
1524 bEnable = false;
1526 m_xHoriLB->set_sensitive(bEnable);
1527 m_xHoriFT->set_sensitive(bEnable);
1529 // select current Pos
1530 // horizontal
1531 if ( nH == USHRT_MAX )
1533 nH = m_nOldH;
1534 nHRel = m_nOldHRel;
1536 // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
1537 sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
1538 FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
1540 // vertical
1541 if ( nV == USHRT_MAX )
1543 nV = m_nOldV;
1544 nVRel = m_nOldVRel;
1546 // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
1547 nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
1548 FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
1550 // Edits init
1551 bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
1552 if (!bEnable)
1554 m_xHoriByMF->set_value(0, FieldUnit::TWIP);
1556 else if(m_bIsMultiSelection)
1558 m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
1560 else
1562 if (nX != LONG_MAX)
1563 m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
1565 m_xHoriByFT->set_sensitive(bEnable);
1566 m_xHoriByMF->set_sensitive(bEnable);
1568 bEnable = nV == VertOrientation::NONE;
1569 if ( !bEnable )
1571 m_xVertByMF->set_value( 0, FieldUnit::TWIP );
1573 else if(m_bIsMultiSelection)
1575 m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
1577 else
1579 if (nAnchor == RndStdIds::FLY_AS_CHAR)
1581 if ( nY == LONG_MAX )
1582 nY = 0;
1583 else
1584 nY *= -1;
1586 if ( nY != LONG_MAX )
1587 m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
1589 m_xVertByFT->set_sensitive( bEnable );
1590 m_xVertByMF->set_sensitive( bEnable );
1591 UpdateExample();
1594 void SvxSwPosSizeTabPage::UpdateExample()
1596 int nPos = m_xHoriLB->get_active();
1597 if (m_pHMap && nPos != -1)
1599 sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
1600 short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
1601 short nRel = GetRelation(*m_xHoriToLB);
1603 m_aExampleWN.SetHAlign(nAlign);
1604 m_aExampleWN.SetHoriRel(nRel);
1607 nPos = m_xVertLB->get_active();
1608 if (m_pVMap && nPos != -1)
1610 sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
1611 sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
1612 sal_uInt16 nRel = GetRelation(*m_xVertToLB);
1614 m_aExampleWN.SetVAlign(nAlign);
1615 m_aExampleWN.SetVertRel(nRel);
1618 // Size
1619 auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
1620 auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
1621 m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
1623 m_aExampleWN.SetAnchor( GetAnchorType() );
1624 m_aExampleWN.Invalidate();
1627 void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
1628 sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
1630 OUString sSelEntry;
1631 LB nLBRelations = LB::NONE;
1632 std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
1634 rLB.clear();
1636 if (nMapPos < nMapCount)
1638 if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1640 OUString sOldEntry(rLB.get_active_text());
1641 SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1643 for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
1645 if (pMap[_nMapPos].eStrId == eStrId)
1647 nLBRelations = pMap[_nMapPos].nLBRelations;
1648 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
1650 if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
1652 SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
1654 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1655 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1656 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
1657 if (pMap[_nMapPos].nAlign == nAlign)
1658 sSelEntry = sEntry;
1659 break;
1664 if (!sSelEntry.isEmpty())
1665 rLB.set_active_text(sSelEntry);
1666 else
1668 rLB.set_active_text(sOldEntry);
1669 if (rLB.get_active() == -1)
1671 for (int i = 0; i < rLB.get_count(); i++)
1673 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1674 if (pEntry->nLBRelation == LB::RelChar) // Default
1676 rLB.set_active(i);
1677 break;
1683 else
1685 // #i22341# - special handling for map <aVCharMap>,
1686 // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1687 if ( pMap == aVCharMap )
1689 nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
1690 ( m_xHoriMirrorCB->get_active()
1691 ? pMap[nMapPos].eMirrorStrId
1692 : pMap[nMapPos].eStrId ),
1693 m_xHoriMirrorCB->get_active() );
1695 else
1697 nLBRelations = pMap[nMapPos].nLBRelations;
1700 for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
1702 if (nLBRelations & static_cast<LB>(nBit))
1704 for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
1706 if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
1708 SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
1709 sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
1710 OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1711 rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
1712 if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
1713 sSelEntry = sEntry;
1718 if (!sSelEntry.isEmpty())
1719 rLB.set_active_text(sSelEntry);
1720 else
1722 // Probably anchor change. So look for a similar relation.
1723 switch (nRel)
1725 case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
1726 case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
1727 case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
1728 case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
1729 case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
1730 case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
1731 case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
1732 case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
1734 default:
1735 if (rLB.get_count())
1737 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
1738 nRel = pEntry->nRelation;
1740 break;
1743 for (int i = 0; i < rLB.get_count(); ++i)
1745 RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
1746 if (pEntry->nRelation == nRel)
1748 rLB.set_active(i);
1749 break;
1753 if (rLB.get_active() == -1)
1754 rLB.set_active(0);
1759 rLB.set_sensitive(rLB.get_count() != 0);
1760 rFT.set_sensitive(rLB.get_count() != 0);
1762 RelHdl(rLB);
1765 sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
1766 sal_uInt16 _nAlign,
1767 const sal_uInt16 _nRel,
1768 weld::ComboBox& _rLB)
1770 OUString sSelEntry, sOldEntry;
1771 sOldEntry = _rLB.get_active_text();
1773 _rLB.clear();
1775 // #i22341# - determine all possible listbox relations for
1776 // given relation for map <aVCharMap>
1777 const LB nLBRelations = (_pMap != aVCharMap)
1778 ? LB::NONE
1779 : ::lcl_GetLBRelationsForRelations( _nRel );
1781 // fill listbox
1782 std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
1783 for (std::size_t i = 0; _pMap && i < nCount; ++i)
1785 SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1786 eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
1787 OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1788 if (_rLB.find_text(sEntry) == -1)
1790 // don't insert duplicate entries at character wrapped borders
1791 _rLB.append_text(sEntry);
1793 // #i22341# - add condition to handle map <aVCharMap>
1794 // that is ambiguous in the alignment.
1795 if ( _pMap[i].nAlign == _nAlign &&
1796 ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
1798 sSelEntry = sEntry;
1802 _rLB.set_active_text(sSelEntry);
1803 if (_rLB.get_active() == -1)
1804 _rLB.set_active_text(sOldEntry);
1806 if (_rLB.get_active() == -1)
1807 _rLB.set_active(0);
1809 PosHdl(_rLB);
1811 return GetMapPos(_pMap, _rLB);
1814 void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
1816 m_pSdrView = pSdrView;
1817 if(!m_pSdrView)
1819 OSL_FAIL("No SdrView* set");
1820 return;
1823 // setting of the rectangle and the working area
1824 m_aRect = m_pSdrView->GetAllMarkedRect();
1825 m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
1827 // get WorkArea
1828 m_aWorkArea = m_pSdrView->GetWorkArea();
1830 // consider anchor position (for Writer)
1831 const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
1832 if( rMarkList.GetMarkCount() > 0 )
1834 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1835 m_aAnchorPos = pObj->GetAnchorPos();
1837 if( m_aAnchorPos != Point(0,0) ) // -> Writer
1839 for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
1841 pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
1842 if( m_aAnchorPos != pObj->GetAnchorPos() )
1844 // different anchor positions -> disable positioning
1845 m_xPosFrame->set_sensitive(false);
1846 m_bPositioningDisabled = true;
1847 return;
1851 Point aPt = m_aAnchorPos * -1;
1852 Point aPt2 = aPt;
1854 aPt += m_aWorkArea.TopLeft();
1855 m_aWorkArea.SetPos( aPt );
1857 aPt2 += m_aRect.TopLeft();
1858 m_aRect.SetPos( aPt2 );
1861 // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
1862 if( rMarkList.GetMarkCount() != 1 )
1863 m_bIsMultiSelection = true;
1864 #if OSL_DEBUG_LEVEL > 1
1865 else
1867 const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
1868 SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
1869 if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
1870 ( eKind==OBJ_TEXT || eKind==OBJ_TITLETEXT || eKind==OBJ_OUTLINETEXT) &&
1871 pObj->HasText() )
1873 OSL_FAIL("AutoWidth/AutoHeight should be enabled");
1876 #endif
1879 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */