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 
10 #include <comphelper/lok.hxx>
11 #include <condformatdlg.hxx>
12 
13 #include <sfx2/dispatch.hxx>
14 #include <sfx2/lokhelper.hxx>
15 #include <vcl/settings.hxx>
16 #include <vcl/svapp.hxx>
17 
18 #include <anyrefdg.hxx>
19 #include <document.hxx>
20 #include <conditio.hxx>
21 #include <tabvwsh.hxx>
22 #include <colorscale.hxx>
23 #include <reffact.hxx>
24 #include <docsh.hxx>
25 #include <docfunc.hxx>
26 #include <condformatdlgentry.hxx>
27 #include <condformatdlgitem.hxx>
28 
ScCondFormatList(ScCondFormatDlg * pDialogParent,std::unique_ptr<weld::ScrolledWindow> xWindow,std::unique_ptr<weld::Container> xGrid)29 ScCondFormatList::ScCondFormatList(ScCondFormatDlg* pDialogParent,
30                                    std::unique_ptr<weld::ScrolledWindow> xWindow,
31                                    std::unique_ptr<weld::Container> xGrid)
32     : mxScrollWindow(std::move(xWindow))
33     , mxGrid(std::move(xGrid))
34     , mbFrozen(false)
35     , mbNewEntry(false)
36     , mpDoc(nullptr)
37     , mpDialogParent(pDialogParent)
38 {
39     mxScrollWindow->set_size_request(mxScrollWindow->get_approximate_digit_width() * 85,
40                                      mxScrollWindow->get_text_height() * 23);
41     mxGrid->set_stack_background();
42 }
43 
GetFrameWeld()44 weld::Window* ScCondFormatList::GetFrameWeld()
45 {
46     return mpDialogParent->getDialog();
47 }
48 
~ScCondFormatList()49 ScCondFormatList::~ScCondFormatList()
50 {
51     Freeze();
52 }
53 
init(ScDocument * pDoc,const ScConditionalFormat * pFormat,const ScRangeList & rRanges,const ScAddress & rPos,condformat::dialog::ScCondFormatDialogType eType)54 void ScCondFormatList::init(ScDocument* pDoc,
55         const ScConditionalFormat* pFormat, const ScRangeList& rRanges,
56         const ScAddress& rPos, condformat::dialog::ScCondFormatDialogType eType)
57 {
58     mpDoc = pDoc;
59     maPos = rPos;
60     maRanges = rRanges;
61 
62     Freeze();
63 
64     if(pFormat)
65     {
66         size_t nCount = pFormat->size();
67         for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
68         {
69             const ScFormatEntry* pEntry = pFormat->GetEntry(nIndex);
70             switch(pEntry->GetType())
71             {
72                 case ScFormatEntry::Type::Condition:
73                 case ScFormatEntry::Type::ExtCondition:
74                     {
75                         const ScCondFormatEntry* pConditionEntry = static_cast<const ScCondFormatEntry*>( pEntry );
76                         if(pConditionEntry->GetOperation() != ScConditionMode::Direct)
77                             maEntries.emplace_back(new ScConditionFrmtEntry( this, mpDoc, mpDialogParent, maPos, pConditionEntry ) );
78                         else
79                             maEntries.emplace_back(new ScFormulaFrmtEntry( this, mpDoc, mpDialogParent, maPos, pConditionEntry ) );
80 
81                     }
82                     break;
83                 case ScFormatEntry::Type::Colorscale:
84                     {
85                         const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>( pEntry );
86                         if( pColorScale->size() == 2 )
87                             maEntries.emplace_back(new ScColorScale2FrmtEntry( this, mpDoc, maPos, pColorScale ) );
88                         else
89                             maEntries.emplace_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos, pColorScale ) );
90                     }
91                     break;
92                 case ScFormatEntry::Type::Databar:
93                     maEntries.emplace_back(new ScDataBarFrmtEntry( this, mpDoc, maPos, static_cast<const ScDataBarFormat*>( pEntry ) ) );
94                     break;
95                 case ScFormatEntry::Type::Iconset:
96                     maEntries.emplace_back(new ScIconSetFrmtEntry( this, mpDoc, maPos, static_cast<const ScIconSetFormat*>( pEntry ) ) );
97                     break;
98                 case ScFormatEntry::Type::Date:
99                     maEntries.emplace_back(new ScDateFrmtEntry( this, mpDoc, static_cast<const ScCondDateFormatEntry*>( pEntry ) ) );
100                     break;
101             }
102         }
103         if(nCount)
104             EntrySelectHdl(*maEntries[0]);
105     }
106     else
107     {
108         switch(eType)
109         {
110             case condformat::dialog::CONDITION:
111                 maEntries.emplace_back(new ScConditionFrmtEntry( this, mpDoc, mpDialogParent, maPos ));
112                 break;
113             case condformat::dialog::COLORSCALE:
114                 maEntries.emplace_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos ));
115                 break;
116             case condformat::dialog::DATABAR:
117                 maEntries.emplace_back(new ScDataBarFrmtEntry( this, mpDoc, maPos ));
118                 break;
119             case condformat::dialog::ICONSET:
120                 maEntries.emplace_back(new ScIconSetFrmtEntry( this, mpDoc, maPos ));
121                 break;
122             case condformat::dialog::DATE:
123                 maEntries.emplace_back(new ScDateFrmtEntry( this, mpDoc ));
124                 break;
125             case condformat::dialog::NONE:
126                 break;
127         }
128         mbNewEntry = true;
129     }
130     Thaw();
131     RecalcAll();
132     if (!maEntries.empty())
133     {
134         (*maEntries.begin())->SetActive();
135         mpDialogParent->OnSelectionChange(0, maEntries.size());
136     }
137 
138     RecalcAll();
139 }
140 
SetRange(const ScRangeList & rRange)141 void ScCondFormatList::SetRange(const ScRangeList& rRange)
142 {
143     maRanges = rRange;
144 }
145 
GetConditionalFormat() const146 std::unique_ptr<ScConditionalFormat> ScCondFormatList::GetConditionalFormat() const
147 {
148     if(maEntries.empty())
149         return nullptr;
150 
151     std::unique_ptr<ScConditionalFormat> pFormat(new ScConditionalFormat(0, mpDoc));
152     pFormat->SetRange(maRanges);
153 
154     for(auto & rEntry: maEntries)
155     {
156         // tdf#119178: Sometimes initial apply-to range (the one this dialog
157         // was opened with) is different from the final apply-to range
158         // (as edited by the user)
159 
160         // If this format entry is new, take top-left corner of the final range
161         // and use it to create the initial entry (token array therein, if applicable)
162         if (mbNewEntry)
163             rEntry->SetPos(maRanges.GetTopLeftCorner());
164         // else do nothing: setting new position when editing recompiles formulas
165         // in entries and nobody wants that
166 
167         ScFormatEntry* pEntry = rEntry->GetEntry();
168         if(pEntry)
169             pFormat->AddEntry(pEntry);
170     }
171 
172     return pFormat;
173 }
174 
RecalcAll()175 void ScCondFormatList::RecalcAll()
176 {
177     if (mbFrozen)
178         return;
179 
180     sal_Int32 nIndex = 1;
181     for (const auto& item : maEntries)
182     {
183         if (!item)
184             continue;
185         item->SetIndex(nIndex);
186         item->set_grid_top_attach(nIndex - 1);
187         ++nIndex;
188     }
189 }
190 
IMPL_LINK(ScCondFormatList,ColFormatTypeHdl,weld::ComboBox &,rBox,void)191 IMPL_LINK(ScCondFormatList, ColFormatTypeHdl, weld::ComboBox&, rBox, void)
192 {
193     Application::PostUserEvent(LINK(this, ScCondFormatList, AfterColFormatTypeHdl), &rBox);
194 }
195 
IMPL_LINK(ScCondFormatList,AfterColFormatTypeHdl,void *,p,void)196 IMPL_LINK(ScCondFormatList, AfterColFormatTypeHdl, void*, p, void)
197 {
198     weld::ComboBox* pBox = static_cast<weld::ComboBox*>(p);
199     EntryContainer::iterator itr = std::find_if(maEntries.begin(), maEntries.end(),
200         [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
201     if(itr == maEntries.end())
202         return;
203 
204     sal_Int32 nPos = pBox->get_active();
205     switch(nPos)
206     {
207         case 0:
208             if((*itr)->GetType() == condformat::entry::COLORSCALE2)
209                 return;
210 
211             Freeze();
212             itr->reset(new ScColorScale2FrmtEntry(this, mpDoc, maPos));
213             break;
214         case 1:
215             if((*itr)->GetType() == condformat::entry::COLORSCALE3)
216                 return;
217 
218             Freeze();
219             itr->reset(new ScColorScale3FrmtEntry(this, mpDoc, maPos));
220             break;
221         case 2:
222             if((*itr)->GetType() == condformat::entry::DATABAR)
223                 return;
224 
225             Freeze();
226             itr->reset(new ScDataBarFrmtEntry(this, mpDoc, maPos));
227             break;
228         case 3:
229             if((*itr)->GetType() == condformat::entry::ICONSET)
230                 return;
231 
232             Freeze();
233             itr->reset(new ScIconSetFrmtEntry(this, mpDoc, maPos));
234             break;
235         default:
236             break;
237     }
238     mpDialogParent->InvalidateRefData();
239     (*itr)->SetActive();
240     Thaw();
241     RecalcAll();
242 }
243 
IMPL_LINK(ScCondFormatList,TypeListHdl,weld::ComboBox &,rBox,void)244 IMPL_LINK(ScCondFormatList, TypeListHdl, weld::ComboBox&, rBox, void)
245 {
246     //Resolves: fdo#79021 At this point we are still inside the ListBox Select.
247     //If we call maEntries.replace here then the pBox will be deleted before it
248     //has finished Select and will crash on accessing its deleted this. So Post
249     //to do the real work after the Select has completed
250     Application::PostUserEvent(LINK(this, ScCondFormatList, AfterTypeListHdl), &rBox);
251 }
252 
IMPL_LINK(ScCondFormatList,AfterTypeListHdl,void *,p,void)253 IMPL_LINK(ScCondFormatList, AfterTypeListHdl, void*, p, void)
254 {
255     weld::ComboBox* pBox = static_cast<weld::ComboBox*>(p);
256     EntryContainer::iterator itr = std::find_if(maEntries.begin(), maEntries.end(),
257         [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
258     if(itr == maEntries.end())
259         return;
260 
261     sal_Int32 nPos = pBox->get_active();
262     switch(nPos)
263     {
264         case 0:
265             switch((*itr)->GetType())
266             {
267                 case condformat::entry::FORMULA:
268                 case condformat::entry::CONDITION:
269                 case condformat::entry::DATE:
270                     break;
271                 case condformat::entry::COLORSCALE2:
272                 case condformat::entry::COLORSCALE3:
273                 case condformat::entry::DATABAR:
274                 case condformat::entry::ICONSET:
275                     return;
276             }
277             Freeze();
278             itr->reset(new ScColorScale3FrmtEntry(this, mpDoc, maPos));
279             mpDialogParent->InvalidateRefData();
280             (*itr)->SetActive();
281             break;
282         case 1:
283             if((*itr)->GetType() == condformat::entry::CONDITION)
284                 return;
285 
286             Freeze();
287             itr->reset(new ScConditionFrmtEntry(this, mpDoc, mpDialogParent, maPos));
288             mpDialogParent->InvalidateRefData();
289             (*itr)->SetActive();
290             break;
291         case 2:
292             if((*itr)->GetType() == condformat::entry::FORMULA)
293                 return;
294 
295             Freeze();
296             itr->reset(new ScFormulaFrmtEntry(this, mpDoc, mpDialogParent, maPos));
297             mpDialogParent->InvalidateRefData();
298             (*itr)->SetActive();
299             break;
300         case 3:
301             if((*itr)->GetType() == condformat::entry::DATE)
302                 return;
303 
304             Freeze();
305             itr->reset(new ScDateFrmtEntry( this, mpDoc ));
306             mpDialogParent->InvalidateRefData();
307             (*itr)->SetActive();
308             break;
309 
310     }
311     Thaw();
312     RecalcAll();
313 }
314 
IMPL_LINK_NOARG(ScCondFormatList,AddBtnHdl,weld::Button &,void)315 IMPL_LINK_NOARG( ScCondFormatList, AddBtnHdl, weld::Button&, void )
316 {
317     Freeze();
318     maEntries.emplace_back(new ScConditionFrmtEntry(this, mpDoc, mpDialogParent, maPos));
319     for(auto& rxEntry : maEntries)
320     {
321         rxEntry->SetInactive();
322     }
323     mpDialogParent->InvalidateRefData();
324     maEntries.back()->SetActive();
325     mpDialogParent->OnSelectionChange(maEntries.size() - 1, maEntries.size());
326     Thaw();
327     RecalcAll();
328 }
329 
IMPL_LINK_NOARG(ScCondFormatList,RemoveBtnHdl,weld::Button &,void)330 IMPL_LINK_NOARG( ScCondFormatList, RemoveBtnHdl, weld::Button&, void )
331 {
332     Freeze();
333     auto itr = std::find_if(maEntries.begin(), maEntries.end(),
334         [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
335     if (itr != maEntries.end())
336     {
337         maEntries.erase(itr);
338     }
339     mpDialogParent->InvalidateRefData();
340     mpDialogParent->OnSelectionChange(0, maEntries.size(), false);
341     Thaw();
342     RecalcAll();
343 }
344 
IMPL_LINK_NOARG(ScCondFormatList,UpBtnHdl,weld::Button &,void)345 IMPL_LINK_NOARG(ScCondFormatList, UpBtnHdl, weld::Button&, void)
346 {
347     Freeze();
348     size_t index = 0;
349     for (size_t i = 0; i < maEntries.size(); i++)
350     {
351         auto& widget = maEntries[i];
352         if (widget->IsSelected() && i > 0)
353         {
354             std::swap(maEntries[i], maEntries[i - 1]);
355             index = i - 1;
356             break;
357         }
358     }
359     mpDialogParent->InvalidateRefData();
360     mpDialogParent->OnSelectionChange(index, maEntries.size());
361     Thaw();
362     RecalcAll();
363 }
364 
IMPL_LINK_NOARG(ScCondFormatList,DownBtnHdl,weld::Button &,void)365 IMPL_LINK_NOARG(ScCondFormatList, DownBtnHdl, weld::Button&, void)
366 {
367     Freeze();
368     size_t index = 0;
369     for (size_t i = 0; i < maEntries.size(); i++)
370     {
371         auto& widget = maEntries[i];
372         if (widget->IsSelected())
373         {
374             index = i;
375             if (i < maEntries.size()-1)
376             {
377                 std::swap(maEntries[i], maEntries[i + 1]);
378                 index = i + 1;
379                 break;
380             }
381         }
382     }
383     mpDialogParent->InvalidateRefData();
384     mpDialogParent->OnSelectionChange(index, maEntries.size());
385     Thaw();
386     RecalcAll();
387 }
388 
IMPL_LINK(ScCondFormatList,EntrySelectHdl,ScCondFrmtEntry &,rEntry,void)389 IMPL_LINK( ScCondFormatList, EntrySelectHdl, ScCondFrmtEntry&, rEntry, void )
390 {
391     if(rEntry.IsSelected())
392         return;
393 
394     Freeze();
395     size_t index = 0;
396     for(size_t i = 0; i < maEntries.size(); i++)
397     {
398         if (maEntries[i].get() == &rEntry)
399         {
400             index = i;
401         }
402         maEntries[i]->SetInactive();
403     }
404     mpDialogParent->InvalidateRefData();
405     mpDialogParent->OnSelectionChange(index, maEntries.size());
406     rEntry.SetActive();
407     Thaw();
408     RecalcAll();
409 }
410 
ScCondFormatDlg(SfxBindings * pB,SfxChildWindow * pCW,weld::Window * pParent,ScViewData * pViewData,const ScCondFormatDlgItem * pItem)411 ScCondFormatDlg::ScCondFormatDlg(SfxBindings* pB, SfxChildWindow* pCW,
412     weld::Window* pParent, ScViewData* pViewData,
413     const ScCondFormatDlgItem* pItem)
414         : ScAnyRefDlgController(pB, pCW, pParent,
415                         (comphelper::LibreOfficeKit::isMobile(SfxLokHelper::getView())?OUString("modules/scalc/ui/conditionalformatdialogmobile.ui"):OUString("modules/scalc/ui/conditionalformatdialog.ui")),
416                         "ConditionalFormatDialog")
417     , mpViewData(pViewData)
418     , mpDlgItem(static_cast<ScCondFormatDlgItem*>(pItem->Clone()))
419     , mpLastEdit(nullptr)
420     , mxBtnOk(m_xBuilder->weld_button("ok"))
421     , mxBtnAdd(m_xBuilder->weld_button("add"))
422     , mxBtnRemove(m_xBuilder->weld_button("delete"))
423     , mxBtnUp(m_xBuilder->weld_button("up"))
424     , mxBtnDown(m_xBuilder->weld_button("down"))
425     , mxBtnCancel(m_xBuilder->weld_button("cancel"))
426     , mxFtRange(m_xBuilder->weld_label("ftassign"))
427     , mxEdRange(new formula::RefEdit(m_xBuilder->weld_entry("edassign")))
428     , mxRbRange(new formula::RefButton(m_xBuilder->weld_button("rbassign")))
429     , mxCondFormList(new ScCondFormatList(this, m_xBuilder->weld_scrolled_window("listwindow"),
430                                           m_xBuilder->weld_container("list")))
431 {
432     mxEdRange->SetReferences(this, mxFtRange.get());
433     mxRbRange->SetReferences(this, mxEdRange.get());
434 
435     ScConditionalFormat* pFormat = nullptr;
436     mnKey = mpDlgItem->GetIndex();
437     if (mpDlgItem->IsManaged() && mpDlgItem->GetConditionalFormatList())
438     {
439         pFormat = mpDlgItem->GetConditionalFormatList()->GetFormat(mnKey);
440     }
441     else if (!mpDlgItem->IsManaged())
442     {
443         ScDocument* pDoc = mpViewData->GetDocument();
444         pFormat = pDoc->GetCondFormList(mpViewData->GetTabNo())->GetFormat ( mnKey );
445     }
446 
447     ScRangeList aRange;
448     if (pFormat)
449     {
450         aRange = pFormat->GetRange();
451     }
452     else
453     {
454         // this is for adding a new entry
455         mpViewData->GetMarkData().FillRangeListWithMarks(&aRange, false);
456         if(aRange.empty())
457         {
458             ScAddress aPos(mpViewData->GetCurX(), mpViewData->GetCurY(), mpViewData->GetTabNo());
459             aRange.push_back(ScRange(aPos));
460         }
461         mnKey = 0;
462     }
463     maPos = aRange.GetTopLeftCorner();
464 
465     mxCondFormList->init(mpViewData->GetDocument(), pFormat, aRange, maPos, mpDlgItem->GetDialogType());
466 
467     mxBtnOk->connect_clicked(LINK(this, ScCondFormatDlg, BtnPressedHdl ) );
468     mxBtnAdd->connect_clicked( LINK( mxCondFormList.get(), ScCondFormatList, AddBtnHdl ) );
469     mxBtnRemove->connect_clicked( LINK( mxCondFormList.get(), ScCondFormatList, RemoveBtnHdl ) );
470     mxBtnUp->connect_clicked(LINK(mxCondFormList.get(), ScCondFormatList, UpBtnHdl));
471     mxBtnDown->connect_clicked(LINK(mxCondFormList.get(), ScCondFormatList, DownBtnHdl));
472     mxBtnCancel->connect_clicked( LINK(this, ScCondFormatDlg, BtnPressedHdl ) );
473     mxEdRange->SetModifyHdl( LINK( this, ScCondFormatDlg, EdRangeModifyHdl ) );
474     mxEdRange->SetGetFocusHdl( LINK( this, ScCondFormatDlg, RangeGetFocusHdl ) );
475 
476     OUString aRangeString;
477     aRange.Format(aRangeString, ScRefFlags::VALID, pViewData->GetDocument(),
478                     pViewData->GetDocument()->GetAddressConvention());
479     mxEdRange->SetText(aRangeString);
480 
481     msBaseTitle = m_xDialog->get_title();
482     updateTitle();
483 }
484 
updateTitle()485 void ScCondFormatDlg::updateTitle()
486 {
487     OUString aTitle = msBaseTitle + " " + mxEdRange->GetText();
488 
489     m_xDialog->set_title(aTitle);
490 }
491 
~ScCondFormatDlg()492 ScCondFormatDlg::~ScCondFormatDlg()
493 {
494 }
495 
SetActive()496 void ScCondFormatDlg::SetActive()
497 {
498     if(mpLastEdit)
499         mpLastEdit->GrabFocus();
500     else
501         mxEdRange->GrabFocus();
502 
503     RefInputDone();
504 }
505 
RefInputDone(bool bForced)506 void ScCondFormatDlg::RefInputDone( bool bForced )
507 {
508     ScAnyRefDlgController::RefInputDone(bForced);
509 
510     // ScAnyRefModalDlg::RefInputDone resets the title back
511     // to its original state.
512     // I.e. if we open the dialog normally, and then click into the sheet
513     // to modify the selection, the title is updated such that the range
514     // is only a single cell (e.g. $A$1), after which the dialog switches
515     // into the RefInput mode. During the RefInput mode the title is updated
516     // as expected, however at the end RefInputDone overwrites the title
517     // with the initial (now incorrect) single cell range. Hence we correct
518     // it here.
519     updateTitle();
520 }
521 
IsTableLocked() const522 bool ScCondFormatDlg::IsTableLocked() const
523 {
524     return !mpLastEdit || mpLastEdit == mxEdRange.get();
525 }
526 
IsRefInputMode() const527 bool ScCondFormatDlg::IsRefInputMode() const
528 {
529     return mxEdRange->GetWidget()->get_sensitive();
530 }
531 
SetReference(const ScRange & rRef,ScDocument *)532 void ScCondFormatDlg::SetReference(const ScRange& rRef, ScDocument*)
533 {
534     formula::RefEdit* pEdit = mpLastEdit;
535     if (!mpLastEdit)
536         pEdit = mxEdRange.get();
537 
538     if (pEdit->GetWidget()->get_sensitive())
539     {
540         if(rRef.aStart != rRef.aEnd)
541             RefInputStart(pEdit);
542 
543         ScRefFlags nFlags;
544         if (mpLastEdit && mpLastEdit != mxEdRange.get())
545             nFlags = ScRefFlags::RANGE_ABS_3D;
546         else
547             nFlags = ScRefFlags::RANGE_ABS;
548 
549         OUString aRefStr(rRef.Format(nFlags, mpViewData->GetDocument(),
550             ScAddress::Details(mpViewData->GetDocument()->GetAddressConvention(), 0, 0)));
551         if (pEdit != mxEdRange.get())
552         {
553             Selection sel = pEdit->GetSelection();
554             sel.Justify();            // in case of RTL selection
555             sel.Max() = sel.Min() + aRefStr.getLength();
556             pEdit->GetWidget()->replace_selection(aRefStr);
557             pEdit->SetSelection(sel); // to replace it again with next drag event
558         }
559         else
560             pEdit->SetRefString( aRefStr );
561         updateTitle();
562     }
563 }
564 
GetConditionalFormat() const565 std::unique_ptr<ScConditionalFormat> ScCondFormatDlg::GetConditionalFormat() const
566 {
567     OUString aRangeStr = mxEdRange->GetText();
568     if(aRangeStr.isEmpty())
569         return nullptr;
570 
571     ScRangeList aRange;
572     ScRefFlags nFlags = aRange.Parse(aRangeStr, mpViewData->GetDocument(),
573         mpViewData->GetDocument()->GetAddressConvention(), maPos.Tab());
574     mxCondFormList->SetRange(aRange);
575     std::unique_ptr<ScConditionalFormat> pFormat = mxCondFormList->GetConditionalFormat();
576 
577     if((nFlags & ScRefFlags::VALID) && !aRange.empty() && pFormat)
578         pFormat->SetRange(aRange);
579     else
580         pFormat.reset();
581 
582     return pFormat;
583 }
584 
InvalidateRefData()585 void ScCondFormatDlg::InvalidateRefData()
586 {
587     mpLastEdit = nullptr;
588 }
589 
590 // Close the Conditional Format Dialog
591 //
Close()592 void ScCondFormatDlg::Close()
593 {
594     DoClose( ScCondFormatDlgWrapper::GetChildWindowId() );
595 }
596 
597 // Occurs when the Conditional Format Dialog the OK button is pressed.
598 //
OkPressed()599 void ScCondFormatDlg::OkPressed()
600 {
601     std::unique_ptr<ScConditionalFormat> pFormat = GetConditionalFormat();
602 
603     if (!mpDlgItem->IsManaged())
604     {
605         if(pFormat)
606         {
607             auto& rRangeList = pFormat->GetRange();
608             mpViewData->GetDocShell()->GetDocFunc().ReplaceConditionalFormat(mnKey,
609                     std::move(pFormat), maPos.Tab(), rRangeList);
610         }
611         else
612             mpViewData->GetDocShell()->GetDocFunc().ReplaceConditionalFormat(mnKey,
613                     nullptr, maPos.Tab(), ScRangeList());
614     }
615     else
616     {
617         ScConditionalFormatList* pList = mpDlgItem->GetConditionalFormatList();
618         sal_uInt32 nKey = mnKey;
619         if (mnKey == 0)
620         {
621             nKey = pList->getMaxKey() + 1;
622         }
623 
624         pList->erase(nKey);
625         if (pFormat)
626         {
627             pFormat->SetKey(nKey);
628             pList->InsertNew(std::move(pFormat));
629         }
630         mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem);
631 
632         SetDispatcherLock( false );
633         // Queue message to open Conditional Format Manager Dialog
634         GetBindings().GetDispatcher()->Execute( SID_OPENDLG_CONDFRMT_MANAGER,
635                                             SfxCallMode::ASYNCHRON );
636     }
637     m_xDialog->response(RET_OK);
638 }
639 
640 // Occurs when the Conditional Format Dialog is cancelled.
641 //
CancelPressed()642 void ScCondFormatDlg::CancelPressed()
643 {
644     if ( mpDlgItem->IsManaged() )
645     {
646         mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem);
647         SetDispatcherLock( false );
648         // Queue message to open Conditional Format Manager Dialog
649         GetBindings().GetDispatcher()->Execute( SID_OPENDLG_CONDFRMT_MANAGER,
650                                             SfxCallMode::ASYNCHRON );
651     }
652     m_xDialog->response(RET_CANCEL);
653 }
654 
OnSelectionChange(size_t nIndex,size_t nSize,bool bSelected)655 void ScCondFormatDlg::OnSelectionChange(size_t nIndex, size_t nSize, bool bSelected)
656 {
657     if (nSize <= 1 || !bSelected)
658     {
659         mxBtnUp->set_sensitive(false);
660         mxBtnDown->set_sensitive(false);
661     }
662     else
663     {
664         mxBtnUp->set_sensitive(nIndex != 0);
665         mxBtnDown->set_sensitive(nIndex < nSize - 1);
666     }
667 }
668 
IMPL_LINK(ScCondFormatDlg,EdRangeModifyHdl,formula::RefEdit &,rEdit,void)669 IMPL_LINK(ScCondFormatDlg, EdRangeModifyHdl, formula::RefEdit&, rEdit, void)
670 {
671     OUString aRangeStr = rEdit.GetText();
672     ScRangeList aRange;
673     ScRefFlags nFlags = aRange.Parse(aRangeStr, mpViewData->GetDocument(),
674         mpViewData->GetDocument()->GetAddressConvention());
675     if(nFlags & ScRefFlags::VALID)
676     {
677         rEdit.GetWidget()->set_message_type(weld::EntryMessageType::Normal);
678         mxBtnOk->set_sensitive(true);
679     }
680     else
681     {
682         rEdit.GetWidget()->set_message_type(weld::EntryMessageType::Error);
683         mxBtnOk->set_sensitive(false);
684     }
685 
686     updateTitle();
687 }
688 
IMPL_LINK(ScCondFormatDlg,RangeGetFocusHdl,formula::RefEdit &,rControl,void)689 IMPL_LINK(ScCondFormatDlg, RangeGetFocusHdl, formula::RefEdit&, rControl, void)
690 {
691     mpLastEdit = &rControl;
692 }
693 
IMPL_LINK(ScCondFormatDlg,BtnPressedHdl,weld::Button &,rBtn,void)694 IMPL_LINK( ScCondFormatDlg, BtnPressedHdl, weld::Button&, rBtn, void)
695 {
696     if (&rBtn == mxBtnOk.get())
697         OkPressed();
698     else if (&rBtn == mxBtnCancel.get())
699         CancelPressed();
700 }
701 
702 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
703