1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <tools/urlobj.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
23 #include <unotools/pathoptions.hxx>
24 #include <sfx2/filedlghelper.hxx>
25 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
26 
27 #include <strings.hrc>
28 
29 #include <svx/xlineit0.hxx>
30 #include <svx/xlnwtit.hxx>
31 #include <svx/xlndsit.hxx>
32 #include <svx/xlnclit.hxx>
33 #include <svx/xtable.hxx>
34 
35 #include <svx/dlgctrl.hxx>
36 #include <cuitabline.hxx>
37 #include <defdlgname.hxx>
38 #include <svx/svxdlg.hxx>
39 #include <dialmgr.hxx>
40 #include <svx/dlgutil.hxx>
41 #include <svx/dialmgr.hxx>
42 #include <svx/strings.hrc>
43 #include <svx/svxids.hrc>
44 #include <cuitabarea.hxx>
45 #include <svtools/unitconv.hxx>
46 #include <osl/diagnose.h>
47 
48 #define XOUT_WIDTH    150
49 
50 using namespace com::sun::star;
51 
52 
SvxLineDefTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rInAttrs)53 SvxLineDefTabPage::SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
54     : SfxTabPage(pPage, pController, "cui/ui/linestyletabpage.ui", "LineStylePage", &rInAttrs)
55     , rOutAttrs(rInAttrs)
56     , aXLineAttr(rInAttrs.GetPool())
57     , rXLSet(aXLineAttr.GetItemSet())
58     , pnDashListState(nullptr)
59     , pPageType(nullptr)
60     , nDlgType(0)
61     , pPosDashLb(nullptr)
62     , m_xLbLineStyles(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINESTYLES")))
63     , m_xLbType1(m_xBuilder->weld_combo_box("LB_TYPE_1"))
64     , m_xLbType2(m_xBuilder->weld_combo_box("LB_TYPE_2"))
65     , m_xNumFldNumber1(m_xBuilder->weld_spin_button("NUM_FLD_1"))
66     , m_xNumFldNumber2(m_xBuilder->weld_spin_button("NUM_FLD_2"))
67     , m_xMtrLength1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_1", FieldUnit::CM))
68     , m_xMtrLength2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_2", FieldUnit::CM))
69     , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
70     , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
71     , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
72     , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
73     , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
74     , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
75     , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
76     , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
77 {
78     // this page needs ExchangeSupport
79     SetExchangeSupport();
80 
81     // adjust metric
82     eFUnit = GetModuleFieldUnit( rInAttrs );
83 
84     switch ( eFUnit )
85     {
86         case FieldUnit::M:
87         case FieldUnit::KM:
88             eFUnit = FieldUnit::MM;
89             break;
90         default: ; //prevent warning
91     }
92     SetFieldUnit(*m_xMtrDistance, eFUnit);
93     SetFieldUnit(*m_xMtrLength1, eFUnit);
94     SetFieldUnit(*m_xMtrLength2, eFUnit);
95 
96     // determine PoolUnit
97     SfxItemPool* pPool = rOutAttrs.GetPool();
98     DBG_ASSERT( pPool, "Where is the pool?" );
99     ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
100 
101     rXLSet.Put( XLineStyleItem(drawing::LineStyle_DASH) );
102     rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
103     rXLSet.Put( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT, 3, 7, 2, 40, 15 ) ) );
104     rXLSet.Put( XLineColorItem(OUString(), COL_BLACK) );
105 
106     // #i34740#
107     m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
108 
109     m_xBtnAdd->connect_clicked(LINK(this, SvxLineDefTabPage, ClickAddHdl_Impl));
110     m_xBtnModify->connect_clicked(LINK(this, SvxLineDefTabPage, ClickModifyHdl_Impl));
111     m_xBtnDelete->connect_clicked(LINK(this, SvxLineDefTabPage, ClickDeleteHdl_Impl));
112     m_xBtnLoad->connect_clicked(LINK(this, SvxLineDefTabPage, ClickLoadHdl_Impl));
113     m_xBtnSave->connect_clicked(LINK(this, SvxLineDefTabPage, ClickSaveHdl_Impl));
114 
115     m_xNumFldNumber1->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber1Hdl_Impl));
116     m_xNumFldNumber2->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber2Hdl_Impl));
117     m_xLbLineStyles->connect_changed(LINK(this, SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl));
118 
119     // #i122042# switch off default adding of 'none' and 'solid' entries
120     // for this ListBox; we want to select only editable/dashed styles
121     m_xLbLineStyles->setAddStandardFields(false);
122 
123     // absolute (in mm) or relative (in %)
124     m_xCbxSynchronize->connect_toggled(LINK(this, SvxLineDefTabPage, ChangeMetricHdl_Impl));
125 
126     // preview must be updated when there's something changed
127     Link<weld::ComboBox&, void> aLink = LINK(this, SvxLineDefTabPage, SelectTypeListBoxHdl_Impl);
128     m_xLbType1->connect_changed(aLink);
129     m_xLbType2->connect_changed(aLink);
130     Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, SvxLineDefTabPage, ChangePreviewHdl_Impl );
131     m_xMtrLength1->connect_value_changed(aLink2);
132     m_xMtrLength2->connect_value_changed(aLink2);
133     m_xMtrDistance->connect_value_changed(aLink2);
134 
135     pDashList = nullptr;
136 }
137 
~SvxLineDefTabPage()138 SvxLineDefTabPage::~SvxLineDefTabPage()
139 {
140     m_xCtlPreview.reset();
141     m_xLbLineStyles.reset();
142 }
143 
Construct()144 void SvxLineDefTabPage::Construct()
145 {
146     // Line style fill; do *not* add default fields here
147     m_xLbLineStyles->Fill( pDashList );
148 }
149 
ActivatePage(const SfxItemSet &)150 void SvxLineDefTabPage::ActivatePage( const SfxItemSet& )
151 {
152     if( nDlgType != 0 ) // area dialog
153         return;
154 
155     // ActivatePage() is called before the dialog receives PageCreated() !!!
156     if( !pDashList.is() )
157         return;
158 
159     if (*pPageType == PageType::Gradient &&
160         *pPosDashLb != -1)
161     {
162         m_xLbLineStyles->set_active(*pPosDashLb);
163     }
164     // so that a possibly existing line style is discarded
165     SelectLinestyleHdl_Impl( nullptr );
166 
167     // determining (and possibly cutting) the name
168     // and displaying it in the GroupBox
169 //             OUString        aString( CuiResId( RID_SVXSTR_TABLE ) );
170 //             aString         += ": ";
171     INetURLObject   aURL( pDashList->GetPath() );
172 
173     aURL.Append( pDashList->GetName() );
174     DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
175 
176     *pPageType = PageType::Area; // 2
177     *pPosDashLb = -1;
178 }
179 
180 
DeactivatePage(SfxItemSet * _pSet)181 DeactivateRC SvxLineDefTabPage::DeactivatePage( SfxItemSet* _pSet )
182 {
183     CheckChanges_Impl();
184 
185     if( _pSet )
186         FillItemSet( _pSet );
187 
188     return DeactivateRC::LeavePage;
189 }
190 
CheckChanges_Impl()191 void SvxLineDefTabPage::CheckChanges_Impl()
192 {
193     // is here used to NOT lose changes
194     //css::drawing::DashStyle eXDS;
195 
196     if( m_xNumFldNumber1->get_value_changed_from_saved() ||
197         m_xMtrLength1->get_value_changed_from_saved() ||
198         m_xLbType1->get_value_changed_from_saved() ||
199         m_xNumFldNumber2->get_value_changed_from_saved() ||
200         m_xMtrLength2->get_value_changed_from_saved() ||
201         m_xLbType2->get_value_changed_from_saved() ||
202         m_xMtrDistance->get_value_changed_from_saved() )
203     {
204         std::unique_ptr<weld::MessageDialog> xMessDlg(Application::CreateMessageDialog(GetFrameWeld(),
205                                                       VclMessageType::Warning, VclButtonsType::Cancel,
206                                                       CuiResId(RID_SVXSTR_ASK_CHANGE_LINESTYLE)));
207         xMessDlg->set_title(SvxResId(RID_SVXSTR_LINESTYLE));
208         xMessDlg->add_button(CuiResId(RID_SVXSTR_CHANGE), RET_BTN_1);
209         xMessDlg->add_button(CuiResId(RID_SVXSTR_ADD), RET_BTN_2);
210 
211         short nRet = xMessDlg->run();
212 
213         switch( nRet )
214         {
215             case RET_BTN_1:
216             {
217                 ClickModifyHdl_Impl(*m_xBtnModify);
218             }
219             break;
220 
221             case RET_BTN_2:
222             {
223                 ClickAddHdl_Impl(*m_xBtnAdd);
224             }
225             break;
226 
227             case RET_CANCEL:
228             break;
229         }
230     }
231 
232     int nPos = m_xLbLineStyles->get_active();
233     if (nPos != -1)
234     {
235         *pPosDashLb = nPos;
236     }
237 }
238 
239 
FillItemSet(SfxItemSet * rAttrs)240 bool SvxLineDefTabPage::FillItemSet( SfxItemSet* rAttrs )
241 {
242     if( nDlgType == 0 ) // line dialog
243     {
244         if( *pPageType == PageType::Hatch )
245         {
246             FillDash_Impl();
247 
248             OUString aString(m_xLbLineStyles->get_active_text());
249             rAttrs->Put( XLineStyleItem( drawing::LineStyle_DASH ) );
250             rAttrs->Put( XLineDashItem( aString, aDash ) );
251         }
252     }
253     return true;
254 }
255 
256 
Reset(const SfxItemSet * rAttrs)257 void SvxLineDefTabPage::Reset( const SfxItemSet* rAttrs )
258 {
259     if( rAttrs->GetItemState( GetWhich( XATTR_LINESTYLE ) ) != SfxItemState::DONTCARE )
260     {
261         drawing::LineStyle eXLS = static_cast<const XLineStyleItem&>( rAttrs->Get( GetWhich( XATTR_LINESTYLE ) ) ).GetValue();
262 
263         switch( eXLS )
264         {
265             case drawing::LineStyle_NONE:
266             case drawing::LineStyle_SOLID:
267                 m_xLbLineStyles->set_active(0);
268                 break;
269             case drawing::LineStyle_DASH:
270             {
271                 const XLineDashItem& rDashItem = rAttrs->Get( XATTR_LINEDASH );
272                 aDash = rDashItem.GetDashValue();
273 
274                 m_xLbLineStyles->set_active(-1);
275                 m_xLbLineStyles->set_active_text(rDashItem.GetName());
276                 break;
277             }
278             default:
279                 break;
280         }
281     }
282     SelectLinestyleHdl_Impl( nullptr );
283 
284     // determine button state
285     if( pDashList->Count() )
286     {
287         m_xBtnModify->set_sensitive(true);
288         m_xBtnDelete->set_sensitive(true);
289         m_xBtnSave->set_sensitive(true);
290     }
291     else
292     {
293         m_xBtnModify->set_sensitive(false);
294         m_xBtnDelete->set_sensitive(false);
295         m_xBtnSave->set_sensitive(false);
296     }
297 }
298 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rOutAttrs)299 std::unique_ptr<SfxTabPage> SvxLineDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs )
300 {
301     return std::make_unique<SvxLineDefTabPage>(pPage, pController, *rOutAttrs);
302 }
303 
IMPL_LINK(SvxLineDefTabPage,SelectLinestyleListBoxHdl_Impl,weld::ComboBox &,rListBox,void)304 IMPL_LINK(SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
305 {
306     SelectLinestyleHdl_Impl(&rListBox);
307 }
308 
SelectLinestyleHdl_Impl(const weld::ComboBox * p)309 void SvxLineDefTabPage::SelectLinestyleHdl_Impl(const weld::ComboBox* p)
310 {
311     if(!pDashList->Count())
312         return;
313 
314     int nTmp = m_xLbLineStyles->get_active();
315     if (nTmp == -1)
316     {
317         OSL_ENSURE(false, "OOps, non-existent LineDash selected (!)");
318         nTmp = 1;
319     }
320 
321     aDash = pDashList->GetDash( nTmp )->GetDash();
322 
323     FillDialog_Impl();
324 
325     rXLSet.Put( XLineDashItem( OUString(), aDash ) );
326 
327     // #i34740#
328     m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
329     m_aCtlPreview.Invalidate();
330 
331     // Is not set before, in order to take the new style
332     // only if there was an entry selected in the ListBox.
333     // If it was called via Reset(), then p is == NULL
334     if( p )
335         *pPageType = PageType::Hatch;
336 }
337 
IMPL_LINK_NOARG(SvxLineDefTabPage,ChangePreviewHdl_Impl,weld::MetricSpinButton &,void)338 IMPL_LINK_NOARG(SvxLineDefTabPage, ChangePreviewHdl_Impl, weld::MetricSpinButton&, void)
339 {
340     FillDash_Impl();
341     m_aCtlPreview.Invalidate();
342 }
343 
IMPL_LINK_NOARG(SvxLineDefTabPage,ChangeNumber1Hdl_Impl,weld::SpinButton &,void)344 IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber1Hdl_Impl, weld::SpinButton&, void)
345 {
346     if (m_xNumFldNumber1->get_value() == 0)
347     {
348         m_xNumFldNumber2->set_min(1);
349     }
350     else
351     {
352         m_xNumFldNumber2->set_min(0);
353     }
354 
355     ChangePreviewHdl_Impl(*m_xMtrLength1);
356 }
357 
IMPL_LINK_NOARG(SvxLineDefTabPage,ChangeNumber2Hdl_Impl,weld::SpinButton &,void)358 IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber2Hdl_Impl, weld::SpinButton&, void)
359 {
360     if (m_xNumFldNumber2->get_value() == 0)
361     {
362         m_xNumFldNumber1->set_min(1);
363     }
364     else
365     {
366         m_xNumFldNumber1->set_min(0);
367     }
368 
369     ChangePreviewHdl_Impl(*m_xMtrLength1);
370 }
371 
IMPL_LINK(SvxLineDefTabPage,ChangeMetricHdl_Impl,weld::Toggleable &,r,void)372 IMPL_LINK( SvxLineDefTabPage, ChangeMetricHdl_Impl, weld::Toggleable&, r, void)
373 {
374     ChangeMetricHdl_Impl(&r);
375 }
376 
ChangeMetricHdl_Impl(const weld::Toggleable * p)377 void SvxLineDefTabPage::ChangeMetricHdl_Impl(const weld::Toggleable* p)
378 {
379     if( !m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != eFUnit )
380     {
381         tools::Long nTmp1, nTmp2, nTmp3;
382 
383         // was changed with Control
384         if( p )
385         {
386             nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * XOUT_WIDTH / 100;
387             nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * XOUT_WIDTH / 100;
388             nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * XOUT_WIDTH / 100;
389         }
390         else
391         {
392             nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
393             nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
394             nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
395         }
396         m_xMtrLength1->set_digits(2);
397         m_xMtrLength2->set_digits(2);
398         m_xMtrDistance->set_digits(2);
399 
400         // adjust metric
401         m_xMtrLength1->set_unit(eFUnit);
402         m_xMtrLength2->set_unit(eFUnit);
403         m_xMtrDistance->set_unit(eFUnit);
404 
405         // tdf#126736 max 5cm
406         m_xMtrLength1->set_range(0, 500, FieldUnit::CM);
407         m_xMtrLength2->set_range(0, 500, FieldUnit::CM);
408         m_xMtrDistance->set_range(0, 500, FieldUnit::CM);
409 
410         SetMetricValue( *m_xMtrLength1, nTmp1, ePoolUnit );
411         SetMetricValue( *m_xMtrLength2, nTmp2, ePoolUnit );
412         SetMetricValue( *m_xMtrDistance, nTmp3, ePoolUnit );
413     }
414     else if( m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != FieldUnit::PERCENT )
415     {
416         tools::Long nTmp1, nTmp2, nTmp3;
417 
418         // was changed with Control
419         if( p )
420         {
421             nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * 100 / XOUT_WIDTH;
422             nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * 100 / XOUT_WIDTH;
423             nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * 100 / XOUT_WIDTH;
424         }
425         else
426         {
427             nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
428             nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
429             nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
430         }
431 
432         m_xMtrLength1->set_digits(0);
433         m_xMtrLength2->set_digits(0);
434         m_xMtrDistance->set_digits(0);
435 
436         m_xMtrLength1->set_unit(FieldUnit::PERCENT);
437         m_xMtrLength2->set_unit(FieldUnit::PERCENT);
438         m_xMtrDistance->set_unit(FieldUnit::PERCENT);
439 
440         // tdf#126736 800%
441         m_xMtrLength1->set_range(0, 800, FieldUnit::PERCENT);
442         m_xMtrLength2->set_range(0, 800, FieldUnit::PERCENT);
443         m_xMtrDistance->set_range(0, 800, FieldUnit::PERCENT);
444 
445         m_xMtrLength1->set_value(nTmp1, FieldUnit::PERCENT);
446         m_xMtrLength2->set_value(nTmp2, FieldUnit::PERCENT);
447         m_xMtrDistance->set_value(nTmp3, FieldUnit::PERCENT);
448     }
449     SelectTypeHdl_Impl( nullptr );
450 }
451 
IMPL_LINK(SvxLineDefTabPage,SelectTypeListBoxHdl_Impl,weld::ComboBox &,rListBox,void)452 IMPL_LINK( SvxLineDefTabPage, SelectTypeListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
453 {
454     SelectTypeHdl_Impl(&rListBox);
455 }
456 
SelectTypeHdl_Impl(const weld::ComboBox * p)457 void  SvxLineDefTabPage::SelectTypeHdl_Impl(const weld::ComboBox* p)
458 {
459     if (p == m_xLbType1.get() || !p)
460     {
461         if (m_xLbType1->get_active() == 0)
462         {
463             m_xMtrLength1->set_sensitive(false);
464             m_xMtrLength1->set_text("");
465         }
466         else if (!m_xMtrLength1->get_sensitive())
467         {
468             m_xMtrLength1->set_sensitive(true);
469             m_xMtrLength1->reformat();
470         }
471     }
472 
473     if (p == m_xLbType2.get() || !p)
474     {
475         if (m_xLbType2->get_active() == 0)
476         {
477             m_xMtrLength2->set_sensitive(false);
478             m_xMtrLength2->set_text("");
479         }
480         else if (!m_xMtrLength2->get_sensitive())
481         {
482             m_xMtrLength2->set_sensitive(true);
483             m_xMtrLength2->reformat();
484         }
485     }
486     ChangePreviewHdl_Impl(*m_xMtrLength1);
487 }
488 
IMPL_LINK_NOARG(SvxLineDefTabPage,ClickAddHdl_Impl,weld::Button &,void)489 IMPL_LINK_NOARG(SvxLineDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
490 {
491     OUString aNewName(SvxResId(RID_SVXSTR_LINESTYLE));
492     OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINESTYLE));
493     OUString aName;
494 
495     tools::Long nCount = pDashList->Count();
496     tools::Long j = 1;
497     bool bDifferent = false;
498 
499     while ( !bDifferent )
500     {
501         aName = aNewName + " " + OUString::number( j++ );
502         bDifferent = true;
503 
504         for ( tools::Long i = 0; i < nCount && bDifferent; i++ )
505             if ( aName == pDashList->GetDash( i )->GetName() )
506                 bDifferent = false;
507     }
508 
509     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
510     ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
511     bool bLoop = true;
512 
513     while ( bLoop && pDlg->Execute() == RET_OK )
514     {
515         pDlg->GetName( aName );
516         bDifferent = true;
517 
518         for( tools::Long i = 0; i < nCount && bDifferent; i++ )
519         {
520             if( aName == pDashList->GetDash( i )->GetName() )
521                 bDifferent = false;
522         }
523 
524         if( bDifferent )
525         {
526             bLoop = false;
527             FillDash_Impl();
528 
529             tools::Long nDashCount = pDashList->Count();
530             pDashList->Insert( std::make_unique<XDashEntry>(aDash, aName), nDashCount );
531             m_xLbLineStyles->Append( *pDashList->GetDash(nDashCount), pDashList->GetUiBitmap(nDashCount) );
532 
533             m_xLbLineStyles->set_active(m_xLbLineStyles->get_count() - 1);
534 
535             *pnDashListState |= ChangeType::MODIFIED;
536 
537             *pPageType = PageType::Hatch;
538 
539             // save values for changes recognition (-> method)
540             m_xNumFldNumber1->save_value();
541             m_xMtrLength1->save_value();
542             m_xLbType1->save_value();
543             m_xNumFldNumber2->save_value();
544             m_xMtrLength2->save_value();
545             m_xLbType2->save_value();
546             m_xMtrDistance->save_value();
547         }
548         else
549         {
550             std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
551             std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
552             xBox->run();
553         }
554     }
555     pDlg.disposeAndClear();
556 
557     // determine button state
558     if ( pDashList->Count() )
559     {
560         m_xBtnModify->set_sensitive(true);
561         m_xBtnDelete->set_sensitive(true);
562         m_xBtnSave->set_sensitive(true);
563     }
564 }
565 
IMPL_LINK_NOARG(SvxLineDefTabPage,ClickModifyHdl_Impl,weld::Button &,void)566 IMPL_LINK_NOARG(SvxLineDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
567 {
568     int nPos = m_xLbLineStyles->get_active();
569     if (nPos == -1)
570         return;
571 
572     OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINESTYLE));
573     OUString aName( pDashList->GetDash( nPos )->GetName() );
574     OUString aOldName = aName;
575 
576     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
577     ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
578 
579     tools::Long nCount = pDashList->Count();
580     bool bLoop = true;
581 
582     while ( bLoop && pDlg->Execute() == RET_OK )
583     {
584         pDlg->GetName( aName );
585         bool bDifferent = true;
586 
587         for( tools::Long i = 0; i < nCount && bDifferent; i++ )
588         {
589             if( aName == pDashList->GetDash( i )->GetName() &&
590                 aName != aOldName )
591                 bDifferent = false;
592         }
593 
594         if ( bDifferent )
595         {
596             bLoop = false;
597             FillDash_Impl();
598 
599             pDashList->Replace(std::make_unique<XDashEntry>(aDash, aName), nPos);
600             m_xLbLineStyles->Modify(*pDashList->GetDash(nPos), nPos, pDashList->GetUiBitmap(nPos));
601 
602             m_xLbLineStyles->set_active(nPos);
603 
604             *pnDashListState |= ChangeType::MODIFIED;
605 
606             *pPageType = PageType::Hatch;
607 
608             // save values for changes recognition (-> method)
609             m_xNumFldNumber1->save_value();
610             m_xMtrLength1->save_value();
611             m_xLbType1->save_value();
612             m_xNumFldNumber2->save_value();
613             m_xMtrLength2->save_value();
614             m_xLbType2->save_value();
615             m_xMtrDistance->save_value();
616         }
617         else
618         {
619             std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
620             std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
621             xBox->run();
622         }
623     }
624 }
625 
IMPL_LINK_NOARG(SvxLineDefTabPage,ClickDeleteHdl_Impl,weld::Button &,void)626 IMPL_LINK_NOARG(SvxLineDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
627 {
628     int nPos = m_xLbLineStyles->get_active();
629     if (nPos != -1)
630     {
631         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelinestyledialog.ui"));
632         std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineStyleDialog"));
633         if (xQueryBox->run() == RET_YES)
634         {
635             pDashList->Remove(nPos);
636             m_xLbLineStyles->remove(nPos);
637             m_xLbLineStyles->set_active(0);
638 
639             SelectLinestyleHdl_Impl( nullptr );
640             *pPageType = PageType::Area; // style should not be taken
641 
642             *pnDashListState |= ChangeType::MODIFIED;
643 
644             ChangePreviewHdl_Impl( *m_xMtrLength1 );
645         }
646     }
647 
648     // determine button state
649     if ( !pDashList->Count() )
650     {
651         m_xBtnModify->set_sensitive(false);
652         m_xBtnDelete->set_sensitive(false);
653         m_xBtnSave->set_sensitive(false);
654     }
655 }
656 
IMPL_LINK_NOARG(SvxLineDefTabPage,ClickLoadHdl_Impl,weld::Button &,void)657 IMPL_LINK_NOARG(SvxLineDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
658 {
659     sal_uInt16 nReturn = RET_YES;
660 
661     if ( *pnDashListState & ChangeType::MODIFIED )
662     {
663         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
664         std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
665 
666         nReturn = xBox->run();
667 
668         if ( nReturn == RET_YES )
669             pDashList->Save();
670     }
671 
672     if ( nReturn != RET_CANCEL )
673     {
674         ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
675                                       FileDialogFlags::NONE, GetFrameWeld());
676         OUString aStrFilterType( "*.sod" );
677         aDlg.AddFilter( aStrFilterType, aStrFilterType );
678         OUString aPalettePath(SvtPathOptions().GetPalettePath());
679         OUString aLastDir;
680         sal_Int32 nIndex = 0;
681         do
682         {
683             aLastDir = aPalettePath.getToken(0, ';', nIndex);
684         }
685         while (nIndex >= 0);
686 
687         INetURLObject aFile(aLastDir);
688         aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
689 
690         if( aDlg.Execute() == ERRCODE_NONE )
691         {
692             INetURLObject aURL( aDlg.GetPath() );
693             INetURLObject aPathURL( aURL );
694 
695             aPathURL.removeSegment();
696             aPathURL.removeFinalSlash();
697 
698             XDashListRef pDshLst = XPropertyList::AsDashList(XPropertyList::CreatePropertyList( XPropertyListType::Dash, aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" ));
699             pDshLst->SetName( aURL.getName() );
700 
701             if( pDshLst->Load() )
702             {
703                 pDashList = pDshLst;
704                 static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewDashList( pDashList );
705 
706                 m_xLbLineStyles->clear();
707                 m_xLbLineStyles->Fill( pDashList );
708                 Reset( &rOutAttrs );
709 
710                 pDashList->SetName( aURL.getName() );
711 
712                 *pnDashListState |= ChangeType::CHANGED;
713                 *pnDashListState &= ~ChangeType::MODIFIED;
714             }
715             else
716             {
717                 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
718                 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
719                 xBox->run();
720             }
721         }
722     }
723 
724     // determine button state
725     if ( pDashList->Count() )
726     {
727         m_xBtnModify->set_sensitive(true);
728         m_xBtnDelete->set_sensitive(true);
729         m_xBtnSave->set_sensitive(true);
730     }
731     else
732     {
733         m_xBtnModify->set_sensitive(false);
734         m_xBtnDelete->set_sensitive(false);
735         m_xBtnSave->set_sensitive(false);
736     }
737 }
738 
IMPL_LINK_NOARG(SvxLineDefTabPage,ClickSaveHdl_Impl,weld::Button &,void)739 IMPL_LINK_NOARG(SvxLineDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
740 {
741     ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
742     OUString aStrFilterType( "*.sod" );
743     aDlg.AddFilter( aStrFilterType, aStrFilterType );
744 
745     OUString aPalettePath(SvtPathOptions().GetPalettePath());
746     OUString aLastDir;
747     sal_Int32 nIndex = 0;
748     do
749     {
750         aLastDir = aPalettePath.getToken(0, ';', nIndex);
751     }
752     while (nIndex >= 0);
753 
754     INetURLObject aFile(aLastDir);
755     DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
756 
757     if( !pDashList->GetName().isEmpty() )
758     {
759         aFile.Append( pDashList->GetName() );
760 
761         if( aFile.getExtension().isEmpty() )
762             aFile.SetExtension( u"sod" );
763     }
764 
765     aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
766     if ( aDlg.Execute() != ERRCODE_NONE )
767         return;
768 
769     INetURLObject aURL( aDlg.GetPath() );
770     INetURLObject aPathURL( aURL );
771 
772     aPathURL.removeSegment();
773     aPathURL.removeFinalSlash();
774 
775     pDashList->SetName( aURL.getName() );
776     pDashList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
777 
778     if( pDashList->Save() )
779     {
780         *pnDashListState &= ~ChangeType::MODIFIED;
781     }
782     else
783     {
784         std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
785         std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
786         xBox->run();
787     }
788 }
789 
FillDash_Impl()790 void SvxLineDefTabPage::FillDash_Impl()
791 {
792     css::drawing::DashStyle eXDS;
793 
794     if (m_xCbxSynchronize->get_active())
795         eXDS = css::drawing::DashStyle_RECTRELATIVE;
796     else
797         eXDS = css::drawing::DashStyle_RECT;
798 
799     aDash.SetDashStyle( eXDS );
800     aDash.SetDots( static_cast<sal_uInt8>(m_xNumFldNumber1->get_value()) );
801     aDash.SetDotLen( m_xLbType1->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength1, ePoolUnit ) );
802     aDash.SetDashes( static_cast<sal_uInt8>(m_xNumFldNumber2->get_value()) );
803     aDash.SetDashLen( m_xLbType2->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength2, ePoolUnit ) );
804     aDash.SetDistance( GetCoreValue( *m_xMtrDistance, ePoolUnit ) );
805 
806     rXLSet.Put( XLineDashItem( OUString(), aDash ) );
807 
808     // #i34740#
809     m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
810 }
811 
FillDialog_Impl()812 void SvxLineDefTabPage::FillDialog_Impl()
813 {
814     css::drawing::DashStyle eXDS = aDash.GetDashStyle(); // css::drawing::DashStyle_RECT, css::drawing::DashStyle_ROUND
815     if( eXDS == css::drawing::DashStyle_RECTRELATIVE )
816         m_xCbxSynchronize->set_active(true);
817     else
818         m_xCbxSynchronize->set_active(false);
819 
820     m_xNumFldNumber1->set_value(aDash.GetDots());
821     SetMetricValue( *m_xMtrLength1, aDash.GetDotLen(), ePoolUnit );
822     m_xLbType1->set_active(aDash.GetDotLen() == 0 ? 0 : 1);
823     m_xNumFldNumber2->set_value(aDash.GetDashes());
824     SetMetricValue( *m_xMtrLength2, aDash.GetDashLen(), ePoolUnit );
825     m_xLbType2->set_active(aDash.GetDashLen() == 0 ? 0 : 1);
826     SetMetricValue( *m_xMtrDistance, aDash.GetDistance(), ePoolUnit );
827 
828     ChangeMetricHdl_Impl(nullptr);
829 
830     // save values for changes recognition (-> method)
831     m_xNumFldNumber1->save_value();
832     m_xMtrLength1->save_value();
833     m_xLbType1->save_value();
834     m_xNumFldNumber2->save_value();
835     m_xMtrLength2->save_value();
836     m_xLbType2->save_value();
837     m_xMtrDistance->save_value();
838 }
839 
840 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
841