Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / tpline.cxx
blob89fc0dc227efc940c71bff9edfa98aa29f143859
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <editeng/sizeitem.hxx>
22 #include <osl/file.hxx>
23 #include <tools/urlobj.hxx>
25 #include <strings.hrc>
26 #include <svx/colorbox.hxx>
27 #include <svx/dlgctrl.hxx>
28 #include <svx/xlineit0.hxx>
29 #include <svx/xlinjoit.hxx>
30 #include <svx/xlncapit.hxx>
31 #include <svx/xlndsit.hxx>
32 #include <svx/xlnwtit.hxx>
33 #include <svx/xlnstwit.hxx>
34 #include <svx/xlnedwit.hxx>
35 #include <svx/xlnclit.hxx>
36 #include <svx/xlnstit.hxx>
37 #include <svx/xlnedit.hxx>
38 #include <svx/xlnstcit.hxx>
39 #include <svx/xlnedcit.hxx>
42 #include <svx/tabline.hxx>
43 #include <svx/xtable.hxx>
44 #include <svx/drawitem.hxx>
45 #include <cuitabline.hxx>
46 #include <dialmgr.hxx>
47 #include <svx/dlgutil.hxx>
48 #include <svx/svxgrahicitem.hxx>
49 #include <svx/ofaitem.hxx>
50 #include <svx/svdobj.hxx>
51 #include <svx/svdpage.hxx>
52 #include <svx/svdview.hxx>
53 #include <svx/svdmodel.hxx>
54 #include <svx/xlntrit.hxx>
55 #include <svx/xfltrit.hxx>
56 #include <editeng/numitem.hxx>
57 #include <editeng/brushitem.hxx>
58 #include <svx/gallery.hxx>
59 #include <sfx2/opengrf.hxx>
60 #include <svx/dialmgr.hxx>
61 #include <svx/svxids.hrc>
62 #include <svx/strings.hrc>
63 #include <vcl/settings.hxx>
64 #include <cuitabarea.hxx>
65 #include <svtools/unitconv.hxx>
67 #define MAX_BMP_WIDTH 16
68 #define MAX_BMP_HEIGHT 16
70 using namespace com::sun::star;
72 // static ----------------------------------------------------------------
74 const sal_uInt16 SvxLineTabPage::pLineRanges[] =
76 XATTR_LINETRANSPARENCE,
77 XATTR_LINETRANSPARENCE,
78 SID_ATTR_LINE_STYLE,
79 SID_ATTR_LINE_ENDCENTER,
83 SvxLineTabPage::SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
84 : SfxTabPage(pPage, pController, "cui/ui/linetabpage.ui", "LineTabPage", &rInAttrs)
85 , m_pSymbolList(nullptr)
86 , m_bNewSize(false)
87 , m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
88 , m_pSymbolAttr(nullptr)
89 , m_bLastWidthModified(false)
90 , m_aSymbolLastSize(Size(0,0))
91 , m_bSymbols(false)
92 , m_rOutAttrs(rInAttrs)
93 , m_bObjSelected(false)
94 , m_aXLineAttr(rInAttrs.GetPool())
95 , m_rXLSet(m_aXLineAttr.GetItemSet())
96 , m_pnLineEndListState(nullptr)
97 , m_pnDashListState(nullptr)
98 , m_pnColorListState(nullptr)
99 , m_nPageType(PageType::Area)
100 , m_nDlgType(0)
101 , m_pPosDashLb(nullptr)
102 , m_pPosLineEndLb(nullptr)
103 , m_xBoxColor(m_xBuilder->weld_widget("boxCOLOR"))
104 , m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINE_STYLE")))
105 , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"), pController->getDialog()))
106 , m_xBoxWidth(m_xBuilder->weld_widget("boxWIDTH"))
107 , m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_WIDTH", FieldUnit::CM))
108 , m_xBoxTransparency(m_xBuilder->weld_widget("boxTRANSPARENCY"))
109 , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_LINE_TRANSPARENT", FieldUnit::PERCENT))
110 , m_xFlLineEnds(m_xBuilder->weld_widget("FL_LINE_ENDS"))
111 , m_xBoxArrowStyles(m_xBuilder->weld_widget("boxARROW_STYLES"))
112 , m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_START_STYLE")))
113 , m_xBoxStart(m_xBuilder->weld_widget("boxSTART"))
114 , m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_START_WIDTH", FieldUnit::CM))
115 , m_xTsbCenterStart(m_xBuilder->weld_check_button("TSB_CENTER_START"))
116 , m_xBoxEnd(m_xBuilder->weld_widget("boxEND"))
117 , m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_END_STYLE")))
118 , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
119 , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
120 , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
121 , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
122 , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
123 , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
124 , m_xLBEdgeStyle(m_xBuilder->weld_combo_box("LB_EDGE_STYLE"))
125 , m_xLBCapStyle(m_xBuilder->weld_combo_box("LB_CAP_STYLE")) // LineCaps
126 , m_xFlSymbol(m_xBuilder->weld_widget("FL_SYMBOL_FORMAT")) //#58425# Symbols on a line (e.g. StarChart)
127 , m_xGridIconSize(m_xBuilder->weld_widget("gridICON_SIZE"))
128 , m_xSymbolMB(m_xBuilder->weld_menu_button("MB_SYMBOL_BITMAP"))
129 , m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_WIDTH", FieldUnit::CM))
130 , m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_HEIGHT", FieldUnit::CM))
131 , m_xSymbolRatioCB(m_xBuilder->weld_check_button("CB_SYMBOL_RATIO"))
133 // This Page requires ExchangeSupport
134 SetExchangeSupport();
136 // Metric set
137 FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
139 switch ( eFUnit )
141 case FieldUnit::M:
142 case FieldUnit::KM:
143 eFUnit = FieldUnit::MM;
144 [[fallthrough]]; // we now have mm
145 case FieldUnit::MM:
146 m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
147 m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
148 m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
149 break;
151 case FieldUnit::INCH:
152 m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
153 m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
154 m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
155 break;
156 default: ;// prevent warning
158 SetFieldUnit( *m_xMtrLineWidth, eFUnit );
159 SetFieldUnit( *m_xMtrStartWidth, eFUnit );
160 SetFieldUnit( *m_xMtrEndWidth, eFUnit );
162 // determine PoolUnit
163 SfxItemPool* pPool = m_rOutAttrs.GetPool();
164 DBG_ASSERT( pPool, "Where is the pool?" );
165 m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
167 m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
168 m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
169 m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
170 m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
172 m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
173 m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
174 m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
175 m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
176 m_xTsbCenterStart->connect_clicked(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
177 m_xTsbCenterEnd->connect_clicked(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
179 Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
180 m_xLBEdgeStyle->connect_changed(aEdgeStyle);
182 // LineCaps
183 Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
184 m_xLBCapStyle->connect_changed(aCapStyle);
186 // Symbols on a line (eg star charts), MB-handler set
187 m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
188 m_xSymbolMB->connect_toggled(LINK(this, SvxLineTabPage, MenuCreateHdl_Impl));
189 m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
190 m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
191 m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
193 m_xSymbolRatioCB->set_active(true);
194 ShowSymbolControls(false);
196 m_nActLineWidth = -1;
199 void SvxLineTabPage::ShowSymbolControls(bool bOn)
201 // Symbols on a line (e.g. StarCharts), symbol-enable controls
203 m_bSymbols=bOn;
204 m_xFlSymbol->set_visible(bOn);
205 m_aCtlPreview.ShowSymbol(bOn);
208 SvxLineTabPage::~SvxLineTabPage()
210 m_xCtlPreview.reset();
211 m_xLbEndStyle.reset();
212 m_xLbStartStyle.reset();
213 m_xLbColor.reset();
214 m_xLbLineStyle.reset();
215 m_aGalleryBrushItems.clear();
216 m_aSymbolBrushItems.clear();
219 void SvxLineTabPage::Construct()
221 FillListboxes();
224 void SvxLineTabPage::FillListboxes()
226 // Line styles
227 auto nOldSelect = m_xLbLineStyle->get_active();
228 // aLbLineStyle.FillStyles();
229 m_xLbLineStyle->Fill( m_pDashList );
230 m_xLbLineStyle->set_active( nOldSelect );
232 // Line end style
233 OUString sNone( SvxResId( RID_SVXSTR_NONE ) );
234 nOldSelect = m_xLbStartStyle->get_active();
235 m_xLbStartStyle->clear();
236 m_xLbStartStyle->append_text(sNone);
237 m_xLbStartStyle->Fill(m_pLineEndList);
238 m_xLbStartStyle->set_active(nOldSelect);
239 nOldSelect = m_xLbEndStyle->get_active();
240 m_xLbEndStyle->clear();
241 m_xLbEndStyle->append_text(sNone);
242 m_xLbEndStyle->Fill(m_pLineEndList, false);
243 m_xLbEndStyle->set_active(nOldSelect);
246 void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
248 const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
249 if (pPageTypeItem)
250 SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
251 if( m_nDlgType == 0 && m_pDashList.is() )
253 sal_Int32 nPos;
254 sal_Int32 nCount;
256 // Dash list
257 if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
258 ( *m_pnDashListState & ChangeType::CHANGED ) )
260 if( *m_pnDashListState & ChangeType::CHANGED )
261 m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
263 *m_pnDashListState = ChangeType::NONE;
265 // Style list
266 nPos = m_xLbLineStyle->get_active();
268 m_xLbLineStyle->clear();
269 m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
270 m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
271 m_xLbLineStyle->Fill(m_pDashList);
272 nCount = m_xLbLineStyle->get_count();
274 if ( nCount == 0 )
275 ; // This case should never occur
276 else if( nCount <= nPos )
277 m_xLbLineStyle->set_active(0);
278 else
279 m_xLbLineStyle->set_active(nPos);
282 INetURLObject aDashURL( m_pDashList->GetPath() );
284 aDashURL.Append( m_pDashList->GetName() );
285 DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
286 // LineEnd list
287 if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
289 if( *m_pnLineEndListState & ChangeType::CHANGED )
290 m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
292 *m_pnLineEndListState = ChangeType::NONE;
294 nPos = m_xLbLineStyle->get_active();
295 OUString sNone(SvxResId(RID_SVXSTR_NONE));
296 m_xLbStartStyle->clear();
297 m_xLbStartStyle->append_text(sNone);
299 m_xLbStartStyle->Fill( m_pLineEndList );
300 nCount = m_xLbStartStyle->get_count();
301 if( nCount == 0 )
302 ; // This case should never occur
303 else if( nCount <= nPos )
304 m_xLbStartStyle->set_active(0);
305 else
306 m_xLbStartStyle->set_active(nPos);
308 m_xLbEndStyle->clear();
309 m_xLbEndStyle->append_text(sNone);
311 m_xLbEndStyle->Fill( m_pLineEndList, false );
312 nCount = m_xLbEndStyle->get_count();
314 if( nCount == 0 )
315 ; // This case should never occur
316 else if( nCount <= nPos )
317 m_xLbEndStyle->set_active(0);
318 else
319 m_xLbEndStyle->set_active(nPos);
321 INetURLObject aLineURL( m_pLineEndList->GetPath() );
323 aLineURL.Append( m_pLineEndList->GetName() );
324 DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
325 // Evaluate if another TabPage set another fill type
326 if( m_xLbLineStyle->get_active() != 0 )
328 if( m_nPageType == PageType::Hatch ) // 1
330 m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
331 ChangePreviewHdl_Impl( nullptr );
333 if( m_nPageType == PageType::Bitmap )
335 m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
336 m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
337 ChangePreviewHdl_Impl( nullptr );
341 // ColorList
342 if( *m_pnColorListState != ChangeType::NONE )
344 ChangePreviewHdl_Impl( nullptr );
347 m_nPageType = PageType::Area;
349 // Page does not yet exist in the ctor, that's why we do it here!
351 else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
353 m_xFlLineEnds->hide();
354 m_xFLEdgeStyle->hide();
359 DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
361 if( m_nDlgType == 0 ) // Line dialog
363 m_nPageType = PageType::Gradient; // possibly for extensions
364 *m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
365 sal_Int32 nPos = m_xLbStartStyle->get_active();
366 if (nPos != -1)
367 nPos--;
368 *m_pPosLineEndLb = nPos;
371 if( _pSet )
372 FillItemSet( _pSet );
374 return DeactivateRC::LeavePage;
378 bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
380 const SfxPoolItem* pOld = nullptr;
381 sal_Int32 nPos;
382 bool bModified = false;
384 // To prevent modifications to the list, we do not set other page's items.
385 if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
387 nPos = m_xLbLineStyle->get_active();
388 if( nPos != -1 &&
389 m_xLbLineStyle->get_value_changed_from_saved() )
391 std::unique_ptr<XLineStyleItem> pStyleItem;
393 if( nPos == 0 )
394 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
395 else if( nPos == 1 )
396 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
397 else
399 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
401 // For added security
402 if( m_pDashList->Count() > static_cast<long>( nPos - 2 ) )
404 XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
405 m_pDashList->GetDash( nPos - 2 )->GetDash() );
406 pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
407 if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
409 rAttrs->Put( aDashItem );
410 bModified = true;
414 pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
415 if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
417 rAttrs->Put( *pStyleItem );
418 bModified = true;
422 // Line width
423 // GetSavedValue() returns OUString!
424 if( m_xMtrLineWidth->get_value_changed_from_saved() )
426 XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
427 pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
428 if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
430 rAttrs->Put( aItem );
431 bModified = true;
434 // Width line start
435 if( m_xMtrStartWidth->get_value_changed_from_saved() )
437 XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
438 pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
439 if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
441 rAttrs->Put( aItem );
442 bModified = true;
445 // Width line end
446 if( m_xMtrEndWidth->get_value_changed_from_saved() )
448 XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
449 pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
450 if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
452 rAttrs->Put( aItem );
453 bModified = true;
457 // Line color
459 NamedColor aColor = m_xLbColor->GetSelectedEntry();
460 XLineColorItem aItem(aColor.second, aColor.first);
461 pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
462 if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
464 rAttrs->Put( aItem );
465 bModified = true;
469 if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
471 // Line start
472 nPos = m_xLbStartStyle->get_active();
473 if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
475 std::unique_ptr<XLineStartItem> pItem;
476 if( nPos == 0 )
477 pItem.reset(new XLineStartItem());
478 else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
479 pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
480 pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
481 if( pItem && ( !pOld || *pOld != *pItem ) )
483 rAttrs->Put( *pItem );
484 bModified = true;
487 // Line end
488 nPos = m_xLbEndStyle->get_active();
489 if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
491 std::unique_ptr<XLineEndItem> pItem;
492 if( nPos == 0 )
493 pItem.reset(new XLineEndItem());
494 else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
495 pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
496 pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
497 if( pItem &&
498 ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
500 rAttrs->Put( *pItem );
501 bModified = true;
506 // Centered line end
507 TriState eState = m_xTsbCenterStart->get_state();
508 if( m_xTsbCenterStart->get_state_changed_from_saved() )
510 XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
511 pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
512 if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
514 rAttrs->Put( aItem );
515 bModified = true;
518 eState = m_xTsbCenterEnd->get_state();
519 if( m_xTsbCenterEnd->get_state_changed_from_saved() )
521 XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
522 pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
523 if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
525 rAttrs->Put( aItem );
526 bModified = true;
530 // Transparency
531 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
532 if( m_xMtrTransparent->get_value_changed_from_saved() )
534 XLineTransparenceItem aItem( nVal );
535 pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
536 if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
538 rAttrs->Put( aItem );
539 bModified = true;
543 nPos = m_xLBEdgeStyle->get_active();
544 if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
546 std::unique_ptr<XLineJointItem> pNew;
548 switch(nPos)
550 case 0: // Rounded, default
552 pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
553 break;
555 case 1: // - none -
557 pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
558 break;
560 case 2: // Miter
562 pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
563 break;
565 case 3: // Bevel
567 pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
568 break;
572 if(pNew)
574 pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
576 if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
578 rAttrs->Put( *pNew );
579 bModified = true;
584 // LineCaps
585 nPos = m_xLBCapStyle->get_active();
586 if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
588 std::unique_ptr<XLineCapItem> pNew;
590 switch(nPos)
592 case 0: // Butt (=Flat), default
594 pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
595 break;
597 case 1: // Round
599 pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
600 break;
602 case 2: // Square
604 pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
605 break;
609 if(pNew)
611 pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
613 if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
615 rAttrs->Put( *pNew );
616 bModified = true;
621 if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
623 // Was set by selection or the size is different
624 SvxSizeItem aSItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
625 const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE) );
626 m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
627 if(m_bNewSize)
629 rAttrs->Put(aSItem);
630 bModified=true;
633 SfxInt32Item aTItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
634 const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE) );
635 bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
636 if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
637 bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
638 if(bNewType)
640 rAttrs->Put(aTItem);
641 bModified=true;
644 if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
646 SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH));
647 const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH) );
648 bool bNewBrush =
649 pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
650 if(bNewBrush)
652 rAttrs->Put(aBItem);
653 bModified=true;
657 rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
658 return bModified;
662 void SvxLineTabPage::FillXLSet_Impl()
664 sal_Int32 nPos;
666 if (m_xLbLineStyle->get_active() == -1)
668 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
670 else if (m_xLbLineStyle->get_active() == 0)
671 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
672 else if (m_xLbLineStyle->get_active() == 1)
673 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
674 else
676 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
678 nPos = m_xLbLineStyle->get_active();
679 if (nPos != -1)
681 m_rXLSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
682 m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
686 nPos = m_xLbStartStyle->get_active();
687 if (nPos != -1)
689 if( nPos == 0 )
690 m_rXLSet.Put( XLineStartItem() );
691 else
692 m_rXLSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
693 m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
695 nPos = m_xLbEndStyle->get_active();
696 if (nPos != -1)
698 if( nPos == 0 )
699 m_rXLSet.Put( XLineEndItem() );
700 else
701 m_rXLSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
702 m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
705 nPos = m_xLBEdgeStyle->get_active();
706 if (nPos != -1)
708 switch(nPos)
710 case 0: // Rounded, default
712 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
713 break;
715 case 1: // - none -
717 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
718 break;
720 case 2: // Miter
722 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
723 break;
725 case 3: // Bevel
727 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
728 break;
733 // LineCaps
734 nPos = m_xLBCapStyle->get_active();
735 if (nPos != -1)
737 switch(nPos)
739 case 0: // Butt (=Flat), default
741 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
742 break;
744 case 1: // Round
746 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
747 break;
749 case 2: // Square
751 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
752 break;
757 m_rXLSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
758 m_rXLSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
760 m_rXLSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
761 NamedColor aColor = m_xLbColor->GetSelectedEntry();
762 m_rXLSet.Put(XLineColorItem(aColor.second, aColor.first));
764 // Centered line end
765 if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
766 m_rXLSet.Put( XLineStartCenterItem( true ) );
767 else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
768 m_rXLSet.Put( XLineStartCenterItem( false ) );
770 if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
771 m_rXLSet.Put( XLineEndCenterItem( true ) );
772 else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
773 m_rXLSet.Put( XLineEndCenterItem( false ) );
775 // Transparency
776 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
777 m_rXLSet.Put( XLineTransparenceItem( nVal ) );
779 m_aCtlPreview.SetLineAttributes(m_aXLineAttr.GetItemSet());
783 void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
785 drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
787 // Line style
788 const SfxPoolItem *pPoolItem;
789 long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
790 bool bPrevSym=false;
791 bool bEnable=true;
792 bool bIgnoreGraphic=false;
793 bool bIgnoreSize=false;
794 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),true,&pPoolItem) == SfxItemState::SET)
796 nSymType=static_cast<const SfxInt32Item *>(pPoolItem)->GetValue();
799 if(nSymType == SVX_SYMBOLTYPE_AUTO)
801 m_aSymbolGraphic=m_aAutoSymbolGraphic;
802 m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
803 bPrevSym=true;
805 else if(nSymType == SVX_SYMBOLTYPE_NONE)
807 bEnable=false;
808 bIgnoreGraphic=true;
809 bIgnoreSize=true;
811 else if(nSymType >= 0)
813 ScopedVclPtrInstance< VirtualDevice > pVDev;
814 pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
816 std::unique_ptr<SdrModel> pModel(
817 new SdrModel(nullptr, nullptr, true));
818 pModel->GetItemPool().FreezeIdRanges();
819 SdrPage* pPage = new SdrPage( *pModel, false );
820 pPage->SetSize(Size(1000,1000));
821 pModel->InsertPage( pPage, 0 );
823 std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
824 pView->hideMarkHandles();
825 pView->ShowSdrPage(pPage);
826 SdrObject *pObj=nullptr;
827 size_t nSymTmp = static_cast<size_t>(nSymType);
828 if(m_pSymbolList)
830 if(m_pSymbolList->GetObjCount())
832 nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
833 pObj=m_pSymbolList->GetObj(nSymTmp);
834 if(pObj)
836 // directly clone to target SdrModel
837 pObj = pObj->CloneSdrObject(*pModel);
839 if(m_pSymbolAttr)
841 pObj->SetMergedItemSet(*m_pSymbolAttr);
843 else
845 pObj->SetMergedItemSet(m_rOutAttrs);
848 pPage->NbcInsertObject(pObj);
850 // Generate invisible square to give all symbol types a
851 // bitmap size, which is independent from specific glyph
852 SdrObject* pInvisibleSquare(m_pSymbolList->GetObj(0));
854 // directly clone to target SdrModel
855 pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
857 pPage->NbcInsertObject(pInvisibleSquare);
858 pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
859 pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
861 pView->MarkAll();
862 GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
864 m_aSymbolGraphic=Graphic(aMeta);
865 m_aSymbolSize=pObj->GetSnapRect().GetSize();
866 m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
867 m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
868 bPrevSym=true;
869 bEnable=true;
870 bIgnoreGraphic=true;
872 pView->UnmarkAll();
873 pInvisibleSquare=pPage->RemoveObject(1);
874 SdrObject::Free( pInvisibleSquare);
875 pObj=pPage->RemoveObject(0);
876 SdrObject::Free( pObj );
882 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH),true,&pPoolItem) == SfxItemState::SET)
884 const Graphic* pGraphic = static_cast<const SvxBrushItem *>(pPoolItem)->GetGraphic();
885 if( pGraphic )
887 if(!bIgnoreGraphic)
889 m_aSymbolGraphic=*pGraphic;
891 if(!bIgnoreSize)
893 m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
894 pGraphic->GetPrefMapMode(),
895 MapMode(MapUnit::Map100thMM));
897 bPrevSym=true;
901 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),true,&pPoolItem) == SfxItemState::SET)
903 m_aSymbolSize = static_cast<const SvxSizeItem *>(pPoolItem)->GetSize();
906 m_xGridIconSize->set_sensitive(bEnable);
908 if(bPrevSym)
910 SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
911 SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
912 m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
913 m_aSymbolLastSize=m_aSymbolSize;
916 if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
918 eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
920 switch( eXLS )
922 case drawing::LineStyle_NONE:
923 m_xLbLineStyle->set_active(0);
924 break;
925 case drawing::LineStyle_SOLID:
926 m_xLbLineStyle->set_active(1);
927 break;
929 case drawing::LineStyle_DASH:
930 m_xLbLineStyle->set_active(-1);
931 m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
932 break;
934 default:
935 break;
938 else
940 m_xLbLineStyle->set_active(-1);
943 // Line strength
944 if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
946 SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
948 else
949 m_xMtrLineWidth->set_text("");
951 // Line color
952 m_xLbColor->SetNoSelection();
954 if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::DONTCARE )
956 Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
957 m_xLbColor->SelectEntry( aCol );
960 // Line start
961 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
963 m_xLbStartStyle->set_sensitive(false);
965 else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::DONTCARE )
967 // #86265# select entry using list and polygon, not string
968 bool bSelected(false);
969 const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
971 for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
973 const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
974 const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
976 if(rItemPolygon == rEntryPolygon)
978 // select this entry
979 m_xLbStartStyle->set_active(a + 1);
980 bSelected = true;
984 if(!bSelected)
985 m_xLbStartStyle->set_active(0);
987 else
989 m_xLbStartStyle->set_active(-1);
992 // Line end
993 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
995 m_xLbEndStyle->set_sensitive(false);
997 else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::DONTCARE )
999 // #86265# select entry using list and polygon, not string
1000 bool bSelected(false);
1001 const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
1003 for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
1005 const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
1006 const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
1008 if(rItemPolygon == rEntryPolygon)
1010 // select this entry
1011 m_xLbEndStyle->set_active(a + 1);
1012 bSelected = true;
1016 if(!bSelected)
1017 m_xLbEndStyle->set_active(0);
1019 else
1021 m_xLbEndStyle->set_active(-1);
1024 // Line start strength
1025 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
1027 m_xMtrStartWidth->set_sensitive(false);
1029 else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::DONTCARE )
1031 SetMetricValue( *m_xMtrStartWidth,
1032 rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
1033 m_ePoolUnit );
1035 else
1036 m_xMtrStartWidth->set_text( "" );
1038 // Line end strength
1039 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
1041 m_xMtrEndWidth->set_sensitive(false);
1043 else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::DONTCARE )
1045 SetMetricValue( *m_xMtrEndWidth,
1046 rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
1047 m_ePoolUnit );
1049 else
1050 m_xMtrEndWidth->set_text("");
1052 // Centered line end (start)
1053 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
1055 m_xTsbCenterStart->set_sensitive(false);
1057 else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::DONTCARE )
1059 if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
1060 m_xTsbCenterStart->set_state(TRISTATE_TRUE);
1061 else
1062 m_xTsbCenterStart->set_state(TRISTATE_FALSE);
1064 else
1066 m_xTsbCenterStart->set_state(TRISTATE_INDET);
1069 // Centered line end (end)
1070 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
1072 m_xTsbCenterEnd->set_sensitive(false);
1074 else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::DONTCARE )
1076 if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
1077 m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
1078 else
1079 m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
1081 else
1083 m_xTsbCenterEnd->set_state(TRISTATE_INDET);
1086 // Transparency
1087 if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::DONTCARE )
1089 sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
1090 m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
1091 ChangeTransparentHdl_Impl(*m_xMtrTransparent);
1093 else
1094 m_xMtrTransparent->set_text( "" );
1096 if( !m_xLbStartStyle->get_sensitive() &&
1097 !m_xLbEndStyle->get_sensitive() &&
1098 !m_xMtrStartWidth->get_sensitive() &&
1099 !m_xMtrEndWidth->get_sensitive() &&
1100 !m_xTsbCenterStart->get_sensitive()&&
1101 !m_xTsbCenterEnd->get_sensitive() )
1103 m_xCbxSynchronize->set_sensitive(false);
1104 m_xFlLineEnds->set_sensitive(false);
1107 // Synchronize
1108 // We get the value from the INI file now
1109 OUString aStr = GetUserData();
1110 m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
1112 if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
1114 // maFTEdgeStyle.set_sensitive(false);
1115 m_xLBEdgeStyle->set_sensitive(false);
1117 else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINEJOINT))
1119 const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
1121 switch(eLineJoint)
1123 case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
1124 case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
1125 case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
1126 case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
1127 case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
1128 case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
1131 else
1133 m_xLBEdgeStyle->set_active(-1);
1136 // fdo#43209
1137 if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
1139 m_xLBCapStyle->set_sensitive(false);
1141 else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINECAP))
1143 const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
1145 switch(eLineCap)
1147 case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
1148 case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
1149 default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
1152 else
1154 m_xLBCapStyle->set_active(-1);
1157 // Save values
1158 m_xLbLineStyle->save_value();
1159 m_xMtrLineWidth->save_value();
1160 m_xLbColor->SaveValue();
1161 m_xLbStartStyle->save_value();
1162 m_xLbEndStyle->save_value();
1163 m_xMtrStartWidth->save_value();
1164 m_xMtrEndWidth->save_value();
1165 m_xTsbCenterStart->save_state();
1166 m_xTsbCenterEnd->save_state();
1167 m_xMtrTransparent->save_value();
1169 m_xLBEdgeStyle->save_value();
1171 // LineCaps
1172 m_xLBCapStyle->save_value();
1174 ClickInvisibleHdl_Impl();
1176 ChangePreviewHdl_Impl( nullptr );
1179 std::unique_ptr<SfxTabPage> SvxLineTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
1180 const SfxItemSet* rAttrs)
1182 return std::make_unique<SvxLineTabPage>(pPage, pController, *rAttrs);
1185 IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
1187 ChangePreviewHdl_Impl(nullptr);
1190 IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
1192 ChangePreviewHdl_Impl(&rEdit);
1195 void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
1197 if (pCntrl == m_xMtrLineWidth.get())
1199 // Line width and start end width
1200 sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
1201 if(m_nActLineWidth == -1)
1203 // Don't initialize yet, get the start value
1204 const SfxPoolItem* pOld = GetOldItem( m_rXLSet, XATTR_LINEWIDTH );
1205 sal_Int32 nStartLineWidth = 0;
1206 if(pOld)
1207 nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
1208 m_nActLineWidth = nStartLineWidth;
1211 if(m_nActLineWidth != nNewLineWidth)
1213 // Adapt start/end width
1214 sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
1215 sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
1216 if(nValNew < 0)
1217 nValNew = 0;
1218 SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
1220 nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
1221 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
1222 if(nValNew < 0)
1223 nValNew = 0;
1224 SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
1227 // Remember current value
1228 m_nActLineWidth = nNewLineWidth;
1231 FillXLSet_Impl();
1232 m_aCtlPreview.Invalidate();
1234 // Make transparency accessible accordingly
1235 if( m_xLbLineStyle->get_active() == 0 ) // invisible
1237 m_xBoxTransparency->set_sensitive(false);
1239 else
1241 m_xBoxTransparency->set_sensitive(true);
1244 const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
1245 const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
1247 m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
1249 const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
1251 m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
1254 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Button&, void)
1256 if (m_xCbxSynchronize->get_active())
1257 m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
1258 ChangePreviewHdl_Impl(nullptr);
1261 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
1263 if (m_xCbxSynchronize->get_active())
1264 m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
1266 ChangePreviewHdl_Impl(nullptr);
1269 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
1271 if (m_xCbxSynchronize->get_active())
1272 m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
1274 ChangePreviewHdl_Impl(nullptr);
1277 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
1279 ChangePreviewHdl_Impl( nullptr );
1282 // fdo#43209
1283 IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
1285 ChangePreviewHdl_Impl( nullptr );
1288 IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
1290 ClickInvisibleHdl_Impl();
1293 void SvxLineTabPage::ClickInvisibleHdl_Impl()
1295 if( m_xLbLineStyle->get_active() == 0 ) // invisible
1297 if(!m_bSymbols)
1298 m_xBoxColor->set_sensitive(false);
1300 m_xBoxWidth->set_sensitive(false);
1302 if( m_xFlLineEnds->get_sensitive() )
1304 m_xBoxStart->set_sensitive(false);
1305 m_xBoxArrowStyles->set_sensitive(false);
1306 m_xGridEdgeCaps->set_sensitive(false);
1309 else
1311 m_xBoxColor->set_sensitive(true);
1312 m_xBoxWidth->set_sensitive(true);
1314 if (m_xFlLineEnds->get_sensitive())
1316 m_xBoxArrowStyles->set_sensitive(true);
1317 m_xGridEdgeCaps->set_sensitive(true);
1320 ChangePreviewHdl_Impl( nullptr );
1323 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Button&, void)
1325 if (m_xCbxSynchronize->get_active())
1326 m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
1328 ChangePreviewHdl_Impl(nullptr);
1331 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
1333 if (m_xCbxSynchronize->get_active())
1334 m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
1336 ChangePreviewHdl_Impl(nullptr);
1339 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
1341 if (m_xCbxSynchronize->get_active())
1342 m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
1344 ChangePreviewHdl_Impl(nullptr);
1347 IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
1349 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
1351 m_rXLSet.Put(XLineTransparenceItem(nVal));
1353 FillXLSet_Impl();
1355 m_aCtlPreview.Invalidate();
1358 void SvxLineTabPage::FillUserData()
1360 // Write the synched value to the INI file
1361 OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
1362 SetUserData( aStrUserData );
1365 // #58425# Symbols on a list (e.g. StarChart)
1366 // Handler for the symbol selection's popup menu (NumMenueButton)
1367 // The following link originates from SvxNumOptionsTabPage
1368 IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
1370 ScopedVclPtrInstance< VirtualDevice > pVD;
1372 // Initialize popup
1373 if (!m_xGalleryMenu)
1375 m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
1376 weld::WaitObject aWait(GetFrameWeld());
1377 // Get gallery entries
1378 GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
1380 sal_uInt32 i = 0;
1381 for (auto const& grfName : m_aGrfNames)
1383 const OUString *pUIName = &grfName;
1385 // Convert URL encodings to UI characters (e.g. %20 for spaces)
1386 OUString aPhysicalName;
1387 if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
1388 == osl::FileBase::E_None)
1390 pUIName = &aPhysicalName;
1393 SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
1394 pInfo->pBrushItem.reset(new SvxBrushItem(grfName, "", GPOS_AREA, SID_ATTR_BRUSH));
1395 pInfo->sItemId = "gallery" + OUString::number(i);
1396 m_aGalleryBrushItems.emplace_back(pInfo);
1397 const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
1399 if(pGraphic)
1401 BitmapEx aBitmap(pGraphic->GetBitmapEx());
1402 Size aSize(aBitmap.GetSizePixel());
1403 if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
1405 bool bWidth = aSize.Width() > aSize.Height();
1406 double nScale = bWidth ?
1407 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
1408 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
1409 aBitmap.Scale(nScale, nScale);
1412 pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
1413 pVD->DrawBitmapEx(Point(), aBitmap);
1414 m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
1416 else
1418 m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
1420 ++i;
1423 if (m_aGrfNames.empty())
1424 m_xSymbolMB->set_item_sensitive("gallery", false);
1427 if (!m_xSymbolsMenu && m_pSymbolList)
1429 m_xSymbolsMenu = m_xBuilder->weld_menu("symbolssubmenu");
1430 ScopedVclPtrInstance< VirtualDevice > pVDev;
1431 pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
1432 std::unique_ptr<SdrModel> pModel(
1433 new SdrModel(nullptr, nullptr, true));
1434 pModel->GetItemPool().FreezeIdRanges();
1435 // Page
1436 SdrPage* pPage = new SdrPage( *pModel, false );
1437 pPage->SetSize(Size(1000,1000));
1438 pModel->InsertPage( pPage, 0 );
1440 // 3D View
1441 std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
1442 pView->hideMarkHandles();
1443 pView->ShowSdrPage(pPage);
1445 // Generate invisible square to give all symbols a
1446 // bitmap size, which is independent from specific glyph
1447 SdrObject *pInvisibleSquare=m_pSymbolList->GetObj(0);
1449 // directly clone to target SdrModel
1450 pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
1452 pPage->NbcInsertObject(pInvisibleSquare);
1453 pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
1454 pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
1456 for(size_t i=0;; ++i)
1458 SdrObject *pObj=m_pSymbolList->GetObj(i);
1459 if(pObj==nullptr)
1460 break;
1462 // directly clone to target SdrModel
1463 pObj = pObj->CloneSdrObject(*pModel);
1465 m_aGrfNames.emplace_back("");
1466 pPage->NbcInsertObject(pObj);
1467 if(m_pSymbolAttr)
1469 pObj->SetMergedItemSet(*m_pSymbolAttr);
1471 else
1473 pObj->SetMergedItemSet(m_rOutAttrs);
1475 pView->MarkAll();
1476 BitmapEx aBitmapEx(pView->GetMarkedObjBitmapEx());
1477 GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
1478 pView->UnmarkAll();
1479 pObj=pPage->RemoveObject(1);
1480 SdrObject::Free(pObj);
1482 SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
1483 pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
1484 pInfo->sItemId = "symbol" + OUString::number(i);
1485 m_aSymbolBrushItems.emplace_back(pInfo);
1487 Size aSize(aBitmapEx.GetSizePixel());
1488 if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
1490 bool bWidth = aSize.Width() > aSize.Height();
1491 double nScale = bWidth ?
1492 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
1493 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
1494 aBitmapEx.Scale(nScale, nScale);
1496 pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
1497 pVD->DrawBitmapEx(Point(), aBitmapEx);
1498 m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
1500 pInvisibleSquare=pPage->RemoveObject(0);
1501 SdrObject::Free(pInvisibleSquare);
1503 if (m_aGrfNames.empty())
1504 m_xSymbolMB->set_item_sensitive("symbols", false);
1509 // #58425# Symbols on a list (e.g. StarChart)
1510 // Handler for menu button
1511 IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
1513 const Graphic* pGraphic = nullptr;
1514 Graphic aGraphic;
1515 bool bResetSize = false;
1516 bool bEnable = true;
1517 long nPreviousSymbolType = m_nSymbolType;
1519 OString sNumber;
1520 if (rIdent.startsWith("gallery", &sNumber))
1522 SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
1523 pGraphic = pInfo->pBrushItem->GetGraphic();
1524 m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
1526 else if (rIdent.startsWith("symbol", &sNumber))
1528 m_nSymbolType = sNumber.toUInt32();
1529 SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
1530 pGraphic = pInfo->pBrushItem->GetGraphic();
1532 else if (rIdent == "automatic")
1534 pGraphic=&m_aAutoSymbolGraphic;
1535 m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
1536 m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
1538 else if (rIdent == "none")
1540 m_nSymbolType=SVX_SYMBOLTYPE_NONE;
1541 pGraphic=nullptr;
1542 bEnable = false;
1544 else if (rIdent == "file")
1546 SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_SVXSTR_EDIT_GRAPHIC), GetFrameWeld());
1547 aGrfDlg.EnableLink(false);
1548 aGrfDlg.AsLink(false);
1549 if( !aGrfDlg.Execute() )
1551 // Remember selected filters
1552 if( !aGrfDlg.GetGraphic(aGraphic) )
1554 m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
1555 pGraphic = &aGraphic;
1556 bResetSize = true;
1559 if( !pGraphic )
1560 return;
1563 if (pGraphic)
1565 Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
1566 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
1567 m_aSymbolGraphic=*pGraphic;
1568 if( bResetSize )
1570 m_aSymbolSize=aSize;
1572 else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
1573 { //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
1574 if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
1576 aSize.setWidth( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
1577 aSize.setHeight( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
1578 m_aSymbolSize = aSize;
1581 m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
1583 else
1585 m_aSymbolGraphic=Graphic();
1586 m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
1587 bEnable = false;
1589 m_aSymbolLastSize=m_aSymbolSize;
1590 SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
1591 SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
1593 m_xGridIconSize->set_sensitive(bEnable);
1594 m_aCtlPreview.Invalidate();
1597 IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
1599 m_bNewSize = true;
1600 bool bWidth = &rField == m_xSymbolWidthMF.get();
1601 m_bLastWidthModified = bWidth;
1602 bool bRatio = m_xSymbolRatioCB->get_active();
1603 long nWidthVal = static_cast<long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
1604 long nHeightVal= static_cast<long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
1605 nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
1606 nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
1607 m_aSymbolSize = Size(nWidthVal,nHeightVal);
1608 double fSizeRatio = double(1);
1610 if(bRatio)
1612 if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
1613 fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
1616 if (bWidth)
1618 long nDelta = nWidthVal - m_aSymbolLastSize.Width();
1619 m_aSymbolSize.setWidth( nWidthVal );
1620 if (bRatio)
1622 m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<long>(static_cast<double>(nDelta) / fSizeRatio) );
1623 m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
1624 //TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
1625 m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
1628 else
1630 long nDelta = nHeightVal - m_aSymbolLastSize.Height();
1631 m_aSymbolSize.setHeight( nHeightVal );
1632 if (bRatio)
1634 m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<long>(static_cast<double>(nDelta) * fSizeRatio) );
1635 m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
1636 //TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
1637 m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
1640 m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
1641 m_aSymbolLastSize=m_aSymbolSize;
1644 IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::ToggleButton&, rBox, void)
1646 if (rBox.get_active())
1648 if (m_bLastWidthModified)
1649 SizeHdl_Impl(*m_xSymbolWidthMF);
1650 else
1651 SizeHdl_Impl(*m_xSymbolHeightMF);
1655 void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
1657 const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
1658 const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
1659 const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
1660 const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
1661 const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
1662 const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
1663 const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
1665 if (pDashListItem)
1666 SetDashList(pDashListItem->GetDashList());
1667 if (pLineEndListItem)
1668 SetLineEndList(pLineEndListItem->GetLineEndList());
1669 if (pPageTypeItem)
1670 SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
1671 if (pDlgTypeItem)
1672 SetDlgType(pDlgTypeItem->GetValue());
1673 Construct();
1675 if(pSdrObjListItem) //symbols
1677 ShowSymbolControls(true);
1678 m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
1679 if (pSymbolAttrItem)
1680 m_pSymbolAttr = new SfxItemSet(pSymbolAttrItem->GetItemSet());
1681 if(pGraphicItem)
1682 m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
1686 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */