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 <com/sun/star/embed/Aspects.hpp>
21 #include <com/sun/star/embed/EmbedMisc.hpp>
22 #include <com/sun/star/embed/XEmbeddedObject.hpp>
23 
24 #include <cmdid.h>
25 #include <hintids.hxx>
26 #include <bitmaps.hlst>
27 #include <o3tl/safeint.hxx>
28 #include <vcl/mnemonic.hxx>
29 #include <svl/stritem.hxx>
30 #include <sfx2/htmlmode.hxx>
31 #include <editeng/sizeitem.hxx>
32 #include <editeng/opaqitem.hxx>
33 #include <editeng/protitem.hxx>
34 #include <editeng/prntitem.hxx>
35 #include <editeng/brushitem.hxx>
36 #include <editeng/ulspitem.hxx>
37 #include <editeng/frmdiritem.hxx>
38 #include <svx/swframeposstrings.hxx>
39 #include <svx/swframevalidation.hxx>
40 #include <svx/sdangitm.hxx>
41 #include <comphelper/classids.hxx>
42 #include <tools/globname.hxx>
43 #include <tools/urlobj.hxx>
44 #include <fmturl.hxx>
45 #include <fmteiro.hxx>
46 #include <fmtcnct.hxx>
47 #include <fmtsrnd.hxx>
48 #include <view.hxx>
49 #include <wrtsh.hxx>
50 #include <swmodule.hxx>
51 #include <uitool.hxx>
52 #include <docsh.hxx>
53 #include <viewopt.hxx>
54 #include <frmdlg.hxx>
55 #include <frmmgr.hxx>
56 #include <frmpage.hxx>
57 #include <colmgr.hxx>
58 #include <grfatr.hxx>
59 #include <fmtfollowtextflow.hxx>
60 #include <svx/sdtaitm.hxx>
61 #include <sal/macros.h>
62 #include <osl/diagnose.h>
63 
64 #include <strings.hrc>
65 #include <svx/strings.hrc>
66 #include <svx/dialmgr.hxx>
67 #include <svx/graphichelper.hxx>
68 #include <sfx2/filedlghelper.hxx>
69 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
70 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
71 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
72 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
73 #include <vcl/graphicfilter.hxx>
74 #include <svtools/embedhlp.hxx>
75 #include <comphelper/lok.hxx>
76 #include <memory>
77 
78 using namespace ::com::sun::star;
79 using namespace ::sfx2;
80 
81 #define SwFPos SvxSwFramePosString
82 
83 namespace {
84 
85 struct StringIdPair_Impl
86 {
87     SvxSwFramePosString::StringId eHori;
88     SvxSwFramePosString::StringId eVert;
89 };
90 
91 }
92 
93 #define MAX_PERCENT_WIDTH   254
94 #define MAX_PERCENT_HEIGHT  254
95 
96 namespace {
97 
98 enum class LB {
99     NONE                = 0x00000000L,
100     Frame               = 0x00000001L,  // text region of the paragraph
101     PrintArea           = 0x00000002L,  // text region of the paragraph + indentions
102     VertFrame           = 0x00000004L,  // vertical text region of the paragraph
103     VertPrintArea       = 0x00000008L,  // vertical text region of the paragraph + indentions
104     RelFrameLeft        = 0x00000010L,  // left paragraph edge
105     RelFrameRight       = 0x00000020L,  // right paragraph edge
106 
107     RelPageLeft         = 0x00000040L,  // left page edge
108     RelPageRight        = 0x00000080L,  // right page edge
109     RelPageFrame        = 0x00000100L,  // whole page
110     RelPagePrintArea    = 0x00000200L,  // text region of the page
111 
112     FlyRelPageLeft      = 0x00000400L,  // left frame edge
113     FlyRelPageRight     = 0x00000800L,   // right frame edge
114     FlyRelPageFrame     = 0x00001000L,  // whole frame
115     FlyRelPagePrintArea = 0x00002000L,  // inside of the frame
116 
117     RelBase             = 0x00010000L,  // character alignment Base
118     RelChar             = 0x00020000L,  // character alignment Character
119     RelRow              = 0x00040000L,  // character alignment Row
120 
121     FlyVertFrame        = 0x00100000L,  // vertical entire frame
122     FlyVertPrintArea    = 0x00200000L,  // vertical frame text area
123 
124     VertLine            = 0x00400000L,  // vertical text line
125 };
126 
127 }
128 
129 namespace o3tl {
130     template<> struct typed_flags<LB> : is_typed_flags<LB, 0x00773fffL> {};
131 }
132 
133 namespace {
134 
135 struct RelationMap
136 {
137     SvxSwFramePosString::StringId eStrId;
138     SvxSwFramePosString::StringId eMirrorStrId;
139     LB         nLBRelation;
140     sal_Int16  nRelation;
141 };
142 
143 }
144 
145 struct FrameMap
146 {
147     SvxSwFramePosString::StringId eStrId;
148     SvxSwFramePosString::StringId eMirrorStrId;
149     sal_Int16  nAlign;
150     LB         nLBRelations;
151 };
152 
153 
154 RelationMap const aRelationMap[] =
155 {
156     {SwFPos::FRAME,  SwFPos::FRAME, LB::Frame, text::RelOrientation::FRAME},
157     {SwFPos::PRTAREA,           SwFPos::PRTAREA,                LB::PrintArea,             text::RelOrientation::PRINT_AREA},
158     {SwFPos::REL_PG_LEFT,       SwFPos::MIR_REL_PG_LEFT,        LB::RelPageLeft,         text::RelOrientation::PAGE_LEFT},
159     {SwFPos::REL_PG_RIGHT,      SwFPos::MIR_REL_PG_RIGHT,       LB::RelPageRight,        text::RelOrientation::PAGE_RIGHT},
160     {SwFPos::REL_FRM_LEFT,      SwFPos::MIR_REL_FRM_LEFT,       LB::RelFrameLeft,        text::RelOrientation::FRAME_LEFT},
161     {SwFPos::REL_FRM_RIGHT,     SwFPos::MIR_REL_FRM_RIGHT,      LB::RelFrameRight,       text::RelOrientation::FRAME_RIGHT},
162     {SwFPos::REL_PG_FRAME,      SwFPos::REL_PG_FRAME,           LB::RelPageFrame,        text::RelOrientation::PAGE_FRAME},
163     {SwFPos::REL_PG_PRTAREA,    SwFPos::REL_PG_PRTAREA,         LB::RelPagePrintArea,      text::RelOrientation::PAGE_PRINT_AREA},
164     {SwFPos::REL_CHAR,          SwFPos::REL_CHAR,               LB::RelChar,            text::RelOrientation::CHAR},
165 
166     {SwFPos::FLY_REL_PG_LEFT,       SwFPos::FLY_MIR_REL_PG_LEFT,    LB::FlyRelPageLeft,     text::RelOrientation::PAGE_LEFT},
167     {SwFPos::FLY_REL_PG_RIGHT,      SwFPos::FLY_MIR_REL_PG_RIGHT,   LB::FlyRelPageRight,    text::RelOrientation::PAGE_RIGHT},
168     {SwFPos::FLY_REL_PG_FRAME,      SwFPos::FLY_REL_PG_FRAME,       LB::FlyRelPageFrame,    text::RelOrientation::PAGE_FRAME},
169     {SwFPos::FLY_REL_PG_PRTAREA,    SwFPos::FLY_REL_PG_PRTAREA,     LB::FlyRelPagePrintArea,  text::RelOrientation::PAGE_PRINT_AREA},
170 
171     {SwFPos::REL_BORDER,        SwFPos::REL_BORDER,             LB::VertFrame,          text::RelOrientation::FRAME},
172     {SwFPos::REL_PRTAREA,       SwFPos::REL_PRTAREA,            LB::VertPrintArea,        text::RelOrientation::PRINT_AREA},
173 
174     {SwFPos::FLY_REL_PG_FRAME,      SwFPos::FLY_REL_PG_FRAME,   LB::FlyVertFrame,      text::RelOrientation::FRAME},
175     {SwFPos::FLY_REL_PG_PRTAREA,    SwFPos::FLY_REL_PG_PRTAREA,     LB::FlyVertPrintArea,    text::RelOrientation::PRINT_AREA},
176 
177     {SwFPos::REL_LINE,  SwFPos::REL_LINE,   LB::VertLine,   text::RelOrientation::TEXT_LINE}
178 };
179 
180 RelationMap const aAsCharRelationMap[] =
181 {
182     {SwFPos::REL_BASE,  SwFPos::REL_BASE,   LB::RelBase,    text::RelOrientation::FRAME},
183     {SwFPos::REL_CHAR,   SwFPos::REL_CHAR,   LB::RelChar,   text::RelOrientation::FRAME},
184     {SwFPos::REL_ROW,    SwFPos::REL_ROW,   LB::RelRow,     text::RelOrientation::FRAME}
185 };
186 
187 // site anchored
188 constexpr auto HORI_PAGE_REL = LB::RelPageFrame | LB::RelPagePrintArea | LB::RelPageLeft |
189                         LB::RelPageRight;
190 
191 FrameMap const aHPageMap[] =
192 {
193     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      HORI_PAGE_REL},
194     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     HORI_PAGE_REL},
195     {SwFPos::CENTER_HORI,   SwFPos::CENTER_HORI,    text::HoriOrientation::CENTER,    HORI_PAGE_REL},
196     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      HORI_PAGE_REL}
197 };
198 
199 FrameMap const aHPageHtmlMap[] =
200 {
201     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      LB::RelPageFrame}
202 };
203 
204 #define VERT_PAGE_REL   (LB::RelPageFrame|LB::RelPagePrintArea)
205 
206 FrameMap const aVPageMap[] =
207 {
208     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,       VERT_PAGE_REL},
209     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::BOTTOM,    VERT_PAGE_REL},
210     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,    VERT_PAGE_REL},
211     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,      VERT_PAGE_REL}
212 };
213 
214 FrameMap const aVPageHtmlMap[] =
215 {
216     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,      LB::RelPageFrame}
217 };
218 
219 // frame anchored
220 constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame | LB::FlyRelPagePrintArea |
221                                        LB::FlyRelPageLeft | LB::FlyRelPageRight;
222 
223 FrameMap const aHFrameMap[] =
224 {
225     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,  HORI_FRAME_REL},
226     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     HORI_FRAME_REL},
227     {SwFPos::CENTER_HORI,   SwFPos::CENTER_HORI,    text::HoriOrientation::CENTER,    HORI_FRAME_REL},
228     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      HORI_FRAME_REL}
229 };
230 
231 FrameMap const aHFlyHtmlMap[] =
232 {
233     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      LB::FlyRelPageFrame},
234     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      LB::FlyRelPageFrame}
235 };
236 
237 // own vertical alignment map for objects anchored to frame
238 #define VERT_FRAME_REL   (LB::FlyVertFrame|LB::FlyVertPrintArea)
239 
240 FrameMap const aVFrameMap[] =
241 {
242     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,       VERT_FRAME_REL},
243     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::BOTTOM,    VERT_FRAME_REL},
244     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,    VERT_FRAME_REL},
245     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,      VERT_FRAME_REL}
246 };
247 
248 FrameMap const aVFlyHtmlMap[] =
249 {
250     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,       LB::FlyVertFrame},
251     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,      LB::FlyVertFrame}
252 };
253 
254 // paragraph anchored
255 constexpr auto HORI_PARA_REL = LB::Frame | LB::PrintArea | LB::RelPageLeft | LB::RelPageRight |
256                         LB::RelPageFrame | LB::RelPagePrintArea | LB::RelFrameLeft |
257                         LB::RelFrameRight;
258 
259 FrameMap const aHParaMap[] =
260 {
261     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      HORI_PARA_REL},
262     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     HORI_PARA_REL},
263     {SwFPos::CENTER_HORI,   SwFPos::CENTER_HORI,    text::HoriOrientation::CENTER,    HORI_PARA_REL},
264     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      HORI_PARA_REL}
265 };
266 
267 #define HTML_HORI_PARA_REL  (LB::Frame|LB::PrintArea)
268 
269 FrameMap const aHParaHtmlMap[] =
270 {
271     {SwFPos::LEFT,  SwFPos::LEFT,   text::HoriOrientation::LEFT,      HTML_HORI_PARA_REL},
272     {SwFPos::RIGHT, SwFPos::RIGHT,  text::HoriOrientation::RIGHT,     HTML_HORI_PARA_REL}
273 };
274 
275 FrameMap const aHParaHtmlAbsMap[] =
276 {
277     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      HTML_HORI_PARA_REL},
278     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     HTML_HORI_PARA_REL}
279 };
280 
281 // allow vertical alignment at page areas
282 constexpr auto VERT_PARA_REL = LB::VertFrame | LB::VertPrintArea |
283                                       LB::RelPageFrame | LB::RelPagePrintArea;
284 
285 FrameMap const aVParaMap[] =
286 {
287     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,       VERT_PARA_REL},
288     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::BOTTOM,    VERT_PARA_REL},
289     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,    VERT_PARA_REL},
290     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,      VERT_PARA_REL}
291 };
292 
293 FrameMap const aVParaHtmlMap[] =
294 {
295     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,       LB::VertPrintArea}
296 };
297 
298 // anchored relative to the character
299 constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea | LB::RelPageLeft | LB::RelPageRight |
300                                       LB::RelPageFrame | LB::RelPagePrintArea | LB::RelFrameLeft |
301                                       LB::RelFrameRight | LB::RelChar;
302 
303 FrameMap const aHCharMap[] =
304 {
305     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      HORI_CHAR_REL},
306     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     HORI_CHAR_REL},
307     {SwFPos::CENTER_HORI,   SwFPos::CENTER_HORI,    text::HoriOrientation::CENTER,    HORI_CHAR_REL},
308     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      HORI_CHAR_REL}
309 };
310 
311 #define HTML_HORI_CHAR_REL  (LB::Frame|LB::PrintArea|LB::RelChar)
312 
313 FrameMap const aHCharHtmlMap[] =
314 {
315     {SwFPos::LEFT,          SwFPos::LEFT,           text::HoriOrientation::LEFT,      HTML_HORI_CHAR_REL},
316     {SwFPos::RIGHT,         SwFPos::RIGHT,          text::HoriOrientation::RIGHT,     HTML_HORI_CHAR_REL}
317 };
318 
319 FrameMap const aHCharHtmlAbsMap[] =
320 {
321     {SwFPos::LEFT,          SwFPos::MIR_LEFT,       text::HoriOrientation::LEFT,      LB::PrintArea|LB::RelChar},
322     {SwFPos::RIGHT,         SwFPos::MIR_RIGHT,      text::HoriOrientation::RIGHT,     LB::PrintArea},
323     {SwFPos::FROMLEFT,      SwFPos::MIR_FROMLEFT,   text::HoriOrientation::NONE,      LB::RelPageFrame}
324 };
325 
326 // allow vertical alignment at page areas
327 constexpr auto VERT_CHAR_REL = LB::VertFrame | LB::VertPrintArea |
328                                       LB::RelPageFrame | LB::RelPagePrintArea;
329 
330 FrameMap const aVCharMap[] =
331 {
332     // introduce mappings for new vertical alignment at top of line <LB::VertLine>
333     // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
334     // Note: Because of these adjustments the map becomes ambiguous in its values
335     //       <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
336     //       in the methods <SwFramePage::FillRelLB(..)>, <SwFramePage::GetAlignment(..)>
337     //       and <SwFramePage::FillPosLB(..)>
338     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,           VERT_CHAR_REL|LB::RelChar},
339     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::BOTTOM,        VERT_CHAR_REL|LB::RelChar},
340     {SwFPos::BELOW,         SwFPos::BELOW,          text::VertOrientation::CHAR_BOTTOM,   LB::RelChar},
341     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,        VERT_CHAR_REL|LB::RelChar},
342     {SwFPos::FROMTOP,       SwFPos::FROMTOP,        text::VertOrientation::NONE,          VERT_CHAR_REL},
343     {SwFPos::FROMBOTTOM,    SwFPos::FROMBOTTOM,     text::VertOrientation::NONE,          LB::RelChar|LB::VertLine},
344     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::LINE_TOP,      LB::VertLine},
345     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::LINE_BOTTOM,   LB::VertLine},
346     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::LINE_CENTER,   LB::VertLine}
347 };
348 
349 FrameMap const aVCharHtmlMap[] =
350 {
351     {SwFPos::BELOW,         SwFPos::BELOW,          text::VertOrientation::CHAR_BOTTOM,   LB::RelChar}
352 };
353 
354 FrameMap const aVCharHtmlAbsMap[] =
355 {
356     {SwFPos::TOP,           SwFPos::TOP,            text::VertOrientation::TOP,           LB::RelChar},
357     {SwFPos::BELOW,             SwFPos::BELOW,          text::VertOrientation::CHAR_BOTTOM,   LB::RelChar}
358 };
359 
360 // anchored as character
361 FrameMap const aVAsCharMap[] =
362 {
363     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::TOP,           LB::RelBase},
364     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::BOTTOM,        LB::RelBase},
365     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,        LB::RelBase},
366 
367     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::CHAR_TOP,      LB::RelChar},
368     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::CHAR_BOTTOM,   LB::RelChar},
369     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CHAR_CENTER,   LB::RelChar},
370 
371     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::LINE_TOP,      LB::RelRow},
372     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::LINE_BOTTOM,   LB::RelRow},
373     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::LINE_CENTER,   LB::RelRow},
374 
375     {SwFPos::FROMBOTTOM,    SwFPos::FROMBOTTOM,     text::VertOrientation::NONE,          LB::RelBase}
376 };
377 
378 FrameMap const aVAsCharHtmlMap[] =
379 {
380     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::TOP,           LB::RelBase},
381     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::CENTER,        LB::RelBase},
382 
383     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::CHAR_TOP,      LB::RelChar},
384 
385     {SwFPos::TOP,               SwFPos::TOP,            text::VertOrientation::LINE_TOP,      LB::RelRow},
386     {SwFPos::BOTTOM,        SwFPos::BOTTOM,         text::VertOrientation::LINE_BOTTOM,   LB::RelRow},
387     {SwFPos::CENTER_VERT,   SwFPos::CENTER_VERT,    text::VertOrientation::LINE_CENTER,   LB::RelRow}
388 };
389 
390 const sal_uInt16 SwFramePage::aPageRg[] = {
391     RES_FRM_SIZE, RES_FRM_SIZE,
392     RES_VERT_ORIENT, RES_ANCHOR,
393     RES_COL, RES_COL,
394     RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW,
395     0
396 };
397 const sal_uInt16 SwFrameAddPage::aAddPgRg[] = {
398     RES_PROTECT,            RES_PROTECT,
399     RES_PRINT,              RES_PRINT,
400     FN_SET_FRM_NAME,        FN_SET_FRM_NAME,
401     FN_SET_FRM_ALT_NAME,    FN_SET_FRM_ALT_NAME,
402     FN_UNO_DESCRIPTION,     FN_UNO_DESCRIPTION,
403     0
404 };
405 
lcl_GetFrameMapCount(const FrameMap * pMap)406 static size_t lcl_GetFrameMapCount( const FrameMap* pMap)
407 {
408     if ( pMap )
409     {
410         if( pMap == aVParaHtmlMap)
411             return SAL_N_ELEMENTS(aVParaHtmlMap);
412         if( pMap == aVAsCharHtmlMap)
413             return SAL_N_ELEMENTS(aVAsCharHtmlMap);
414         if( pMap == aHParaHtmlMap)
415             return SAL_N_ELEMENTS(aHParaHtmlMap);
416         if( pMap == aHParaHtmlAbsMap)
417             return SAL_N_ELEMENTS(aHParaHtmlAbsMap);
418         if ( pMap == aVPageMap )
419             return SAL_N_ELEMENTS(aVPageMap);
420         if ( pMap == aVPageHtmlMap )
421             return SAL_N_ELEMENTS(aVPageHtmlMap);
422         if ( pMap == aVAsCharMap )
423             return SAL_N_ELEMENTS(aVAsCharMap);
424         if ( pMap == aVParaMap )
425             return SAL_N_ELEMENTS(aVParaMap);
426         if ( pMap == aHParaMap )
427             return SAL_N_ELEMENTS(aHParaMap);
428         if ( pMap == aHFrameMap )
429             return SAL_N_ELEMENTS(aHFrameMap);
430         if ( pMap == aVFrameMap )
431             return SAL_N_ELEMENTS(aVFrameMap);
432         if ( pMap == aHCharMap )
433             return SAL_N_ELEMENTS(aHCharMap);
434         if ( pMap == aHCharHtmlMap )
435             return SAL_N_ELEMENTS(aHCharHtmlMap);
436         if ( pMap == aHCharHtmlAbsMap )
437             return SAL_N_ELEMENTS(aHCharHtmlAbsMap);
438         if ( pMap == aVCharMap )
439             return SAL_N_ELEMENTS(aVCharMap);
440         if ( pMap == aVCharHtmlMap )
441             return SAL_N_ELEMENTS(aVCharHtmlMap);
442         if ( pMap == aVCharHtmlAbsMap )
443             return SAL_N_ELEMENTS(aVCharHtmlAbsMap);
444         if ( pMap == aHPageHtmlMap )
445             return SAL_N_ELEMENTS(aHPageHtmlMap);
446         if ( pMap == aHFlyHtmlMap )
447             return SAL_N_ELEMENTS(aHFlyHtmlMap);
448         if ( pMap == aVFlyHtmlMap )
449             return SAL_N_ELEMENTS(aVFlyHtmlMap);
450         return SAL_N_ELEMENTS(aHPageMap);
451     }
452     return 0;
453 }
454 
lcl_InsertVectors(weld::ComboBox & rBox,const std::vector<OUString> & rPrev,const std::vector<OUString> & rThis,const std::vector<OUString> & rNext,const std::vector<OUString> & rRemain)455 static void lcl_InsertVectors(weld::ComboBox& rBox,
456     const std::vector< OUString >& rPrev, const std::vector< OUString >& rThis,
457     const std::vector< OUString >& rNext, const std::vector< OUString >& rRemain)
458 {
459     for(const auto& rItem : rPrev)
460         rBox.append_text(rItem);
461     for(const auto& rItem : rThis)
462         rBox.append_text(rItem);
463     for(const auto& rItem : rNext)
464         rBox.append_text(rItem);
465     rBox.append_separator("");
466     //now insert all strings sorted
467     const auto nStartPos = rBox.get_count();
468 
469     for(const auto& rItem : rPrev)
470         ::InsertStringSorted("", rItem, rBox, nStartPos );
471     for(const auto& rItem : rThis)
472         ::InsertStringSorted("", rItem, rBox, nStartPos );
473     for(const auto& rItem : rNext)
474         ::InsertStringSorted("", rItem, rBox, nStartPos );
475     for(const auto& rItem : rRemain)
476         ::InsertStringSorted("", rItem, rBox, nStartPos );
477 }
478 
479 // --> OD 2009-08-31 #mongolianlayout#
480 // add input parameter
lcl_ChangeResIdToVerticalOrRTL(SvxSwFramePosString::StringId eStringId,bool bVertical,bool bVerticalL2R,bool bRTL)481 static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(SvxSwFramePosString::StringId eStringId, bool bVertical, bool bVerticalL2R, bool bRTL)
482 {
483     //special handling of STR_FROMLEFT
484     if ( SwFPos::FROMLEFT == eStringId )
485     {
486         eStringId = bVertical
487                     ? ( bRTL
488                         ? SwFPos::FROMBOTTOM
489                         : SwFPos::FROMTOP )
490                     : ( bRTL
491                         ? SwFPos::FROMRIGHT
492                         : SwFPos::FROMLEFT );
493         return eStringId;
494     }
495     // --> OD 2009-08-31 #mongolianlayout#
496     // special handling of STR_FROMTOP in case of mongolianlayout (vertical left-to-right)
497     if ( SwFPos::FROMTOP == eStringId &&
498          bVertical && bVerticalL2R )
499     {
500         eStringId = SwFPos::FROMLEFT;
501         return eStringId;
502     }
503     if ( bVertical )
504     {
505         //exchange horizontal strings with vertical strings and vice versa
506         static const StringIdPair_Impl aHoriIds[] =
507         {
508             {SwFPos::LEFT,           SwFPos::TOP},
509             {SwFPos::RIGHT,          SwFPos::BOTTOM},
510             {SwFPos::CENTER_HORI,    SwFPos::CENTER_VERT},
511             {SwFPos::FROMTOP,        SwFPos::FROMRIGHT},
512             {SwFPos::REL_PG_LEFT,    SwFPos::REL_PG_TOP},
513             {SwFPos::REL_PG_RIGHT,   SwFPos::REL_PG_BOTTOM} ,
514             {SwFPos::REL_FRM_LEFT,   SwFPos::REL_FRM_TOP},
515             {SwFPos::REL_FRM_RIGHT,  SwFPos::REL_FRM_BOTTOM}
516         };
517         static const StringIdPair_Impl aVertIds[] =
518         {
519             {SwFPos::TOP,            SwFPos::RIGHT},
520             {SwFPos::BOTTOM,         SwFPos::LEFT },
521             {SwFPos::CENTER_VERT,    SwFPos::CENTER_HORI},
522             {SwFPos::FROMTOP,        SwFPos::FROMRIGHT },
523             {SwFPos::REL_PG_TOP,     SwFPos::REL_PG_LEFT },
524             {SwFPos::REL_PG_BOTTOM,  SwFPos::REL_PG_RIGHT } ,
525             {SwFPos::REL_FRM_TOP,    SwFPos::REL_FRM_LEFT },
526             {SwFPos::REL_FRM_BOTTOM, SwFPos::REL_FRM_RIGHT }
527         };
528         // --> OD 2009-08-31 #monglianlayout#
529         static const StringIdPair_Impl aVertL2RIds[] =
530         {
531             {SwFPos::TOP,            SwFPos::LEFT },
532             {SwFPos::BOTTOM,         SwFPos::RIGHT },
533             {SwFPos::CENTER_VERT,    SwFPos::CENTER_HORI },
534             {SwFPos::FROMTOP,        SwFPos::FROMLEFT },
535             {SwFPos::REL_PG_TOP,     SwFPos::REL_PG_LEFT },
536             {SwFPos::REL_PG_BOTTOM,  SwFPos::REL_PG_RIGHT } ,
537             {SwFPos::REL_FRM_TOP,    SwFPos::REL_FRM_LEFT },
538             {SwFPos::REL_FRM_BOTTOM, SwFPos::REL_FRM_RIGHT }
539         };
540         for(const StringIdPair_Impl & rHoriId : aHoriIds)
541         {
542             if(rHoriId.eHori == eStringId)
543             {
544                 eStringId = rHoriId.eVert;
545                 return eStringId;
546             }
547         }
548         for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
549         {
550             // --> OD 2009-08-31 #mongolianlayout#
551             if ( !bVerticalL2R )
552             {
553                 if(aVertIds[nIndex].eHori == eStringId)
554                 {
555                     eStringId = aVertIds[nIndex].eVert;
556                     break;
557                 }
558             }
559             else
560             {
561                 if(aVertL2RIds[nIndex].eHori == eStringId)
562                 {
563                     eStringId = aVertL2RIds[nIndex].eVert;
564                     break;
565                 }
566             }
567         }
568     }
569     return eStringId;
570 }
571 
572 // helper method in order to determine all possible
573 // listbox relations in a relation map for a given relation
lcl_GetLBRelationsForRelations(const sal_Int16 _nRel)574 static LB lcl_GetLBRelationsForRelations( const sal_Int16 _nRel )
575 {
576     LB nLBRelations = LB::NONE;
577 
578     for (RelationMap const & i : aRelationMap)
579     {
580         if ( i.nRelation == _nRel )
581         {
582             nLBRelations |= i.nLBRelation;
583         }
584     }
585 
586     return nLBRelations;
587 }
588 
589 // helper method on order to determine all possible
590 // listbox relations in a relation map for a given string ID
lcl_GetLBRelationsForStrID(const FrameMap * _pMap,const SvxSwFramePosString::StringId _eStrId,const bool _bUseMirrorStr)591 static LB lcl_GetLBRelationsForStrID( const FrameMap* _pMap,
592                                              const SvxSwFramePosString::StringId _eStrId,
593                                              const bool _bUseMirrorStr )
594 {
595     LB nLBRelations = LB::NONE;
596 
597     size_t nRelMapSize = lcl_GetFrameMapCount( _pMap );
598     for ( size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
599     {
600         if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
601              ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
602         {
603             nLBRelations |= _pMap[nRelMapPos].nLBRelations;
604         }
605     }
606 
607     return nLBRelations;
608 }
609 
610 // standard frame TabPage
611 namespace
612 {
HandleAutoCB(bool _bChecked,weld::Label & _rFT_man,weld::Label & _rFT_auto,weld::MetricSpinButton & _rPF_Edit)613     void HandleAutoCB(bool _bChecked, weld::Label& _rFT_man, weld::Label& _rFT_auto, weld::MetricSpinButton& _rPF_Edit)
614     {
615         _rFT_man.set_visible( !_bChecked );
616         _rFT_auto.set_visible( _bChecked );
617         OUString accName = _bChecked ? _rFT_auto.get_label() : _rFT_man.get_label();
618         _rPF_Edit.set_accessible_name(accName);
619     }
620 }
621 
SwFramePage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)622 SwFramePage::SwFramePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
623     : SfxTabPage(pPage, pController, "modules/swriter/ui/frmtypepage.ui", "FrameTypePage", &rSet)
624     , m_bAtHorzPosModified(false)
625     , m_bAtVertPosModified(false)
626     , m_bFormat(false)
627     , m_bNew(true)
628     , m_bNoModifyHdl(true)
629     , m_bIsVerticalFrame(false)
630     , m_bIsVerticalL2R(false)
631     , m_bIsInRightToLeft(false)
632     , m_bHtmlMode(false)
633     , m_nHtmlMode(0)
634     , m_nUpperBorder(0)
635     , m_nLowerBorder(0)
636     , m_fWidthHeightRatio(1.0)
637     , mpToCharContentPos(nullptr)
638     , m_nOldH(text::HoriOrientation::CENTER)
639     , m_nOldHRel(text::RelOrientation::FRAME)
640     , m_nOldV(text::VertOrientation::TOP)
641     , m_nOldVRel(text::RelOrientation::PRINT_AREA)
642     , m_pVMap(nullptr)
643     , m_pHMap(nullptr)
644     , m_bAllowVertPositioning( true )
645     , m_bIsMathOLE(false)
646     , m_bIsMathBaselineAlignment(true)
647     , m_xWidthFT(m_xBuilder->weld_label("widthft"))
648     , m_xWidthAutoFT(m_xBuilder->weld_label("autowidthft"))
649     , m_xRelWidthCB(m_xBuilder->weld_check_button("relwidth"))
650     , m_xRelWidthRelationLB(m_xBuilder->weld_combo_box("relwidthrelation"))
651     , m_xAutoWidthCB(m_xBuilder->weld_check_button("autowidth"))
652     , m_xHeightFT(m_xBuilder->weld_label("heightft"))
653     , m_xHeightAutoFT(m_xBuilder->weld_label("autoheightft"))
654     , m_xRelHeightCB(m_xBuilder->weld_check_button("relheight"))
655     , m_xRelHeightRelationLB(m_xBuilder->weld_combo_box("relheightrelation"))
656     , m_xAutoHeightCB(m_xBuilder->weld_check_button("autoheight"))
657     , m_xFixedRatioCB(m_xBuilder->weld_check_button("ratio"))
658     , m_xRealSizeBT(m_xBuilder->weld_button("origsize"))
659     , m_xAnchorFrame(m_xBuilder->weld_widget("anchorframe"))
660     , m_xAnchorAtPageRB(m_xBuilder->weld_radio_button("topage"))
661     , m_xAnchorAtParaRB(m_xBuilder->weld_radio_button("topara"))
662     , m_xAnchorAtCharRB(m_xBuilder->weld_radio_button("tochar"))
663     , m_xAnchorAsCharRB(m_xBuilder->weld_radio_button("aschar"))
664     , m_xAnchorAtFrameRB(m_xBuilder->weld_radio_button("toframe"))
665     , m_xHorizontalFT(m_xBuilder->weld_label("horiposft"))
666     , m_xHorizontalDLB(m_xBuilder->weld_combo_box("horipos"))
667     , m_xAtHorzPosFT(m_xBuilder->weld_label("horibyft"))
668     , m_xAtHorzPosED(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
669     , m_xHoriRelationFT(m_xBuilder->weld_label("horitoft"))
670     , m_xHoriRelationLB(m_xBuilder->weld_combo_box("horianchor"))
671     , m_xMirrorPagesCB(m_xBuilder->weld_check_button("mirror"))
672     , m_xVerticalFT(m_xBuilder->weld_label("vertposft"))
673     , m_xVerticalDLB(m_xBuilder->weld_combo_box("vertpos"))
674     , m_xAtVertPosFT(m_xBuilder->weld_label("vertbyft"))
675     , m_xAtVertPosED(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
676     , m_xVertRelationFT(m_xBuilder->weld_label("verttoft"))
677     , m_xVertRelationLB(m_xBuilder->weld_combo_box("vertanchor"))
678     , m_xFollowTextFlowCB(m_xBuilder->weld_check_button("followtextflow"))
679     , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
680     , m_xWidthED(new SwPercentField(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM)))
681     , m_xHeightED(new SwPercentField(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM)))
682 {
683     const auto nWidthRequest = m_xAtHorzPosED->get_preferred_size().Width();
684     m_xAtHorzPosED->set_size_request(nWidthRequest, -1);
685     m_xAtVertPosED->set_size_request(nWidthRequest, -1);
686 
687     setOptimalFrameWidth();
688     setOptimalRelWidth();
689 
690     SetExchangeSupport();
691 
692     Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SwFramePage, ModifyHdl);
693     m_xWidthED->connect_value_changed( aLk3 );
694     m_xHeightED->connect_value_changed( aLk3 );
695     m_xAtHorzPosED->connect_value_changed( aLk3 );
696     m_xAtVertPosED->connect_value_changed( aLk3 );
697     m_xFollowTextFlowCB->connect_toggled(LINK(this, SwFramePage, RangeModifyClickHdl));
698 
699     Link<weld::Toggleable&,void> aLk2 = LINK(this, SwFramePage, AnchorTypeHdl);
700     m_xAnchorAtPageRB->connect_toggled( aLk2 );
701     m_xAnchorAtParaRB->connect_toggled( aLk2 );
702     m_xAnchorAtCharRB->connect_toggled( aLk2 );
703     m_xAnchorAsCharRB->connect_toggled( aLk2 );
704     m_xAnchorAtFrameRB->connect_toggled( aLk2 );
705 
706     m_xHorizontalDLB->connect_changed(LINK(this, SwFramePage, PosHdl));
707     m_xVerticalDLB->connect_changed(LINK(this, SwFramePage, PosHdl));
708 
709     m_xHoriRelationLB->connect_changed(LINK(this, SwFramePage, RelHdl));
710     m_xVertRelationLB->connect_changed(LINK(this, SwFramePage, RelHdl));
711 
712     m_xMirrorPagesCB->connect_toggled(LINK(this, SwFramePage, MirrorHdl));
713 
714     aLk2 = LINK(this, SwFramePage, RelSizeClickHdl);
715     m_xRelWidthCB->connect_toggled(aLk2);
716     m_xRelHeightCB->connect_toggled(aLk2);
717 
718     m_xAutoWidthCB->connect_toggled(LINK(this, SwFramePage, AutoWidthClickHdl));
719     m_xAutoHeightCB->connect_toggled(LINK(this, SwFramePage, AutoHeightClickHdl));
720 
721     if (comphelper::LibreOfficeKit::isActive())
722     {
723         m_xAnchorAtPageRB->hide();
724         m_xAnchorAtParaRB->hide();
725         m_xAnchorAtFrameRB->hide();
726     }
727 }
728 
~SwFramePage()729 SwFramePage::~SwFramePage()
730 {
731 }
732 
733 namespace
734 {
735     struct FrameMaps
736     {
737         FrameMap const * pMap;
738         size_t nCount;
739     };
740 }
741 
setOptimalFrameWidth()742 void SwFramePage::setOptimalFrameWidth()
743 {
744     static FrameMaps const aMaps[] = {
745         { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
746         { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
747         { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
748         { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
749         { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
750         { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
751         { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
752         { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
753         { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
754         { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
755         { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
756         { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
757         { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
758         { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
759         { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
760         { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
761         { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
762         { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
763         { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
764         { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
765         { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
766     };
767 
768     std::vector<SvxSwFramePosString::StringId> aFrames;
769     for (const FrameMaps & rMap : aMaps)
770     {
771         for (size_t j = 0; j < rMap.nCount; ++j)
772         {
773             aFrames.push_back(rMap.pMap[j].eStrId);
774             aFrames.push_back(rMap.pMap[j].eMirrorStrId);
775         }
776     }
777 
778     std::sort(aFrames.begin(), aFrames.end());
779     aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
780 
781     for (const auto& rFrame : aFrames)
782     {
783         m_xHorizontalDLB->append_text(SvxSwFramePosString::GetString(rFrame));
784     }
785 
786     Size aBiggest(m_xHorizontalDLB->get_preferred_size());
787     m_xHorizontalDLB->set_size_request(aBiggest.Width(), -1);
788     m_xVerticalDLB->set_size_request(aBiggest.Width(), -1);
789     m_xHorizontalDLB->clear();
790 }
791 
792 namespace
793 {
794     struct RelationMaps
795     {
796         RelationMap const * pMap;
797         size_t nCount;
798     };
799 }
800 
setOptimalRelWidth()801 void SwFramePage::setOptimalRelWidth()
802 {
803     static const RelationMaps aMaps[] = {
804         { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
805         { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
806     };
807 
808     std::vector<SvxSwFramePosString::StringId> aRels;
809     for (const RelationMaps & rMap : aMaps)
810     {
811         for (size_t j = 0; j < rMap.nCount; ++j)
812         {
813             aRels.push_back(rMap.pMap[j].eStrId);
814             aRels.push_back(rMap.pMap[j].eMirrorStrId);
815         }
816     }
817 
818     std::sort(aRels.begin(), aRels.end());
819     aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
820 
821     for (const auto& rRel : aRels)
822     {
823         m_xHoriRelationLB->append_text(SvxSwFramePosString::GetString(rRel));
824     }
825 
826     Size aBiggest(m_xHoriRelationLB->get_preferred_size());
827     m_xHoriRelationLB->set_size_request(aBiggest.Width(), -1);
828     m_xVertRelationLB->set_size_request(aBiggest.Width(), -1);
829     m_xRelWidthRelationLB->set_size_request(aBiggest.Width(), -1);
830     m_xRelHeightRelationLB->set_size_request(aBiggest.Width(), -1);
831     m_xHoriRelationLB->clear();
832 }
833 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)834 std::unique_ptr<SfxTabPage> SwFramePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
835 {
836     return std::make_unique<SwFramePage>(pPage, pController, *rSet);
837 }
838 
EnableGraficMode()839 void SwFramePage::EnableGraficMode()
840 {
841     // i#39692 - mustn't be called more than once
842     if (!m_xRealSizeBT->get_visible())
843     {
844         m_xWidthFT->show();
845         m_xWidthAutoFT->hide();
846         m_xAutoHeightCB->hide();
847 
848         m_xHeightFT->show();
849         m_xHeightAutoFT->hide();
850         m_xAutoWidthCB->hide();
851 
852         m_xRealSizeBT->show();
853     }
854 }
855 
getFrameDlgParentShell()856 SwWrtShell *SwFramePage::getFrameDlgParentShell()
857 {
858     return static_cast<SwFrameDlg*>(GetDialogController())->GetWrtShell();
859 }
860 
Reset(const SfxItemSet * rSet)861 void SwFramePage::Reset( const SfxItemSet *rSet )
862 {
863     SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell() :
864             getFrameDlgParentShell();
865 
866     m_nHtmlMode = ::GetHtmlMode(pSh->GetView().GetDocShell());
867     m_bHtmlMode = (m_nHtmlMode & HTMLMODE_ON) != 0;
868 
869     FieldUnit aMetric = ::GetDfltMetric(m_bHtmlMode);
870     m_xWidthED->SetMetric(aMetric);
871     m_xHeightED->SetMetric(aMetric);
872     ::SetFieldUnit(*m_xAtHorzPosED, aMetric);
873     ::SetFieldUnit(*m_xAtVertPosED, aMetric);
874 
875     const SfxPoolItem* pItem = nullptr;
876     const SwFormatAnchor& rAnchor = rSet->Get(RES_ANCHOR);
877 
878     if (SfxItemState::SET == rSet->GetItemState(FN_OLE_IS_MATH, false, &pItem))
879         m_bIsMathOLE = static_cast<const SfxBoolItem*>(pItem)->GetValue();
880     if (SfxItemState::SET == rSet->GetItemState(FN_MATH_BASELINE_ALIGNMENT, false, &pItem))
881         m_bIsMathBaselineAlignment = static_cast<const SfxBoolItem*>(pItem)->GetValue();
882     EnableVerticalPositioning( !(m_bIsMathOLE && m_bIsMathBaselineAlignment
883             && RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) );
884 
885     if (m_bFormat)
886     {
887         // at formats no to-fly anchor
888         m_xAnchorAtFrameRB->set_sensitive(false);
889         if (rSet->GetItemState(FN_KEEP_ASPECT_RATIO) != SfxItemState::SET)
890         {
891             m_xFixedRatioCB->set_sensitive(false);
892         }
893     }
894     else
895     {
896         if (rAnchor.GetAnchorId() != RndStdIds::FLY_AT_FLY && !pSh->IsFlyInFly())
897             m_xAnchorAtFrameRB->hide();
898         if ( pSh->IsFrameVertical( true, m_bIsInRightToLeft, m_bIsVerticalL2R ) )
899         {
900             OUString sHLabel = m_xHorizontalFT->get_label();
901             m_xHorizontalFT->set_label(m_xVerticalFT->get_label());
902             m_xVerticalFT->set_label(sHLabel);
903             m_bIsVerticalFrame = true;
904         }
905     }
906 
907     if ( m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog" )
908     {
909         OSL_ENSURE(pSh , "shell not found");
910         //OS: only for the variant Insert/Graphic/Properties
911         if(SfxItemState::SET == rSet->GetItemState(FN_PARAM_GRF_REALSIZE, false, &pItem))
912             m_aGrfSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
913         else
914             pSh->GetGrfSize( m_aGrfSize );
915 
916         if ( !m_bNew )
917         {
918             m_xRealSizeBT->connect_clicked(LINK(this, SwFramePage, RealSizeHdl));
919             EnableGraficMode();
920         }
921 
922         if (m_sDlgType == "PictureDialog")
923             m_xFixedRatioCB->set_active(false);
924         else
925         {
926             if ( m_bNew )
927                 SetPageTitle(SwResId(STR_FRMUI_OLE_INSERT));
928             else
929                 SetPageTitle(SwResId(STR_FRMUI_OLE_EDIT));
930         }
931     }
932     else
933     {
934         m_aGrfSize = rSet->Get(RES_FRM_SIZE).GetSize();
935     }
936 
937     // entering percent value made possible
938 
939     // the available space is not yet known so the RefValue has to be calculated from size and relative size values
940     // this is needed only if relative values are already set
941     const SwFormatFrameSize& rFrameSize = rSet->Get(RES_FRM_SIZE);
942 
943     m_xRelWidthRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::FRAME));
944     m_xRelWidthRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::REL_PG_FRAME));
945     if (rFrameSize.GetWidthPercent() != SwFormatFrameSize::SYNCED && rFrameSize.GetWidthPercent() != 0)
946     {
947         //calculate the reference value from the width and relative width values
948         sal_Int32 nSpace = rFrameSize.GetWidth() * 100 / rFrameSize.GetWidthPercent();
949         m_xWidthED->SetRefValue( nSpace );
950 
951         m_xRelWidthRelationLB->set_sensitive(true);
952     }
953     else
954         m_xRelWidthRelationLB->set_sensitive(false);
955 
956     m_xRelHeightRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::FRAME));
957     m_xRelHeightRelationLB->append_text(SvxSwFramePosString::GetString(SwFPos::REL_PG_FRAME));
958     if (rFrameSize.GetHeightPercent() != SwFormatFrameSize::SYNCED && rFrameSize.GetHeightPercent() != 0)
959     {
960         //calculate the reference value from the with and relative width values
961         sal_Int32 nSpace = rFrameSize.GetHeight() * 100 / rFrameSize.GetHeightPercent();
962         m_xHeightED->SetRefValue( nSpace );
963 
964         m_xRelHeightRelationLB->set_sensitive(true);
965     }
966     else
967         m_xRelHeightRelationLB->set_sensitive(false);
968 
969     // general initialisation part
970     switch(rAnchor.GetAnchorId())
971     {
972         case RndStdIds::FLY_AT_PAGE: m_xAnchorAtPageRB->set_active(true); break;
973         case RndStdIds::FLY_AT_PARA: m_xAnchorAtParaRB->set_active(true); break;
974         case RndStdIds::FLY_AT_CHAR: m_xAnchorAtCharRB->set_active(true); break;
975         case RndStdIds::FLY_AS_CHAR: m_xAnchorAsCharRB->set_active(true); break;
976         case RndStdIds::FLY_AT_FLY: m_xAnchorAtFrameRB->set_active(true);break;
977         default:; //prevent warning
978     }
979 
980     // i#22341 - determine content position of character
981     // Note: content position can be NULL
982     mpToCharContentPos = rAnchor.GetContentAnchor();
983 
984     // i#18732 - init checkbox value
985     {
986         const bool bFollowTextFlow =
987             rSet->Get(RES_FOLLOW_TEXT_FLOW).GetValue();
988         m_xFollowTextFlowCB->set_active(bFollowTextFlow);
989     }
990 
991     if(m_bHtmlMode)
992     {
993         m_xAutoHeightCB->set_sensitive(false);
994         m_xAutoWidthCB->set_sensitive(false);
995         m_xMirrorPagesCB->hide();
996         if (m_sDlgType == "FrameDialog")
997             m_xFixedRatioCB->set_sensitive(false);
998         // i#18732 hide checkbox in HTML mode
999         m_xFollowTextFlowCB->hide();
1000     }
1001     else
1002     {
1003         // enable/disable of check box 'Mirror on..'
1004         m_xMirrorPagesCB->set_sensitive(!m_xAnchorAsCharRB->get_active());
1005 
1006         // enable/disable check box 'Follow text flow'.
1007         // enable check box 'Follow text
1008         // flow' also for anchor type to-frame.
1009         m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
1010                                            m_xAnchorAtCharRB->get_active() ||
1011                                            m_xAnchorAtFrameRB->get_active());
1012     }
1013 
1014     Init(*rSet);
1015     m_xAtVertPosED->save_value();
1016     m_xAtHorzPosED->save_value();
1017     m_xFollowTextFlowCB->save_state();
1018 
1019     m_xWidthED->save_value();
1020     m_xHeightED->save_value();
1021 
1022     m_bNoModifyHdl = false;
1023     //lock PercentFields
1024     m_xWidthED->LockAutoCalculation(true);
1025     m_xHeightED->LockAutoCalculation(true);
1026     RangeModifyHdl();  // set all maximum values initially
1027     m_xHeightED->LockAutoCalculation(false);
1028     m_xWidthED->LockAutoCalculation(false);
1029 
1030     m_xAutoHeightCB->save_state();
1031     m_xAutoWidthCB->save_state();
1032 
1033     SwTwips nWidth  = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
1034     SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
1035     m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
1036 }
1037 
1038 // stuff attributes into the set when OK
FillItemSet(SfxItemSet * rSet)1039 bool SwFramePage::FillItemSet(SfxItemSet *rSet)
1040 {
1041     bool bRet = false;
1042     SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
1043                         : getFrameDlgParentShell();
1044     OSL_ENSURE( pSh , "shell not found");
1045     const SfxItemSet& rOldSet = GetItemSet();
1046     const SfxPoolItem* pOldItem = nullptr;
1047 
1048     RndStdIds eAnchorId = GetAnchor();
1049 
1050     if ( !m_bFormat || eAnchorId != RndStdIds::FLY_AT_FLY )
1051     {
1052         pOldItem = GetOldItem(*rSet, RES_ANCHOR);
1053         if (m_bNew || !pOldItem || eAnchorId != static_cast<const SwFormatAnchor*>(pOldItem)->GetAnchorId())
1054         {
1055             SwFormatAnchor aAnc( eAnchorId, pSh->GetPhyPageNum() );
1056             bRet = nullptr != rSet->Put( aAnc );
1057         }
1058     }
1059 
1060     if ( m_pHMap )
1061     {
1062         SwFormatHoriOrient aHoriOrient( rOldSet.Get(RES_HORI_ORIENT) );
1063 
1064         const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
1065         const sal_Int16 eHOri = GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB);
1066         const sal_Int16 eRel = GetRelation(*m_xHoriRelationLB);
1067 
1068         aHoriOrient.SetHoriOrient( eHOri );
1069         aHoriOrient.SetRelationOrient( eRel );
1070         aHoriOrient.SetPosToggle(m_xMirrorPagesCB->get_active());
1071 
1072         bool bMod = m_xAtHorzPosED->get_value_changed_from_saved();
1073         bMod |= m_xMirrorPagesCB->get_state_changed_from_saved();
1074 
1075         if ( eHOri == text::HoriOrientation::NONE &&
1076              (m_bNew || (m_bAtHorzPosModified || bMod) || m_nOldH != eHOri ) )
1077         {
1078             SwTwips nX = static_cast< SwTwips >(m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP)));
1079             aHoriOrient.SetPos( nX );
1080         }
1081 
1082         pOldItem = GetOldItem(*rSet, FN_HORI_ORIENT);
1083         bool bSame = false;
1084         if ((m_bNew == m_bFormat) && pOldItem)
1085         {
1086              bSame = aHoriOrient == static_cast<const SwFormatHoriOrient&>(*pOldItem);
1087         }
1088         if ((m_bNew && !m_bFormat) || ((m_bAtHorzPosModified || bMod) && !bSame))
1089         {
1090             bRet |= nullptr != rSet->Put( aHoriOrient );
1091         }
1092     }
1093 
1094     if ( m_pVMap )
1095     {
1096         // alignment vertical
1097         SwFormatVertOrient aVertOrient( rOldSet.Get(RES_VERT_ORIENT) );
1098 
1099         const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
1100         const sal_Int16 eVOri = GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB);
1101         const sal_Int16 eRel = GetRelation(*m_xVertRelationLB);
1102 
1103         aVertOrient.SetVertOrient    ( eVOri);
1104         aVertOrient.SetRelationOrient( eRel );
1105 
1106         bool bMod = m_xAtVertPosED->get_value_changed_from_saved();
1107 
1108         if ( eVOri == text::VertOrientation::NONE &&
1109              ( m_bNew || (m_bAtVertPosModified || bMod) || m_nOldV != eVOri) )
1110         {
1111             // vertical position
1112             // recalculate offset for character bound frames
1113             SwTwips nY = static_cast< SwTwips >(m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP)));
1114             if (eAnchorId == RndStdIds::FLY_AS_CHAR)
1115             {
1116                 nY *= -1;
1117             }
1118             aVertOrient.SetPos( nY );
1119         }
1120         pOldItem = GetOldItem(*rSet, FN_VERT_ORIENT);
1121         bool bSame = false;
1122         if((m_bNew == m_bFormat) && pOldItem)
1123         {
1124              bSame = m_bFormat ?
1125                       aVertOrient.GetVertOrient() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetVertOrient() &&
1126                       aVertOrient.GetRelationOrient() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetRelationOrient() &&
1127                       aVertOrient.GetPos() == static_cast<const SwFormatVertOrient*>(pOldItem)->GetPos()
1128                     : aVertOrient == static_cast<const SwFormatVertOrient&>(*pOldItem);
1129         }
1130         if( ( m_bNew && !m_bFormat ) || ((m_bAtVertPosModified || bMod) && !bSame ))
1131         {
1132             bRet |= nullptr != rSet->Put( aVertOrient );
1133         }
1134     }
1135 
1136     // set size
1137     // new exception: when the size of pMgr(, 0), then the properties
1138     // for a graphic that isn't even loaded, are set. Then no SetSize
1139     // is done here when the size settings were not changed by the
1140     // user.
1141     const SwFormatFrameSize& rOldSize = rOldSet.Get(RES_FRM_SIZE);
1142     SwFormatFrameSize aSz( rOldSize );
1143 
1144     auto nRelWidthRelation = m_xRelWidthRelationLB->get_active();
1145     if (nRelWidthRelation != -1)
1146     {
1147         if (nRelWidthRelation == 0)
1148             aSz.SetWidthPercentRelation(text::RelOrientation::FRAME);
1149         else if (nRelWidthRelation == 1)
1150             aSz.SetWidthPercentRelation(text::RelOrientation::PAGE_FRAME);
1151     }
1152     auto nRelHeightRelation = m_xRelHeightRelationLB->get_active();
1153     if (nRelHeightRelation != -1)
1154     {
1155         if (nRelHeightRelation == 0)
1156             aSz.SetHeightPercentRelation(text::RelOrientation::FRAME);
1157         else if (nRelHeightRelation == 1)
1158             aSz.SetHeightPercentRelation(text::RelOrientation::PAGE_FRAME);
1159     }
1160 
1161     bool bValueModified = m_xWidthED->get_value_changed_from_saved() ||
1162                           m_xHeightED->get_value_changed_from_saved();
1163     bool bCheckChanged = m_xRelWidthCB->get_state_changed_from_saved() ||
1164                          m_xRelHeightCB->get_state_changed_from_saved();
1165 
1166     bool bLegalValue = !(!rOldSize.GetWidth () && !rOldSize.GetHeight() &&
1167                             m_xWidthED->get_value() == m_xWidthED->get_min() &&
1168                             m_xHeightED->get_value() == m_xHeightED->get_min());
1169 
1170     if ((m_bNew && !m_bFormat) || ((bValueModified || bCheckChanged) && bLegalValue))
1171     {
1172         sal_Int64 nNewWidth  = m_xWidthED->DenormalizePercent(m_xWidthED->GetRealValue(FieldUnit::TWIP));
1173         sal_Int64 nNewHeight = m_xHeightED->DenormalizePercent(m_xHeightED->GetRealValue(FieldUnit::TWIP));
1174         aSz.SetWidth (static_cast< SwTwips >(nNewWidth));
1175         aSz.SetHeight(static_cast< SwTwips >(nNewHeight));
1176 
1177         if (m_xRelWidthCB->get_active())
1178         {
1179             aSz.SetWidthPercent(static_cast<sal_uInt8>(std::min(MAX_PERCENT_WIDTH, m_xWidthED->Convert(m_xWidthED->NormalizePercent(nNewWidth), FieldUnit::TWIP, FieldUnit::PERCENT))));
1180         }
1181         else
1182             aSz.SetWidthPercent(0);
1183         if (m_xRelHeightCB->get_active())
1184             aSz.SetHeightPercent(static_cast<sal_uInt8>(std::min(MAX_PERCENT_HEIGHT, m_xHeightED->Convert(m_xHeightED->NormalizePercent(nNewHeight), FieldUnit::TWIP, FieldUnit::PERCENT))));
1185         else
1186             aSz.SetHeightPercent(0);
1187 
1188         if (m_xFixedRatioCB->get_active() && (m_xRelWidthCB->get_active() != m_xRelHeightCB->get_active()))
1189         {
1190             if (m_xRelWidthCB->get_active())
1191                 aSz.SetHeightPercent(SwFormatFrameSize::SYNCED);
1192             else
1193                 aSz.SetWidthPercent(SwFormatFrameSize::SYNCED);
1194         }
1195     }
1196     if( !IsInGraficMode() )
1197     {
1198         if (m_xAutoHeightCB->get_state_changed_from_saved())
1199         {
1200             SwFrameSize eFrameSize = m_xAutoHeightCB->get_active()? SwFrameSize::Minimum : SwFrameSize::Fixed;
1201             if( eFrameSize != aSz.GetHeightSizeType() )
1202                 aSz.SetHeightSizeType(eFrameSize);
1203         }
1204         if (m_xAutoWidthCB->get_state_changed_from_saved())
1205         {
1206             SwFrameSize eFrameSize = m_xAutoWidthCB->get_active()? SwFrameSize::Minimum : SwFrameSize::Fixed;
1207             if( eFrameSize != aSz.GetWidthSizeType() )
1208                 aSz.SetWidthSizeType( eFrameSize );
1209         }
1210     }
1211     if (m_xFixedRatioCB->get_state_changed_from_saved())
1212         bRet |= nullptr != rSet->Put(SfxBoolItem(FN_KEEP_ASPECT_RATIO, m_xFixedRatioCB->get_active()));
1213 
1214     pOldItem = GetOldItem(*rSet, RES_FRM_SIZE);
1215 
1216     if ((pOldItem && aSz != *pOldItem) || (!pOldItem && !m_bFormat) ||
1217             (m_bFormat &&
1218                 (aSz.GetWidth() > 0 || aSz.GetWidthPercent() > 0) &&
1219                     (aSz.GetHeight() > 0 || aSz.GetHeightPercent() > 0)))
1220     {
1221         if (aSz.GetHeightSizeType() == SwFrameSize::Variable)    // there is no VAR_SIZE in frames
1222             aSz.SetHeightSizeType(SwFrameSize::Minimum);
1223 
1224         bRet |= nullptr != rSet->Put( aSz );
1225     }
1226     if (m_xFollowTextFlowCB->get_state_changed_from_saved())
1227     {
1228         bRet |= nullptr != rSet->Put(SwFormatFollowTextFlow(m_xFollowTextFlowCB->get_active()));
1229     }
1230     return bRet;
1231 }
1232 
1233 // initialise horizontal and vertical Pos
InitPos(RndStdIds eId,sal_Int16 nH,sal_Int16 nHRel,sal_Int16 nV,sal_Int16 nVRel,tools::Long nX,tools::Long nY)1234 void SwFramePage::InitPos(RndStdIds eId,
1235                                 sal_Int16 nH,
1236                                 sal_Int16 nHRel,
1237                                 sal_Int16 nV,
1238                                 sal_Int16 nVRel,
1239                                 tools::Long   nX,
1240                                 tools::Long   nY)
1241 {
1242     auto nPos = m_xVerticalDLB->get_active();
1243     if (nPos != -1 && m_pVMap)
1244     {
1245         m_nOldV    = m_pVMap[nPos].nAlign;
1246 
1247         nPos = m_xVertRelationLB->get_active();
1248         if (nPos != -1)
1249             m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertRelationLB->get_id(nPos).toInt64())->nRelation;
1250     }
1251 
1252     nPos = m_xHorizontalDLB->get_active();
1253     if (nPos != -1 && m_pHMap)
1254     {
1255         m_nOldH    = m_pHMap[nPos].nAlign;
1256 
1257         nPos = m_xHoriRelationLB->get_active();
1258         if (nPos != -1)
1259             m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriRelationLB->get_id(nPos).toInt64())->nRelation;
1260     }
1261 
1262     bool bEnable = true;
1263     if ( eId == RndStdIds::FLY_AT_PAGE )
1264     {
1265         m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
1266         m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
1267     }
1268     else if ( eId == RndStdIds::FLY_AT_FLY )
1269     {
1270         // own vertical alignment map for to frame
1271         // anchored objects.
1272         m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
1273         m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
1274     }
1275     else if ( eId == RndStdIds::FLY_AT_PARA )
1276     {
1277         if(m_bHtmlMode)
1278         {
1279             m_pVMap = aVParaHtmlMap;
1280             m_pHMap = aHParaHtmlAbsMap;
1281         }
1282         else
1283         {
1284             m_pVMap = aVParaMap;
1285             m_pHMap = aHParaMap;
1286         }
1287     }
1288     else if ( eId == RndStdIds::FLY_AT_CHAR )
1289     {
1290         if(m_bHtmlMode)
1291         {
1292             m_pVMap = aVCharHtmlAbsMap;
1293             m_pHMap = aHCharHtmlAbsMap;
1294         }
1295         else
1296         {
1297             m_pVMap = aVCharMap;
1298             m_pHMap = aHCharMap;
1299         }
1300     }
1301     else if ( eId == RndStdIds::FLY_AS_CHAR )
1302     {
1303         m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap     : aVAsCharMap;
1304         m_pHMap = nullptr;
1305         bEnable = false;
1306     }
1307     m_xHorizontalDLB->set_sensitive( bEnable );
1308     m_xHorizontalFT->set_sensitive( bEnable );
1309 
1310     // select current Pos
1311     // horizontal
1312     if ( nH < 0 )
1313     {
1314         nH    = m_nOldH;
1315         nHRel = m_nOldHRel;
1316     }
1317     sal_Int32 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHorizontalDLB);
1318     FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriRelationLB, *m_xHoriRelationFT);
1319 
1320     // vertical
1321     if ( nV < 0 )
1322     {
1323         nV    = m_nOldV;
1324         nVRel = m_nOldVRel;
1325     }
1326     nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVerticalDLB);
1327     FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertRelationLB, *m_xVertRelationFT);
1328 
1329     bEnable = nH == text::HoriOrientation::NONE && eId != RndStdIds::FLY_AS_CHAR;
1330     if (!bEnable)
1331         m_xAtHorzPosED->set_value(0, FieldUnit::TWIP);
1332     else
1333     {
1334         if (nX != LONG_MAX)
1335             m_xAtHorzPosED->set_value(m_xAtHorzPosED->normalize(nX), FieldUnit::TWIP);
1336     }
1337     m_xAtHorzPosFT->set_sensitive( bEnable );
1338     m_xAtHorzPosED->set_sensitive( bEnable );
1339 
1340     bEnable = nV == text::VertOrientation::NONE;
1341     if ( !bEnable )
1342         m_xAtVertPosED->set_value(0, FieldUnit::TWIP);
1343     else
1344     {
1345         if (eId == RndStdIds::FLY_AS_CHAR)
1346         {
1347             if ( nY == LONG_MAX )
1348                 nY = 0;
1349             else
1350                 nY *= -1;
1351         }
1352         if ( nY != LONG_MAX )
1353             m_xAtVertPosED->set_value(m_xAtVertPosED->normalize(nY), FieldUnit::TWIP);
1354     }
1355     m_xAtVertPosFT->set_sensitive( bEnable && m_bAllowVertPositioning );
1356     m_xAtVertPosED->set_sensitive( bEnable && m_bAllowVertPositioning );
1357     UpdateExample();
1358 }
1359 
FillPosLB(const FrameMap * _pMap,const sal_Int16 _nAlign,const sal_Int16 _nRel,weld::ComboBox & _rLB)1360 sal_Int32 SwFramePage::FillPosLB(const FrameMap* _pMap,
1361                             const sal_Int16 _nAlign,
1362                             const sal_Int16 _nRel,
1363                             weld::ComboBox& _rLB )
1364 {
1365     OUString sSelEntry;
1366     const OUString sOldEntry = _rLB.get_active_text();
1367 
1368     _rLB.clear();
1369 
1370     // i#22341 determine all possible listbox relations for
1371     // given relation for map <aVCharMap>
1372     const LB nLBRelations = (_pMap != aVCharMap)
1373                                ? LB::NONE
1374                                : ::lcl_GetLBRelationsForRelations( _nRel );
1375 
1376     // fill Listbox
1377     size_t nCount = ::lcl_GetFrameMapCount(_pMap);
1378     for (size_t i = 0; _pMap && i < nCount; ++i)
1379     {
1380 //      Why not from the left/from inside or from above?
1381         SvxSwFramePosString::StringId eStrId = m_xMirrorPagesCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
1382         // --> OD 2009-08-31 #mongolianlayout#
1383         eStrId = lcl_ChangeResIdToVerticalOrRTL( eStrId,
1384                                                  m_bIsVerticalFrame,
1385                                                  m_bIsVerticalL2R,
1386                                                  m_bIsInRightToLeft);
1387         OUString sEntry(SvxSwFramePosString::GetString(eStrId));
1388         if (_rLB.find_text(sEntry) == -1)
1389         {
1390             // don't insert entries when frames are character bound
1391             _rLB.append_text(sEntry);
1392         }
1393         // i#22341 - add condition to handle map <aVCharMap>
1394         // that is ambiguous in the alignment.
1395         if ( _pMap[i].nAlign == _nAlign &&
1396              ( (_pMap != aVCharMap) || _pMap[i].nLBRelations & nLBRelations ) )
1397         {
1398             sSelEntry = sEntry;
1399         }
1400     }
1401 
1402     _rLB.set_active_text(sSelEntry);
1403     if (_rLB.get_active() == -1)
1404         _rLB.set_active_text(sOldEntry);
1405 
1406     if (_rLB.get_active() == -1)
1407         _rLB.set_active(0);
1408 
1409     PosHdl(_rLB);
1410 
1411     return GetMapPos(_pMap, _rLB);
1412 }
1413 
FillRelLB(const FrameMap * _pMap,const sal_uInt16 _nLBSelPos,const sal_Int16 _nAlign,const sal_Int16 _nRel,weld::ComboBox & _rLB,weld::Label & _rFT)1414 void SwFramePage::FillRelLB(const FrameMap* _pMap,
1415                             const sal_uInt16 _nLBSelPos,
1416                             const sal_Int16 _nAlign,
1417                             const sal_Int16 _nRel,
1418                             weld::ComboBox& _rLB,
1419                             weld::Label& _rFT)
1420 {
1421     OUString sSelEntry;
1422     LB       nLBRelations = LB::NONE;
1423     size_t   nMapCount = ::lcl_GetFrameMapCount(_pMap);
1424 
1425     _rLB.clear();
1426 
1427     if (_nLBSelPos < nMapCount)
1428     {
1429         if (_pMap == aVAsCharHtmlMap || _pMap == aVAsCharMap)
1430         {
1431             const OUString sOldEntry(_rLB.get_active_text());
1432             SvxSwFramePosString::StringId eStrId = _pMap[_nLBSelPos].eStrId;
1433 
1434             for (size_t nMapPos = 0; nMapPos < nMapCount; nMapPos++)
1435             {
1436                 if (_pMap[nMapPos].eStrId == eStrId)
1437                 {
1438                     nLBRelations = _pMap[nMapPos].nLBRelations;
1439                     for (RelationMap const & rCharMap : aAsCharRelationMap)
1440                     {
1441                         if (nLBRelations & rCharMap.nLBRelation)
1442                         {
1443                             // --> OD 2009-08-31 #mongolianlayout#
1444                             SvxSwFramePosString::StringId sStrId1 =
1445                                 lcl_ChangeResIdToVerticalOrRTL( rCharMap.eStrId,
1446                                                                 m_bIsVerticalFrame,
1447                                                                 m_bIsVerticalL2R,
1448                                                                 m_bIsInRightToLeft);
1449                             const OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
1450                             _rLB.append(OUString::number(reinterpret_cast<sal_Int64>(&rCharMap)), sEntry);
1451                             if (_pMap[nMapPos].nAlign == _nAlign)
1452                                 sSelEntry = sEntry;
1453                             break;
1454                         }
1455                     }
1456                 }
1457             }
1458             if (!sSelEntry.isEmpty())
1459                 _rLB.set_active_text(sSelEntry);
1460             else
1461             {
1462                 _rLB.set_active_text(sOldEntry);
1463 
1464                 if (_rLB.get_active() == -1)
1465                 {
1466                     for (int i = 0; i < _rLB.get_count(); i++)
1467                     {
1468                         RelationMap *pEntry = reinterpret_cast<RelationMap*>(_rLB.get_id(i).toInt64());
1469                         if (pEntry->nLBRelation == LB::RelChar) // default
1470                         {
1471                             _rLB.set_active(i);
1472                             break;
1473                         }
1474                     }
1475                 }
1476             }
1477         }
1478         else
1479         {
1480             // special handling for map <aVCharMap>,
1481             // because its ambiguous in its <eStrId>/<eMirrorStrId>.
1482             if ( _pMap == aVCharMap )
1483             {
1484                 nLBRelations = ::lcl_GetLBRelationsForStrID( _pMap,
1485                                              ( m_xMirrorPagesCB->get_active()
1486                                                ? _pMap[_nLBSelPos].eMirrorStrId
1487                                                : _pMap[_nLBSelPos].eStrId),
1488                                              m_xMirrorPagesCB->get_active() );
1489             }
1490             else
1491             {
1492                 nLBRelations = _pMap[_nLBSelPos].nLBRelations;
1493             }
1494 
1495             for (sal_uLong nBit = 1; nBit < 0x80000000; nBit <<= 1)
1496             {
1497                 if (nLBRelations & static_cast<LB>(nBit))
1498                 {
1499                     for (RelationMap const & rMap : aRelationMap)
1500                     {
1501                         if (rMap.nLBRelation == static_cast<LB>(nBit))
1502                         {
1503                             SvxSwFramePosString::StringId eStrId1 = m_xMirrorPagesCB->get_active() ?
1504                                             rMap.eMirrorStrId : rMap.eStrId;
1505                             // --> OD 2009-08-31 #mongolianlayout#
1506                             eStrId1 =
1507                                 lcl_ChangeResIdToVerticalOrRTL( eStrId1,
1508                                                                 m_bIsVerticalFrame,
1509                                                                 m_bIsVerticalL2R,
1510                                                                 m_bIsInRightToLeft);
1511                             const OUString sEntry = SvxSwFramePosString::GetString(eStrId1);
1512                             _rLB.append(OUString::number(reinterpret_cast<sal_Int64>(&rMap)), sEntry);
1513                             if (sSelEntry.isEmpty() && rMap.nRelation == _nRel)
1514                                 sSelEntry = sEntry;
1515                         }
1516                     }
1517                 }
1518             }
1519             if (!sSelEntry.isEmpty())
1520                 _rLB.set_active_text(sSelEntry);
1521             else
1522             {
1523                 // Probably anchor switch. So look for similar relation
1524                 sal_Int16 nSimRel = -1;
1525                 switch (_nRel)
1526                 {
1527                     case text::RelOrientation::FRAME:
1528                         nSimRel = text::RelOrientation::PAGE_FRAME;
1529                         break;
1530                     case text::RelOrientation::PRINT_AREA:
1531                         nSimRel = text::RelOrientation::PAGE_PRINT_AREA;
1532                         break;
1533                     case text::RelOrientation::PAGE_LEFT:
1534                         nSimRel = text::RelOrientation::FRAME_LEFT;
1535                         break;
1536                     case text::RelOrientation::PAGE_RIGHT:
1537                         nSimRel = text::RelOrientation::FRAME_RIGHT;
1538                         break;
1539                     case text::RelOrientation::FRAME_LEFT:
1540                         nSimRel = text::RelOrientation::PAGE_LEFT;
1541                         break;
1542                     case text::RelOrientation::FRAME_RIGHT:
1543                         nSimRel = text::RelOrientation::PAGE_RIGHT;
1544                         break;
1545                     case text::RelOrientation::PAGE_FRAME:
1546                         nSimRel = text::RelOrientation::FRAME;
1547                         break;
1548                     case text::RelOrientation::PAGE_PRINT_AREA:
1549                         nSimRel = text::RelOrientation::PRINT_AREA;
1550                         break;
1551 
1552                     default:
1553                         if (_rLB.get_active() != -1)
1554                         {
1555                             RelationMap *pEntry = reinterpret_cast<RelationMap*>(_rLB.get_id(_rLB.get_count() - 1).toInt64());
1556                             nSimRel = pEntry->nRelation;
1557                         }
1558                         break;
1559                 }
1560 
1561                 for (int i = 0; i < _rLB.get_count(); i++)
1562                 {
1563                     RelationMap *pEntry = reinterpret_cast<RelationMap*>(_rLB.get_id(i).toInt64());
1564                     if (pEntry->nRelation == nSimRel)
1565                     {
1566                         _rLB.set_active(i);
1567                         break;
1568                     }
1569                 }
1570 
1571                 if (_rLB.get_active() == -1)
1572                     _rLB.set_active(0);
1573             }
1574         }
1575     }
1576 
1577     const bool bEnable = _rLB.get_count() != 0
1578             && (&_rLB != m_xVertRelationLB.get() || m_bAllowVertPositioning);
1579     _rLB.set_sensitive( bEnable );
1580     _rFT.set_sensitive( bEnable );
1581 
1582     RelHdl(_rLB);
1583 }
1584 
GetRelation(const weld::ComboBox & rRelationLB)1585 sal_Int16 SwFramePage::GetRelation(const weld::ComboBox& rRelationLB)
1586 {
1587     const auto nPos = rRelationLB.get_active();
1588     if (nPos != -1)
1589     {
1590         RelationMap *pEntry = reinterpret_cast<RelationMap *>(rRelationLB.get_id(nPos).toInt64());
1591         return pEntry->nRelation;
1592     }
1593 
1594     return 0;
1595 }
1596 
GetAlignment(FrameMap const * pMap,sal_Int32 nMapPos,const weld::ComboBox & rRelationLB)1597 sal_Int16 SwFramePage::GetAlignment(FrameMap const *pMap, sal_Int32 nMapPos,
1598                                     const weld::ComboBox& rRelationLB)
1599 {
1600     if (!pMap || nMapPos < 0)
1601         return 0;
1602 
1603     const size_t nMapCount = ::lcl_GetFrameMapCount(pMap);
1604 
1605     if (o3tl::make_unsigned(nMapPos) >= nMapCount)
1606         return 0;
1607 
1608     // i#22341 special handling also for map <aVCharMap>,
1609     // because it contains ambiguous items for alignment
1610     if ( pMap != aVAsCharHtmlMap && pMap != aVAsCharMap && pMap != aVCharMap )
1611         return pMap[nMapPos].nAlign;
1612 
1613     if (rRelationLB.get_active() == -1)
1614         return 0;
1615 
1616     const RelationMap *const pRelationMap = reinterpret_cast<const RelationMap *>(
1617         rRelationLB.get_active_id().toInt64());
1618     const LB nRel = pRelationMap->nLBRelation;
1619     const SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
1620 
1621     for (size_t i = 0; i < nMapCount; ++i)
1622     {
1623         if (pMap[i].eStrId == eStrId && (pMap[i].nLBRelations & nRel))
1624             return pMap[i].nAlign;
1625     }
1626 
1627     return 0;
1628 }
1629 
GetMapPos(const FrameMap * pMap,const weld::ComboBox & rAlignLB)1630 sal_Int32 SwFramePage::GetMapPos(const FrameMap *pMap, const weld::ComboBox& rAlignLB)
1631 {
1632     sal_Int32 nMapPos = 0;
1633     auto nLBSelPos = rAlignLB.get_active();
1634 
1635     if (nLBSelPos != -1)
1636     {
1637         if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
1638         {
1639             const size_t nMapCount = ::lcl_GetFrameMapCount(pMap);
1640             const OUString sSelEntry(rAlignLB.get_active_text());
1641 
1642             for (size_t i = 0; i < nMapCount; i++)
1643             {
1644                 SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
1645 
1646                 OUString sEntry = SvxSwFramePosString::GetString(eResId);
1647                 sEntry = MnemonicGenerator::EraseAllMnemonicChars( sEntry );
1648 
1649                 if (sEntry == sSelEntry)
1650                 {
1651                     nMapPos = static_cast< sal_Int32 >(i);
1652                     break;
1653                 }
1654             }
1655         }
1656         else
1657             nMapPos = nLBSelPos;
1658     }
1659 
1660     return nMapPos;
1661 }
1662 
GetAnchor() const1663 RndStdIds SwFramePage::GetAnchor() const
1664 {
1665     RndStdIds nRet = RndStdIds::FLY_AT_PAGE;
1666     if (m_xAnchorAtParaRB->get_active())
1667     {
1668         nRet = RndStdIds::FLY_AT_PARA;
1669     }
1670     else if (m_xAnchorAtCharRB->get_active())
1671     {
1672         nRet = RndStdIds::FLY_AT_CHAR;
1673     }
1674     else if (m_xAnchorAsCharRB->get_active())
1675     {
1676         nRet = RndStdIds::FLY_AS_CHAR;
1677     }
1678     else if (m_xAnchorAtFrameRB->get_active())
1679     {
1680         nRet = RndStdIds::FLY_AT_FLY;
1681     }
1682     return nRet;
1683 }
1684 
1685 // Bsp - Update
ActivatePage(const SfxItemSet & rSet)1686 void SwFramePage::ActivatePage(const SfxItemSet& rSet)
1687 {
1688     m_bNoModifyHdl = true;
1689     Init(rSet);
1690     m_bNoModifyHdl = false;
1691     //lock PercentFields
1692     m_xWidthED->LockAutoCalculation(true);
1693     m_xHeightED->LockAutoCalculation(true);
1694     RangeModifyHdl();  // set all maximum values initially
1695     m_xHeightED->LockAutoCalculation(false);
1696     m_xWidthED->LockAutoCalculation(false);
1697     m_xFollowTextFlowCB->save_state();
1698 }
1699 
DeactivatePage(SfxItemSet * _pSet)1700 DeactivateRC SwFramePage::DeactivatePage(SfxItemSet * _pSet)
1701 {
1702     if ( _pSet )
1703     {
1704         FillItemSet( _pSet );
1705 
1706         if (!m_bFormat) // tdf#112574 no anchor in styles
1707         {
1708             //FillItemSet doesn't set the anchor into the set when it matches
1709             //the original. But for the other pages we need the current anchor.
1710             SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
1711                                 : getFrameDlgParentShell();
1712             RndStdIds eAnchorId = GetAnchor();
1713             SwFormatAnchor aAnc( eAnchorId, pSh->GetPhyPageNum() );
1714             _pSet->Put( aAnc );
1715         }
1716     }
1717 
1718     return DeactivateRC::LeavePage;
1719 }
1720 
1721 // swap left/right with inside/outside
IMPL_LINK_NOARG(SwFramePage,MirrorHdl,weld::Toggleable &,void)1722 IMPL_LINK_NOARG(SwFramePage, MirrorHdl, weld::Toggleable&, void)
1723 {
1724     RndStdIds eId = GetAnchor();
1725     InitPos(eId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
1726 }
1727 
IMPL_LINK(SwFramePage,RelSizeClickHdl,weld::Toggleable &,rBtn,void)1728 IMPL_LINK( SwFramePage, RelSizeClickHdl, weld::Toggleable&, rBtn, void )
1729 {
1730     if (&rBtn == m_xRelWidthCB.get())
1731     {
1732         m_xWidthED->ShowPercent(rBtn.get_active());
1733         m_xRelWidthRelationLB->set_sensitive(rBtn.get_active());
1734         if (rBtn.get_active())
1735             m_xWidthED->get()->set_max(MAX_PERCENT_WIDTH, FieldUnit::NONE);
1736     }
1737     else // rBtn == m_xRelHeightCB.get()
1738     {
1739         m_xHeightED->ShowPercent(rBtn.get_active());
1740         m_xRelHeightRelationLB->set_sensitive(rBtn.get_active());
1741         if (rBtn.get_active())
1742             m_xHeightED->get()->set_max(MAX_PERCENT_HEIGHT, FieldUnit::NONE);
1743     }
1744 
1745     RangeModifyHdl();  // correct the values again
1746 
1747     if (&rBtn == m_xRelWidthCB.get())
1748         ModifyHdl(*m_xWidthED->get());
1749     else // rBtn == m_xRelHeightCB.get()
1750         ModifyHdl(*m_xHeightED->get());
1751 }
1752 
1753 // range check
IMPL_LINK_NOARG(SwFramePage,RangeModifyClickHdl,weld::Toggleable &,void)1754 IMPL_LINK_NOARG(SwFramePage, RangeModifyClickHdl, weld::Toggleable&, void)
1755 {
1756     RangeModifyHdl();
1757 }
1758 
RangeModifyHdl()1759 void SwFramePage::RangeModifyHdl()
1760 {
1761     if (m_bNoModifyHdl)
1762         return;
1763 
1764     SwWrtShell* pSh = m_bFormat ? ::GetActiveWrtShell()
1765                         : getFrameDlgParentShell();
1766     OSL_ENSURE(pSh , "shell not found");
1767     SwFlyFrameAttrMgr aMgr( m_bNew, pSh, GetItemSet() );
1768     SvxSwFrameValidation        aVal;
1769 
1770     aVal.nAnchorType = GetAnchor();
1771     aVal.bAutoHeight = m_xAutoHeightCB->get_active();
1772     aVal.bMirror = m_xMirrorPagesCB->get_active();
1773     aVal.bFollowTextFlow = m_xFollowTextFlowCB->get_active();
1774 
1775     if ( m_pHMap )
1776     {
1777         // alignment horizontal
1778         const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
1779         aVal.nHoriOrient = GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB);
1780         aVal.nHRelOrient = GetRelation(*m_xHoriRelationLB);
1781     }
1782     else
1783         aVal.nHoriOrient = text::HoriOrientation::NONE;
1784 
1785     if ( m_pVMap )
1786     {
1787         // alignment vertical
1788         const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
1789         aVal.nVertOrient = GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB);
1790         aVal.nVRelOrient = GetRelation(*m_xVertRelationLB);
1791     }
1792     else
1793         aVal.nVertOrient = text::VertOrientation::NONE;
1794 
1795     const tools::Long nAtHorzPosVal = static_cast< tools::Long >(
1796                     m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP)) );
1797     const tools::Long nAtVertPosVal = static_cast< tools::Long >(
1798                     m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP)) );
1799 
1800     aVal.nHPos = nAtHorzPosVal;
1801     aVal.nVPos = nAtVertPosVal;
1802 
1803     aMgr.ValidateMetrics(aVal, mpToCharContentPos, true);   // one time, to get reference values for percental values
1804 
1805     // set reference values for percental values (100%) ...
1806     m_xWidthED->SetRefValue(aVal.aPercentSize.Width());
1807     m_xHeightED->SetRefValue(aVal.aPercentSize.Height());
1808 
1809     // ... and correctly convert width and height with it
1810     SwTwips nWidth  = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
1811     SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
1812     aVal.nWidth  = nWidth;
1813     aVal.nHeight = nHeight;
1814 
1815     aMgr.ValidateMetrics(aVal, mpToCharContentPos);    // one more time, to determine all remaining values with correct width and height.
1816 
1817     // all columns have to be correct
1818     const SfxItemSet* pExampleSet = GetDialogExampleSet();
1819     if (pExampleSet && SfxItemState::DEFAULT <= pExampleSet->GetItemState(RES_COL))
1820     {
1821         const SwFormatCol& rCol = pExampleSet->Get(RES_COL);
1822         if ( rCol.GetColumns().size() > 1 )
1823         {
1824             for (const SwColumn & i : rCol.GetColumns())
1825             {
1826                 aVal.nMinWidth += i.GetLeft() +
1827                                   i.GetRight() +
1828                                   MINFLY;
1829             }
1830             aVal.nMinWidth -= MINFLY;//one was already in there!
1831         }
1832     }
1833 
1834     nWidth = aVal.nWidth;
1835     nHeight = aVal.nHeight;
1836 
1837     // minimum range also for template
1838     m_xHeightED->set_min(m_xHeightED->NormalizePercent(aVal.nMinHeight), FieldUnit::TWIP);
1839     m_xWidthED->set_min(m_xWidthED->NormalizePercent(aVal.nMinWidth), FieldUnit::TWIP);
1840 
1841     SwTwips nMaxWidth(aVal.nMaxWidth);
1842     SwTwips nMaxHeight(aVal.nMaxHeight);
1843 
1844     if (aVal.bAutoHeight && (m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog"))
1845     {
1846         SwTwips nTmp = std::min(nWidth * nMaxHeight / std::max(nHeight, SwTwips(1)), nMaxHeight);
1847         m_xWidthED->set_max(m_xWidthED->NormalizePercent(nTmp), FieldUnit::TWIP);
1848 
1849         nTmp = std::min(nHeight * nMaxWidth / std::max(nWidth, SwTwips(1)), nMaxWidth);
1850         m_xHeightED->set_max(m_xWidthED->NormalizePercent(nTmp), FieldUnit::TWIP);
1851     }
1852     else
1853     {
1854         SwTwips nTmp = static_cast< SwTwips >(m_xHeightED->NormalizePercent(nMaxHeight));
1855         m_xHeightED->set_max(nTmp, FieldUnit::TWIP);
1856 
1857         nTmp = static_cast< SwTwips >(m_xWidthED->NormalizePercent(nMaxWidth));
1858         m_xWidthED->set_max(nTmp, FieldUnit::TWIP);
1859     }
1860 
1861     m_xAtHorzPosED->set_range(m_xAtHorzPosED->normalize(aVal.nMinHPos),
1862                               m_xAtHorzPosED->normalize(aVal.nMaxHPos),
1863                               FieldUnit::TWIP);
1864     if (aVal.nHPos != nAtHorzPosVal)
1865         m_xAtHorzPosED->set_value(m_xAtHorzPosED->normalize(aVal.nHPos), FieldUnit::TWIP);
1866 
1867     const SwTwips nUpperOffset = (aVal.nAnchorType == RndStdIds::FLY_AS_CHAR)
1868         ? m_nUpperBorder : 0;
1869     const SwTwips nLowerOffset = (aVal.nAnchorType == RndStdIds::FLY_AS_CHAR)
1870         ? m_nLowerBorder : 0;
1871 
1872     m_xAtVertPosED->set_range(m_xAtVertPosED->normalize(aVal.nMinVPos + nLowerOffset + nUpperOffset),
1873                               m_xAtVertPosED->normalize(aVal.nMaxVPos),
1874                               FieldUnit::TWIP);
1875     if (aVal.nVPos != nAtVertPosVal)
1876         m_xAtVertPosED->set_value(m_xAtVertPosED->normalize(aVal.nVPos), FieldUnit::TWIP);
1877 }
1878 
IMPL_LINK_NOARG(SwFramePage,AnchorTypeHdl,weld::Toggleable &,void)1879 IMPL_LINK_NOARG(SwFramePage, AnchorTypeHdl, weld::Toggleable&, void)
1880 {
1881     m_xMirrorPagesCB->set_sensitive(!m_xAnchorAsCharRB->get_active());
1882 
1883     // i#18732 - enable check box 'Follow text flow' for anchor
1884     // type to-paragraph' and to-character
1885     // i#22305 - enable check box 'Follow text
1886     // flow' also for anchor type to-frame.
1887     m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
1888                                        m_xAnchorAtCharRB->get_active() ||
1889                                        m_xAnchorAtFrameRB->get_active());
1890 
1891     RndStdIds eId = GetAnchor();
1892 
1893     InitPos( eId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
1894     RangeModifyHdl();
1895 
1896     if(m_bHtmlMode)
1897     {
1898         PosHdl(*m_xHorizontalDLB);
1899         PosHdl(*m_xVerticalDLB);
1900     }
1901 
1902     EnableVerticalPositioning( !(m_bIsMathOLE && m_bIsMathBaselineAlignment
1903             && RndStdIds::FLY_AS_CHAR == eId) );
1904 }
1905 
IMPL_LINK(SwFramePage,PosHdl,weld::ComboBox &,rLB,void)1906 IMPL_LINK( SwFramePage, PosHdl, weld::ComboBox&, rLB, void )
1907 {
1908     bool bHori = &rLB == m_xHorizontalDLB.get();
1909     weld::ComboBox *pRelLB = bHori ? m_xHoriRelationLB.get() : m_xVertRelationLB.get();
1910     weld::Label *pRelFT = bHori ? m_xHoriRelationFT.get() : m_xVertRelationFT.get();
1911     FrameMap const *pMap = bHori ? m_pHMap : m_pVMap;
1912 
1913     const sal_Int32 nMapPos = GetMapPos(pMap, rLB);
1914     const sal_Int16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
1915 
1916     if (bHori)
1917     {
1918         bool bEnable = text::HoriOrientation::NONE == nAlign;
1919         m_xAtHorzPosED->set_sensitive( bEnable );
1920         m_xAtHorzPosFT->set_sensitive( bEnable );
1921     }
1922     else
1923     {
1924         bool bEnable = text::VertOrientation::NONE == nAlign && m_bAllowVertPositioning;
1925         m_xAtVertPosED->set_sensitive( bEnable );
1926         m_xAtVertPosFT->set_sensitive( bEnable );
1927     }
1928 
1929     RangeModifyHdl();
1930 
1931     sal_Int16 nRel = 0;
1932     if (rLB.get_active() != -1)
1933     {
1934         if (pRelLB->get_active() != -1)
1935             nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toInt64())->nRelation;
1936         FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
1937     }
1938     else
1939         pRelLB->clear();
1940 
1941     UpdateExample();
1942 
1943     if (bHori)
1944         m_bAtHorzPosModified = true;
1945     else
1946         m_bAtVertPosModified = true;
1947 
1948     // special treatment for HTML-Mode with horizontal-vertical-dependencies
1949     if(!(m_bHtmlMode && (RndStdIds::FLY_AT_CHAR == GetAnchor())))
1950         return;
1951 
1952     bool bSet = false;
1953     if(bHori)
1954     {
1955         // right is allowed only above - from the left only above
1956         // from the left at character -> below
1957         if((text::HoriOrientation::LEFT == nAlign || text::HoriOrientation::RIGHT == nAlign) &&
1958                 0 == m_xVerticalDLB->get_active())
1959         {
1960             if(text::RelOrientation::FRAME == nRel)
1961                 m_xVerticalDLB->set_active(1);
1962             else
1963                 m_xVerticalDLB->set_active(0);
1964             bSet = true;
1965         }
1966         else if(text::HoriOrientation::LEFT == nAlign && 1 == m_xVerticalDLB->get_active())
1967         {
1968             m_xVerticalDLB->set_active(0);
1969             bSet = true;
1970         }
1971         else if(text::HoriOrientation::NONE == nAlign && 1 == m_xVerticalDLB->get_active())
1972         {
1973             m_xVerticalDLB->set_active(0);
1974             bSet = true;
1975         }
1976         if(bSet)
1977             PosHdl(*m_xVerticalDLB);
1978     }
1979     else
1980     {
1981         if(text::VertOrientation::TOP == nAlign)
1982         {
1983             if (1 == m_xHorizontalDLB->get_active())
1984             {
1985                 m_xHorizontalDLB->set_active(0);
1986                 bSet = true;
1987             }
1988             m_xHoriRelationLB->set_active(1);
1989         }
1990         else if(text::VertOrientation::CHAR_BOTTOM == nAlign)
1991         {
1992             if (2 == m_xHorizontalDLB->get_active())
1993             {
1994                 m_xHorizontalDLB->set_active(0);
1995                 bSet = true;
1996             }
1997             m_xHoriRelationLB->set_active(0) ;
1998         }
1999         if(bSet)
2000             PosHdl(*m_xHorizontalDLB);
2001     }
2002 }
2003 
2004 //  horizontal Pos
IMPL_LINK(SwFramePage,RelHdl,weld::ComboBox &,rLB,void)2005 IMPL_LINK( SwFramePage, RelHdl, weld::ComboBox&, rLB, void )
2006 {
2007     bool bHori = &rLB == m_xHoriRelationLB.get();
2008 
2009     UpdateExample();
2010 
2011     if (bHori)
2012         m_bAtHorzPosModified = true;
2013     else
2014         m_bAtVertPosModified = true;
2015 
2016     if (m_bHtmlMode && (RndStdIds::FLY_AT_CHAR == GetAnchor()))
2017     {
2018         if(bHori)
2019         {
2020             const sal_Int16 nRel = GetRelation(*m_xHoriRelationLB);
2021             if(text::RelOrientation::PRINT_AREA == nRel && 0 == m_xVerticalDLB->get_active())
2022             {
2023                 m_xVerticalDLB->set_active(1);
2024             }
2025             else if(text::RelOrientation::CHAR == nRel && 1 == m_xVerticalDLB->get_active())
2026             {
2027                 m_xVerticalDLB->set_active(0);
2028             }
2029         }
2030     }
2031     RangeModifyHdl();
2032 }
2033 
IMPL_LINK_NOARG(SwFramePage,RealSizeHdl,weld::Button &,void)2034 IMPL_LINK_NOARG(SwFramePage, RealSizeHdl, weld::Button&, void)
2035 {
2036     m_xWidthED->set_value(m_xWidthED->NormalizePercent(m_aGrfSize.Width()), FieldUnit::TWIP);
2037     m_xHeightED->set_value(m_xHeightED->NormalizePercent(m_aGrfSize.Height()), FieldUnit::TWIP);
2038     m_fWidthHeightRatio = m_aGrfSize.Height() ? double(m_aGrfSize.Width()) / double(m_aGrfSize.Height()) : 1.0;
2039     UpdateExample();
2040 }
2041 
IMPL_LINK_NOARG(SwFramePage,AutoWidthClickHdl,weld::Toggleable &,void)2042 IMPL_LINK_NOARG(SwFramePage, AutoWidthClickHdl, weld::Toggleable&, void)
2043 {
2044     if( !IsInGraficMode() )
2045         HandleAutoCB( m_xAutoWidthCB->get_active(), *m_xWidthFT, *m_xWidthAutoFT, *m_xWidthED->get() );
2046 }
2047 
IMPL_LINK_NOARG(SwFramePage,AutoHeightClickHdl,weld::Toggleable &,void)2048 IMPL_LINK_NOARG(SwFramePage, AutoHeightClickHdl, weld::Toggleable&, void)
2049 {
2050     if (!IsInGraficMode())
2051         HandleAutoCB(m_xAutoHeightCB->get_active(), *m_xHeightFT, *m_xHeightAutoFT, *m_xWidthED->get());
2052 }
2053 
IMPL_LINK(SwFramePage,ModifyHdl,weld::MetricSpinButton &,rEdit,void)2054 IMPL_LINK( SwFramePage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
2055 {
2056     SwTwips nWidth  = static_cast< SwTwips >(m_xWidthED->DenormalizePercent(m_xWidthED->get_value(FieldUnit::TWIP)));
2057     SwTwips nHeight = static_cast< SwTwips >(m_xHeightED->DenormalizePercent(m_xHeightED->get_value(FieldUnit::TWIP)));
2058     if (m_xFixedRatioCB->get_active())
2059     {
2060         if (&rEdit == m_xWidthED->get())
2061         {
2062             nHeight = SwTwips(static_cast<double>(nWidth) / m_fWidthHeightRatio);
2063             m_xHeightED->set_value(m_xHeightED->NormalizePercent(nHeight), FieldUnit::TWIP);
2064         }
2065         else if (&rEdit == m_xHeightED->get())
2066         {
2067             nWidth = SwTwips(static_cast<double>(nHeight) * m_fWidthHeightRatio);
2068             m_xWidthED->set_value(m_xWidthED->NormalizePercent(nWidth), FieldUnit::TWIP);
2069         }
2070     }
2071     m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
2072     UpdateExample();
2073 }
2074 
UpdateExample()2075 void SwFramePage::UpdateExample()
2076 {
2077     auto nPos = m_xHorizontalDLB->get_active();
2078     if (m_pHMap && nPos != -1)
2079     {
2080         const sal_Int32 nMapPos = GetMapPos(m_pHMap, *m_xHorizontalDLB);
2081         m_aExampleWN.SetHAlign(GetAlignment(m_pHMap, nMapPos, *m_xHoriRelationLB));
2082         m_aExampleWN.SetHoriRel(GetRelation(*m_xHoriRelationLB));
2083     }
2084 
2085     nPos = m_xVerticalDLB->get_active();
2086     if (m_pVMap && nPos != -1)
2087     {
2088         const sal_Int32 nMapPos = GetMapPos(m_pVMap, *m_xVerticalDLB);
2089         m_aExampleWN.SetVAlign(GetAlignment(m_pVMap, nMapPos, *m_xVertRelationLB));
2090         m_aExampleWN.SetVertRel(GetRelation(*m_xVertRelationLB));
2091     }
2092 
2093     // size
2094     auto nXPos = m_xAtHorzPosED->denormalize(m_xAtHorzPosED->get_value(FieldUnit::TWIP));
2095     auto nYPos = m_xAtVertPosED->denormalize(m_xAtVertPosED->get_value(FieldUnit::TWIP));
2096     m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
2097 
2098     m_aExampleWN.SetAnchor(GetAnchor());
2099     m_aExampleWN.Invalidate();
2100 }
2101 
Init(const SfxItemSet & rSet)2102 void SwFramePage::Init(const SfxItemSet& rSet)
2103 {
2104     if(!m_bFormat)
2105     {
2106         SwWrtShell* pSh = getFrameDlgParentShell();
2107 
2108         // size
2109         const bool bSizeFixed = pSh->IsSelObjProtected( FlyProtectFlags::Fixed ) != FlyProtectFlags::NONE;
2110 
2111         m_xWidthED->set_sensitive( !bSizeFixed );
2112         m_xHeightED->set_sensitive( !bSizeFixed );
2113 
2114         // size controls for math OLE objects
2115         if ( m_sDlgType == "ObjectDialog" && ! m_bNew )
2116         {
2117             // disable width and height for math objects
2118             const SvGlobalName& rFactNm( pSh->GetOLEObject()->getClassID() );
2119 
2120             static struct GlobalNameId {
2121                 sal_uInt32 n1;
2122                 sal_uInt16 n2, n3;
2123                 sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
2124             } const aGlbNmIds[] = { { SO3_SM_CLASSID_60 }, { SO3_SM_CLASSID_50 },
2125                                     { SO3_SM_CLASSID_40 }, { SO3_SM_CLASSID_30 } };
2126 
2127             for (const GlobalNameId & rId : aGlbNmIds) {
2128                 SvGlobalName aGlbNm( rId.n1, rId.n2, rId.n3,
2129                                      rId.b8, rId.b9, rId.b10, rId.b11,
2130                                      rId.b12, rId.b13, rId.b14, rId.b15 );
2131 
2132                 if( rFactNm == aGlbNm )
2133                 {
2134                     // disable size controls for math OLE objects
2135                     m_xWidthFT->set_sensitive(false);
2136                     m_xWidthED->set_sensitive(false);
2137                     m_xRelWidthCB->set_sensitive(false);
2138                     m_xHeightFT->set_sensitive(false);
2139                     m_xHeightED->set_sensitive(false);
2140                     m_xRelHeightCB->set_sensitive(false);
2141                     m_xFixedRatioCB->set_sensitive(false);
2142                     m_xRealSizeBT->set_sensitive(false);
2143                     break;
2144                 }
2145             }
2146 
2147             // TODO/LATER: get correct aspect
2148             if(0 != (pSh->GetOLEObject()->getStatus( embed::Aspects::MSOLE_CONTENT ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE ) )
2149                 m_xRealSizeBT->set_sensitive(false);
2150         }
2151     }
2152 
2153     const SwFormatFrameSize& rSize = rSet.Get(RES_FRM_SIZE);
2154     sal_Int64 nWidth  = m_xWidthED->NormalizePercent(rSize.GetWidth());
2155     sal_Int64 nHeight = m_xHeightED->NormalizePercent(rSize.GetHeight());
2156 
2157     if (nWidth != m_xWidthED->get_value(FieldUnit::TWIP))
2158         m_xWidthED->set_value(nWidth, FieldUnit::TWIP);
2159 
2160     if (nHeight != m_xHeightED->get_value(FieldUnit::TWIP))
2161         m_xHeightED->set_value(nHeight, FieldUnit::TWIP);
2162 
2163     if (!IsInGraficMode())
2164     {
2165         SwFrameSize eSize = rSize.GetHeightSizeType();
2166         bool bCheck = eSize != SwFrameSize::Fixed;
2167         m_xAutoHeightCB->set_active(bCheck);
2168         HandleAutoCB( bCheck, *m_xHeightFT, *m_xHeightAutoFT, *m_xWidthED->get() );
2169         if( eSize == SwFrameSize::Variable )
2170             m_xHeightED->set_value(m_xHeightED->get_min());
2171 
2172         eSize = rSize.GetWidthSizeType();
2173         bCheck = eSize != SwFrameSize::Fixed;
2174         m_xAutoWidthCB->set_active(bCheck);
2175         HandleAutoCB( bCheck, *m_xWidthFT, *m_xWidthAutoFT, *m_xWidthED->get() );
2176         if( eSize == SwFrameSize::Variable )
2177             m_xWidthED->set_value(m_xWidthED->get_min());
2178 
2179         if ( !m_bFormat )
2180         {
2181             SwWrtShell* pSh = getFrameDlgParentShell();
2182             const SwFrameFormat* pFormat = pSh->GetFlyFrameFormat();
2183             if( pFormat && pFormat->GetChain().GetNext() )
2184                 m_xAutoHeightCB->set_sensitive( false );
2185         }
2186     }
2187     else
2188         m_xAutoHeightCB->hide();
2189 
2190     // organise circulation-gap for character bound frames
2191     const SvxULSpaceItem &rUL = rSet.Get(RES_UL_SPACE);
2192     m_nUpperBorder = rUL.GetUpper();
2193     m_nLowerBorder = rUL.GetLower();
2194 
2195     if(SfxItemState::SET == rSet.GetItemState(FN_KEEP_ASPECT_RATIO))
2196     {
2197         m_xFixedRatioCB->set_active(static_cast<const SfxBoolItem&>(rSet.Get(FN_KEEP_ASPECT_RATIO)).GetValue());
2198         m_xFixedRatioCB->save_state();
2199     }
2200 
2201     // columns
2202     SwFormatCol aCol( rSet.Get(RES_COL) );
2203     ::FitToActualSize( aCol, o3tl::narrowing<sal_uInt16>(rSize.GetWidth()) );
2204 
2205     RndStdIds eAnchorId = GetAnchor();
2206 
2207     if ( m_bNew && !m_bFormat )
2208         InitPos(eAnchorId, -1, 0, -1, 0, LONG_MAX, LONG_MAX);
2209     else
2210     {
2211         const SwFormatHoriOrient& rHori = rSet.Get(RES_HORI_ORIENT);
2212         const SwFormatVertOrient& rVert = rSet.Get(RES_VERT_ORIENT);
2213         m_nOldH    = rHori.GetHoriOrient();
2214         m_nOldHRel = rHori.GetRelationOrient();
2215         m_nOldV    = rVert.GetVertOrient();
2216         m_nOldVRel = rVert.GetRelationOrient();
2217 
2218         if (eAnchorId == RndStdIds::FLY_AT_PAGE)
2219         {
2220             if (m_nOldHRel == text::RelOrientation::FRAME)
2221                 m_nOldHRel = text::RelOrientation::PAGE_FRAME;
2222             else if (m_nOldHRel == text::RelOrientation::PRINT_AREA)
2223                 m_nOldHRel = text::RelOrientation::PAGE_PRINT_AREA;
2224             if (m_nOldVRel == text::RelOrientation::FRAME)
2225                 m_nOldVRel = text::RelOrientation::PAGE_FRAME;
2226             else if (m_nOldVRel == text::RelOrientation::PRINT_AREA)
2227                 m_nOldVRel = text::RelOrientation::PAGE_PRINT_AREA;
2228         }
2229 
2230         m_xMirrorPagesCB->set_active(rHori.IsPosToggle());
2231         m_xMirrorPagesCB->save_state();
2232 
2233         InitPos(eAnchorId,
2234                 m_nOldH,
2235                 m_nOldHRel,
2236                 m_nOldV,
2237                 m_nOldVRel,
2238                 rHori.GetPos(),
2239                 rVert.GetPos());
2240     }
2241 
2242     // transparent for example
2243     // circulation for example
2244     const SwFormatSurround& rSurround = rSet.Get(RES_SURROUND);
2245     m_aExampleWN.SetWrap( rSurround.GetSurround() );
2246 
2247     if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH )
2248     {
2249         const SvxOpaqueItem& rOpaque = rSet.Get(RES_OPAQUE);
2250         m_aExampleWN.SetTransparent(!rOpaque.GetValue());
2251     }
2252 
2253     // switch to percent if applicable
2254     RangeModifyHdl();  // set reference values (for 100%)
2255 
2256     if (rSize.GetWidthPercent() == SwFormatFrameSize::SYNCED || rSize.GetHeightPercent() == SwFormatFrameSize::SYNCED)
2257         m_xFixedRatioCB->set_active(true);
2258     if (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED &&
2259         !m_xRelWidthCB->get_active())
2260     {
2261         m_xRelWidthCB->set_active(true);
2262         RelSizeClickHdl(*m_xRelWidthCB);
2263         m_xWidthED->set_value(rSize.GetWidthPercent(), FieldUnit::PERCENT);
2264     }
2265     if (rSize.GetHeightPercent() && rSize.GetHeightPercent() != SwFormatFrameSize::SYNCED &&
2266         !m_xRelHeightCB->get_active())
2267     {
2268         m_xRelHeightCB->set_active(true);
2269         RelSizeClickHdl(*m_xRelHeightCB);
2270         m_xHeightED->set_value(rSize.GetHeightPercent(), FieldUnit::PERCENT);
2271     }
2272     m_xRelWidthCB->save_state();
2273     m_xRelHeightCB->save_state();
2274 
2275     if (rSize.GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
2276         m_xRelWidthRelationLB->set_active(1);
2277     else
2278         m_xRelWidthRelationLB->set_active(0);
2279 
2280     if (rSize.GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
2281         m_xRelHeightRelationLB->set_active(1);
2282     else
2283         m_xRelHeightRelationLB->set_active(0);
2284 }
2285 
SetFormatUsed(bool bFormatUsed)2286 void SwFramePage::SetFormatUsed(bool bFormatUsed)
2287 {
2288     m_bFormat = bFormatUsed;
2289     if (m_bFormat)
2290         m_xAnchorAtFrameRB->hide();
2291 }
2292 
EnableVerticalPositioning(bool bEnable)2293 void SwFramePage::EnableVerticalPositioning( bool bEnable )
2294 {
2295     m_bAllowVertPositioning = bEnable;
2296     m_xVerticalFT->set_sensitive( bEnable );
2297     m_xVerticalDLB->set_sensitive( bEnable );
2298     m_xAtVertPosFT->set_sensitive( bEnable );
2299     m_xAtVertPosED->set_sensitive( bEnable );
2300     m_xVertRelationFT->set_sensitive( bEnable );
2301     m_xVertRelationLB->set_sensitive( bEnable );
2302 }
2303 
SwGrfExtPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)2304 SwGrfExtPage::SwGrfExtPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
2305     : SfxTabPage(pPage, pController, "modules/swriter/ui/picturepage.ui", "PicturePage", &rSet)
2306     , m_bHtmlMode(false)
2307     , m_xMirror(m_xBuilder->weld_widget("flipframe"))
2308     , m_xMirrorVertBox(m_xBuilder->weld_check_button("vert"))
2309     , m_xMirrorHorzBox(m_xBuilder->weld_check_button("hori"))
2310     , m_xAllPagesRB(m_xBuilder->weld_radio_button("allpages"))
2311     , m_xLeftPagesRB(m_xBuilder->weld_radio_button("leftpages"))
2312     , m_xRightPagesRB(m_xBuilder->weld_radio_button("rightpages"))
2313     , m_xConnectED(m_xBuilder->weld_entry("entry"))
2314     , m_xBrowseBT(m_xBuilder->weld_button("browse"))
2315     , m_xLinkFrame(m_xBuilder->weld_frame("linkframe"))
2316     // RotGrfFlyFrame: Need Angle and RotateControls now
2317     , m_xFlAngle(m_xBuilder->weld_frame("FL_ANGLE"))
2318     , m_xNfAngle(m_xBuilder->weld_metric_spin_button("NF_ANGLE", FieldUnit::DEGREE))
2319     , m_xCtlAngle(new svx::DialControl)
2320     , m_xCtlAngleWin(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", *m_xCtlAngle))
2321     , m_xBmpWin(new weld::CustomWeld(*m_xBuilder, "preview", m_aBmpWin))
2322     // tdf#138843 place holder for the graphic type
2323     , m_xLabelGraphicType(m_xBuilder->weld_label("label-graphic-type"))
2324 {
2325     m_aBmpWin.SetBitmapEx(BitmapEx(RID_BMP_PREVIEW_FALLBACK));
2326 
2327     m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
2328 
2329     SetExchangeSupport();
2330     m_xMirrorHorzBox->connect_toggled(LINK(this, SwGrfExtPage, MirrorHdl));
2331     m_xMirrorVertBox->connect_toggled(LINK(this, SwGrfExtPage, MirrorHdl));
2332     m_xBrowseBT->connect_clicked(LINK(this, SwGrfExtPage, BrowseHdl));
2333 }
2334 
~SwGrfExtPage()2335 SwGrfExtPage::~SwGrfExtPage()
2336 {
2337     m_xBmpWin.reset();
2338     m_xCtlAngleWin.reset();
2339     m_xCtlAngle.reset();
2340     m_xGrfDlg.reset();
2341 }
2342 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)2343 std::unique_ptr<SfxTabPage> SwGrfExtPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
2344 {
2345     return std::make_unique<SwGrfExtPage>(pPage, pController, *rSet);
2346 }
2347 
Reset(const SfxItemSet * rSet)2348 void SwGrfExtPage::Reset(const SfxItemSet *rSet)
2349 {
2350     const SfxPoolItem* pItem;
2351     const sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
2352     m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
2353 
2354     if( SfxItemState::SET == rSet->GetItemState( FN_PARAM_GRF_CONNECT, true, &pItem)
2355         && static_cast<const SfxBoolItem *>(pItem)->GetValue() )
2356     {
2357         m_xBrowseBT->set_sensitive(true);
2358         m_xConnectED->set_editable(true);
2359     }
2360 
2361     // RotGrfFlyFrame: Get RotationAngle and set at control
2362     if(SfxItemState::SET == rSet->GetItemState( SID_ATTR_TRANSFORM_ANGLE, false, &pItem))
2363     {
2364         m_xCtlAngle->SetRotation(static_cast<const SdrAngleItem*>(pItem)->GetValue());
2365     }
2366     else
2367     {
2368         m_xCtlAngle->SetRotation(0_deg100);
2369     }
2370     m_xCtlAngle->SaveValue();
2371 
2372     ActivatePage(*rSet);
2373 }
2374 
ActivatePage(const SfxItemSet & rSet)2375 void SwGrfExtPage::ActivatePage(const SfxItemSet& rSet)
2376 {
2377     const SvxProtectItem& rProt = rSet.Get(RES_PROTECT);
2378     bool bProtContent = rProt.IsContentProtected();
2379 
2380     const SfxPoolItem* pItem = nullptr;
2381     bool bEnable = false;
2382     bool bEnableMirrorRB = false;
2383 
2384     SfxItemState eState = rSet.GetItemState(RES_GRFATR_MIRRORGRF, true, &pItem);
2385     if (SfxItemState::UNKNOWN != eState && !bProtContent && !m_bHtmlMode)
2386     {
2387         if( SfxItemState::SET != eState )
2388             pItem = &rSet.Get( RES_GRFATR_MIRRORGRF );
2389 
2390         bEnable = true;
2391 
2392         MirrorGraph eMirror = static_cast<const SwMirrorGrf* >(pItem)->GetValue();
2393         switch( eMirror )
2394         {
2395         case MirrorGraph::Dont: break;
2396         case MirrorGraph::Vertical:    m_xMirrorHorzBox->set_active(true); break;
2397         case MirrorGraph::Horizontal:  m_xMirrorVertBox->set_active(true); break;
2398         case MirrorGraph::Both:        m_xMirrorHorzBox->set_active(true);
2399                                        m_xMirrorVertBox->set_active(true);
2400                                        break;
2401         default:
2402             ;
2403         }
2404 
2405         const int nPos = (static_cast<const SwMirrorGrf* >(pItem)->IsGrfToggle() ? 1 : 0)
2406             + ((eMirror == MirrorGraph::Vertical || eMirror == MirrorGraph::Both) ? 2 : 0);
2407 
2408         bEnableMirrorRB = nPos != 0;
2409 
2410         switch (nPos)
2411         {
2412             case 1: // mirror at left / even pages
2413                 m_xLeftPagesRB->set_active(true);
2414                 m_xMirrorHorzBox->set_active(true);
2415                 break;
2416             case 2: // mirror on all pages
2417                 m_xAllPagesRB->set_active(true);
2418                 break;
2419             case 3: // mirror on right / odd pages
2420                 m_xRightPagesRB->set_active(true);
2421                 break;
2422             default:
2423                 m_xAllPagesRB->set_active(true);
2424                 break;
2425         }
2426     }
2427 
2428     if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
2429     {
2430         const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem);
2431         if( !rBrush.GetGraphicLink().isEmpty() )
2432         {
2433             aGrfName = aNewGrfName = rBrush.GetGraphicLink();
2434             m_xConnectED->set_text(aNewGrfName);
2435         }
2436         OUString referer;
2437         SfxStringItem const * it = static_cast<SfxStringItem const *>(
2438             rSet.GetItem(SID_REFERER));
2439         if (it != nullptr) {
2440             referer = it->GetValue();
2441         }
2442         const Graphic* pGrf = rBrush.GetGraphic(referer);
2443         if( pGrf )
2444         {
2445             m_aBmpWin.SetGraphic( *pGrf );
2446             m_xLabelGraphicType->set_label(GraphicHelper::GetImageType(*pGrf));
2447         }
2448     }
2449 
2450     m_xConnectED->save_value();
2451 
2452     m_xMirror->set_sensitive(bEnable);
2453     m_xAllPagesRB->set_sensitive(bEnableMirrorRB);
2454     m_xLeftPagesRB->set_sensitive(bEnableMirrorRB);
2455     m_xRightPagesRB->set_sensitive(bEnableMirrorRB);
2456 
2457     m_xAllPagesRB->save_state();
2458     m_xLeftPagesRB->save_state();
2459     m_xRightPagesRB->save_state();
2460     m_xMirrorHorzBox->save_state();
2461     m_xMirrorVertBox->save_state();
2462 
2463     m_aBmpWin.MirrorHorz( m_xMirrorVertBox->get_active() );
2464     m_aBmpWin.MirrorVert( m_xMirrorHorzBox->get_active() );
2465     m_aBmpWin.Invalidate();
2466 }
2467 
FillItemSet(SfxItemSet * rSet)2468 bool SwGrfExtPage::FillItemSet( SfxItemSet *rSet )
2469 {
2470     bool bModified = false;
2471     if ( m_xMirrorHorzBox->get_state_changed_from_saved() ||
2472          m_xMirrorVertBox->get_state_changed_from_saved() ||
2473          m_xAllPagesRB->get_state_changed_from_saved() ||
2474          m_xLeftPagesRB->get_state_changed_from_saved() ||
2475          m_xRightPagesRB->get_state_changed_from_saved() )
2476     {
2477         bModified = true;
2478 
2479         bool bHori = false;
2480 
2481         if (m_xMirrorHorzBox->get_active() &&
2482                 !m_xLeftPagesRB->get_active())
2483             bHori = true;
2484 
2485         MirrorGraph eMirror;
2486         eMirror = m_xMirrorVertBox->get_active() && bHori ?
2487                     MirrorGraph::Both : bHori ?
2488                     MirrorGraph::Vertical : m_xMirrorVertBox->get_active() ?
2489                     MirrorGraph::Horizontal  : MirrorGraph::Dont;
2490 
2491         bool bMirror = !m_xAllPagesRB->get_active();
2492         SwMirrorGrf aMirror( eMirror );
2493         aMirror.SetGrfToggle(bMirror );
2494         rSet->Put( aMirror );
2495     }
2496 
2497     if (aGrfName != aNewGrfName || m_xConnectED->get_value_changed_from_saved())
2498     {
2499         bModified = true;
2500         aGrfName = m_xConnectED->get_text();
2501         rSet->Put( SvxBrushItem( aGrfName, aFilterName, GPOS_LT,
2502                                 SID_ATTR_GRAF_GRAPHIC ));
2503     }
2504 
2505     // RotGrfFlyFrame: Safe rotation if modified
2506     if(m_xCtlAngle->IsValueModified())
2507     {
2508         rSet->Put(SdrAngleItem(GetWhich(SID_ATTR_TRANSFORM_ANGLE), m_xCtlAngle->GetRotation()));
2509         bModified = true;
2510     }
2511 
2512     return bModified;
2513 }
2514 
DeactivatePage(SfxItemSet * _pSet)2515 DeactivateRC SwGrfExtPage::DeactivatePage(SfxItemSet *_pSet)
2516 {
2517     if( _pSet )
2518         FillItemSet( _pSet );
2519     return DeactivateRC::LeavePage;
2520 }
2521 
IMPL_LINK_NOARG(SwGrfExtPage,BrowseHdl,weld::Button &,void)2522 IMPL_LINK_NOARG(SwGrfExtPage, BrowseHdl, weld::Button&, void)
2523 {
2524     if(!m_xGrfDlg)
2525     {
2526         m_xGrfDlg.reset(new FileDialogHelper(
2527                 ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
2528                 FileDialogFlags::Graphic, GetFrameWeld()));
2529         m_xGrfDlg->SetTitle(m_xLinkFrame->get_label());
2530     }
2531     m_xGrfDlg->SetDisplayDirectory(m_xConnectED->get_text());
2532     uno::Reference < ui::dialogs::XFilePicker3 > xFP = m_xGrfDlg->GetFilePicker();
2533     uno::Reference < ui::dialogs::XFilePickerControlAccess > xCtrlAcc(xFP, uno::UNO_QUERY);
2534     xCtrlAcc->setValue( ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, uno::makeAny(true) );
2535 
2536     if ( m_xGrfDlg->Execute() != ERRCODE_NONE )
2537         return;
2538 
2539 // remember selected filter
2540     aFilterName = m_xGrfDlg->GetCurrentFilter();
2541     aNewGrfName = INetURLObject::decode( m_xGrfDlg->GetPath(),
2542                                        INetURLObject::DecodeMechanism::Unambiguous );
2543     m_xConnectED->set_text(aNewGrfName);
2544     //reset mirrors because maybe a Bitmap was swapped with
2545     //another type of graphic that cannot be mirrored.
2546     m_xMirrorVertBox->set_active(false);
2547     m_xMirrorHorzBox->set_active(false);
2548     m_xAllPagesRB->set_sensitive(false);
2549     m_xLeftPagesRB->set_sensitive(false);
2550     m_xRightPagesRB->set_sensitive(false);
2551     m_aBmpWin.MirrorHorz(false);
2552     m_aBmpWin.MirrorVert(false);
2553 
2554     Graphic aGraphic;
2555     (void)GraphicFilter::LoadGraphic(m_xGrfDlg->GetPath(), OUString(), aGraphic);
2556     m_aBmpWin.SetGraphic(aGraphic);
2557     m_xLabelGraphicType->set_label(GraphicHelper::GetImageType(aGraphic));
2558 
2559     bool bEnable = GraphicType::Bitmap      == aGraphic.GetType() ||
2560                         GraphicType::GdiMetafile == aGraphic.GetType();
2561     m_xMirrorVertBox->set_sensitive(bEnable);
2562     m_xMirrorHorzBox->set_sensitive(bEnable);
2563     m_xAllPagesRB->set_sensitive(bEnable);
2564     m_xLeftPagesRB->set_sensitive(bEnable);
2565     m_xRightPagesRB->set_sensitive(bEnable);
2566 
2567 }
2568 
IMPL_LINK_NOARG(SwGrfExtPage,MirrorHdl,weld::Toggleable &,void)2569 IMPL_LINK_NOARG(SwGrfExtPage, MirrorHdl, weld::Toggleable&, void)
2570 {
2571     bool bEnable = m_xMirrorHorzBox->get_active();
2572 
2573     m_aBmpWin.MirrorHorz( m_xMirrorVertBox->get_active() );
2574     m_aBmpWin.MirrorVert( bEnable );
2575 
2576     m_xAllPagesRB->set_sensitive(bEnable);
2577     m_xLeftPagesRB->set_sensitive(bEnable);
2578     m_xRightPagesRB->set_sensitive(bEnable);
2579 
2580     if (!m_xAllPagesRB->get_active() && !m_xLeftPagesRB->get_active() && !m_xRightPagesRB->get_active())
2581         m_xAllPagesRB->set_active(true);
2582 }
2583 
2584 // example window
BmpWindow()2585 BmpWindow::BmpWindow()
2586     : bHorz(false)
2587     , bVert(false)
2588     , bGraphic(false)
2589 {
2590 }
2591 
SetDrawingArea(weld::DrawingArea * pDrawingArea)2592 void BmpWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
2593 {
2594     CustomWidgetController::SetDrawingArea(pDrawingArea);
2595     Size aSize = pDrawingArea->get_ref_device().LogicToPixel(Size(127 , 66), MapMode(MapUnit::MapAppFont));
2596     set_size_request(aSize.Width(), aSize.Height());
2597     SetOutputSizePixel(aSize);
2598 }
2599 
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle &)2600 void BmpWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
2601 {
2602     // Setup
2603     rRenderContext.SetBackground();
2604     // #i119307# the graphic might have transparency, set up white as the color
2605     // to use when drawing a rectangle under the image
2606     rRenderContext.SetLineColor(COL_WHITE);
2607     rRenderContext.SetFillColor(COL_WHITE);
2608 
2609     // Paint
2610     Point aPntPos;
2611     Size aPntSz(GetOutputSizePixel());
2612     Size aGrfSize;
2613     if (bGraphic)
2614         aGrfSize = ::GetGraphicSizeTwip(aGraphic, &rRenderContext);
2615     //it should show the default bitmap also if no graphic can be found
2616     if (!aGrfSize.Width() && !aGrfSize.Height())
2617         aGrfSize = rRenderContext.PixelToLogic(aBmp.GetSizePixel());
2618 
2619     tools::Long nRelGrf = aGrfSize.Width() * 100 / aGrfSize.Height();
2620     tools::Long nRelWin = aPntSz.Width() * 100 / aPntSz.Height();
2621     if (nRelGrf < nRelWin)
2622     {
2623         const tools::Long nWidth = aPntSz.Width();
2624         // if we use a replacement preview, try to draw at original size
2625         if (!bGraphic && (aGrfSize.Width() <= aPntSz.Width())
2626                       && (aGrfSize.Height() <= aPntSz.Height()))
2627         {
2628             const tools::Long nHeight = aPntSz.Height();
2629             aPntSz.setWidth( aGrfSize.Width() );
2630             aPntSz.setHeight( aGrfSize.Height() );
2631             aPntPos.AdjustY((nHeight - aPntSz.Height()) / 2 );
2632         }
2633         else
2634             aPntSz.setWidth( aPntSz.Height() * nRelGrf /100 );
2635 
2636         aPntPos.AdjustX(nWidth - aPntSz.Width() ) ;
2637     }
2638 
2639     // #i119307# clear window background, the graphic might have transparency
2640     rRenderContext.DrawRect(tools::Rectangle(aPntPos, aPntSz));
2641 
2642     if (bHorz || bVert)
2643     {
2644         BitmapEx aTmpBmp(bGraphic ? aGraphic.GetBitmapEx() : aBmp);
2645         BmpMirrorFlags nMirrorFlags(BmpMirrorFlags::NONE);
2646         if (bHorz)
2647             nMirrorFlags |= BmpMirrorFlags::Vertical;
2648         if (bVert)
2649             nMirrorFlags |= BmpMirrorFlags::Horizontal;
2650         aTmpBmp.Mirror(nMirrorFlags);
2651         rRenderContext.DrawBitmapEx(aPntPos, aPntSz, aTmpBmp);
2652     }
2653     else if (bGraphic)  //draw unmirrored preview graphic
2654     {
2655         aGraphic.Draw(rRenderContext, aPntPos, aPntSz);
2656     }
2657     else    //draw unmirrored stock sample image
2658     {
2659         rRenderContext.DrawBitmapEx(aPntPos, aPntSz, aBmp);
2660     }
2661 }
2662 
~BmpWindow()2663 BmpWindow::~BmpWindow()
2664 {
2665 }
2666 
SetGraphic(const Graphic & rGraphic)2667 void BmpWindow::SetGraphic(const Graphic& rGraphic)
2668 {
2669     aGraphic = rGraphic;
2670     Size aSize = aGraphic.GetPrefSize();
2671     bGraphic = aSize.Width() && aSize.Height();
2672     Invalidate();
2673 }
2674 
SetBitmapEx(const BitmapEx & rBmp)2675 void BmpWindow::SetBitmapEx(const BitmapEx& rBmp)
2676 {
2677     aBmp = rBmp;
2678     Invalidate();
2679 }
2680 
2681 // set URL and ImageMap at frames
SwFrameURLPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)2682 SwFrameURLPage::SwFrameURLPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
2683     : SfxTabPage(pPage, pController, "modules/swriter/ui/frmurlpage.ui", "FrameURLPage", &rSet)
2684     , m_xURLED(m_xBuilder->weld_entry("url"))
2685     , m_xSearchPB(m_xBuilder->weld_button("search"))
2686     , m_xNameED(m_xBuilder->weld_entry("name"))
2687     , m_xFrameCB(m_xBuilder->weld_combo_box("frame"))
2688     , m_xServerCB(m_xBuilder->weld_check_button("server"))
2689     , m_xClientCB(m_xBuilder->weld_check_button("client"))
2690 {
2691     m_xSearchPB->connect_clicked(LINK(this, SwFrameURLPage, InsertFileHdl));
2692 }
2693 
~SwFrameURLPage()2694 SwFrameURLPage::~SwFrameURLPage()
2695 {
2696 }
2697 
Reset(const SfxItemSet * rSet)2698 void SwFrameURLPage::Reset( const SfxItemSet *rSet )
2699 {
2700     const SfxPoolItem* pItem;
2701     if ( SfxItemState::SET == rSet->GetItemState( SID_DOCFRAME, true, &pItem))
2702     {
2703         TargetList aList;
2704         SfxFrame::GetDefaultTargetList(aList);
2705         size_t nCount = aList.size();
2706         for (size_t i = 0; i < nCount; ++i)
2707         {
2708             m_xFrameCB->append_text(aList.at(i));
2709         }
2710     }
2711 
2712     if ( SfxItemState::SET == rSet->GetItemState( RES_URL, true, &pItem ) )
2713     {
2714         const SwFormatURL* pFormatURL = static_cast<const SwFormatURL*>(pItem);
2715         m_xURLED->set_text(INetURLObject::decode(pFormatURL->GetURL(),
2716                                            INetURLObject::DecodeMechanism::Unambiguous));
2717         m_xNameED->set_text(pFormatURL->GetName());
2718 
2719         m_xClientCB->set_sensitive(pFormatURL->GetMap() != nullptr);
2720         m_xClientCB->set_active(pFormatURL->GetMap() != nullptr);
2721         m_xServerCB->set_active(pFormatURL->IsServerMap());
2722 
2723         m_xFrameCB->set_entry_text(pFormatURL->GetTargetFrameName());
2724         m_xFrameCB->save_value();
2725     }
2726     else
2727         m_xClientCB->set_sensitive(false);
2728 
2729     m_xServerCB->save_state();
2730     m_xClientCB->save_state();
2731 }
2732 
FillItemSet(SfxItemSet * rSet)2733 bool SwFrameURLPage::FillItemSet(SfxItemSet *rSet)
2734 {
2735     bool bModified = false;
2736     const SwFormatURL* pOldURL = GetOldItem(*rSet, RES_URL);
2737     std::unique_ptr<SwFormatURL> pFormatURL;
2738     if(pOldURL)
2739         pFormatURL.reset(pOldURL->Clone());
2740     else
2741         pFormatURL.reset(new SwFormatURL());
2742 
2743     {
2744         const OUString sText = m_xURLED->get_text();
2745 
2746         if( pFormatURL->GetURL() != sText ||
2747             pFormatURL->GetName() != m_xNameED->get_text() ||
2748             m_xServerCB->get_active() != pFormatURL->IsServerMap() )
2749         {
2750             pFormatURL->SetURL(sText, m_xServerCB->get_active());
2751             pFormatURL->SetName(m_xNameED->get_text());
2752             bModified = true;
2753         }
2754     }
2755 
2756     if (!m_xClientCB->get_active() && pFormatURL->GetMap() != nullptr)
2757     {
2758         pFormatURL->SetMap(nullptr);
2759         bModified = true;
2760     }
2761 
2762     if(pFormatURL->GetTargetFrameName() != m_xFrameCB->get_active_text())
2763     {
2764         pFormatURL->SetTargetFrameName(m_xFrameCB->get_active_text());
2765         bModified = true;
2766     }
2767     rSet->Put(*pFormatURL);
2768     return bModified;
2769 }
2770 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)2771 std::unique_ptr<SfxTabPage> SwFrameURLPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
2772 {
2773     return std::make_unique<SwFrameURLPage>(pPage, pController, *rSet);
2774 }
2775 
IMPL_LINK_NOARG(SwFrameURLPage,InsertFileHdl,weld::Button &,void)2776 IMPL_LINK_NOARG(SwFrameURLPage, InsertFileHdl, weld::Button&, void)
2777 {
2778     FileDialogHelper aDlgHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
2779                                 FileDialogFlags::NONE, GetFrameWeld());
2780     uno::Reference < ui::dialogs::XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
2781 
2782     try
2783     {
2784         const OUString sTemp(m_xURLED->get_text());
2785         if(!sTemp.isEmpty())
2786             xFP->setDisplayDirectory(sTemp);
2787     }
2788     catch( const uno::Exception& ) {}
2789     if( aDlgHelper.Execute() == ERRCODE_NONE )
2790     {
2791         m_xURLED->set_text(xFP->getSelectedFiles().getConstArray()[0]);
2792     }
2793 }
2794 
SwFrameAddPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)2795 SwFrameAddPage::SwFrameAddPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
2796     : SfxTabPage(pPage, pController, "modules/swriter/ui/frmaddpage.ui", "FrameAddPage", &rSet)
2797     , m_pWrtSh(nullptr)
2798     , m_bHtmlMode(false)
2799     , m_bFormat(false)
2800     , m_bNew(false)
2801     , m_xNameFrame(m_xBuilder->weld_widget("nameframe"))
2802     , m_xNameFT(m_xBuilder->weld_label("name_label"))
2803     , m_xNameED(m_xBuilder->weld_entry("name"))
2804     , m_xAltNameFT(m_xBuilder->weld_label("altname_label"))
2805     , m_xAltNameED(m_xBuilder->weld_entry("altname"))
2806     , m_xDescriptionFT(m_xBuilder->weld_label("description_label"))
2807     , m_xDescriptionED(m_xBuilder->weld_text_view("description"))
2808     , m_xPrevFT(m_xBuilder->weld_label("prev_label"))
2809     , m_xPrevLB(m_xBuilder->weld_combo_box("prev"))
2810     , m_xNextFT(m_xBuilder->weld_label("next_label"))
2811     , m_xNextLB(m_xBuilder->weld_combo_box("next"))
2812     , m_xProtectFrame(m_xBuilder->weld_widget("protect"))
2813     , m_xProtectContentCB(m_xBuilder->weld_check_button("protectcontent"))
2814     , m_xProtectFrameCB(m_xBuilder->weld_check_button("protectframe"))
2815     , m_xProtectSizeCB(m_xBuilder->weld_check_button("protectsize"))
2816     , m_xContentAlignFrame(m_xBuilder->weld_widget("contentalign"))
2817     , m_xVertAlignLB(m_xBuilder->weld_combo_box("vertalign"))
2818     , m_xPropertiesFrame(m_xBuilder->weld_widget("properties"))
2819     , m_xEditInReadonlyCB(m_xBuilder->weld_check_button("editinreadonly"))
2820     , m_xPrintFrameCB(m_xBuilder->weld_check_button("printframe"))
2821     , m_xTextFlowFT(m_xBuilder->weld_label("textflow_label"))
2822     , m_xTextFlowLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("textflow")))
2823 {
2824     m_xTextFlowLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
2825     m_xTextFlowLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
2826     m_xTextFlowLB->append(SvxFrameDirection::Vertical_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_VERT));
2827     m_xTextFlowLB->append(SvxFrameDirection::Vertical_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_VERT));
2828     m_xTextFlowLB->append(SvxFrameDirection::Vertical_LR_BT, SvxResId(RID_SVXSTR_PAGEDIR_LTR_BTT_VERT));
2829     m_xTextFlowLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
2830     m_xDescriptionED->set_size_request(-1, m_xDescriptionED->get_preferred_size().Height());
2831 }
2832 
~SwFrameAddPage()2833 SwFrameAddPage::~SwFrameAddPage()
2834 {
2835     m_xTextFlowLB.reset();
2836 }
2837 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)2838 std::unique_ptr<SfxTabPage> SwFrameAddPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
2839 {
2840     return std::make_unique<SwFrameAddPage>(pPage, pController, *rSet);
2841 }
2842 
Reset(const SfxItemSet * rSet)2843 void SwFrameAddPage::Reset(const SfxItemSet *rSet )
2844 {
2845     const SfxPoolItem* pItem;
2846     sal_uInt16 nHtmlMode = ::GetHtmlMode(static_cast<const SwDocShell*>(SfxObjectShell::Current()));
2847     m_bHtmlMode = (nHtmlMode & HTMLMODE_ON) != 0;
2848     if (m_bHtmlMode)
2849     {
2850         m_xProtectFrame->hide();
2851         m_xEditInReadonlyCB->hide();
2852         m_xPrintFrameCB->hide();
2853     }
2854     if (m_sDlgType == "PictureDialog" || m_sDlgType == "ObjectDialog")
2855     {
2856         m_xEditInReadonlyCB->hide();
2857         if (m_bHtmlMode)
2858         {
2859             m_xPropertiesFrame->hide();
2860         }
2861         m_xContentAlignFrame->hide();
2862     }
2863 
2864     if(SfxItemState::SET == rSet->GetItemState(FN_SET_FRM_ALT_NAME, false, &pItem))
2865     {
2866         m_xAltNameED->set_text(static_cast<const SfxStringItem*>(pItem)->GetValue());
2867         m_xAltNameED->save_value();
2868     }
2869 
2870     if(SfxItemState::SET == rSet->GetItemState(FN_UNO_DESCRIPTION, false, &pItem))
2871     {
2872         m_xDescriptionED->set_text(static_cast<const SfxStringItem*>(pItem)->GetValue());
2873         m_xDescriptionED->save_value();
2874     }
2875 
2876     if(!m_bFormat)
2877     {
2878         // insert graphic - properties
2879         // bNew is not set, so recognise by selection
2880         OUString aTmpName1;
2881         if(SfxItemState::SET == rSet->GetItemState(FN_SET_FRM_NAME, false, &pItem))
2882         {
2883             aTmpName1 = static_cast<const SfxStringItem*>(pItem)->GetValue();
2884         }
2885 
2886         OSL_ENSURE(m_pWrtSh, "no Shell?");
2887         if( m_bNew || aTmpName1.isEmpty() )
2888         {
2889             if (m_sDlgType == "PictureDialog")
2890                 aTmpName1 = m_pWrtSh->GetUniqueGrfName();
2891             else if (m_sDlgType == "ObjectDialog")
2892                 aTmpName1 = m_pWrtSh->GetUniqueOLEName();
2893             else
2894                 aTmpName1 = m_pWrtSh->GetUniqueFrameName();
2895 
2896             m_pWrtSh->SetFlyName(aTmpName1);
2897         }
2898 
2899         m_xNameED->set_text( aTmpName1 );
2900         m_xNameED->save_value();
2901     }
2902     else
2903     {
2904         m_xNameED->set_sensitive( false );
2905         m_xAltNameED->set_sensitive(false);
2906         m_xNameFT->set_sensitive( false );
2907         m_xAltNameFT->set_sensitive(false);
2908     }
2909     if (m_sDlgType == "FrameDialog" && m_xAltNameFT->get_visible())
2910     {
2911         m_xAltNameFT->hide();
2912         m_xAltNameED->hide();
2913     }
2914     else
2915     {
2916         m_xNameED->connect_changed(LINK(this, SwFrameAddPage, EditModifyHdl));
2917     }
2918 
2919     if (!m_bNew)
2920     {
2921         SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
2922 
2923         if (pFormat)
2924         {
2925             const SwFormatChain &rChain = pFormat->GetChain();
2926             const SwFlyFrameFormat* pFlyFormat;
2927             OUString sNextChain, sPrevChain;
2928             pFlyFormat = rChain.GetPrev();
2929             if (pFlyFormat != nullptr)
2930             {
2931                 sPrevChain = pFlyFormat->GetName();
2932             }
2933 
2934             pFlyFormat = rChain.GetNext();
2935             if (pFlyFormat != nullptr)
2936             {
2937                 sNextChain = pFlyFormat->GetName();
2938             }
2939             //determine chainable frames
2940             std::vector< OUString > aPrevPageFrames;
2941             std::vector< OUString > aThisPageFrames;
2942             std::vector< OUString > aNextPageFrames;
2943             std::vector< OUString > aRemainFrames;
2944             m_pWrtSh->GetConnectableFrameFormats(*pFormat, sNextChain, false,
2945                             aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
2946             for (sal_Int32 nEntry = m_xPrevLB->get_count(); nEntry > 1; nEntry--)
2947                 m_xPrevLB->remove(nEntry - 1);
2948             lcl_InsertVectors(*m_xPrevLB, aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
2949             if(!sPrevChain.isEmpty())
2950             {
2951                 if (m_xPrevLB->find_text(sPrevChain) == -1)
2952                     m_xPrevLB->insert_text(1, sPrevChain);
2953                 m_xPrevLB->set_active_text(sPrevChain);
2954             }
2955             else
2956                 m_xPrevLB->set_active(0);
2957             aPrevPageFrames.clear();
2958             aNextPageFrames.clear();
2959             aThisPageFrames.clear();
2960             aRemainFrames.clear();
2961 
2962             m_pWrtSh->GetConnectableFrameFormats(*pFormat, sPrevChain, true,
2963                             aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
2964             for (sal_Int32 nEntry = m_xNextLB->get_count(); nEntry > 1; nEntry--)
2965                 m_xNextLB->remove(nEntry - 1);
2966             lcl_InsertVectors(*m_xNextLB, aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
2967             if(!sNextChain.isEmpty())
2968             {
2969                 if (m_xNextLB->find_text(sNextChain) == -1)
2970                     m_xNextLB->insert_text(1, sNextChain);
2971                 m_xNextLB->set_active_text(sNextChain);
2972             }
2973             else
2974                 m_xNextLB->set_active(0);
2975             Link<weld::ComboBox&,void> aLink(LINK(this, SwFrameAddPage, ChainModifyHdl));
2976             m_xPrevLB->connect_changed(aLink);
2977             m_xNextLB->connect_changed(aLink);
2978         }
2979     }
2980     // Pos Protected
2981     const SvxProtectItem& rProt = rSet->Get(RES_PROTECT);
2982     m_xProtectFrameCB->set_active(rProt.IsPosProtected());
2983     m_xProtectContentCB->set_active(rProt.IsContentProtected());
2984     m_xProtectSizeCB->set_active(rProt.IsSizeProtected());
2985 
2986     const SwFormatEditInReadonly& rEdit = rSet->Get(RES_EDIT_IN_READONLY);
2987     m_xEditInReadonlyCB->set_active(rEdit.GetValue());
2988     m_xEditInReadonlyCB->save_state();
2989 
2990     // print
2991     const SvxPrintItem& rPrt = rSet->Get(RES_PRINT);
2992     m_xPrintFrameCB->set_active(rPrt.GetValue());
2993     m_xPrintFrameCB->save_state();
2994 
2995     // textflow
2996     if( (!m_bHtmlMode || (0 != (nHtmlMode&HTMLMODE_SOME_STYLES)))
2997         && m_sDlgType != "PictureDialog" && m_sDlgType != "ObjectDialog"
2998         && SfxItemState::UNKNOWN != rSet->GetItemState( RES_FRAMEDIR ) )
2999     {
3000         m_xTextFlowFT->show();
3001         m_xTextFlowLB->show();
3002 
3003         //vertical text flow is not possible in HTML
3004         if(m_bHtmlMode)
3005         {
3006             m_xTextFlowLB->remove_id(SvxFrameDirection::Vertical_RL_TB);
3007         }
3008         SvxFrameDirection nVal = rSet->Get(RES_FRAMEDIR).GetValue();
3009         m_xTextFlowLB->set_active_id(nVal);
3010         m_xTextFlowLB->save_value();
3011     }
3012     else
3013     {
3014         m_xTextFlowFT->hide();
3015         m_xTextFlowLB->hide();
3016     }
3017 
3018     // Content alignment
3019     if ( rSet->GetItemState(RES_TEXT_VERT_ADJUST) > SfxItemState::DEFAULT )
3020     {
3021         SdrTextVertAdjust nAdjust = rSet->Get(RES_TEXT_VERT_ADJUST).GetValue();
3022         sal_Int32 nPos = 0;
3023         switch(nAdjust)
3024         {
3025             case SDRTEXTVERTADJUST_TOP:      nPos = 0;   break;
3026             case SDRTEXTVERTADJUST_CENTER:
3027             case SDRTEXTVERTADJUST_BLOCK:    nPos = 1;   break;
3028             case SDRTEXTVERTADJUST_BOTTOM:   nPos = 2;   break;
3029         }
3030         m_xVertAlignLB->set_active(nPos);
3031     }
3032     m_xVertAlignLB->save_value();
3033 }
3034 
FillItemSet(SfxItemSet * rSet)3035 bool SwFrameAddPage::FillItemSet(SfxItemSet *rSet)
3036 {
3037     bool bRet = false;
3038     if (m_xNameED->get_value_changed_from_saved())
3039         bRet |= nullptr != rSet->Put(SfxStringItem(FN_SET_FRM_NAME, m_xNameED->get_text()));
3040     if (m_xAltNameED->get_value_changed_from_saved())
3041         bRet |= nullptr != rSet->Put(SfxStringItem(FN_SET_FRM_ALT_NAME, m_xAltNameED->get_text()));
3042     if (m_xDescriptionED->get_value_changed_from_saved())
3043         bRet |= nullptr != rSet->Put(SfxStringItem(FN_UNO_DESCRIPTION, m_xDescriptionED->get_text()));
3044 
3045     const SfxPoolItem* pOldItem;
3046     SvxProtectItem aProt ( GetItemSet().Get(RES_PROTECT) );
3047     aProt.SetContentProtect( m_xProtectContentCB->get_active() );
3048     aProt.SetSizeProtect ( m_xProtectSizeCB->get_active() );
3049     aProt.SetPosProtect  ( m_xProtectFrameCB->get_active() );
3050     if ( nullptr == (pOldItem = GetOldItem(*rSet, FN_SET_PROTECT)) ||
3051                 aProt != *pOldItem )
3052         bRet |= nullptr != rSet->Put( aProt);
3053 
3054     if ( m_xEditInReadonlyCB->get_state_changed_from_saved() )
3055         bRet |= nullptr != rSet->Put( SwFormatEditInReadonly( RES_EDIT_IN_READONLY, m_xEditInReadonlyCB->get_active()));
3056 
3057     if ( m_xPrintFrameCB->get_state_changed_from_saved() )
3058         bRet |= nullptr != rSet->Put( SvxPrintItem( RES_PRINT, m_xPrintFrameCB->get_active()));
3059 
3060     // textflow
3061     if (m_xTextFlowLB->get_visible() && m_xTextFlowLB->get_value_changed_from_saved())
3062     {
3063         SvxFrameDirection eDirection = m_xTextFlowLB->get_active_id();
3064         bRet |= nullptr != rSet->Put( SvxFrameDirectionItem(eDirection, RES_FRAMEDIR ));
3065     }
3066     if(m_pWrtSh)
3067     {
3068         const SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
3069         if (pFormat)
3070         {
3071             OUString sCurrentPrevChain, sCurrentNextChain;
3072             if (m_xPrevLB->get_active())
3073                 sCurrentPrevChain = m_xPrevLB->get_active_text();
3074             if (m_xNextLB->get_active())
3075                 sCurrentNextChain = m_xNextLB->get_active_text();
3076             const SwFormatChain &rChain = pFormat->GetChain();
3077             const SwFlyFrameFormat* pFlyFormat;
3078             OUString sNextChain, sPrevChain;
3079             pFlyFormat = rChain.GetPrev();
3080             if (pFlyFormat != nullptr)
3081                 sPrevChain = pFlyFormat->GetName();
3082 
3083             pFlyFormat = rChain.GetNext();
3084             if (pFlyFormat != nullptr)
3085                 sNextChain = pFlyFormat->GetName();
3086             if(sPrevChain != sCurrentPrevChain)
3087                 bRet |= nullptr != rSet->Put(SfxStringItem(FN_PARAM_CHAIN_PREVIOUS, sCurrentPrevChain));
3088             if(sNextChain != sCurrentNextChain)
3089                 bRet |= nullptr != rSet->Put(SfxStringItem(FN_PARAM_CHAIN_NEXT, sCurrentNextChain));
3090         }
3091     }
3092 
3093     if (m_xVertAlignLB->get_value_changed_from_saved())
3094     {
3095         SdrTextVertAdjust nAdjust;
3096         switch (m_xVertAlignLB->get_active())
3097         {
3098             default:
3099             case 0 : nAdjust = SDRTEXTVERTADJUST_TOP; break;
3100             case 1 : nAdjust = SDRTEXTVERTADJUST_CENTER; break;
3101             case 2 : nAdjust = SDRTEXTVERTADJUST_BOTTOM; break;
3102         }
3103         bRet |= nullptr != rSet->Put(SdrTextVertAdjustItem(nAdjust, RES_TEXT_VERT_ADJUST));
3104     }
3105 
3106     return bRet;
3107 }
3108 
IMPL_LINK_NOARG(SwFrameAddPage,EditModifyHdl,weld::Entry &,void)3109 IMPL_LINK_NOARG(SwFrameAddPage, EditModifyHdl, weld::Entry&, void)
3110 {
3111     bool bEnable = !m_xNameED->get_text().isEmpty();
3112     m_xAltNameED->set_sensitive(bEnable);
3113     m_xAltNameFT->set_sensitive(bEnable);
3114 }
3115 
SetFormatUsed(bool bFormatUsed)3116 void SwFrameAddPage::SetFormatUsed(bool bFormatUsed)
3117 {
3118     m_bFormat = bFormatUsed;
3119     if (m_bFormat)
3120     {
3121         m_xNameFrame->hide();
3122     }
3123 }
3124 
IMPL_LINK(SwFrameAddPage,ChainModifyHdl,weld::ComboBox &,rBox,void)3125 IMPL_LINK(SwFrameAddPage, ChainModifyHdl, weld::ComboBox&, rBox, void)
3126 {
3127     OUString sCurrentPrevChain, sCurrentNextChain;
3128     if (m_xPrevLB->get_active())
3129         sCurrentPrevChain = m_xPrevLB->get_active_text();
3130     if (m_xNextLB->get_active())
3131         sCurrentNextChain = m_xNextLB->get_active_text();
3132     SwFrameFormat* pFormat = m_pWrtSh->GetFlyFrameFormat();
3133     if (!pFormat)
3134         return;
3135 
3136     bool bNextBox = m_xNextLB.get() == &rBox;
3137     weld::ComboBox& rChangeLB = bNextBox ? *m_xPrevLB : *m_xNextLB;
3138     for (sal_Int32 nEntry = rChangeLB.get_count(); nEntry > 1; nEntry--)
3139         rChangeLB.remove(nEntry - 1);
3140     //determine chainable frames
3141     std::vector< OUString > aPrevPageFrames;
3142     std::vector< OUString > aThisPageFrames;
3143     std::vector< OUString > aNextPageFrames;
3144     std::vector< OUString > aRemainFrames;
3145     m_pWrtSh->GetConnectableFrameFormats(*pFormat, bNextBox ? sCurrentNextChain : sCurrentPrevChain, !bNextBox,
3146                     aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames );
3147     lcl_InsertVectors(rChangeLB,
3148             aPrevPageFrames, aThisPageFrames, aNextPageFrames, aRemainFrames);
3149     const OUString sToSelect = bNextBox ? sCurrentPrevChain : sCurrentNextChain;
3150     if (rChangeLB.find_text(sToSelect) != -1)
3151         rChangeLB.set_active_text(sToSelect);
3152     else
3153         rChangeLB.set_active(0);
3154 
3155 }
3156 
3157 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3158