cid#1606642 Data race condition
[LibreOffice.git] / cui / source / tabpages / tpgradnt.cxx
blob6e24a438fbf15f8ca857997853e9e9cde0ee8a85
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 <tools/urlobj.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/weld.hxx>
24 #include <sfx2/dialoghelper.hxx>
25 #include <sfx2/objsh.hxx>
27 #include <strings.hrc>
28 #include <svx/drawitem.hxx>
29 #include <svx/xfillit0.hxx>
30 #include <svx/xflgrit.hxx>
31 #include <svx/colorbox.hxx>
32 #include <svx/xtable.hxx>
33 #include <svx/xgrscit.hxx>
34 #include <cuitabarea.hxx>
35 #include <svx/svxdlg.hxx>
36 #include <dialmgr.hxx>
37 #include <svx/dialmgr.hxx>
38 #include <svx/strings.hrc>
39 #include <svx/svxids.hrc>
40 #include <basegfx/utils/gradienttools.hxx>
41 #include <sal/log.hxx>
43 using namespace com::sun::star;
45 SvxGradientTabPage::SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
46 : SfxTabPage(pPage, pController, u"cui/ui/gradientpage.ui"_ustr, u"GradientPage"_ustr, &rInAttrs)
47 , m_rOutAttrs(rInAttrs)
48 , m_nGradientListState(ChangeType::NONE)
49 , m_pnColorListState(nullptr)
50 , m_aXFillAttr(rInAttrs.GetPool())
51 , m_rXFSet(m_aXFillAttr.GetItemSet())
52 , m_xLbGradientType(m_xBuilder->weld_combo_box(u"gradienttypelb"_ustr))
53 , m_xFtCenter(m_xBuilder->weld_label(u"centerft"_ustr))
54 , m_xMtrCenterX(m_xBuilder->weld_metric_spin_button(u"centerxmtr"_ustr, FieldUnit::PERCENT))
55 , m_xMtrCenterY(m_xBuilder->weld_metric_spin_button(u"centerymtr"_ustr, FieldUnit::PERCENT))
56 , m_xFtAngle(m_xBuilder->weld_label(u"angleft"_ustr))
57 , m_xMtrAngle(m_xBuilder->weld_metric_spin_button(u"anglemtr"_ustr, FieldUnit::DEGREE))
58 , m_xSliderAngle(m_xBuilder->weld_scale(u"angleslider"_ustr))
59 , m_xMtrBorder(m_xBuilder->weld_metric_spin_button(u"bordermtr"_ustr, FieldUnit::PERCENT))
60 , m_xSliderBorder(m_xBuilder->weld_scale(u"borderslider"_ustr))
61 , m_xLbColorFrom(new ColorListBox(m_xBuilder->weld_menu_button(u"colorfromlb"_ustr),
62 [this]{ return GetDialogController()->getDialog(); }))
63 , m_xMtrColorFrom(m_xBuilder->weld_metric_spin_button(u"colorfrommtr"_ustr, FieldUnit::PERCENT))
64 , m_xLbColorTo(new ColorListBox(m_xBuilder->weld_menu_button(u"colortolb"_ustr),
65 [this]{ return GetDialogController()->getDialog(); }))
66 , m_xMtrColorTo(m_xBuilder->weld_metric_spin_button(u"colortomtr"_ustr, FieldUnit::PERCENT))
67 , m_xGradientLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window(u"gradientpresetlistwin"_ustr, true)))
68 , m_xMtrIncrement(m_xBuilder->weld_spin_button(u"incrementmtr"_ustr))
69 , m_xCbIncrement(m_xBuilder->weld_check_button(u"autoincrement"_ustr))
70 , m_xBtnAdd(m_xBuilder->weld_button(u"add"_ustr))
71 , m_xBtnModify(m_xBuilder->weld_button(u"modify"_ustr))
72 , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, u"previewctl"_ustr, m_aCtlPreview))
73 , m_xGradientLBWin(new weld::CustomWeld(*m_xBuilder, u"gradientpresetlist"_ustr, *m_xGradientLB))
75 Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
76 m_xGradientLB->set_size_request(aSize.Width(), aSize.Height());
77 m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
78 // this page needs ExchangeSupport
79 SetExchangeSupport();
81 // as long as NOT supported by the item
83 m_xMtrColorTo->set_value(100, FieldUnit::PERCENT);
84 m_xMtrColorFrom->set_value(100, FieldUnit::PERCENT);
86 // setting the output device
87 m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
88 m_rXFSet.Put( XFillGradientItem(OUString(), basegfx::BGradient()));
89 m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
91 // set handler
92 m_xGradientLB->SetSelectHdl( LINK( this, SvxGradientTabPage, ChangeGradientHdl ) );
93 m_xGradientLB->SetRenameHdl( LINK( this, SvxGradientTabPage, ClickRenameHdl_Impl ) );
94 m_xGradientLB->SetDeleteHdl( LINK( this, SvxGradientTabPage, ClickDeleteHdl_Impl ) );
95 m_xBtnAdd->connect_clicked(LINK(this, SvxGradientTabPage, ClickAddHdl_Impl));
96 m_xBtnModify->connect_clicked(LINK(this, SvxGradientTabPage, ClickModifyHdl_Impl));
98 Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxGradientTabPage, ModifiedMetricHdl_Impl );
99 Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxGradientTabPage, ModifiedListBoxHdl_Impl );
100 m_xLbGradientType->connect_changed( aLink2 );
101 m_xCbIncrement->connect_toggled(LINK(this, SvxGradientTabPage, ChangeAutoStepHdl_Impl));
102 m_xMtrIncrement->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedEditHdl_Impl));
103 m_xMtrCenterX->connect_value_changed( aLink );
104 m_xMtrCenterY->connect_value_changed( aLink );
105 m_xMtrAngle->connect_value_changed( aLink );
106 m_xSliderAngle->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
107 m_xMtrBorder->connect_value_changed( aLink );
108 m_xSliderBorder->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
109 m_xMtrColorFrom->connect_value_changed( aLink );
110 Link<ColorListBox&,void> aLink3 = LINK( this, SvxGradientTabPage, ModifiedColorListBoxHdl_Impl );
111 m_xLbColorFrom->SetSelectHdl( aLink3 );
112 m_xMtrColorTo->connect_value_changed( aLink );
113 m_xLbColorTo->SetSelectHdl( aLink3 );
115 m_xGradientLB->SetStyle(WB_FLATVALUESET | WB_NO_DIRECTSELECT | WB_TABSTOP);
117 // #i76307# always paint the preview in LTR, because this is what the document does
118 m_aCtlPreview.EnableRTL(false);
121 SvxGradientTabPage::~SvxGradientTabPage()
123 m_xCtlPreview.reset();
124 m_xGradientLBWin.reset();
125 m_xGradientLB.reset();
126 m_xLbColorTo.reset();
127 m_xLbColorFrom.reset();
129 if (m_nGradientListState & ChangeType::MODIFIED)
131 m_pGradientList->SetPath(AreaTabHelper::GetPalettePath());
132 m_pGradientList->Save();
134 // ToolBoxControls are informed:
135 SfxObjectShell* pShell = SfxObjectShell::Current();
136 if (pShell)
137 pShell->PutItem(SvxGradientListItem(m_pGradientList, SID_GRADIENT_LIST));
141 void SvxGradientTabPage::Construct()
143 m_xGradientLB->FillPresetListBox( *m_pGradientList );
146 void SvxGradientTabPage::ActivatePage( const SfxItemSet& rSet )
148 if( !m_pColorList.is() )
149 return;
151 // ColorList
152 if( *m_pnColorListState & ChangeType::CHANGED ||
153 *m_pnColorListState & ChangeType::MODIFIED )
155 SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
156 dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
157 if (pArea)
158 m_pColorList = pArea->GetNewColorList();
160 ModifiedHdl_Impl( this );
163 // determining (and possibly cutting) the name and
164 // displaying it in the GroupBox
165 OUString aString = CuiResId( RID_CUISTR_TABLE ) + ": ";
166 INetURLObject aURL( m_pGradientList->GetPath() );
168 aURL.Append( m_pGradientList->GetName() );
169 SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
171 if ( aURL.getBase().getLength() > 18 )
173 aString += OUString::Concat(aURL.getBase().subView( 0, 15 )) + "...";
175 else
176 aString += aURL.getBase();
178 sal_Int32 nPos = SearchGradientList( rSet.Get(XATTR_FILLGRADIENT).GetName() );
179 if ( nPos != -1)
181 sal_uInt16 nId = m_xGradientLB->GetItemId( static_cast<size_t>( nPos ) );
182 m_xGradientLB->SelectItem( nId );
184 // colors could have been deleted
185 ChangeGradientHdl_Impl();
189 DeactivateRC SvxGradientTabPage::DeactivatePage( SfxItemSet* _pSet )
191 if( _pSet )
192 FillItemSet( _pSet );
194 return DeactivateRC::LeavePage;
197 bool SvxGradientTabPage::FillItemSet( SfxItemSet* rSet )
199 std::unique_ptr<basegfx::BGradient> pBGradient;
200 size_t nPos = m_xGradientLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xGradientLB->GetSelectItemPos();
202 sal_uInt16 nValue = 0; // automatic step count
203 if (!m_xCbIncrement->get_active())
204 nValue = m_xMtrIncrement->get_value();
206 if( nPos != VALUESET_ITEM_NOTFOUND )
208 pBGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetGradient() ));
209 OUString aString = m_xGradientLB->GetItemText( m_xGradientLB->GetSelectedItemId() );
210 // update StepCount to current value to be in sync with FillGradientStepCount
211 pBGradient->SetSteps(nValue);
212 rSet->Put( XFillGradientItem( aString, *pBGradient ) );
214 else
215 // gradient was passed (unidentified)
217 pBGradient.reset(new basegfx::BGradient(
218 createColorStops(),
219 static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
220 Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
221 static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
222 static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
223 static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
224 static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
225 static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
226 nValue));
227 rSet->Put( XFillGradientItem( OUString(), *pBGradient ) );
230 assert( pBGradient && "basegfx::BGradient could not be created" );
231 rSet->Put( XFillStyleItem( drawing::FillStyle_GRADIENT ) );
232 rSet->Put( XGradientStepCountItem( nValue ) );
233 return true;
236 void SvxGradientTabPage::Reset( const SfxItemSet* )
238 ChangeGradientHdl_Impl(); // includes setting m_xCbIncrement and m_xMtrIncrement
240 // determine state of the buttons
241 if( m_pGradientList->Count() )
242 m_xBtnModify->set_sensitive(true);
243 else
244 m_xBtnModify->set_sensitive(false);
247 std::unique_ptr<SfxTabPage> SvxGradientTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
248 const SfxItemSet* rOutAttrs )
250 return std::make_unique<SvxGradientTabPage>(pPage, pController, *rOutAttrs);
253 IMPL_LINK( SvxGradientTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
255 ModifiedHdl_Impl(&rListBox);
256 // gradient params changed, it is no longer one of the presets
257 m_xGradientLB->SetNoSelection();
260 IMPL_LINK( SvxGradientTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
262 ModifiedHdl_Impl(&rListBox);
263 m_xGradientLB->SetNoSelection();
266 IMPL_LINK( SvxGradientTabPage, ModifiedEditHdl_Impl, weld::SpinButton&, rBox, void )
268 ModifiedHdl_Impl(&rBox);
269 m_xGradientLB->SetNoSelection();
272 IMPL_LINK( SvxGradientTabPage, ModifiedMetricHdl_Impl, weld::MetricSpinButton&, rBox, void )
274 ModifiedHdl_Impl(&rBox);
275 m_xGradientLB->SetNoSelection();
278 IMPL_LINK( SvxGradientTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
280 ModifiedHdl_Impl(&rSlider);
281 m_xGradientLB->SetNoSelection();
284 IMPL_LINK_NOARG( SvxGradientTabPage, ChangeAutoStepHdl_Impl, weld::Toggleable&, void )
286 if (m_xCbIncrement->get_active())
288 m_xMtrIncrement->set_sensitive(false);
290 else
292 m_xMtrIncrement->set_sensitive(true);
294 ModifiedHdl_Impl(m_xMtrIncrement.get());
297 void SvxGradientTabPage::ModifiedHdl_Impl( void const * pControl )
299 if (pControl == m_xMtrBorder.get())
300 m_xSliderBorder->set_value(m_xMtrBorder->get_value(FieldUnit::NONE));
301 if (pControl == m_xSliderBorder.get())
302 m_xMtrBorder->set_value(m_xSliderBorder->get_value(), FieldUnit::NONE);
303 if (pControl == m_xMtrAngle.get())
304 m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
305 if (pControl == m_xSliderAngle.get())
306 m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
308 css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active());
310 sal_uInt16 nValue = 0; // automatic
311 if (!m_xCbIncrement->get_active())
312 nValue = static_cast<sal_uInt16>(m_xMtrIncrement->get_value());
314 basegfx::BGradient aBGradient(
315 createColorStops(),
316 eXGS,
317 Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
318 static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
319 static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
320 static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
321 static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
322 static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
323 nValue);
325 // enable/disable controls
326 if (pControl == m_xLbGradientType.get() || pControl == this)
327 SetControlState_Impl( eXGS );
329 m_rXFSet.Put( XGradientStepCountItem( nValue ) );
331 // displaying in XOutDev
332 m_rXFSet.Put( XFillGradientItem( OUString(), aBGradient ) );
333 m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
334 m_aCtlPreview.Invalidate();
337 IMPL_LINK_NOARG(SvxGradientTabPage, ClickAddHdl_Impl, weld::Button&, void)
339 OUString aNewName( SvxResId( RID_SVXSTR_GRADIENT ) );
340 OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
341 OUString aName;
343 tools::Long nCount = m_pGradientList->Count();
344 tools::Long j = 1;
345 bool bValidGradientName = false;
347 while( !bValidGradientName )
349 aName = aNewName + " " + OUString::number( j++ );
350 bValidGradientName = (SearchGradientList(aName) == -1);
353 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
354 ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
355 sal_uInt16 nError = 1;
357 while (pDlg->Execute() == RET_OK)
359 aName = pDlg->GetName();
361 bValidGradientName = (SearchGradientList(aName) == -1);
363 if (bValidGradientName)
365 nError = 0;
366 break;
369 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"cui/ui/queryduplicatedialog.ui"_ustr));
370 std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog(u"DuplicateNameDialog"_ustr));
371 if (xWarnBox->run() != RET_OK)
372 break;
374 pDlg.disposeAndClear();
376 if( !nError )
378 sal_uInt16 nValue = 0; // automatic step count
379 if (!m_xCbIncrement->get_active())
380 nValue = m_xMtrIncrement->get_value();
381 basegfx::BGradient aBGradient(
382 createColorStops(),
383 static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
384 Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
385 static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
386 static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
387 static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
388 static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
389 static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
390 nValue);
392 m_pGradientList->Insert(std::make_unique<XGradientEntry>(aBGradient, aName), nCount);
394 sal_Int32 nId = m_xGradientLB->GetItemId(nCount - 1); //calculate the last ID
395 BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( nCount, m_xGradientLB->GetIconSize() );
396 m_xGradientLB->InsertItem( nId + 1, Image(aBitmap), aName );
397 m_xGradientLB->SelectItem( nId + 1 );
398 m_xGradientLB->Resize();
400 m_nGradientListState |= ChangeType::MODIFIED;
402 ChangeGradientHdl_Impl();
405 // determine button state
406 if (m_pGradientList->Count())
407 m_xBtnModify->set_sensitive(true);
411 IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, weld::Button&, void)
413 sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
414 size_t nPos = m_xGradientLB->GetSelectItemPos();
416 if ( nPos == VALUESET_ITEM_NOTFOUND )
417 return;
419 OUString aName( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetName() );
421 sal_uInt16 nValue = 0; // automatic step count
422 if (!m_xCbIncrement->get_active())
423 nValue = m_xMtrIncrement->get_value();
425 basegfx::BGradient aBGradient(
426 createColorStops(),
427 static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
428 Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
429 static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
430 static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
431 static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
432 static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
433 static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
434 nValue);
436 m_pGradientList->Replace(std::make_unique<XGradientEntry>(aBGradient, aName), nPos);
438 BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xGradientLB->GetIconSize() );
439 m_xGradientLB->RemoveItem( nId );
440 m_xGradientLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
441 m_xGradientLB->SelectItem( nId );
443 m_nGradientListState |= ChangeType::MODIFIED;
446 IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
448 const sal_uInt16 nId = m_xGradientLB->GetContextMenuItemId();
449 const size_t nPos = m_xGradientLB->GetItemPos(nId);
451 if( nPos != VALUESET_ITEM_NOTFOUND )
453 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"cui/ui/querydeletegradientdialog.ui"_ustr));
454 std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog(u"AskDelGradientDialog"_ustr));
455 if (xQueryBox->run() == RET_YES)
457 const bool bDeletingSelectedItem(nId == m_xGradientLB->GetSelectedItemId());
458 m_pGradientList->Remove(nPos);
459 m_xGradientLB->RemoveItem( nId );
460 if (bDeletingSelectedItem)
462 m_xGradientLB->SelectItem(m_xGradientLB->GetItemId(/*Position=*/0));
463 m_aCtlPreview.Invalidate();
465 m_xGradientLB->Resize();
467 ChangeGradientHdl_Impl();
469 m_nGradientListState |= ChangeType::MODIFIED;
472 // determine button state
473 if( !m_pGradientList->Count() )
474 m_xBtnModify->set_sensitive(false);
477 IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
479 const sal_uInt16 nId = m_xGradientLB->GetContextMenuItemId();
480 const size_t nPos = m_xGradientLB->GetItemPos(nId);
482 if ( nPos == VALUESET_ITEM_NOTFOUND )
483 return;
485 OUString aDesc( CuiResId( RID_CUISTR_DESC_GRADIENT ) );
486 OUString aName( m_pGradientList->GetGradient( nPos )->GetName() );
488 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
489 ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
491 bool bLoop = true;
492 while( bLoop && pDlg->Execute() == RET_OK )
494 aName = pDlg->GetName();
495 sal_Int32 nGradientPos = SearchGradientList(aName);
496 bool bValidGradientName = (nGradientPos == static_cast<sal_Int32>(nPos) ) || (nGradientPos == -1);
498 if( bValidGradientName )
500 bLoop = false;
501 m_pGradientList->GetGradient(nPos)->SetName(aName);
503 m_xGradientLB->SetItemText( nId, aName );
505 m_nGradientListState |= ChangeType::MODIFIED;
507 else
509 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), u"cui/ui/queryduplicatedialog.ui"_ustr));
510 std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog(u"DuplicateNameDialog"_ustr));
511 xBox->run();
516 IMPL_LINK_NOARG(SvxGradientTabPage, ChangeGradientHdl, ValueSet*, void)
518 ChangeGradientHdl_Impl();
521 void SvxGradientTabPage::ChangeGradientHdl_Impl()
523 std::unique_ptr<basegfx::BGradient> pGradient;
524 size_t nPos = m_xGradientLB->GetSelectItemPos();
526 if( nPos != VALUESET_ITEM_NOTFOUND )
527 pGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>( nPos ) )->GetGradient() ));
528 else
530 if( const XFillStyleItem* pFillStyleItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLSTYLE ) ) )
532 const XFillGradientItem* pGradientItem;
533 if( ( drawing::FillStyle_GRADIENT == pFillStyleItem->GetValue() ) &&
534 ( pGradientItem = m_rOutAttrs.GetItemIfSet( GetWhich( XATTR_FILLGRADIENT ) ) ) )
536 pGradient.reset(new basegfx::BGradient( pGradientItem->GetGradientValue() ));
539 if( !pGradient )
541 sal_uInt16 nPosition = m_xGradientLB->GetItemId(0);
542 m_xGradientLB->SelectItem( nPosition );
543 if( nPosition != 0 )
544 pGradient.reset(new basegfx::BGradient( m_pGradientList->GetGradient( 0 )->GetGradient() ));
548 if( !pGradient )
549 return;
551 css::awt::GradientStyle eXGS = pGradient->GetGradientStyle();
552 sal_uInt16 nValue = pGradient->GetSteps();
553 if (const XGradientStepCountItem* pGradientStepCountItem = m_rOutAttrs.GetItemIfSet(GetWhich(XATTR_GRADIENTSTEPCOUNT)))
555 nValue = pGradientStepCountItem->GetValue();
557 if( nValue == 0 )
559 m_xCbIncrement->set_state(TRISTATE_TRUE);
560 m_xMtrIncrement->set_sensitive(false);
562 else
564 m_xCbIncrement->set_state(TRISTATE_FALSE);
565 m_xMtrIncrement->set_sensitive(true);
566 m_xMtrIncrement->set_value( nValue );
568 m_xLbGradientType->set_active(
569 sal::static_int_cast< sal_Int32 >( eXGS ) );
570 // if the entry is not in the listbox,
571 // colors are added temporarily
572 m_xLbColorFrom->SetNoSelection();
573 m_xLbColorFrom->SelectEntry(Color(pGradient->GetColorStops().front().getStopColor()));
575 m_xLbColorTo->SetNoSelection();
576 m_xLbColorTo->SelectEntry(Color(pGradient->GetColorStops().back().getStopColor()));
578 // MCGR: preserve ColorStops if given.
579 // tdf#155901 We need offset of first and last stop, so include them.
580 if (pGradient->GetColorStops().size() >= 2)
581 m_aColorStops = pGradient->GetColorStops();
582 else
583 m_aColorStops.clear();
585 m_xMtrAngle->set_value(pGradient->GetAngle().get() / 10, FieldUnit::NONE); // should be changed in resource
586 m_xSliderAngle->set_value(pGradient->GetAngle().get() / 10);
587 m_xMtrBorder->set_value(pGradient->GetBorder(), FieldUnit::NONE);
588 m_xSliderBorder->set_value(pGradient->GetBorder());
589 m_xMtrCenterX->set_value(pGradient->GetXOffset(), FieldUnit::NONE);
590 m_xMtrCenterY->set_value(pGradient->GetYOffset(), FieldUnit::NONE);
591 m_xMtrColorFrom->set_value(pGradient->GetStartIntens(), FieldUnit::NONE);
592 m_xMtrColorTo->set_value(pGradient->GetEndIntens(), FieldUnit::NONE);
594 // disable/enable controls
595 SetControlState_Impl( eXGS );
597 // fill ItemSet and pass it on to aCtlPreview
598 m_rXFSet.Put( XFillGradientItem( OUString(), *pGradient ) );
599 m_rXFSet.Put( XGradientStepCountItem( nValue ) );
600 m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
602 m_aCtlPreview.Invalidate();
605 void SvxGradientTabPage::SetControlState_Impl( css::awt::GradientStyle eXGS )
607 switch( eXGS )
609 case css::awt::GradientStyle_LINEAR:
610 case css::awt::GradientStyle_AXIAL:
611 m_xFtCenter->set_sensitive(false);
612 m_xMtrCenterX->set_sensitive(false);
613 m_xMtrCenterY->set_sensitive(false);
614 m_xFtAngle->set_sensitive(true);
615 m_xMtrAngle->set_sensitive(true);
616 m_xSliderAngle->set_sensitive(true);
617 break;
619 case css::awt::GradientStyle_RADIAL:
620 m_xFtCenter->set_sensitive(true);
621 m_xMtrCenterX->set_sensitive(true);
622 m_xMtrCenterY->set_sensitive(true);
623 m_xFtAngle->set_sensitive(false);
624 m_xMtrAngle->set_sensitive(false);
625 m_xSliderAngle->set_sensitive(false);
626 break;
628 case css::awt::GradientStyle_ELLIPTICAL:
629 case css::awt::GradientStyle_SQUARE:
630 case css::awt::GradientStyle_RECT:
631 m_xFtCenter->set_sensitive(true);
632 m_xMtrCenterX->set_sensitive(true);
633 m_xMtrCenterY->set_sensitive(true);
634 m_xFtAngle->set_sensitive(true);
635 m_xMtrAngle->set_sensitive(true);
636 m_xSliderAngle->set_sensitive(true);
637 break;
639 default:
640 break;
644 sal_Int32 SvxGradientTabPage::SearchGradientList(std::u16string_view rGradientName)
646 tools::Long nCount = m_pGradientList->Count();
647 bool bValidGradientName = true;
648 sal_Int32 nPos = -1;
650 for(tools::Long i = 0;i < nCount && bValidGradientName;i++)
652 if(rGradientName == m_pGradientList->GetGradient( i )->GetName())
654 nPos = i;
655 bValidGradientName = false;
658 return nPos;
661 basegfx::BColorStops SvxGradientTabPage::createColorStops()
663 basegfx::BColorStops aColorStops;
665 if(m_aColorStops.size() >= 2)
667 aColorStops = m_aColorStops;
668 aColorStops.front() = basegfx::BColorStop(m_aColorStops.front().getStopOffset(),
669 m_xLbColorFrom->GetSelectEntryColor().getBColor());
670 aColorStops.back() = basegfx::BColorStop(m_aColorStops.back().getStopOffset(),
671 m_xLbColorTo->GetSelectEntryColor().getBColor());
673 else
675 aColorStops.emplace_back(0.0, m_xLbColorFrom->GetSelectEntryColor().getBColor());
676 aColorStops.emplace_back(1.0, m_xLbColorTo->GetSelectEntryColor().getBColor());
679 return aColorStops;
682 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */