bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / tpline.cxx
blob8dd8dc36f52794eb831c663b0ca4e8d295be6591
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>
24 #include <sfx2/app.hxx>
25 #include <sfx2/module.hxx>
27 #include <strings.hrc>
28 #include <svx/colorbox.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/xpool.hxx>
43 #include <svx/xtable.hxx>
44 #include <svx/drawitem.hxx>
45 #include <cuitabline.hxx>
46 #include <dlgname.hxx>
47 #include <dialmgr.hxx>
48 #include <svx/dlgutil.hxx>
49 #include <svx/svxgrahicitem.hxx>
50 #include <sfx2/request.hxx>
51 #include <sfx2/dialoghelper.hxx>
52 #include <svx/ofaitem.hxx>
53 #include <svx/svdobj.hxx>
54 #include <svx/svdview.hxx>
55 #include <svx/svdmodel.hxx>
56 #include <svx/numvset.hxx>
57 #include <svx/xlntrit.hxx>
58 #include <svx/xfltrit.hxx>
59 #include <editeng/numitem.hxx>
60 #include <editeng/svxenum.hxx>
61 #include <sfx2/objsh.hxx>
62 #include <editeng/brushitem.hxx>
63 #include <svx/gallery.hxx>
64 #include <sfx2/opengrf.hxx>
65 #include <svx/dialmgr.hxx>
66 #include <svx/dialogs.hrc>
67 #include <svx/svxids.hrc>
68 #include <svx/strings.hrc>
69 #include <vcl/settings.hxx>
70 #include <cuitabarea.hxx>
71 #include <svtools/unitconv.hxx>
73 #define MAX_BMP_WIDTH 16
74 #define MAX_BMP_HEIGHT 16
76 using namespace com::sun::star;
78 // static ----------------------------------------------------------------
80 const sal_uInt16 SvxLineTabPage::pLineRanges[] =
82 XATTR_LINETRANSPARENCE,
83 XATTR_LINETRANSPARENCE,
84 SID_ATTR_LINE_STYLE,
85 SID_ATTR_LINE_ENDCENTER,
89 SvxLineTabPage::SvxLineTabPage(TabPageParent pParent, const SfxItemSet& rInAttrs)
90 : SfxTabPage(pParent, "cui/ui/linetabpage.ui", "LineTabPage", &rInAttrs)
91 , m_pSymbolList(nullptr)
92 , m_bNewSize(false)
93 , m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
94 , m_pSymbolAttr(nullptr)
95 , m_bLastWidthModified(false)
96 , m_aSymbolLastSize(Size(0,0))
97 , m_bSymbols(false)
98 , m_rOutAttrs(rInAttrs)
99 , m_bObjSelected(false)
100 , m_aXLineAttr(rInAttrs.GetPool())
101 , m_rXLSet(m_aXLineAttr.GetItemSet())
102 , m_pnLineEndListState(nullptr)
103 , m_pnDashListState(nullptr)
104 , m_pnColorListState(nullptr)
105 , m_nPageType(PageType::Area)
106 , m_nDlgType(0)
107 , m_pPosDashLb(nullptr)
108 , m_pPosLineEndLb(nullptr)
109 , m_xBoxColor(m_xBuilder->weld_widget("boxCOLOR"))
110 , m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINE_STYLE")))
111 , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"), pParent.GetFrameWeld()))
112 , m_xBoxWidth(m_xBuilder->weld_widget("boxWIDTH"))
113 , m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_WIDTH", FieldUnit::CM))
114 , m_xBoxTransparency(m_xBuilder->weld_widget("boxTRANSPARENCY"))
115 , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_LINE_TRANSPARENT", FieldUnit::PERCENT))
116 , m_xFlLineEnds(m_xBuilder->weld_widget("FL_LINE_ENDS"))
117 , m_xBoxArrowStyles(m_xBuilder->weld_widget("boxARROW_STYLES"))
118 , m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_START_STYLE")))
119 , m_xBoxStart(m_xBuilder->weld_widget("boxSTART"))
120 , m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_START_WIDTH", FieldUnit::CM))
121 , m_xTsbCenterStart(m_xBuilder->weld_check_button("TSB_CENTER_START"))
122 , m_xBoxEnd(m_xBuilder->weld_widget("boxEND"))
123 , m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_END_STYLE")))
124 , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
125 , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
126 , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
127 , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
128 , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
129 , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
130 , m_xLBEdgeStyle(m_xBuilder->weld_combo_box("LB_EDGE_STYLE"))
131 , m_xLBCapStyle(m_xBuilder->weld_combo_box("LB_CAP_STYLE")) // LineCaps
132 , m_xFlSymbol(m_xBuilder->weld_widget("FL_SYMBOL_FORMAT")) //#58425# Symbols on a line (e.g. StarChart)
133 , m_xGridIconSize(m_xBuilder->weld_widget("gridICON_SIZE"))
134 , m_xSymbolMB(m_xBuilder->weld_menu_button("MB_SYMBOL_BITMAP"))
135 , m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_WIDTH", FieldUnit::CM))
136 , m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_HEIGHT", FieldUnit::CM))
137 , m_xSymbolRatioCB(m_xBuilder->weld_check_button("CB_SYMBOL_RATIO"))
139 // This Page requires ExchangeSupport
140 SetExchangeSupport();
142 // Metric set
143 FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
145 switch ( eFUnit )
147 case FieldUnit::M:
148 case FieldUnit::KM:
149 eFUnit = FieldUnit::MM;
150 [[fallthrough]]; // we now have mm
151 case FieldUnit::MM:
152 m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
153 m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
154 m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
155 break;
157 case FieldUnit::INCH:
158 m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
159 m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
160 m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
161 break;
162 default: ;// prevent warning
164 SetFieldUnit( *m_xMtrLineWidth, eFUnit );
165 SetFieldUnit( *m_xMtrStartWidth, eFUnit );
166 SetFieldUnit( *m_xMtrEndWidth, eFUnit );
168 // determine PoolUnit
169 SfxItemPool* pPool = m_rOutAttrs.GetPool();
170 DBG_ASSERT( pPool, "Where is the pool?" );
171 m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
173 m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
174 m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
175 m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
176 m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
178 m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
179 m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
180 m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
181 m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
182 m_xTsbCenterStart->connect_clicked(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
183 m_xTsbCenterEnd->connect_clicked(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
185 Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
186 m_xLBEdgeStyle->connect_changed(aEdgeStyle);
188 // LineCaps
189 Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
190 m_xLBCapStyle->connect_changed(aCapStyle);
192 // Symbols on a line (eg star charts), MB-handler set
193 m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
194 m_xSymbolMB->connect_toggled(LINK(this, SvxLineTabPage, MenuCreateHdl_Impl));
195 m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
196 m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
197 m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
199 m_xSymbolRatioCB->set_active(true);
200 ShowSymbolControls(false);
202 m_nActLineWidth = -1;
205 void SvxLineTabPage::ShowSymbolControls(bool bOn)
207 // Symbols on a line (e.g. StarCharts), symbol-enable controls
209 m_bSymbols=bOn;
210 m_xFlSymbol->set_visible(bOn);
211 m_aCtlPreview.ShowSymbol(bOn);
214 SvxLineTabPage::~SvxLineTabPage()
216 disposeOnce();
219 void SvxLineTabPage::dispose()
221 m_xCtlPreview.reset();
222 m_xLbEndStyle.reset();
223 m_xLbStartStyle.reset();
224 m_xLbColor.reset();
225 m_xLbLineStyle.reset();
226 m_aGalleryBrushItems.clear();
227 m_aSymbolBrushItems.clear();
229 SfxTabPage::dispose();
232 void SvxLineTabPage::Construct()
234 FillListboxes();
237 void SvxLineTabPage::FillListboxes()
239 // Line styles
240 auto nOldSelect = m_xLbLineStyle->get_active();
241 // aLbLineStyle.FillStyles();
242 m_xLbLineStyle->Fill( m_pDashList );
243 m_xLbLineStyle->set_active( nOldSelect );
245 // Line end style
246 OUString sNone( SvxResId( RID_SVXSTR_NONE ) );
247 nOldSelect = m_xLbStartStyle->get_active();
248 m_xLbStartStyle->clear();
249 m_xLbStartStyle->append_text(sNone);
250 m_xLbStartStyle->Fill(m_pLineEndList);
251 m_xLbStartStyle->set_active(nOldSelect);
252 nOldSelect = m_xLbEndStyle->get_active();
253 m_xLbEndStyle->clear();
254 m_xLbEndStyle->append_text(sNone);
255 m_xLbEndStyle->Fill(m_pLineEndList, false);
256 m_xLbEndStyle->set_active(nOldSelect);
259 void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
261 const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
262 if (pPageTypeItem)
263 SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
264 if( m_nDlgType == 0 && m_pDashList.is() )
266 sal_Int32 nPos;
267 sal_Int32 nCount;
269 // Dash list
270 if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
271 ( *m_pnDashListState & ChangeType::CHANGED ) )
273 if( *m_pnDashListState & ChangeType::CHANGED )
274 m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
276 *m_pnDashListState = ChangeType::NONE;
278 // Style list
279 nPos = m_xLbLineStyle->get_active();
281 m_xLbLineStyle->clear();
282 m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
283 m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
284 m_xLbLineStyle->Fill(m_pDashList);
285 nCount = m_xLbLineStyle->get_count();
287 if ( nCount == 0 )
288 ; // This case should never occur
289 else if( nCount <= nPos )
290 m_xLbLineStyle->set_active(0);
291 else
292 m_xLbLineStyle->set_active(nPos);
295 INetURLObject aDashURL( m_pDashList->GetPath() );
297 aDashURL.Append( m_pDashList->GetName() );
298 DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
299 // LineEnd list
300 if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
302 if( *m_pnLineEndListState & ChangeType::CHANGED )
303 m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
305 *m_pnLineEndListState = ChangeType::NONE;
307 nPos = m_xLbLineStyle->get_active();
308 OUString sNone(SvxResId(RID_SVXSTR_NONE));
309 m_xLbStartStyle->clear();
310 m_xLbStartStyle->append_text(sNone);
312 m_xLbStartStyle->Fill( m_pLineEndList );
313 nCount = m_xLbStartStyle->get_count();
314 if( nCount == 0 )
315 ; // This case should never occur
316 else if( nCount <= nPos )
317 m_xLbStartStyle->set_active(0);
318 else
319 m_xLbStartStyle->set_active(nPos);
321 m_xLbEndStyle->clear();
322 m_xLbEndStyle->append_text(sNone);
324 m_xLbEndStyle->Fill( m_pLineEndList, false );
325 nCount = m_xLbEndStyle->get_count();
327 if( nCount == 0 )
328 ; // This case should never occur
329 else if( nCount <= nPos )
330 m_xLbEndStyle->set_active(0);
331 else
332 m_xLbEndStyle->set_active(nPos);
334 INetURLObject aLineURL( m_pLineEndList->GetPath() );
336 aLineURL.Append( m_pLineEndList->GetName() );
337 DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
338 // Evaluate if another TabPage set another fill type
339 if( m_xLbLineStyle->get_active() != 0 )
341 if( m_nPageType == PageType::Hatch ) // 1
343 m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
344 ChangePreviewHdl_Impl( nullptr );
346 if( m_nPageType == PageType::Bitmap )
348 m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
349 m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
350 ChangePreviewHdl_Impl( nullptr );
354 // ColorList
355 if( *m_pnColorListState != ChangeType::NONE )
357 ChangePreviewHdl_Impl( nullptr );
360 m_nPageType = PageType::Area;
362 // Page does not yet exist in the ctor, that's why we do it here!
364 else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
366 m_xFlLineEnds->hide();
367 m_xFLEdgeStyle->hide();
372 DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
374 if( m_nDlgType == 0 ) // Line dialog
376 m_nPageType = PageType::Gradient; // possibly for extensions
377 *m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
378 sal_Int32 nPos = m_xLbStartStyle->get_active();
379 if (nPos != -1)
380 nPos--;
381 *m_pPosLineEndLb = nPos;
384 if( _pSet )
385 FillItemSet( _pSet );
387 return DeactivateRC::LeavePage;
391 bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
393 const SfxPoolItem* pOld = nullptr;
394 sal_Int32 nPos;
395 bool bModified = false;
397 // To prevent modifications to the list, we do not set other page's items.
398 if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
400 nPos = m_xLbLineStyle->get_active();
401 if( nPos != -1 &&
402 m_xLbLineStyle->get_value_changed_from_saved() )
404 std::unique_ptr<XLineStyleItem> pStyleItem;
406 if( nPos == 0 )
407 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
408 else if( nPos == 1 )
409 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
410 else
412 pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
414 // For added security
415 if( m_pDashList->Count() > static_cast<long>( nPos - 2 ) )
417 XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
418 m_pDashList->GetDash( nPos - 2 )->GetDash() );
419 pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
420 if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
422 rAttrs->Put( aDashItem );
423 bModified = true;
427 pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
428 if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
430 rAttrs->Put( *pStyleItem );
431 bModified = true;
435 // Line width
436 // GetSavedValue() returns OUString!
437 if( m_xMtrLineWidth->get_value_changed_from_saved() )
439 XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
440 pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
441 if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
443 rAttrs->Put( aItem );
444 bModified = true;
447 // Width line start
448 if( m_xMtrStartWidth->get_value_changed_from_saved() )
450 XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
451 pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
452 if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
454 rAttrs->Put( aItem );
455 bModified = true;
458 // Width line end
459 if( m_xMtrEndWidth->get_value_changed_from_saved() )
461 XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
462 pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
463 if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
465 rAttrs->Put( aItem );
466 bModified = true;
470 // Line color
472 NamedColor aColor = m_xLbColor->GetSelectedEntry();
473 XLineColorItem aItem(aColor.second, aColor.first);
474 pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
475 if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
477 rAttrs->Put( aItem );
478 bModified = true;
482 if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
484 // Line start
485 nPos = m_xLbStartStyle->get_active();
486 if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
488 std::unique_ptr<XLineStartItem> pItem;
489 if( nPos == 0 )
490 pItem.reset(new XLineStartItem());
491 else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
492 pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
493 pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
494 if( pItem && ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
496 rAttrs->Put( *pItem );
497 bModified = true;
500 // Line end
501 nPos = m_xLbEndStyle->get_active();
502 if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
504 std::unique_ptr<XLineEndItem> pItem;
505 if( nPos == 0 )
506 pItem.reset(new XLineEndItem());
507 else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
508 pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
509 pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
510 if( pItem &&
511 ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
513 rAttrs->Put( *pItem );
514 bModified = true;
519 // Centered line end
520 TriState eState = m_xTsbCenterStart->get_state();
521 if( m_xTsbCenterStart->get_state_changed_from_saved() )
523 XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
524 pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
525 if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
527 rAttrs->Put( aItem );
528 bModified = true;
531 eState = m_xTsbCenterEnd->get_state();
532 if( m_xTsbCenterEnd->get_state_changed_from_saved() )
534 XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
535 pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
536 if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
538 rAttrs->Put( aItem );
539 bModified = true;
543 // Transparency
544 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
545 if( m_xMtrTransparent->get_value_changed_from_saved() )
547 XLineTransparenceItem aItem( nVal );
548 pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
549 if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
551 rAttrs->Put( aItem );
552 bModified = true;
556 nPos = m_xLBEdgeStyle->get_active();
557 if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
559 std::unique_ptr<XLineJointItem> pNew;
561 switch(nPos)
563 case 0: // Rounded, default
565 pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
566 break;
568 case 1: // - none -
570 pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
571 break;
573 case 2: // Miter
575 pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
576 break;
578 case 3: // Bevel
580 pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
581 break;
585 if(pNew)
587 pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
589 if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
591 rAttrs->Put( *pNew );
592 bModified = true;
597 // LineCaps
598 nPos = m_xLBCapStyle->get_active();
599 if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
601 std::unique_ptr<XLineCapItem> pNew;
603 switch(nPos)
605 case 0: // Butt (=Flat), default
607 pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
608 break;
610 case 1: // Round
612 pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
613 break;
615 case 2: // Square
617 pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
618 break;
622 if(pNew)
624 pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
626 if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
628 rAttrs->Put( *pNew );
629 bModified = true;
634 if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
636 // Was set by selection or the size is different
637 SvxSizeItem aSItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
638 const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE) );
639 m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
640 if(m_bNewSize)
642 rAttrs->Put(aSItem);
643 bModified=true;
646 SfxInt32Item aTItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
647 const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE) );
648 bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
649 if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
650 bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
651 if(bNewType)
653 rAttrs->Put(aTItem);
654 bModified=true;
657 if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
659 SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH));
660 const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH) );
661 bool bNewBrush =
662 pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
663 if(bNewBrush)
665 rAttrs->Put(aBItem);
666 bModified=true;
670 rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
671 return bModified;
675 void SvxLineTabPage::FillXLSet_Impl()
677 sal_Int32 nPos;
679 if (m_xLbLineStyle->get_active() == -1)
681 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
683 else if (m_xLbLineStyle->get_active() == 0)
684 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
685 else if (m_xLbLineStyle->get_active() == 1)
686 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
687 else
689 m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
691 nPos = m_xLbLineStyle->get_active();
692 if (nPos != -1)
694 m_rXLSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
695 m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
699 nPos = m_xLbStartStyle->get_active();
700 if (nPos != -1)
702 if( nPos == 0 )
703 m_rXLSet.Put( XLineStartItem() );
704 else
705 m_rXLSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
706 m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
708 nPos = m_xLbEndStyle->get_active();
709 if (nPos != -1)
711 if( nPos == 0 )
712 m_rXLSet.Put( XLineEndItem() );
713 else
714 m_rXLSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
715 m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
718 nPos = m_xLBEdgeStyle->get_active();
719 if (nPos != -1)
721 switch(nPos)
723 case 0: // Rounded, default
725 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
726 break;
728 case 1: // - none -
730 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
731 break;
733 case 2: // Miter
735 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
736 break;
738 case 3: // Bevel
740 m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
741 break;
746 // LineCaps
747 nPos = m_xLBCapStyle->get_active();
748 if (nPos != -1)
750 switch(nPos)
752 case 0: // Butt (=Flat), default
754 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
755 break;
757 case 1: // Round
759 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
760 break;
762 case 2: // Square
764 m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
765 break;
770 m_rXLSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
771 m_rXLSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
773 m_rXLSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
774 NamedColor aColor = m_xLbColor->GetSelectedEntry();
775 m_rXLSet.Put(XLineColorItem(aColor.second, aColor.first));
777 // Centered line end
778 if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
779 m_rXLSet.Put( XLineStartCenterItem( true ) );
780 else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
781 m_rXLSet.Put( XLineStartCenterItem( false ) );
783 if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
784 m_rXLSet.Put( XLineEndCenterItem( true ) );
785 else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
786 m_rXLSet.Put( XLineEndCenterItem( false ) );
788 // Transparency
789 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
790 m_rXLSet.Put( XLineTransparenceItem( nVal ) );
792 m_aCtlPreview.SetLineAttributes(m_aXLineAttr.GetItemSet());
796 void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
798 drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
800 // Line style
801 const SfxPoolItem *pPoolItem;
802 long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
803 bool bPrevSym=false;
804 bool bEnable=true;
805 bool bIgnoreGraphic=false;
806 bool bIgnoreSize=false;
807 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),true,&pPoolItem) == SfxItemState::SET)
809 nSymType=static_cast<const SfxInt32Item *>(pPoolItem)->GetValue();
812 if(nSymType == SVX_SYMBOLTYPE_AUTO)
814 m_aSymbolGraphic=m_aAutoSymbolGraphic;
815 m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
816 bPrevSym=true;
818 else if(nSymType == SVX_SYMBOLTYPE_NONE)
820 bEnable=false;
821 bIgnoreGraphic=true;
822 bIgnoreSize=true;
824 else if(nSymType >= 0)
826 ScopedVclPtrInstance< VirtualDevice > pVDev;
827 pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
829 std::unique_ptr<SdrModel> pModel(
830 new SdrModel(nullptr, nullptr, true));
831 pModel->GetItemPool().FreezeIdRanges();
832 SdrPage* pPage = new SdrPage( *pModel, false );
833 pPage->SetSize(Size(1000,1000));
834 pModel->InsertPage( pPage, 0 );
836 std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
837 pView->hideMarkHandles();
838 pView->ShowSdrPage(pPage);
839 SdrObject *pObj=nullptr;
840 size_t nSymTmp = static_cast<size_t>(nSymType);
841 if(m_pSymbolList)
843 if(m_pSymbolList->GetObjCount())
845 nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
846 pObj=m_pSymbolList->GetObj(nSymTmp);
847 if(pObj)
849 // directly clone to target SdrModel
850 pObj = pObj->CloneSdrObject(*pModel);
852 if(m_pSymbolAttr)
854 pObj->SetMergedItemSet(*m_pSymbolAttr);
856 else
858 pObj->SetMergedItemSet(m_rOutAttrs);
861 pPage->NbcInsertObject(pObj);
863 // Generate invisible square to give all symbol types a
864 // bitmap size, which is independent from specific glyph
865 SdrObject* pInvisibleSquare(m_pSymbolList->GetObj(0));
867 // directly clone to target SdrModel
868 pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
870 pPage->NbcInsertObject(pInvisibleSquare);
871 pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
872 pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
874 pView->MarkAll();
875 GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
877 m_aSymbolGraphic=Graphic(aMeta);
878 m_aSymbolSize=pObj->GetSnapRect().GetSize();
879 m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
880 m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
881 bPrevSym=true;
882 bEnable=true;
883 bIgnoreGraphic=true;
885 pView->UnmarkAll();
886 pInvisibleSquare=pPage->RemoveObject(1);
887 SdrObject::Free( pInvisibleSquare);
888 pObj=pPage->RemoveObject(0);
889 SdrObject::Free( pObj );
895 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH),true,&pPoolItem) == SfxItemState::SET)
897 const Graphic* pGraphic = static_cast<const SvxBrushItem *>(pPoolItem)->GetGraphic();
898 if( pGraphic )
900 if(!bIgnoreGraphic)
902 m_aSymbolGraphic=*pGraphic;
904 if(!bIgnoreSize)
906 m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
907 pGraphic->GetPrefMapMode(),
908 MapMode(MapUnit::Map100thMM));
910 bPrevSym=true;
914 if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),true,&pPoolItem) == SfxItemState::SET)
916 m_aSymbolSize = static_cast<const SvxSizeItem *>(pPoolItem)->GetSize();
919 m_xGridIconSize->set_sensitive(bEnable);
921 if(bPrevSym)
923 SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
924 SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
925 m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
926 m_aSymbolLastSize=m_aSymbolSize;
929 if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
931 eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
933 switch( eXLS )
935 case drawing::LineStyle_NONE:
936 m_xLbLineStyle->set_active(0);
937 break;
938 case drawing::LineStyle_SOLID:
939 m_xLbLineStyle->set_active(1);
940 break;
942 case drawing::LineStyle_DASH:
943 m_xLbLineStyle->set_active(-1);
944 m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
945 break;
947 default:
948 break;
951 else
953 m_xLbLineStyle->set_active(-1);
956 // Line strength
957 if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
959 SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
961 else
962 m_xMtrLineWidth->set_text("");
964 // Line color
965 m_xLbColor->SetNoSelection();
967 if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::DONTCARE )
969 Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
970 m_xLbColor->SelectEntry( aCol );
973 // Line start
974 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
976 m_xLbStartStyle->set_sensitive(false);
978 else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::DONTCARE )
980 // #86265# select entry using list and polygon, not string
981 bool bSelected(false);
982 const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
984 for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
986 const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
987 const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
989 if(rItemPolygon == rEntryPolygon)
991 // select this entry
992 m_xLbStartStyle->set_active(a + 1);
993 bSelected = true;
997 if(!bSelected)
998 m_xLbStartStyle->set_active(0);
1000 else
1002 m_xLbStartStyle->set_active(-1);
1005 // Line end
1006 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
1008 m_xLbEndStyle->set_sensitive(false);
1010 else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::DONTCARE )
1012 // #86265# select entry using list and polygon, not string
1013 bool bSelected(false);
1014 const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
1016 for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
1018 const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
1019 const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
1021 if(rItemPolygon == rEntryPolygon)
1023 // select this entry
1024 m_xLbEndStyle->set_active(a + 1);
1025 bSelected = true;
1029 if(!bSelected)
1030 m_xLbEndStyle->set_active(0);
1032 else
1034 m_xLbEndStyle->set_active(-1);
1037 // Line start strength
1038 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
1040 m_xMtrStartWidth->set_sensitive(false);
1042 else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::DONTCARE )
1044 SetMetricValue( *m_xMtrStartWidth,
1045 rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
1046 m_ePoolUnit );
1048 else
1049 m_xMtrStartWidth->set_text( "" );
1051 // Line end strength
1052 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
1054 m_xMtrEndWidth->set_sensitive(false);
1056 else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::DONTCARE )
1058 SetMetricValue( *m_xMtrEndWidth,
1059 rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
1060 m_ePoolUnit );
1062 else
1063 m_xMtrEndWidth->set_text("");
1065 // Centered line end (start)
1066 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
1068 m_xTsbCenterStart->set_sensitive(false);
1070 else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::DONTCARE )
1072 if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
1073 m_xTsbCenterStart->set_state(TRISTATE_TRUE);
1074 else
1075 m_xTsbCenterStart->set_state(TRISTATE_FALSE);
1077 else
1079 m_xTsbCenterStart->set_state(TRISTATE_INDET);
1082 // Centered line end (end)
1083 if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
1085 m_xTsbCenterEnd->set_sensitive(false);
1087 else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::DONTCARE )
1089 if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
1090 m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
1091 else
1092 m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
1094 else
1096 m_xTsbCenterEnd->set_state(TRISTATE_INDET);
1099 // Transparency
1100 if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::DONTCARE )
1102 sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
1103 m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
1104 ChangeTransparentHdl_Impl(*m_xMtrTransparent);
1106 else
1107 m_xMtrTransparent->set_text( "" );
1109 if( !m_xLbStartStyle->get_sensitive() &&
1110 !m_xLbEndStyle->get_sensitive() &&
1111 !m_xMtrStartWidth->get_sensitive() &&
1112 !m_xMtrEndWidth->get_sensitive() &&
1113 !m_xTsbCenterStart->get_sensitive()&&
1114 !m_xTsbCenterEnd->get_sensitive() )
1116 m_xCbxSynchronize->set_sensitive(false);
1117 m_xFlLineEnds->set_sensitive(false);
1120 // Synchronize
1121 // We get the value from the INI file now
1122 OUString aStr = GetUserData();
1123 m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
1125 if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
1127 // maFTEdgeStyle.set_sensitive(false);
1128 m_xLBEdgeStyle->set_sensitive(false);
1130 else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINEJOINT))
1132 const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
1134 switch(eLineJoint)
1136 case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
1137 case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
1138 case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
1139 case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
1140 case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
1141 case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
1144 else
1146 m_xLBEdgeStyle->set_active(-1);
1149 // fdo#43209
1150 if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
1152 m_xLBCapStyle->set_sensitive(false);
1154 else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINECAP))
1156 const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
1158 switch(eLineCap)
1160 case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
1161 case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
1162 default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
1165 else
1167 m_xLBCapStyle->set_active(-1);
1170 // Save values
1171 m_xLbLineStyle->save_value();
1172 m_xMtrLineWidth->save_value();
1173 m_xLbColor->SaveValue();
1174 m_xLbStartStyle->save_value();
1175 m_xLbEndStyle->save_value();
1176 m_xMtrStartWidth->save_value();
1177 m_xMtrEndWidth->save_value();
1178 m_xTsbCenterStart->save_state();
1179 m_xTsbCenterEnd->save_state();
1180 m_xMtrTransparent->save_value();
1182 m_xLBEdgeStyle->save_value();
1184 // LineCaps
1185 m_xLBCapStyle->save_value();
1187 ClickInvisibleHdl_Impl();
1189 ChangePreviewHdl_Impl( nullptr );
1192 VclPtr<SfxTabPage> SvxLineTabPage::Create(TabPageParent pParent,
1193 const SfxItemSet* rAttrs)
1195 return VclPtr<SvxLineTabPage>::Create(pParent, *rAttrs);
1198 IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
1200 ChangePreviewHdl_Impl(nullptr);
1203 IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
1205 ChangePreviewHdl_Impl(&rEdit);
1208 void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
1210 if (pCntrl == m_xMtrLineWidth.get())
1212 // Line width and start end width
1213 sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
1214 if(m_nActLineWidth == -1)
1216 // Don't initialize yet, get the start value
1217 const SfxPoolItem* pOld = GetOldItem( m_rXLSet, XATTR_LINEWIDTH );
1218 sal_Int32 nStartLineWidth = 0;
1219 if(pOld)
1220 nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
1221 m_nActLineWidth = nStartLineWidth;
1224 if(m_nActLineWidth != nNewLineWidth)
1226 // Adapt start/end width
1227 sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
1228 sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
1229 if(nValNew < 0)
1230 nValNew = 0;
1231 SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
1233 nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
1234 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
1235 if(nValNew < 0)
1236 nValNew = 0;
1237 SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
1240 // Remember current value
1241 m_nActLineWidth = nNewLineWidth;
1244 FillXLSet_Impl();
1245 m_aCtlPreview.Invalidate();
1247 // Make transparency accessible accordingly
1248 if( m_xLbLineStyle->get_active() == 0 ) // invisible
1250 m_xBoxTransparency->set_sensitive(false);
1252 else
1254 m_xBoxTransparency->set_sensitive(true);
1257 const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
1258 const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
1260 m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
1262 const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
1264 m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
1267 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Button&, void)
1269 if (m_xCbxSynchronize->get_active())
1270 m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
1271 ChangePreviewHdl_Impl(nullptr);
1274 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
1276 if (m_xCbxSynchronize->get_active())
1277 m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
1279 ChangePreviewHdl_Impl(nullptr);
1282 IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
1284 if (m_xCbxSynchronize->get_active())
1285 m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
1287 ChangePreviewHdl_Impl(nullptr);
1290 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
1292 ChangePreviewHdl_Impl( nullptr );
1295 // fdo#43209
1296 IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
1298 ChangePreviewHdl_Impl( nullptr );
1301 IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
1303 ClickInvisibleHdl_Impl();
1306 void SvxLineTabPage::ClickInvisibleHdl_Impl()
1308 if( m_xLbLineStyle->get_active() == 0 ) // invisible
1310 if(!m_bSymbols)
1311 m_xBoxColor->set_sensitive(false);
1313 m_xBoxWidth->set_sensitive(false);
1315 if( m_xFlLineEnds->get_sensitive() )
1317 m_xBoxStart->set_sensitive(false);
1318 m_xBoxArrowStyles->set_sensitive(false);
1319 m_xGridEdgeCaps->set_sensitive(false);
1322 else
1324 m_xBoxColor->set_sensitive(true);
1325 m_xBoxWidth->set_sensitive(true);
1327 if (m_xFlLineEnds->get_sensitive())
1329 m_xBoxArrowStyles->set_sensitive(true);
1330 m_xGridEdgeCaps->set_sensitive(true);
1333 ChangePreviewHdl_Impl( nullptr );
1336 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Button&, void)
1338 if (m_xCbxSynchronize->get_active())
1339 m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
1341 ChangePreviewHdl_Impl(nullptr);
1344 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
1346 if (m_xCbxSynchronize->get_active())
1347 m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
1349 ChangePreviewHdl_Impl(nullptr);
1352 IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
1354 if (m_xCbxSynchronize->get_active())
1355 m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
1357 ChangePreviewHdl_Impl(nullptr);
1360 IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
1362 sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
1364 m_rXLSet.Put(XLineTransparenceItem(nVal));
1366 FillXLSet_Impl();
1368 m_aCtlPreview.Invalidate();
1371 void SvxLineTabPage::FillUserData()
1373 // Write the synched value to the INI file
1374 OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
1375 SetUserData( aStrUserData );
1378 // #58425# Symbols on a list (e.g. StarChart)
1379 // Handler for the symbol selection's popup menu (NumMenueButton)
1380 // The following link originates from SvxNumOptionsTabPage
1381 IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
1383 ScopedVclPtrInstance< VirtualDevice > pVD;
1385 // Initialize popup
1386 if (!m_xGalleryMenu)
1388 m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
1389 weld::WaitObject aWait(GetDialogFrameWeld());
1390 // Get gallery entries
1391 GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
1393 sal_uInt32 i = 0;
1394 for (auto const& grfName : m_aGrfNames)
1396 const OUString *pUIName = &grfName;
1398 // Convert URL encodings to UI characters (e.g. %20 for spaces)
1399 OUString aPhysicalName;
1400 if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
1401 == osl::FileBase::E_None)
1403 pUIName = &aPhysicalName;
1406 SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
1407 pInfo->pBrushItem.reset(new SvxBrushItem(grfName, "", GPOS_AREA, SID_ATTR_BRUSH));
1408 pInfo->sItemId = "gallery" + OUString::number(i);
1409 m_aGalleryBrushItems.emplace_back(pInfo);
1410 const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
1412 if(pGraphic)
1414 BitmapEx aBitmap(pGraphic->GetBitmapEx());
1415 Size aSize(aBitmap.GetSizePixel());
1416 if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
1418 bool bWidth = aSize.Width() > aSize.Height();
1419 double nScale = bWidth ?
1420 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
1421 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
1422 aBitmap.Scale(nScale, nScale);
1425 pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
1426 pVD->DrawBitmapEx(Point(), aBitmap);
1427 m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
1429 else
1431 m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
1433 ++i;
1436 if (m_aGrfNames.empty())
1437 m_xSymbolMB->set_item_sensitive("gallery", false);
1440 if (!m_xSymbolsMenu && m_pSymbolList)
1442 m_xSymbolsMenu = m_xBuilder->weld_menu("symbolssubmenu");
1443 ScopedVclPtrInstance< VirtualDevice > pVDev;
1444 pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
1445 std::unique_ptr<SdrModel> pModel(
1446 new SdrModel(nullptr, nullptr, true));
1447 pModel->GetItemPool().FreezeIdRanges();
1448 // Page
1449 SdrPage* pPage = new SdrPage( *pModel, false );
1450 pPage->SetSize(Size(1000,1000));
1451 pModel->InsertPage( pPage, 0 );
1453 // 3D View
1454 std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
1455 pView->hideMarkHandles();
1456 pView->ShowSdrPage(pPage);
1458 // Generate invisible square to give all symbols a
1459 // bitmap size, which is independent from specific glyph
1460 SdrObject *pInvisibleSquare=m_pSymbolList->GetObj(0);
1462 // directly clone to target SdrModel
1463 pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
1465 pPage->NbcInsertObject(pInvisibleSquare);
1466 pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
1467 pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
1469 for(size_t i=0;; ++i)
1471 SdrObject *pObj=m_pSymbolList->GetObj(i);
1472 if(pObj==nullptr)
1473 break;
1475 // directly clone to target SdrModel
1476 pObj = pObj->CloneSdrObject(*pModel);
1478 m_aGrfNames.emplace_back("");
1479 pPage->NbcInsertObject(pObj);
1480 if(m_pSymbolAttr)
1482 pObj->SetMergedItemSet(*m_pSymbolAttr);
1484 else
1486 pObj->SetMergedItemSet(m_rOutAttrs);
1488 pView->MarkAll();
1489 BitmapEx aBitmapEx(pView->GetMarkedObjBitmapEx());
1490 GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
1491 pView->UnmarkAll();
1492 pObj=pPage->RemoveObject(1);
1493 SdrObject::Free(pObj);
1495 SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
1496 pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
1497 pInfo->sItemId = "symbol" + OUString::number(i);
1498 m_aSymbolBrushItems.emplace_back(pInfo);
1500 Size aSize(aBitmapEx.GetSizePixel());
1501 if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
1503 bool bWidth = aSize.Width() > aSize.Height();
1504 double nScale = bWidth ?
1505 double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
1506 double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
1507 aBitmapEx.Scale(nScale, nScale);
1509 pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
1510 pVD->DrawBitmapEx(Point(), aBitmapEx);
1511 m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
1513 pInvisibleSquare=pPage->RemoveObject(0);
1514 SdrObject::Free(pInvisibleSquare);
1516 if (m_aGrfNames.empty())
1517 m_xSymbolMB->set_item_sensitive("symbols", false);
1522 // #58425# Symbols on a list (e.g. StarChart)
1523 // Handler for menu button
1524 IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
1526 const Graphic* pGraphic = nullptr;
1527 Graphic aGraphic;
1528 bool bResetSize = false;
1529 bool bEnable = true;
1530 long nPreviousSymbolType = m_nSymbolType;
1532 OString sNumber;
1533 if (rIdent.startsWith("gallery", &sNumber))
1535 SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
1536 pGraphic = pInfo->pBrushItem->GetGraphic();
1537 m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
1539 else if (rIdent.startsWith("symbol", &sNumber))
1541 m_nSymbolType = sNumber.toUInt32();
1542 SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
1543 pGraphic = pInfo->pBrushItem->GetGraphic();
1545 else if (rIdent == "automatic")
1547 pGraphic=&m_aAutoSymbolGraphic;
1548 m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
1549 m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
1551 else if (rIdent == "none")
1553 m_nSymbolType=SVX_SYMBOLTYPE_NONE;
1554 pGraphic=nullptr;
1555 bEnable = false;
1557 else if (rIdent == "file")
1559 SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_SVXSTR_EDIT_GRAPHIC), GetDialogFrameWeld());
1560 aGrfDlg.EnableLink(false);
1561 aGrfDlg.AsLink(false);
1562 if( !aGrfDlg.Execute() )
1564 // Remember selected filters
1565 if( !aGrfDlg.GetGraphic(aGraphic) )
1567 m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
1568 pGraphic = &aGraphic;
1569 bResetSize = true;
1572 if( !pGraphic )
1573 return;
1576 if (pGraphic)
1578 Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
1579 aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
1580 m_aSymbolGraphic=*pGraphic;
1581 if( bResetSize )
1583 m_aSymbolSize=aSize;
1585 else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
1586 { //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
1587 if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
1589 aSize.setWidth( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
1590 aSize.setHeight( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
1591 m_aSymbolSize = aSize;
1594 m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
1596 else
1598 m_aSymbolGraphic=Graphic();
1599 m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
1600 bEnable = false;
1602 m_aSymbolLastSize=m_aSymbolSize;
1603 SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
1604 SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
1606 m_xGridIconSize->set_sensitive(bEnable);
1607 m_aCtlPreview.Invalidate();
1610 IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
1612 m_bNewSize = true;
1613 bool bWidth = &rField == m_xSymbolWidthMF.get();
1614 m_bLastWidthModified = bWidth;
1615 bool bRatio = m_xSymbolRatioCB->get_active();
1616 long nWidthVal = static_cast<long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
1617 long nHeightVal= static_cast<long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
1618 nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
1619 nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
1620 m_aSymbolSize = Size(nWidthVal,nHeightVal);
1621 double fSizeRatio = double(1);
1623 if(bRatio)
1625 if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
1626 fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
1629 if (bWidth)
1631 long nDelta = nWidthVal - m_aSymbolLastSize.Width();
1632 m_aSymbolSize.setWidth( nWidthVal );
1633 if (bRatio)
1635 m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<long>(static_cast<double>(nDelta) / fSizeRatio) );
1636 m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
1637 //TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
1638 m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
1641 else
1643 long nDelta = nHeightVal - m_aSymbolLastSize.Height();
1644 m_aSymbolSize.setHeight( nHeightVal );
1645 if (bRatio)
1647 m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<long>(static_cast<double>(nDelta) * fSizeRatio) );
1648 m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
1649 //TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
1650 m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
1653 m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
1654 m_aSymbolLastSize=m_aSymbolSize;
1657 IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::ToggleButton&, rBox, void)
1659 if (rBox.get_active())
1661 if (m_bLastWidthModified)
1662 SizeHdl_Impl(*m_xSymbolWidthMF);
1663 else
1664 SizeHdl_Impl(*m_xSymbolHeightMF);
1668 void SvxLineTabPage::DataChanged( const DataChangedEvent& rDCEvt )
1670 SfxTabPage::DataChanged( rDCEvt );
1672 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1674 FillListboxes();
1678 void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
1680 const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
1681 const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
1682 const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
1683 const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
1684 const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
1685 const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
1686 const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
1688 if (pDashListItem)
1689 SetDashList(pDashListItem->GetDashList());
1690 if (pLineEndListItem)
1691 SetLineEndList(pLineEndListItem->GetLineEndList());
1692 if (pPageTypeItem)
1693 SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
1694 if (pDlgTypeItem)
1695 SetDlgType(pDlgTypeItem->GetValue());
1696 Construct();
1698 if(pSdrObjListItem) //symbols
1700 ShowSymbolControls(true);
1701 m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
1702 if (pSymbolAttrItem)
1703 m_pSymbolAttr = new SfxItemSet(pSymbolAttrItem->GetItemSet());
1704 if(pGraphicItem)
1705 m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
1709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */