summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/condformat
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/condformat')
-rw-r--r--sc/source/ui/condformat/colorformat.cxx302
-rw-r--r--sc/source/ui/condformat/condformatdlg.cxx703
-rw-r--r--sc/source/ui/condformat/condformatdlgentry.cxx1526
-rw-r--r--sc/source/ui/condformat/condformatdlgitem.cxx66
-rw-r--r--sc/source/ui/condformat/condformathelper.cxx229
-rw-r--r--sc/source/ui/condformat/condformatmgr.cxx169
6 files changed, 2995 insertions, 0 deletions
diff --git a/sc/source/ui/condformat/colorformat.cxx b/sc/source/ui/condformat/colorformat.cxx
new file mode 100644
index 000000000..a5935d48e
--- /dev/null
+++ b/sc/source/ui/condformat/colorformat.cxx
@@ -0,0 +1,302 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <colorformat.hxx>
+#include <colorscale.hxx>
+
+#include <document.hxx>
+
+#include <svx/colorbox.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+namespace {
+
+void SetType(const ScColorScaleEntry* pEntry, weld::ComboBox& rLstBox)
+{
+ rLstBox.set_active(pEntry->GetType());
+}
+
+void GetType(const weld::ComboBox& rLstBox, const weld::Entry& rEd, ScColorScaleEntry* pEntry, SvNumberFormatter* pNumberFormatter,
+ ScDocument* pDoc, const ScAddress& rPos )
+{
+ double nVal = 0;
+ sal_uInt32 nIndex = 0;
+ pEntry->SetType(static_cast<ScColorScaleEntryType>(rLstBox.get_active()));
+ switch (rLstBox.get_active())
+ {
+ case COLORSCALE_AUTO:
+ case COLORSCALE_MIN:
+ case COLORSCALE_MAX:
+ break;
+ case COLORSCALE_PERCENTILE:
+ case COLORSCALE_VALUE:
+ case COLORSCALE_PERCENT:
+ (void)pNumberFormatter->IsNumberFormat( rEd.get_text(), nIndex, nVal );
+ pEntry->SetValue(nVal);
+ break;
+ case COLORSCALE_FORMULA:
+ pEntry->SetFormula(rEd.get_text(), pDoc, rPos);
+ break;
+ }
+}
+
+OUString convertNumberToString(double nVal, const ScDocument* pDoc)
+{
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ OUString aText;
+ pNumberFormatter->GetInputLineString(nVal, 0, aText);
+ return aText;
+}
+
+void SetValue( const ScDocument* pDoc, const ScColorScaleEntry* pEntry, weld::Entry& rEdit)
+{
+ if(pEntry->GetType() == COLORSCALE_FORMULA)
+ rEdit.set_text(pEntry->GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
+ else if(pEntry->GetType() != COLORSCALE_MIN && pEntry->GetType() != COLORSCALE_MAX)
+ rEdit.set_text(convertNumberToString(pEntry->GetValue(), pDoc));
+ else
+ rEdit.set_sensitive(false);
+}
+
+}
+
+ScDataBarSettingsDlg::ScDataBarSettingsDlg(weld::Window* pParent, const ScDataBarFormatData& rData, ScDocument* pDoc, const ScAddress& rPos)
+ : GenericDialogController(pParent, "modules/scalc/ui/databaroptions.ui", "DataBarOptions")
+ , mpNumberFormatter(pDoc->GetFormatTable())
+ , mpDoc(pDoc)
+ , maPos(rPos)
+ , mxBtnOk(m_xBuilder->weld_button("ok"))
+ , mxBtnCancel(m_xBuilder->weld_button("cancel"))
+ , mxLbPos(new ColorListBox(m_xBuilder->weld_menu_button("positive_colour"), pParent))
+ , mxLbNeg(new ColorListBox(m_xBuilder->weld_menu_button("negative_colour"), pParent))
+ , mxLbAxisCol(new ColorListBox(m_xBuilder->weld_menu_button("axis_colour"), pParent))
+ , mxLbFillType(m_xBuilder->weld_combo_box("fill_type"))
+ , mxLbTypeMin(m_xBuilder->weld_combo_box("min"))
+ , mxLbTypeMax(m_xBuilder->weld_combo_box("max"))
+ , mxLbAxisPos(m_xBuilder->weld_combo_box("axis_pos"))
+ , mxEdMin(m_xBuilder->weld_entry("min_value"))
+ , mxEdMax(m_xBuilder->weld_entry("max_value"))
+ , mxLenMin(m_xBuilder->weld_entry("min_length"))
+ , mxLenMax(m_xBuilder->weld_entry("max_length"))
+ , mxCbOnlyBar(m_xBuilder->weld_check_button("only_bar"))
+ , mxStrSameValueFT(m_xBuilder->weld_label("str_same_value"))
+{
+ maStrWarnSameValue = mxStrSameValueFT->get_label();
+
+ Init();
+
+ mxLbPos->SelectEntry(rData.maPositiveColor);
+ mxLbFillType->set_active( rData.mbGradient ? 1 : 0 );
+ if (rData.mpNegativeColor)
+ mxLbNeg->SelectEntry(*rData.mpNegativeColor);
+
+ switch (rData.meAxisPosition)
+ {
+ case databar::NONE:
+ mxLbAxisPos->set_active(2);
+ break;
+ case databar::AUTOMATIC:
+ mxLbAxisPos->set_active(0);
+ break;
+ case databar::MIDDLE:
+ mxLbAxisPos->set_active(1);
+ break;
+ }
+ ::SetType(rData.mpLowerLimit.get(), *mxLbTypeMin);
+ ::SetType(rData.mpUpperLimit.get(), *mxLbTypeMax);
+ SetValue(mpDoc, rData.mpLowerLimit.get(), *mxEdMin);
+ SetValue(mpDoc, rData.mpUpperLimit.get(), *mxEdMax);
+ mxLenMin->set_text(convertNumberToString(rData.mnMinLength, mpDoc));
+ mxLenMax->set_text(convertNumberToString(rData.mnMaxLength, mpDoc));
+ mxLbAxisCol->SelectEntry(rData.maAxisColor);
+ mxCbOnlyBar->set_active(rData.mbOnlyBar);
+
+ TypeSelectHdl(*mxLbTypeMin);
+ PosSelectHdl(*mxLbTypeMin);
+}
+
+ScDataBarSettingsDlg::~ScDataBarSettingsDlg()
+{
+}
+
+void ScDataBarSettingsDlg::Init()
+{
+ mxLbNeg->SelectEntry(COL_LIGHTRED);
+ mxLbAxisCol->SelectEntry(COL_BLACK);
+ mxLbPos->SelectEntry(0x2a6099);
+ mxBtnOk->connect_clicked( LINK( this, ScDataBarSettingsDlg, OkBtnHdl ) );
+
+ mxLbTypeMin->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
+ mxLbTypeMax->connect_changed( LINK( this, ScDataBarSettingsDlg, TypeSelectHdl ) );
+ mxLbAxisPos->connect_changed( LINK( this, ScDataBarSettingsDlg, PosSelectHdl ) );
+
+}
+
+namespace {
+
+void GetAxesPosition(ScDataBarFormatData* pData, const weld::ComboBox& rLbox)
+{
+ switch (rLbox.get_active())
+ {
+ case 0:
+ pData->meAxisPosition = databar::AUTOMATIC;
+ break;
+ case 1:
+ pData->meAxisPosition = databar::MIDDLE;
+ break;
+ case 2:
+ pData->meAxisPosition = databar::NONE;
+ break;
+ }
+}
+
+void SetBarLength(ScDataBarFormatData* pData, const OUString& minStr, const OUString& maxStr, SvNumberFormatter* mpNumberFormatter)
+{
+ double nMinValue = 0;
+ sal_uInt32 nIndex = 0;
+ (void)mpNumberFormatter->IsNumberFormat(minStr, nIndex, nMinValue);
+ nIndex = 0;
+ double nMaxValue = 0;
+ (void)mpNumberFormatter->IsNumberFormat(maxStr, nIndex, nMaxValue);
+ pData->mnMinLength = nMinValue;
+ pData->mnMaxLength = nMaxValue;
+}
+
+}
+
+ScDataBarFormatData* ScDataBarSettingsDlg::GetData()
+{
+ ScDataBarFormatData* pData = new ScDataBarFormatData();
+ pData->maPositiveColor = mxLbPos->GetSelectEntryColor();
+ pData->mpNegativeColor.reset(new Color(mxLbNeg->GetSelectEntryColor()));
+ pData->mbGradient = ( mxLbFillType->get_active() == 1 );
+ pData->mpUpperLimit.reset(new ScColorScaleEntry());
+ pData->mpLowerLimit.reset(new ScColorScaleEntry());
+ pData->maAxisColor = mxLbAxisCol->GetSelectEntryColor();
+ pData->mbOnlyBar = mxCbOnlyBar->get_active();
+
+ ::GetType(*mxLbTypeMin, *mxEdMin, pData->mpLowerLimit.get(), mpNumberFormatter, mpDoc, maPos);
+ ::GetType(*mxLbTypeMax, *mxEdMax, pData->mpUpperLimit.get(), mpNumberFormatter, mpDoc, maPos);
+ GetAxesPosition(pData, *mxLbAxisPos);
+ SetBarLength(pData, mxLenMin->get_text(), mxLenMax->get_text(), mpNumberFormatter);
+
+ return pData;
+}
+
+IMPL_LINK_NOARG(ScDataBarSettingsDlg, OkBtnHdl, weld::Button&, void)
+{
+ //check that min < max
+ bool bWarn = false;
+ int nSelectMin = mxLbTypeMin->get_active();
+ if( nSelectMin == COLORSCALE_MAX )
+ bWarn = true;
+ int nSelectMax = mxLbTypeMax->get_active();
+ if( nSelectMax == COLORSCALE_MIN )
+ bWarn = true;
+ if(!bWarn) // databar length checks
+ {
+ OUString aMinString = mxLenMin->get_text();
+ OUString aMaxString = mxLenMax->get_text();
+ double nMinValue = 0;
+ sal_uInt32 nIndex = 0;
+ (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
+ nIndex = 0;
+ double nMaxValue = 0;
+ (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
+ if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue || nMaxValue > 100 || nMinValue < 0)
+ bWarn = true;
+ }
+ if (!bWarn && mxLbTypeMin->get_active() == mxLbTypeMax->get_active())
+ {
+
+ if(nSelectMax != COLORSCALE_FORMULA && nSelectMax != COLORSCALE_AUTO)
+ {
+ OUString aMinString = mxEdMin->get_text();
+ OUString aMaxString = mxEdMax->get_text();
+ double nMinValue = 0;
+ sal_uInt32 nIndex = 0;
+ (void)mpNumberFormatter->IsNumberFormat(aMinString, nIndex, nMinValue);
+ nIndex = 0;
+ double nMaxValue = 0;
+ (void)mpNumberFormatter->IsNumberFormat(aMaxString, nIndex, nMaxValue);
+ if(rtl::math::approxEqual(nMinValue, nMaxValue) || nMinValue > nMaxValue)
+ bWarn = true;
+ }
+ }
+
+ if(bWarn)
+ {
+ //show warning message and don't close
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ maStrWarnSameValue));
+ xWarn->run();
+ }
+ else
+ {
+ m_xDialog->response(RET_OK);
+ }
+}
+
+IMPL_LINK_NOARG(ScDataBarSettingsDlg, TypeSelectHdl, weld::ComboBox&, void)
+{
+ int nSelectMin = mxLbTypeMin->get_active();
+ if( nSelectMin <= COLORSCALE_MAX)
+ mxEdMin->set_sensitive(false);
+ else
+ {
+ mxEdMin->set_sensitive(true);
+ if(mxEdMin->get_text().isEmpty())
+ {
+ if(nSelectMin == COLORSCALE_PERCENTILE || nSelectMin == COLORSCALE_PERCENT)
+ mxEdMin->set_text(OUString::number(50));
+ else
+ mxEdMin->set_text(OUString::number(0));
+ }
+ }
+
+ int nSelectMax = mxLbTypeMax->get_active();
+ if (nSelectMax <= COLORSCALE_MAX)
+ mxEdMax->set_sensitive(false);
+ else
+ {
+ mxEdMax->set_sensitive(true);
+ if (mxEdMax->get_text().isEmpty())
+ {
+ if(nSelectMax == COLORSCALE_PERCENTILE || nSelectMax == COLORSCALE_PERCENT)
+ mxEdMax->set_text(OUString::number(50));
+ else
+ mxEdMax->set_text(OUString::number(0));
+ }
+ }
+}
+
+IMPL_LINK_NOARG(ScDataBarSettingsDlg, PosSelectHdl, weld::ComboBox&, void)
+{
+ int axisPos = mxLbAxisPos->get_active();
+ if(axisPos != 2 && axisPos != 1) // disable if axis vertical position is automatic
+ {
+ mxLenMin->set_sensitive(false);
+ mxLenMax->set_sensitive(false);
+ }
+ else
+ {
+ mxLenMin->set_sensitive(true);
+ mxLenMax->set_sensitive(true);
+ if(mxLenMin->get_text().isEmpty())
+ {
+ mxLenMin->set_text(OUString::number(0));
+ mxLenMax->set_text(OUString::number(100));
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+
diff --git a/sc/source/ui/condformat/condformatdlg.cxx b/sc/source/ui/condformat/condformatdlg.cxx
new file mode 100644
index 000000000..d38d70d2a
--- /dev/null
+++ b/sc/source/ui/condformat/condformatdlg.cxx
@@ -0,0 +1,703 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <comphelper/lok.hxx>
+#include <condformatdlg.hxx>
+
+#include <sfx2/dispatch.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <anyrefdg.hxx>
+#include <document.hxx>
+#include <conditio.hxx>
+#include <tabvwsh.hxx>
+#include <colorscale.hxx>
+#include <reffact.hxx>
+#include <docsh.hxx>
+#include <docfunc.hxx>
+#include <condformatdlgentry.hxx>
+#include <condformatdlgitem.hxx>
+
+ScCondFormatList::ScCondFormatList(ScCondFormatDlg* pDialogParent,
+ std::unique_ptr<weld::ScrolledWindow> xWindow,
+ std::unique_ptr<weld::Container> xGrid)
+ : mxScrollWindow(std::move(xWindow))
+ , mxGrid(std::move(xGrid))
+ , mbFrozen(false)
+ , mbNewEntry(false)
+ , mpDoc(nullptr)
+ , mpDialogParent(pDialogParent)
+{
+ mxScrollWindow->set_size_request(mxScrollWindow->get_approximate_digit_width() * 85,
+ mxScrollWindow->get_text_height() * 23);
+ mxGrid->set_stack_background();
+}
+
+weld::Window* ScCondFormatList::GetFrameWeld()
+{
+ return mpDialogParent->getDialog();
+}
+
+ScCondFormatList::~ScCondFormatList()
+{
+ Freeze();
+}
+
+void ScCondFormatList::init(ScDocument* pDoc,
+ const ScConditionalFormat* pFormat, const ScRangeList& rRanges,
+ const ScAddress& rPos, condformat::dialog::ScCondFormatDialogType eType)
+{
+ mpDoc = pDoc;
+ maPos = rPos;
+ maRanges = rRanges;
+
+ Freeze();
+
+ if(pFormat)
+ {
+ size_t nCount = pFormat->size();
+ for (size_t nIndex = 0; nIndex < nCount; ++nIndex)
+ {
+ const ScFormatEntry* pEntry = pFormat->GetEntry(nIndex);
+ switch(pEntry->GetType())
+ {
+ case ScFormatEntry::Type::Condition:
+ case ScFormatEntry::Type::ExtCondition:
+ {
+ const ScCondFormatEntry* pConditionEntry = static_cast<const ScCondFormatEntry*>( pEntry );
+ if(pConditionEntry->GetOperation() != ScConditionMode::Direct)
+ maEntries.emplace_back(new ScConditionFrmtEntry( this, mpDoc, mpDialogParent, maPos, pConditionEntry ) );
+ else
+ maEntries.emplace_back(new ScFormulaFrmtEntry( this, mpDoc, mpDialogParent, maPos, pConditionEntry ) );
+
+ }
+ break;
+ case ScFormatEntry::Type::Colorscale:
+ {
+ const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>( pEntry );
+ if( pColorScale->size() == 2 )
+ maEntries.emplace_back(new ScColorScale2FrmtEntry( this, mpDoc, maPos, pColorScale ) );
+ else
+ maEntries.emplace_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos, pColorScale ) );
+ }
+ break;
+ case ScFormatEntry::Type::Databar:
+ maEntries.emplace_back(new ScDataBarFrmtEntry( this, mpDoc, maPos, static_cast<const ScDataBarFormat*>( pEntry ) ) );
+ break;
+ case ScFormatEntry::Type::Iconset:
+ maEntries.emplace_back(new ScIconSetFrmtEntry( this, mpDoc, maPos, static_cast<const ScIconSetFormat*>( pEntry ) ) );
+ break;
+ case ScFormatEntry::Type::Date:
+ maEntries.emplace_back(new ScDateFrmtEntry( this, mpDoc, static_cast<const ScCondDateFormatEntry*>( pEntry ) ) );
+ break;
+ }
+ }
+ if(nCount)
+ EntrySelectHdl(*maEntries[0]);
+ }
+ else
+ {
+ switch(eType)
+ {
+ case condformat::dialog::CONDITION:
+ maEntries.emplace_back(new ScConditionFrmtEntry( this, mpDoc, mpDialogParent, maPos ));
+ break;
+ case condformat::dialog::COLORSCALE:
+ maEntries.emplace_back(new ScColorScale3FrmtEntry( this, mpDoc, maPos ));
+ break;
+ case condformat::dialog::DATABAR:
+ maEntries.emplace_back(new ScDataBarFrmtEntry( this, mpDoc, maPos ));
+ break;
+ case condformat::dialog::ICONSET:
+ maEntries.emplace_back(new ScIconSetFrmtEntry( this, mpDoc, maPos ));
+ break;
+ case condformat::dialog::DATE:
+ maEntries.emplace_back(new ScDateFrmtEntry( this, mpDoc ));
+ break;
+ case condformat::dialog::NONE:
+ break;
+ }
+ mbNewEntry = true;
+ }
+ Thaw();
+ RecalcAll();
+ if (!maEntries.empty())
+ {
+ (*maEntries.begin())->SetActive();
+ mpDialogParent->OnSelectionChange(0, maEntries.size());
+ }
+
+ RecalcAll();
+}
+
+void ScCondFormatList::SetRange(const ScRangeList& rRange)
+{
+ maRanges = rRange;
+}
+
+std::unique_ptr<ScConditionalFormat> ScCondFormatList::GetConditionalFormat() const
+{
+ if(maEntries.empty())
+ return nullptr;
+
+ std::unique_ptr<ScConditionalFormat> pFormat(new ScConditionalFormat(0, mpDoc));
+ pFormat->SetRange(maRanges);
+
+ for(auto & rEntry: maEntries)
+ {
+ // tdf#119178: Sometimes initial apply-to range (the one this dialog
+ // was opened with) is different from the final apply-to range
+ // (as edited by the user)
+
+ // If this format entry is new, take top-left corner of the final range
+ // and use it to create the initial entry (token array therein, if applicable)
+ if (mbNewEntry)
+ rEntry->SetPos(maRanges.GetTopLeftCorner());
+ // else do nothing: setting new position when editing recompiles formulas
+ // in entries and nobody wants that
+
+ ScFormatEntry* pEntry = rEntry->GetEntry();
+ if(pEntry)
+ pFormat->AddEntry(pEntry);
+ }
+
+ return pFormat;
+}
+
+void ScCondFormatList::RecalcAll()
+{
+ if (mbFrozen)
+ return;
+
+ sal_Int32 nIndex = 1;
+ for (const auto& item : maEntries)
+ {
+ if (!item)
+ continue;
+ item->SetIndex(nIndex);
+ item->set_grid_top_attach(nIndex - 1);
+ ++nIndex;
+ }
+}
+
+IMPL_LINK(ScCondFormatList, ColFormatTypeHdl, weld::ComboBox&, rBox, void)
+{
+ Application::PostUserEvent(LINK(this, ScCondFormatList, AfterColFormatTypeHdl), &rBox);
+}
+
+IMPL_LINK(ScCondFormatList, AfterColFormatTypeHdl, void*, p, void)
+{
+ weld::ComboBox* pBox = static_cast<weld::ComboBox*>(p);
+ EntryContainer::iterator itr = std::find_if(maEntries.begin(), maEntries.end(),
+ [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
+ if(itr == maEntries.end())
+ return;
+
+ sal_Int32 nPos = pBox->get_active();
+ switch(nPos)
+ {
+ case 0:
+ if((*itr)->GetType() == condformat::entry::COLORSCALE2)
+ return;
+
+ Freeze();
+ itr->reset(new ScColorScale2FrmtEntry(this, mpDoc, maPos));
+ break;
+ case 1:
+ if((*itr)->GetType() == condformat::entry::COLORSCALE3)
+ return;
+
+ Freeze();
+ itr->reset(new ScColorScale3FrmtEntry(this, mpDoc, maPos));
+ break;
+ case 2:
+ if((*itr)->GetType() == condformat::entry::DATABAR)
+ return;
+
+ Freeze();
+ itr->reset(new ScDataBarFrmtEntry(this, mpDoc, maPos));
+ break;
+ case 3:
+ if((*itr)->GetType() == condformat::entry::ICONSET)
+ return;
+
+ Freeze();
+ itr->reset(new ScIconSetFrmtEntry(this, mpDoc, maPos));
+ break;
+ default:
+ break;
+ }
+ mpDialogParent->InvalidateRefData();
+ (*itr)->SetActive();
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK(ScCondFormatList, TypeListHdl, weld::ComboBox&, rBox, void)
+{
+ //Resolves: fdo#79021 At this point we are still inside the ListBox Select.
+ //If we call maEntries.replace here then the pBox will be deleted before it
+ //has finished Select and will crash on accessing its deleted this. So Post
+ //to do the real work after the Select has completed
+ Application::PostUserEvent(LINK(this, ScCondFormatList, AfterTypeListHdl), &rBox);
+}
+
+IMPL_LINK(ScCondFormatList, AfterTypeListHdl, void*, p, void)
+{
+ weld::ComboBox* pBox = static_cast<weld::ComboBox*>(p);
+ EntryContainer::iterator itr = std::find_if(maEntries.begin(), maEntries.end(),
+ [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
+ if(itr == maEntries.end())
+ return;
+
+ sal_Int32 nPos = pBox->get_active();
+ switch(nPos)
+ {
+ case 0:
+ switch((*itr)->GetType())
+ {
+ case condformat::entry::FORMULA:
+ case condformat::entry::CONDITION:
+ case condformat::entry::DATE:
+ break;
+ case condformat::entry::COLORSCALE2:
+ case condformat::entry::COLORSCALE3:
+ case condformat::entry::DATABAR:
+ case condformat::entry::ICONSET:
+ return;
+ }
+ Freeze();
+ itr->reset(new ScColorScale3FrmtEntry(this, mpDoc, maPos));
+ mpDialogParent->InvalidateRefData();
+ (*itr)->SetActive();
+ break;
+ case 1:
+ if((*itr)->GetType() == condformat::entry::CONDITION)
+ return;
+
+ Freeze();
+ itr->reset(new ScConditionFrmtEntry(this, mpDoc, mpDialogParent, maPos));
+ mpDialogParent->InvalidateRefData();
+ (*itr)->SetActive();
+ break;
+ case 2:
+ if((*itr)->GetType() == condformat::entry::FORMULA)
+ return;
+
+ Freeze();
+ itr->reset(new ScFormulaFrmtEntry(this, mpDoc, mpDialogParent, maPos));
+ mpDialogParent->InvalidateRefData();
+ (*itr)->SetActive();
+ break;
+ case 3:
+ if((*itr)->GetType() == condformat::entry::DATE)
+ return;
+
+ Freeze();
+ itr->reset(new ScDateFrmtEntry( this, mpDoc ));
+ mpDialogParent->InvalidateRefData();
+ (*itr)->SetActive();
+ break;
+
+ }
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK_NOARG( ScCondFormatList, AddBtnHdl, weld::Button&, void )
+{
+ Freeze();
+ maEntries.emplace_back(new ScConditionFrmtEntry(this, mpDoc, mpDialogParent, maPos));
+ for(auto& rxEntry : maEntries)
+ {
+ rxEntry->SetInactive();
+ }
+ mpDialogParent->InvalidateRefData();
+ maEntries.back()->SetActive();
+ mpDialogParent->OnSelectionChange(maEntries.size() - 1, maEntries.size());
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK_NOARG( ScCondFormatList, RemoveBtnHdl, weld::Button&, void )
+{
+ Freeze();
+ auto itr = std::find_if(maEntries.begin(), maEntries.end(),
+ [](const std::unique_ptr<ScCondFrmtEntry>& widget) { return widget->IsSelected(); });
+ if (itr != maEntries.end())
+ {
+ maEntries.erase(itr);
+ }
+ mpDialogParent->InvalidateRefData();
+ mpDialogParent->OnSelectionChange(0, maEntries.size(), false);
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK_NOARG(ScCondFormatList, UpBtnHdl, weld::Button&, void)
+{
+ Freeze();
+ size_t index = 0;
+ for (size_t i = 0; i < maEntries.size(); i++)
+ {
+ auto& widget = maEntries[i];
+ if (widget->IsSelected() && i > 0)
+ {
+ std::swap(maEntries[i], maEntries[i - 1]);
+ index = i - 1;
+ break;
+ }
+ }
+ mpDialogParent->InvalidateRefData();
+ mpDialogParent->OnSelectionChange(index, maEntries.size());
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK_NOARG(ScCondFormatList, DownBtnHdl, weld::Button&, void)
+{
+ Freeze();
+ size_t index = 0;
+ for (size_t i = 0; i < maEntries.size(); i++)
+ {
+ auto& widget = maEntries[i];
+ if (widget->IsSelected())
+ {
+ index = i;
+ if (i < maEntries.size()-1)
+ {
+ std::swap(maEntries[i], maEntries[i + 1]);
+ index = i + 1;
+ break;
+ }
+ }
+ }
+ mpDialogParent->InvalidateRefData();
+ mpDialogParent->OnSelectionChange(index, maEntries.size());
+ Thaw();
+ RecalcAll();
+}
+
+IMPL_LINK( ScCondFormatList, EntrySelectHdl, ScCondFrmtEntry&, rEntry, void )
+{
+ if(rEntry.IsSelected())
+ return;
+
+ Freeze();
+ size_t index = 0;
+ for(size_t i = 0; i < maEntries.size(); i++)
+ {
+ if (maEntries[i].get() == &rEntry)
+ {
+ index = i;
+ }
+ maEntries[i]->SetInactive();
+ }
+ mpDialogParent->InvalidateRefData();
+ mpDialogParent->OnSelectionChange(index, maEntries.size());
+ rEntry.SetActive();
+ Thaw();
+ RecalcAll();
+}
+
+ScCondFormatDlg::ScCondFormatDlg(SfxBindings* pB, SfxChildWindow* pCW,
+ weld::Window* pParent, ScViewData* pViewData,
+ const ScCondFormatDlgItem* pItem)
+ : ScAnyRefDlgController(pB, pCW, pParent,
+ (SfxViewShell::Current() && SfxViewShell::Current()->isLOKMobilePhone())?OUString("modules/scalc/ui/conditionalformatdialogmobile.ui"):OUString("modules/scalc/ui/conditionalformatdialog.ui"),
+ "ConditionalFormatDialog")
+ , mpViewData(pViewData)
+ , mpDlgItem(pItem->Clone())
+ , mpLastEdit(nullptr)
+ , mxBtnOk(m_xBuilder->weld_button("ok"))
+ , mxBtnAdd(m_xBuilder->weld_button("add"))
+ , mxBtnRemove(m_xBuilder->weld_button("delete"))
+ , mxBtnUp(m_xBuilder->weld_button("up"))
+ , mxBtnDown(m_xBuilder->weld_button("down"))
+ , mxBtnCancel(m_xBuilder->weld_button("cancel"))
+ , mxFtRange(m_xBuilder->weld_label("ftassign"))
+ , mxEdRange(new formula::RefEdit(m_xBuilder->weld_entry("edassign")))
+ , mxRbRange(new formula::RefButton(m_xBuilder->weld_button("rbassign")))
+ , mxCondFormList(new ScCondFormatList(this, m_xBuilder->weld_scrolled_window("listwindow"),
+ m_xBuilder->weld_container("list")))
+{
+ mxEdRange->SetReferences(this, mxFtRange.get());
+ mxRbRange->SetReferences(this, mxEdRange.get());
+
+ ScConditionalFormat* pFormat = nullptr;
+ mnKey = mpDlgItem->GetIndex();
+ if (mpDlgItem->IsManaged() && mpDlgItem->GetConditionalFormatList())
+ {
+ pFormat = mpDlgItem->GetConditionalFormatList()->GetFormat(mnKey);
+ }
+ else if (!mpDlgItem->IsManaged())
+ {
+ ScDocument* pDoc = mpViewData->GetDocument();
+ pFormat = pDoc->GetCondFormList(mpViewData->GetTabNo())->GetFormat ( mnKey );
+ }
+
+ ScRangeList aRange;
+ if (pFormat)
+ {
+ aRange = pFormat->GetRange();
+ }
+ else
+ {
+ // this is for adding a new entry
+ mpViewData->GetMarkData().FillRangeListWithMarks(&aRange, false);
+ if(aRange.empty())
+ {
+ ScAddress aPos(mpViewData->GetCurX(), mpViewData->GetCurY(), mpViewData->GetTabNo());
+ aRange.push_back(ScRange(aPos));
+ }
+ mnKey = 0;
+ }
+ maPos = aRange.GetTopLeftCorner();
+
+ mxCondFormList->init(mpViewData->GetDocument(), pFormat, aRange, maPos, mpDlgItem->GetDialogType());
+
+ mxBtnOk->connect_clicked(LINK(this, ScCondFormatDlg, BtnPressedHdl ) );
+ mxBtnAdd->connect_clicked( LINK( mxCondFormList.get(), ScCondFormatList, AddBtnHdl ) );
+ mxBtnRemove->connect_clicked( LINK( mxCondFormList.get(), ScCondFormatList, RemoveBtnHdl ) );
+ mxBtnUp->connect_clicked(LINK(mxCondFormList.get(), ScCondFormatList, UpBtnHdl));
+ mxBtnDown->connect_clicked(LINK(mxCondFormList.get(), ScCondFormatList, DownBtnHdl));
+ mxBtnCancel->connect_clicked( LINK(this, ScCondFormatDlg, BtnPressedHdl ) );
+ mxEdRange->SetModifyHdl( LINK( this, ScCondFormatDlg, EdRangeModifyHdl ) );
+ mxEdRange->SetGetFocusHdl( LINK( this, ScCondFormatDlg, RangeGetFocusHdl ) );
+
+ OUString aRangeString;
+ const ScDocument* pDoc = pViewData->GetDocument();
+ aRange.Format(aRangeString, ScRefFlags::VALID, *pDoc, pDoc->GetAddressConvention());
+ mxEdRange->SetText(aRangeString);
+
+ msBaseTitle = m_xDialog->get_title();
+ updateTitle();
+}
+
+void ScCondFormatDlg::updateTitle()
+{
+ OUString aTitle = msBaseTitle + " " + mxEdRange->GetText();
+
+ m_xDialog->set_title(aTitle);
+}
+
+ScCondFormatDlg::~ScCondFormatDlg()
+{
+}
+
+void ScCondFormatDlg::SetActive()
+{
+ if(mpLastEdit)
+ mpLastEdit->GrabFocus();
+ else
+ mxEdRange->GrabFocus();
+
+ RefInputDone();
+}
+
+void ScCondFormatDlg::RefInputDone( bool bForced )
+{
+ ScAnyRefDlgController::RefInputDone(bForced);
+
+ // ScAnyRefModalDlg::RefInputDone resets the title back
+ // to its original state.
+ // I.e. if we open the dialog normally, and then click into the sheet
+ // to modify the selection, the title is updated such that the range
+ // is only a single cell (e.g. $A$1), after which the dialog switches
+ // into the RefInput mode. During the RefInput mode the title is updated
+ // as expected, however at the end RefInputDone overwrites the title
+ // with the initial (now incorrect) single cell range. Hence we correct
+ // it here.
+ updateTitle();
+}
+
+bool ScCondFormatDlg::IsTableLocked() const
+{
+ return !mpLastEdit || mpLastEdit == mxEdRange.get();
+}
+
+bool ScCondFormatDlg::IsRefInputMode() const
+{
+ return mxEdRange->GetWidget()->get_sensitive();
+}
+
+void ScCondFormatDlg::SetReference(const ScRange& rRef, ScDocument&)
+{
+ formula::RefEdit* pEdit = mpLastEdit;
+ if (!mpLastEdit)
+ pEdit = mxEdRange.get();
+
+ if (pEdit->GetWidget()->get_sensitive())
+ {
+ if(rRef.aStart != rRef.aEnd)
+ RefInputStart(pEdit);
+
+ ScRefFlags nFlags;
+ if (mpLastEdit && mpLastEdit != mxEdRange.get())
+ nFlags = ScRefFlags::RANGE_ABS_3D;
+ else
+ nFlags = ScRefFlags::RANGE_ABS;
+
+ const ScDocument* pDoc = mpViewData->GetDocument();
+ OUString aRefStr(rRef.Format(*pDoc, nFlags,
+ ScAddress::Details(pDoc->GetAddressConvention(), 0, 0)));
+ if (pEdit != mxEdRange.get())
+ {
+ Selection sel = pEdit->GetSelection();
+ sel.Justify(); // in case of RTL selection
+ sel.Max() = sel.Min() + aRefStr.getLength();
+ pEdit->GetWidget()->replace_selection(aRefStr);
+ pEdit->SetSelection(sel); // to replace it again with next drag event
+ }
+ else
+ pEdit->SetRefString( aRefStr );
+ updateTitle();
+ }
+}
+
+std::unique_ptr<ScConditionalFormat> ScCondFormatDlg::GetConditionalFormat() const
+{
+ OUString aRangeStr = mxEdRange->GetText();
+ if(aRangeStr.isEmpty())
+ return nullptr;
+
+ ScRangeList aRange;
+ ScRefFlags nFlags = aRange.Parse(aRangeStr, mpViewData->GetDocument(),
+ mpViewData->GetDocument()->GetAddressConvention(), maPos.Tab());
+ mxCondFormList->SetRange(aRange);
+ std::unique_ptr<ScConditionalFormat> pFormat = mxCondFormList->GetConditionalFormat();
+
+ if((nFlags & ScRefFlags::VALID) && !aRange.empty() && pFormat)
+ pFormat->SetRange(aRange);
+ else
+ pFormat.reset();
+
+ return pFormat;
+}
+
+void ScCondFormatDlg::InvalidateRefData()
+{
+ mpLastEdit = nullptr;
+}
+
+// Close the Conditional Format Dialog
+//
+void ScCondFormatDlg::Close()
+{
+ DoClose( ScCondFormatDlgWrapper::GetChildWindowId() );
+}
+
+// Occurs when the Conditional Format Dialog the OK button is pressed.
+//
+void ScCondFormatDlg::OkPressed()
+{
+ std::unique_ptr<ScConditionalFormat> pFormat = GetConditionalFormat();
+
+ if (!mpDlgItem->IsManaged())
+ {
+ if(pFormat)
+ {
+ auto& rRangeList = pFormat->GetRange();
+ mpViewData->GetDocShell()->GetDocFunc().ReplaceConditionalFormat(mnKey,
+ std::move(pFormat), maPos.Tab(), rRangeList);
+ }
+ else
+ mpViewData->GetDocShell()->GetDocFunc().ReplaceConditionalFormat(mnKey,
+ nullptr, maPos.Tab(), ScRangeList());
+ }
+ else
+ {
+ ScConditionalFormatList* pList = mpDlgItem->GetConditionalFormatList();
+ sal_uInt32 nKey = mnKey;
+ if (mnKey == 0)
+ {
+ nKey = pList->getMaxKey() + 1;
+ }
+
+ pList->erase(nKey);
+ if (pFormat)
+ {
+ pFormat->SetKey(nKey);
+ pList->InsertNew(std::move(pFormat));
+ }
+ mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem);
+
+ SetDispatcherLock( false );
+ // Queue message to open Conditional Format Manager Dialog
+ GetBindings().GetDispatcher()->Execute( SID_OPENDLG_CONDFRMT_MANAGER,
+ SfxCallMode::ASYNCHRON );
+ }
+ m_xDialog->response(RET_OK);
+}
+
+// Occurs when the Conditional Format Dialog is cancelled.
+//
+void ScCondFormatDlg::CancelPressed()
+{
+ if ( mpDlgItem->IsManaged() )
+ {
+ mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem);
+ SetDispatcherLock( false );
+ // Queue message to open Conditional Format Manager Dialog
+ GetBindings().GetDispatcher()->Execute( SID_OPENDLG_CONDFRMT_MANAGER,
+ SfxCallMode::ASYNCHRON );
+ }
+ m_xDialog->response(RET_CANCEL);
+}
+
+void ScCondFormatDlg::OnSelectionChange(size_t nIndex, size_t nSize, bool bSelected)
+{
+ if (nSize <= 1 || !bSelected)
+ {
+ mxBtnUp->set_sensitive(false);
+ mxBtnDown->set_sensitive(false);
+ }
+ else
+ {
+ mxBtnUp->set_sensitive(nIndex != 0);
+ mxBtnDown->set_sensitive(nIndex < nSize - 1);
+ }
+}
+
+IMPL_LINK(ScCondFormatDlg, EdRangeModifyHdl, formula::RefEdit&, rEdit, void)
+{
+ OUString aRangeStr = rEdit.GetText();
+ ScRangeList aRange;
+ ScRefFlags nFlags = aRange.Parse(aRangeStr, mpViewData->GetDocument(),
+ mpViewData->GetDocument()->GetAddressConvention());
+ if(nFlags & ScRefFlags::VALID)
+ {
+ rEdit.GetWidget()->set_message_type(weld::EntryMessageType::Normal);
+ mxBtnOk->set_sensitive(true);
+ }
+ else
+ {
+ rEdit.GetWidget()->set_message_type(weld::EntryMessageType::Error);
+ mxBtnOk->set_sensitive(false);
+ }
+
+ updateTitle();
+}
+
+IMPL_LINK(ScCondFormatDlg, RangeGetFocusHdl, formula::RefEdit&, rControl, void)
+{
+ mpLastEdit = &rControl;
+}
+
+IMPL_LINK( ScCondFormatDlg, BtnPressedHdl, weld::Button&, rBtn, void)
+{
+ if (&rBtn == mxBtnOk.get())
+ OkPressed();
+ else if (&rBtn == mxBtnCancel.get())
+ CancelPressed();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/condformat/condformatdlgentry.cxx b/sc/source/ui/condformat/condformatdlgentry.cxx
new file mode 100644
index 000000000..9ba1e652c
--- /dev/null
+++ b/sc/source/ui/condformat/condformatdlgentry.cxx
@@ -0,0 +1,1526 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <memory>
+#include <condformatdlg.hxx>
+#include <condformatdlgentry.hxx>
+#include <conditio.hxx>
+#include <compiler.hxx>
+#include <colorscale.hxx>
+#include <condformathelper.hxx>
+
+#include <document.hxx>
+
+#include <svl/style.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/lokhelper.hxx>
+#include <svl/stritem.hxx>
+#include <svl/intitem.hxx>
+#include <svx/colorbox.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <formula/token.hxx>
+#include <formula/errorcodes.hxx>
+#include <tokenarray.hxx>
+#include <stlpool.hxx>
+#include <tabvwsh.hxx>
+#include <unotools/charclass.hxx>
+#include <comphelper/lok.hxx>
+
+#include <colorformat.hxx>
+#include <scresid.hxx>
+#include <globstr.hrc>
+#include <strings.hrc>
+
+#include <set>
+
+// set the widget width to something to override their auto-width calc and
+// force them to take a 1/3 of the available space
+#define CommonWidgetWidth 10
+
+ScCondFrmtEntry::ScCondFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos)
+ : mpParent(pParent)
+ , mxBuilder(Application::CreateBuilder(pParent->GetContainer(), (SfxViewShell::Current() && SfxViewShell::Current()->isLOKMobilePhone())?OUString("modules/scalc/ui/conditionalentrymobile.ui"):OUString("modules/scalc/ui/conditionalentry.ui")))
+ , mxBorder(mxBuilder->weld_widget("border"))
+ , mxGrid(mxBuilder->weld_container("grid"))
+ , mxFtCondNr(mxBuilder->weld_label("number"))
+ , mxFtCondition(mxBuilder->weld_label("condition"))
+ , mbActive(false)
+ , maStrCondition(ScResId(SCSTR_CONDITION))
+ , mxLbType(mxBuilder->weld_combo_box("type"))
+ , mpDoc(pDoc)
+ , maPos(rPos)
+{
+ mxLbType->set_size_request(CommonWidgetWidth, -1);
+ mxLbType->connect_changed(LINK(pParent, ScCondFormatList, TypeListHdl));
+ mxGrid->connect_mouse_press(LINK(this, ScCondFrmtEntry, EntrySelectHdl));
+ maClickHdl = LINK( pParent, ScCondFormatList, EntrySelectHdl );
+
+ Show();
+}
+
+ScCondFrmtEntry::~ScCondFrmtEntry()
+{
+ mpParent->GetContainer()->move(mxBorder.get(), nullptr);
+}
+
+IMPL_LINK_NOARG(ScCondFrmtEntry, EntrySelectHdl, const MouseEvent&, bool)
+{
+ maClickHdl.Call(*this);
+ return false;
+}
+
+void ScCondFrmtEntry::SetIndex(sal_Int32 nIndex)
+{
+ mxFtCondNr->set_label(maStrCondition + OUString::number(nIndex));
+}
+
+void ScCondFrmtEntry::Select()
+{
+ mxFtCondition->set_label(OUString());
+ mxFtCondition->hide();
+ mxLbType->show();
+ mbActive = true;
+}
+
+void ScCondFrmtEntry::Deselect()
+{
+ OUString aCondText = GetExpressionString();
+ mxFtCondition->set_label(aCondText);
+ mxFtCondition->show();
+ mxLbType->hide();
+ mbActive = false;
+}
+
+//condition
+
+namespace {
+
+void FillStyleListBox( const ScDocument* pDoc, weld::ComboBox& rLbStyle )
+{
+ std::set<OUString> aStyleNames;
+ SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para );
+ for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle; pStyle = aStyleIter.Next() )
+ {
+ aStyleNames.insert(pStyle->GetName());
+ }
+ for(const auto& rStyleName : aStyleNames)
+ {
+ rLbStyle.append_text(rStyleName);
+ }
+}
+
+}
+
+const ScConditionMode ScConditionFrmtEntry::mpEntryToCond[ScConditionFrmtEntry::NUM_COND_ENTRIES] = {
+ ScConditionMode::Equal,
+ ScConditionMode::Less,
+ ScConditionMode::Greater,
+ ScConditionMode::EqLess,
+ ScConditionMode::EqGreater,
+ ScConditionMode::NotEqual,
+ ScConditionMode::Between,
+ ScConditionMode::NotBetween,
+ ScConditionMode::Duplicate,
+ ScConditionMode::NotDuplicate,
+ ScConditionMode::Top10,
+ ScConditionMode::Bottom10,
+ ScConditionMode::TopPercent,
+ ScConditionMode::BottomPercent,
+ ScConditionMode::AboveAverage,
+ ScConditionMode::BelowAverage,
+ ScConditionMode::AboveEqualAverage,
+ ScConditionMode::BelowEqualAverage,
+ ScConditionMode::Error,
+ ScConditionMode::NoError,
+ ScConditionMode::BeginsWith,
+ ScConditionMode::EndsWith,
+ ScConditionMode::ContainsText,
+ ScConditionMode::NotContainsText
+};
+
+ScConditionFrmtEntry::ScConditionFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent,
+ const ScAddress& rPos, const ScCondFormatEntry* pFormatEntry)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxLbCondType(mxBuilder->weld_combo_box("typeis"))
+ , mxEdVal1(new formula::RefEdit(mxBuilder->weld_entry("val1")))
+ , mxEdVal2(new formula::RefEdit(mxBuilder->weld_entry("val2")))
+ , mxFtVal(mxBuilder->weld_label("valueft"))
+ , mxFtStyle(mxBuilder->weld_label("styleft"))
+ , mxLbStyle(mxBuilder->weld_combo_box("style"))
+ , mxWdPreviewWin(mxBuilder->weld_widget("previewwin"))
+ , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview))
+ , mbIsInStyleCreate(false)
+{
+ mxLbCondType->set_size_request(CommonWidgetWidth, -1);
+ mxLbType->set_size_request(CommonWidgetWidth, -1);
+ mxWdPreview->set_size_request(-1, mxLbStyle->get_preferred_size().Height());
+
+ mxLbType->set_active(1);
+
+ Init(pDialogParent);
+
+ StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent);
+
+ if(pFormatEntry)
+ {
+ mxLbStyle->set_active_text(pFormatEntry->GetStyle());
+ StyleSelectHdl(*mxLbStyle);
+ ScConditionMode eMode = pFormatEntry->GetOperation();
+
+ mxLbCondType->set_active(ConditionModeToEntryPos(eMode));
+
+ switch(GetNumberEditFields(eMode))
+ {
+ case 0:
+ mxEdVal1->GetWidget()->hide();
+ mxEdVal2->GetWidget()->hide();
+ break;
+ case 1:
+ mxEdVal1->GetWidget()->show();
+ mxEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0));
+ mxEdVal2->GetWidget()->hide();
+ OnEdChanged(*mxEdVal1);
+ break;
+ case 2:
+ mxEdVal1->GetWidget()->show();
+ mxEdVal1->SetText(pFormatEntry->GetExpression(maPos, 0));
+ OnEdChanged(*mxEdVal1);
+ mxEdVal2->GetWidget()->show();
+ mxEdVal2->SetText(pFormatEntry->GetExpression(maPos, 1));
+ OnEdChanged(*mxEdVal2);
+ break;
+ }
+ }
+ else
+ {
+ mxLbCondType->set_active(0);
+ mxEdVal2->GetWidget()->hide();
+ mxLbStyle->set_active(1);
+ }
+}
+
+ScConditionFrmtEntry::~ScConditionFrmtEntry()
+{
+}
+
+void ScConditionFrmtEntry::Init(ScCondFormatDlg* pDialogParent)
+{
+ mxEdVal1->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );
+ mxEdVal2->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );
+
+ mxEdVal1->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) );
+ mxEdVal2->SetModifyHdl( LINK( this, ScConditionFrmtEntry, OnEdChanged ) );
+
+ FillStyleListBox( mpDoc, *mxLbStyle );
+ mxLbStyle->connect_changed( LINK( this, ScConditionFrmtEntry, StyleSelectHdl ) );
+
+ mxLbCondType->connect_changed( LINK( this, ScConditionFrmtEntry, ConditionTypeSelectHdl ) );
+}
+
+ScFormatEntry* ScConditionFrmtEntry::createConditionEntry() const
+{
+ ScConditionMode eMode = EntryPosToConditionMode(mxLbCondType->get_active());
+ OUString aExpr1 = mxEdVal1->GetText();
+ OUString aExpr2;
+ if (GetNumberEditFields(eMode) == 2)
+ {
+ aExpr2 = mxEdVal2->GetText();
+ if (aExpr2.isEmpty())
+ {
+ return nullptr;
+ }
+ }
+
+ ScFormatEntry* pEntry = new ScCondFormatEntry(eMode, aExpr1, aExpr2, mpDoc, maPos, mxLbStyle->get_active_text());
+ return pEntry;
+}
+
+IMPL_LINK(ScConditionFrmtEntry, OnEdChanged, formula::RefEdit&, rRefEdit, void)
+{
+ weld::Entry& rEdit = *rRefEdit.GetWidget();
+ OUString aFormula = rEdit.get_text();
+
+ if( aFormula.isEmpty() )
+ {
+ mxFtVal->set_label(ScResId(STR_ENTER_VALUE));
+ return;
+ }
+
+ ScCompiler aComp( mpDoc, maPos, mpDoc->GetGrammar() );
+ std::unique_ptr<ScTokenArray> ta(aComp.CompileString(aFormula));
+
+ // Error, warn the user
+ if( ta->GetCodeError() != FormulaError::NONE || ( ta->GetLen() == 0 ) )
+ {
+ rEdit.set_message_type(weld::EntryMessageType::Error);
+ mxFtVal->set_label(ScResId(STR_VALID_DEFERROR));
+ return;
+ }
+
+ // Recognized col/row name or string token, warn the user
+ formula::FormulaToken* token = ta->FirstToken();
+ formula::StackVar t = token->GetType();
+ OpCode op = token->GetOpCode();
+ if( ( op == ocColRowName ) ||
+ ( ( op == ocBad ) && ( t == formula::svString ) )
+ )
+ {
+ rEdit.set_message_type(weld::EntryMessageType::Warning);
+ mxFtVal->set_label(ScResId(STR_UNQUOTED_STRING));
+ return;
+ }
+
+ rEdit.set_message_type(weld::EntryMessageType::Normal);
+ mxFtVal->set_label("");
+}
+
+void ScConditionFrmtEntry::Select()
+{
+ mxFtVal->show();
+ ScCondFrmtEntry::Select();
+}
+
+void ScConditionFrmtEntry::Deselect()
+{
+ mxFtVal->hide();
+ ScCondFrmtEntry::Deselect();
+}
+
+sal_Int32 ScConditionFrmtEntry::ConditionModeToEntryPos( ScConditionMode eMode )
+{
+ for ( sal_Int32 i = 0; i < NUM_COND_ENTRIES; ++i )
+ {
+ if (mpEntryToCond[i] == eMode)
+ {
+ return i;
+ }
+ }
+ assert(false); // should never get here
+ return 0;
+}
+
+ScConditionMode ScConditionFrmtEntry::EntryPosToConditionMode( sal_Int32 aEntryPos )
+{
+ assert( 0 <= aEntryPos && aEntryPos < NUM_COND_ENTRIES );
+ return mpEntryToCond[aEntryPos];
+}
+
+sal_Int32 ScConditionFrmtEntry::GetNumberEditFields( ScConditionMode eMode )
+{
+ switch(eMode)
+ {
+ case ScConditionMode::Equal:
+ case ScConditionMode::Less:
+ case ScConditionMode::Greater:
+ case ScConditionMode::EqLess:
+ case ScConditionMode::EqGreater:
+ case ScConditionMode::NotEqual:
+ case ScConditionMode::Top10:
+ case ScConditionMode::Bottom10:
+ case ScConditionMode::TopPercent:
+ case ScConditionMode::BottomPercent:
+ case ScConditionMode::BeginsWith:
+ case ScConditionMode::EndsWith:
+ case ScConditionMode::ContainsText:
+ case ScConditionMode::NotContainsText:
+ case ScConditionMode::Error:
+ case ScConditionMode::NoError:
+ return 1;
+ case ScConditionMode::AboveAverage:
+ case ScConditionMode::BelowAverage:
+ case ScConditionMode::AboveEqualAverage:
+ case ScConditionMode::BelowEqualAverage:
+ case ScConditionMode::Duplicate:
+ case ScConditionMode::NotDuplicate:
+ return 0;
+ case ScConditionMode::Between:
+ case ScConditionMode::NotBetween:
+ return 2;
+ default:
+ assert(false); // should never get here
+ return 0;
+ }
+}
+
+OUString ScConditionFrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression(CONDITION, mxLbCondType->get_active(), mxEdVal1->GetText(), mxEdVal2->GetText());
+}
+
+ScFormatEntry* ScConditionFrmtEntry::GetEntry() const
+{
+ return createConditionEntry();
+}
+
+void ScConditionFrmtEntry::SetActive()
+{
+ ScConditionMode eMode = EntryPosToConditionMode(mxLbCondType->get_active());
+ mxLbCondType->show();
+ switch(GetNumberEditFields(eMode))
+ {
+ case 1:
+ mxEdVal1->GetWidget()->show();
+ break;
+ case 2:
+ mxEdVal1->GetWidget()->show();
+ mxEdVal2->GetWidget()->show();
+ break;
+ }
+ mxFtStyle->show();
+ mxLbStyle->show();
+ mxWdPreviewWin->show();
+
+ Select();
+}
+
+void ScConditionFrmtEntry::SetInactive()
+{
+ mxLbCondType->hide();
+ mxEdVal1->GetWidget()->hide();
+ mxEdVal2->GetWidget()->hide();
+ mxFtStyle->hide();
+ mxLbStyle->hide();
+ mxWdPreviewWin->hide();
+
+ Deselect();
+}
+
+namespace {
+
+void UpdateStyleList(weld::ComboBox& rLbStyle, const ScDocument* pDoc)
+{
+ OUString aSelectedStyle = rLbStyle.get_active_text();
+ for (sal_Int32 i = rLbStyle.get_count(); i > 1; --i)
+ rLbStyle.remove(i - 1);
+ FillStyleListBox(pDoc, rLbStyle);
+ rLbStyle.set_active_text(aSelectedStyle);
+}
+
+}
+
+void ScConditionFrmtEntry::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if(rHint.GetId() == SfxHintId::StyleSheetModified)
+ {
+ if(!mbIsInStyleCreate)
+ UpdateStyleList(*mxLbStyle, mpDoc);
+ }
+}
+
+namespace {
+
+void StyleSelect(weld::Window* pDialogParent, weld::ComboBox& rLbStyle, const ScDocument* pDoc, SvxFontPrevWindow& rWdPreview)
+{
+ if (rLbStyle.get_active() == 0)
+ {
+ // call new style dialog
+ SfxUInt16Item aFamilyItem( SID_STYLE_FAMILY, sal_uInt16(SfxStyleFamily::Para) );
+ SfxStringItem aRefItem( SID_STYLE_REFERENCE, ScResId(STR_STYLENAME_STANDARD) );
+ css::uno::Any aAny(pDialogParent->GetXWindow());
+ SfxUnoAnyItem aDialogParent( SID_DIALOG_PARENT, aAny );
+
+ // unlock the dispatcher so SID_STYLE_NEW can be executed
+ // (SetDispatcherLock would affect all Calc documents)
+ ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ SfxDispatcher* pDisp = pViewShell->GetDispatcher();
+ bool bLocked = pDisp->IsLocked();
+ if (bLocked)
+ pDisp->Lock(false);
+
+ // Execute the "new style" slot, complete with undo and all necessary updates.
+ // The return value (SfxUInt16Item) is ignored, look for new styles instead.
+ pDisp->ExecuteList(SID_STYLE_NEW,
+ SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
+ { &aFamilyItem, &aRefItem }, { &aDialogParent });
+
+ if (bLocked)
+ pDisp->Lock(true);
+
+ // Find the new style and add it into the style list boxes
+ SfxStyleSheetIterator aStyleIter( pDoc->GetStyleSheetPool(), SfxStyleFamily::Para );
+ bool bFound = false;
+ for ( SfxStyleSheetBase* pStyle = aStyleIter.First(); pStyle && !bFound; pStyle = aStyleIter.Next() )
+ {
+ const OUString& aName = pStyle->GetName();
+ if (rLbStyle.find_text(aName) == -1) // all lists contain the same entries
+ {
+ for( sal_Int32 i = 1, n = rLbStyle.get_count(); i <= n && !bFound; ++i)
+ {
+ OUString aStyleName = ScGlobal::getCharClassPtr()->uppercase(rLbStyle.get_text(i));
+ if( i == n )
+ {
+ rLbStyle.append_text(aName);
+ rLbStyle.set_active_text(aName);
+ bFound = true;
+ }
+ else if( aStyleName > ScGlobal::getCharClassPtr()->uppercase(aName) )
+ {
+ rLbStyle.insert_text(i, aName);
+ rLbStyle.set_active_text(aName);
+ bFound = true;
+ }
+ }
+ }
+ }
+ }
+
+ OUString aStyleName = rLbStyle.get_active_text();
+ SfxStyleSheetBase* pStyleSheet = pDoc->GetStyleSheetPool()->Find( aStyleName, SfxStyleFamily::Para );
+ if(pStyleSheet)
+ {
+ const SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ rWdPreview.SetFromItemSet(rSet, false);
+ }
+}
+
+}
+
+IMPL_LINK_NOARG(ScConditionFrmtEntry, StyleSelectHdl, weld::ComboBox&, void)
+{
+ mbIsInStyleCreate = true;
+ StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview);
+ mbIsInStyleCreate = false;
+}
+
+// formula
+
+ScFormulaFrmtEntry::ScFormulaFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, ScCondFormatDlg* pDialogParent, const ScAddress& rPos, const ScCondFormatEntry* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxFtStyle(mxBuilder->weld_label("styleft"))
+ , mxLbStyle(mxBuilder->weld_combo_box("style"))
+ , mxWdPreviewWin(mxBuilder->weld_widget("previewwin"))
+ , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview))
+ , mxEdFormula(new formula::RefEdit(mxBuilder->weld_entry("formula")))
+{
+ mxLbType->set_size_request(CommonWidgetWidth, -1);
+ mxWdPreview->set_size_request(-1, mxLbStyle->get_preferred_size().Height());
+
+ Init(pDialogParent);
+
+ mxLbType->set_active(2);
+
+ if(pFormat)
+ {
+ mxEdFormula->SetText(pFormat->GetExpression(rPos, 0, 0, pDoc->GetGrammar()));
+ mxLbStyle->set_active_text(pFormat->GetStyle());
+ }
+ else
+ {
+ mxLbStyle->set_active(1);
+ }
+
+ StyleSelectHdl(*mxLbStyle);
+}
+
+ScFormulaFrmtEntry::~ScFormulaFrmtEntry()
+{
+}
+
+void ScFormulaFrmtEntry::Init(ScCondFormatDlg* pDialogParent)
+{
+ mxEdFormula->SetGetFocusHdl( LINK( pDialogParent, ScCondFormatDlg, RangeGetFocusHdl ) );
+
+ FillStyleListBox( mpDoc, *mxLbStyle );
+ mxLbStyle->connect_changed( LINK( this, ScFormulaFrmtEntry, StyleSelectHdl ) );
+}
+
+IMPL_LINK_NOARG(ScFormulaFrmtEntry, StyleSelectHdl, weld::ComboBox&, void)
+{
+ StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview);
+}
+
+ScFormatEntry* ScFormulaFrmtEntry::createFormulaEntry() const
+{
+ OUString aFormula = mxEdFormula->GetText();
+ if(aFormula.isEmpty())
+ return nullptr;
+
+ ScFormatEntry* pEntry = new ScCondFormatEntry(ScConditionMode::Direct, aFormula, OUString(), mpDoc, maPos, mxLbStyle->get_active_text());
+ return pEntry;
+}
+
+ScFormatEntry* ScFormulaFrmtEntry::GetEntry() const
+{
+ return createFormulaEntry();
+}
+
+OUString ScFormulaFrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression(FORMULA, 0, mxEdFormula->GetText());
+}
+
+void ScFormulaFrmtEntry::SetActive()
+{
+ mxWdPreviewWin->show();
+ mxFtStyle->show();
+ mxLbStyle->show();
+ mxEdFormula->GetWidget()->show();
+
+ Select();
+}
+
+void ScFormulaFrmtEntry::SetInactive()
+{
+ mxWdPreviewWin->hide();
+ mxFtStyle->hide();
+ mxLbStyle->hide();
+ mxEdFormula->GetWidget()->hide();
+
+ Deselect();
+}
+
+//color scale
+
+namespace {
+
+OUString convertNumberToString(double nVal, const ScDocument* pDoc)
+{
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ OUString aText;
+ pNumberFormatter->GetInputLineString(nVal, 0, aText);
+ return aText;
+}
+
+const struct
+{
+ ScColorScaleEntryType eType;
+ const char* sId;
+} TypeIdMap[] = {
+ { COLORSCALE_AUTO, "auto" },
+ { COLORSCALE_MIN, "min" },
+ { COLORSCALE_MAX, "max" },
+ { COLORSCALE_PERCENTILE, "percentil" },
+ { COLORSCALE_VALUE, "value" },
+ { COLORSCALE_PERCENT, "percent" },
+ { COLORSCALE_FORMULA, "formula" },
+};
+
+ScColorScaleEntryType getTypeForId(const OUString& sId)
+{
+ for (auto& r : TypeIdMap)
+ {
+ if (sId.equalsAscii(r.sId))
+ return r.eType;
+ }
+ assert(false); // The id is not in TypeIdMap - something not in sync?
+ return COLORSCALE_AUTO; // invalid id - use default
+}
+
+// Item ids are imported from .ui into OUString* and are referenced by entry data.
+// See commit 83cefb5ceb4428d61a5b9fae80d1e673131e9bfe
+
+ScColorScaleEntryType getSelectedType(const weld::ComboBox& rListBox)
+{
+ return getTypeForId(rListBox.get_active_id());
+}
+
+sal_Int32 getEntryPos(const weld::ComboBox& rListBox, ScColorScaleEntryType eType)
+{
+ const sal_Int32 nSize = rListBox.get_count();
+ for (sal_Int32 i = 0; i < nSize; ++i)
+ {
+ if (getTypeForId(rListBox.get_id(i)) == eType)
+ return i;
+ }
+ return -1;
+}
+
+void selectType(weld::ComboBox& rListBox, ScColorScaleEntryType eType)
+{
+ const sal_Int32 nPos = getEntryPos(rListBox, eType);
+ if (nPos >= 0)
+ rListBox.set_active(nPos);
+}
+
+void removeType(weld::ComboBox& rListBox, ScColorScaleEntryType eType)
+{
+ const sal_Int32 nPos = getEntryPos(rListBox, eType);
+ if (nPos >= 0)
+ rListBox.remove(nPos);
+}
+
+void SetColorScaleEntryTypes( const ScColorScaleEntry& rEntry, weld::ComboBox& rLbType, weld::Entry& rEdit, ColorListBox& rLbCol, const ScDocument* pDoc )
+{
+ // entry Automatic is not available for color scales
+ assert(rEntry.GetType() > COLORSCALE_AUTO);
+ selectType(rLbType, rEntry.GetType());
+ switch(rEntry.GetType())
+ {
+ case COLORSCALE_MIN:
+ case COLORSCALE_MAX:
+ break;
+ case COLORSCALE_PERCENTILE:
+ case COLORSCALE_VALUE:
+ case COLORSCALE_PERCENT:
+ {
+ double nVal = rEntry.GetValue();
+ rEdit.set_text(convertNumberToString(nVal, pDoc));
+ }
+ break;
+ case COLORSCALE_FORMULA:
+ rEdit.set_text(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
+ break;
+ case COLORSCALE_AUTO:
+ abort();
+ break;
+ }
+ rLbCol.SelectEntry(rEntry.GetColor());
+}
+
+void SetColorScaleEntry(ScColorScaleEntry* pEntry, const weld::ComboBox& rType, const weld::Entry& rValue,
+ ScDocument* pDoc, const ScAddress& rPos)
+{
+ ScColorScaleEntryType eType = getSelectedType(rType);
+
+ pEntry->SetType(eType);
+ switch (eType)
+ {
+ case COLORSCALE_AUTO:
+ case COLORSCALE_MIN:
+ case COLORSCALE_MAX:
+ break;
+ case COLORSCALE_PERCENTILE:
+ case COLORSCALE_VALUE:
+ case COLORSCALE_PERCENT:
+ {
+ sal_uInt32 nIndex = 0;
+ double nVal = 0;
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ (void)pNumberFormatter->IsNumberFormat(rValue.get_text(), nIndex, nVal);
+ pEntry->SetValue(nVal);
+ }
+ break;
+ case COLORSCALE_FORMULA:
+ pEntry->SetFormula(rValue.get_text(), pDoc, rPos);
+ break;
+ default:
+ break;
+ }
+}
+
+ScColorScaleEntry* createColorScaleEntry( const weld::ComboBox& rType, const ColorListBox& rColor, const weld::Entry& rValue, ScDocument* pDoc, const ScAddress& rPos )
+{
+ ScColorScaleEntry* pEntry = new ScColorScaleEntry();
+
+ SetColorScaleEntry(pEntry, rType, rValue, pDoc, rPos);
+ Color aColor = rColor.GetSelectEntryColor();
+ pEntry->SetColor(aColor);
+ return pEntry;
+}
+
+}
+
+ScColorScale2FrmtEntry::ScColorScale2FrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat"))
+ , mxLbEntryTypeMin(mxBuilder->weld_combo_box("colscalemin"))
+ , mxLbEntryTypeMax(mxBuilder->weld_combo_box("colscalemax"))
+ , mxEdMin(mxBuilder->weld_entry("edcolscalemin"))
+ , mxEdMax(mxBuilder->weld_entry("edcolscalemax"))
+ , mxLbColMin(new ColorListBox(mxBuilder->weld_menu_button("lbcolmin"), pParent->GetFrameWeld()))
+ , mxLbColMax(new ColorListBox(mxBuilder->weld_menu_button("lbcolmax"), pParent->GetFrameWeld()))
+ , mxFtMin(mxBuilder->weld_label("Label_minimum"))
+ , mxFtMax(mxBuilder->weld_label("Label_maximum"))
+{
+ mxLbColorFormat->set_size_request(CommonWidgetWidth, -1);
+ mxLbEntryTypeMin->set_size_request(CommonWidgetWidth, -1);
+ mxLbEntryTypeMax->set_size_request(CommonWidgetWidth, -1);
+ mxLbColMin->get_widget().set_size_request(CommonWidgetWidth, -1);
+ mxLbColMax->get_widget().set_size_request(CommonWidgetWidth, -1);
+
+ mxFtMin->show();
+ mxFtMax->show();
+
+ // remove the automatic entry from color scales
+ removeType(*mxLbEntryTypeMin, COLORSCALE_AUTO);
+ removeType(*mxLbEntryTypeMax, COLORSCALE_AUTO);
+ // "min" selector doesn't need "max" entry, and vice versa
+ removeType(*mxLbEntryTypeMin, COLORSCALE_MAX);
+ removeType(*mxLbEntryTypeMax, COLORSCALE_MIN);
+
+ mxLbType->set_active(0);
+ mxLbColorFormat->set_active(0);
+ Init();
+ if(pFormat)
+ {
+ ScColorScaleEntries::const_iterator itr = pFormat->begin();
+ SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMin, *mxEdMin, *mxLbColMin, pDoc);
+ ++itr;
+ SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMax, *mxEdMax, *mxLbColMax, pDoc);
+ }
+ else
+ {
+ selectType(*mxLbEntryTypeMin, COLORSCALE_MIN);
+ selectType(*mxLbEntryTypeMax, COLORSCALE_MAX);
+ }
+
+ mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );
+
+ EntryTypeHdl(*mxLbEntryTypeMin);
+ EntryTypeHdl(*mxLbEntryTypeMax);
+}
+
+ScColorScale2FrmtEntry::~ScColorScale2FrmtEntry()
+{
+}
+
+void ScColorScale2FrmtEntry::Init()
+{
+ mxLbEntryTypeMin->connect_changed( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) );
+ mxLbEntryTypeMax->connect_changed( LINK( this, ScColorScale2FrmtEntry, EntryTypeHdl ) );
+ mxLbColMin->SelectEntry(Color(0xffff6d)); // Light Yellow 2
+ mxLbColMax->SelectEntry(Color(0x77bc65)); // Light Green 2
+}
+
+ScFormatEntry* ScColorScale2FrmtEntry::createColorscaleEntry() const
+{
+ ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc);
+ pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMin, *mxLbColMin, *mxEdMin, mpDoc, maPos));
+ pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMax, *mxLbColMax, *mxEdMax, mpDoc, maPos));
+ return pColorScale;
+}
+
+OUString ScColorScale2FrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression( COLORSCALE, 0 );
+}
+
+ScFormatEntry* ScColorScale2FrmtEntry::GetEntry() const
+{
+ return createColorscaleEntry();
+}
+
+void ScColorScale2FrmtEntry::SetActive()
+{
+ mxLbColorFormat->show();
+
+ mxLbEntryTypeMin->show();
+ mxLbEntryTypeMax->show();
+
+ mxEdMin->show();
+ mxEdMax->show();
+
+ mxLbColMin->show();
+ mxLbColMax->show();
+
+ Select();
+}
+
+void ScColorScale2FrmtEntry::SetInactive()
+{
+ mxLbColorFormat->hide();
+
+ mxLbEntryTypeMin->hide();
+ mxLbEntryTypeMax->hide();
+
+ mxEdMin->hide();
+ mxEdMax->hide();
+
+ mxLbColMin->hide();
+ mxLbColMax->hide();
+
+ Deselect();
+}
+
+IMPL_LINK( ScColorScale2FrmtEntry, EntryTypeHdl, weld::ComboBox&, rBox, void )
+{
+ weld::Entry* pEd = nullptr;
+ if (&rBox == mxLbEntryTypeMin.get())
+ pEd = mxEdMin.get();
+ else if (&rBox == mxLbEntryTypeMax.get())
+ pEd = mxEdMax.get();
+
+ if (!pEd)
+ return;
+
+ bool bEnableEdit = true;
+ if (getSelectedType(rBox) <= COLORSCALE_MAX)
+ {
+ bEnableEdit = false;
+ }
+
+ if (bEnableEdit)
+ pEd->set_sensitive(true);
+ else
+ pEd->set_sensitive(false);
+}
+
+ScColorScale3FrmtEntry::ScColorScale3FrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScColorScaleFormat* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat"))
+ , mxLbEntryTypeMin(mxBuilder->weld_combo_box("colscalemin"))
+ , mxLbEntryTypeMiddle(mxBuilder->weld_combo_box("colscalemiddle"))
+ , mxLbEntryTypeMax(mxBuilder->weld_combo_box("colscalemax"))
+ , mxEdMin(mxBuilder->weld_entry("edcolscalemin"))
+ , mxEdMiddle(mxBuilder->weld_entry("edcolscalemiddle"))
+ , mxEdMax(mxBuilder->weld_entry("edcolscalemax"))
+ , mxLbColMin(new ColorListBox(mxBuilder->weld_menu_button("lbcolmin"), pParent->GetFrameWeld()))
+ , mxLbColMiddle(new ColorListBox(mxBuilder->weld_menu_button("lbcolmiddle"), pParent->GetFrameWeld()))
+ , mxLbColMax(new ColorListBox(mxBuilder->weld_menu_button("lbcolmax"), pParent->GetFrameWeld()))
+ , mxFtMin(mxBuilder->weld_label("Label_minimum"))
+ , mxFtMax(mxBuilder->weld_label("Label_maximum"))
+{
+ mxLbColorFormat->set_size_request(CommonWidgetWidth, -1);
+ mxLbEntryTypeMin->set_size_request(CommonWidgetWidth, -1);
+ mxLbEntryTypeMiddle->set_size_request(CommonWidgetWidth, -1);
+ mxLbEntryTypeMax->set_size_request(CommonWidgetWidth, -1);
+ mxLbColMin->get_widget().set_size_request(CommonWidgetWidth, -1);
+ mxLbColMiddle->get_widget().set_size_request(CommonWidgetWidth, -1);
+ mxLbColMax->get_widget().set_size_request(CommonWidgetWidth, -1);
+ mxFtMin->show();
+ mxFtMax->show();
+
+ // remove the automatic entry from color scales
+ removeType(*mxLbEntryTypeMin, COLORSCALE_AUTO);
+ removeType(*mxLbEntryTypeMiddle, COLORSCALE_AUTO);
+ removeType(*mxLbEntryTypeMax, COLORSCALE_AUTO);
+ // "min" selector doesn't need "max" entry, and vice versa
+ removeType(*mxLbEntryTypeMin, COLORSCALE_MAX);
+ removeType(*mxLbEntryTypeMax, COLORSCALE_MIN);
+ mxLbColorFormat->set_active(1);
+
+ Init();
+ mxLbType->set_active(0);
+ if(pFormat)
+ {
+ ScColorScaleEntries::const_iterator itr = pFormat->begin();
+ SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMin, *mxEdMin, *mxLbColMin, pDoc);
+ assert(pFormat->size() == 3);
+ ++itr;
+ SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMiddle, *mxEdMiddle, *mxLbColMiddle, pDoc);
+ ++itr;
+ SetColorScaleEntryTypes(*itr[0], *mxLbEntryTypeMax, *mxEdMax, *mxLbColMax, pDoc);
+ }
+ else
+ {
+ mxLbColorFormat->set_active(1);
+ selectType(*mxLbEntryTypeMin, COLORSCALE_MIN);
+ selectType(*mxLbEntryTypeMiddle, COLORSCALE_PERCENTILE);
+ selectType(*mxLbEntryTypeMax, COLORSCALE_MAX);
+ mxEdMiddle->set_text(OUString::number(50));
+ }
+
+ mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );
+ EntryTypeHdl(*mxLbEntryTypeMin);
+ EntryTypeHdl(*mxLbEntryTypeMiddle);
+ EntryTypeHdl(*mxLbEntryTypeMax);
+}
+
+ScColorScale3FrmtEntry::~ScColorScale3FrmtEntry()
+{
+}
+
+void ScColorScale3FrmtEntry::Init()
+{
+ mxLbEntryTypeMin->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
+ mxLbEntryTypeMax->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
+ mxLbEntryTypeMiddle->connect_changed( LINK( this, ScColorScale3FrmtEntry, EntryTypeHdl ) );
+ mxLbColMin->SelectEntry(COL_LIGHTRED);
+ mxLbColMiddle->SelectEntry(COL_YELLOW);
+ mxLbColMax->SelectEntry(Color(0x00a933));
+}
+
+ScFormatEntry* ScColorScale3FrmtEntry::createColorscaleEntry() const
+{
+ ScColorScaleFormat* pColorScale = new ScColorScaleFormat(mpDoc);
+ pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMin, *mxLbColMin, *mxEdMin, mpDoc, maPos));
+ if (mxLbColorFormat->get_active() == 1)
+ pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMiddle, *mxLbColMiddle, *mxEdMiddle, mpDoc, maPos));
+ pColorScale->AddEntry(createColorScaleEntry(*mxLbEntryTypeMax, *mxLbColMax, *mxEdMax, mpDoc, maPos));
+ return pColorScale;
+}
+
+OUString ScColorScale3FrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression( COLORSCALE, 0 );
+}
+
+ScFormatEntry* ScColorScale3FrmtEntry::GetEntry() const
+{
+ return createColorscaleEntry();
+}
+
+void ScColorScale3FrmtEntry::SetActive()
+{
+ mxLbColorFormat->show();
+ mxLbEntryTypeMin->show();
+ mxLbEntryTypeMiddle->show();
+ mxLbEntryTypeMax->show();
+
+ mxEdMin->show();
+ mxEdMiddle->show();
+ mxEdMax->show();
+
+ mxLbColMin->show();
+ mxLbColMiddle->show();
+ mxLbColMax->show();
+
+ Select();
+}
+
+void ScColorScale3FrmtEntry::SetInactive()
+{
+ mxLbColorFormat->hide();
+
+ mxLbEntryTypeMin->hide();
+ mxLbEntryTypeMiddle->hide();
+ mxLbEntryTypeMax->hide();
+
+ mxEdMin->hide();
+ mxEdMiddle->hide();
+ mxEdMax->hide();
+
+ mxLbColMin->hide();
+ mxLbColMiddle->hide();
+ mxLbColMax->hide();
+
+ Deselect();
+}
+
+IMPL_LINK( ScColorScale3FrmtEntry, EntryTypeHdl, weld::ComboBox&, rBox, void )
+{
+ weld::Entry* pEd = nullptr;
+ if(&rBox == mxLbEntryTypeMin.get())
+ pEd = mxEdMin.get();
+ else if(&rBox == mxLbEntryTypeMiddle.get())
+ pEd = mxEdMiddle.get();
+ else if(&rBox == mxLbEntryTypeMax.get())
+ pEd = mxEdMax.get();
+
+ if (!pEd)
+ return;
+
+ bool bEnableEdit = true;
+ if (getSelectedType(rBox) <= COLORSCALE_MAX)
+ {
+ bEnableEdit = false;
+ }
+
+ if(bEnableEdit)
+ pEd->set_sensitive(true);
+ else
+ pEd->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(ScConditionFrmtEntry, ConditionTypeSelectHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nSelectPos = mxLbCondType->get_active();
+ ScConditionMode eMode = EntryPosToConditionMode(nSelectPos);
+ switch(GetNumberEditFields(eMode))
+ {
+ case 0:
+ mxEdVal1->GetWidget()->hide();
+ mxEdVal2->GetWidget()->hide();
+ mxFtVal->hide();
+ break;
+ case 1:
+ mxEdVal1->GetWidget()->show();
+ mxEdVal2->GetWidget()->hide();
+ mxFtVal->show();
+ break;
+ case 2:
+ mxEdVal1->GetWidget()->show();
+ mxEdVal2->GetWidget()->show();
+ mxFtVal->show();
+ break;
+ }
+}
+
+//databar
+
+namespace {
+
+void SetDataBarEntryTypes( const ScColorScaleEntry& rEntry, weld::ComboBox& rLbType, weld::Entry& rEdit, const ScDocument* pDoc )
+{
+ selectType(rLbType, rEntry.GetType());
+ switch(rEntry.GetType())
+ {
+ case COLORSCALE_AUTO:
+ case COLORSCALE_MIN:
+ case COLORSCALE_MAX:
+ break;
+ case COLORSCALE_VALUE:
+ case COLORSCALE_PERCENT:
+ case COLORSCALE_PERCENTILE:
+ {
+ double nVal = rEntry.GetValue();
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ OUString aText;
+ pNumberFormatter->GetInputLineString(nVal, 0, aText);
+ rEdit.set_text(aText);
+ }
+ break;
+ case COLORSCALE_FORMULA:
+ rEdit.set_text(rEntry.GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
+ break;
+ }
+}
+
+}
+
+ScDataBarFrmtEntry::ScDataBarFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScDataBarFormat* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat"))
+ , mxLbDataBarMinType(mxBuilder->weld_combo_box("colscalemin"))
+ , mxLbDataBarMaxType(mxBuilder->weld_combo_box("colscalemax"))
+ , mxEdDataBarMin(mxBuilder->weld_entry("edcolscalemin"))
+ , mxEdDataBarMax(mxBuilder->weld_entry("edcolscalemax"))
+ , mxBtOptions(mxBuilder->weld_button("options"))
+ , mxFtMin(mxBuilder->weld_label("Label_minimum"))
+ , mxFtMax(mxBuilder->weld_label("Label_maximum"))
+{
+ mxLbColorFormat->set_size_request(CommonWidgetWidth, -1);
+ mxLbDataBarMinType->set_size_request(CommonWidgetWidth, -1);
+ mxLbDataBarMaxType->set_size_request(CommonWidgetWidth, -1);
+
+ // "min" selector doesn't need "max" entry, and vice versa
+ removeType(*mxLbDataBarMinType, COLORSCALE_MAX);
+ removeType(*mxLbDataBarMaxType, COLORSCALE_MIN);
+
+ mxFtMin->show();
+ mxFtMax->show();
+
+ mxLbColorFormat->set_active(2);
+ mxLbType->set_active(0);
+ if(pFormat)
+ {
+ mpDataBarData.reset(new ScDataBarFormatData(*pFormat->GetDataBarData()));
+ SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *mxLbDataBarMinType, *mxEdDataBarMin, pDoc);
+ SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *mxLbDataBarMaxType, *mxEdDataBarMax, pDoc);
+ DataBarTypeSelectHdl(*mxLbDataBarMinType);
+ }
+ else
+ {
+ selectType(*mxLbDataBarMinType, COLORSCALE_AUTO);
+ selectType(*mxLbDataBarMaxType, COLORSCALE_AUTO);
+ DataBarTypeSelectHdl(*mxLbDataBarMinType);
+ }
+ Init();
+
+ mxLbColorFormat->connect_changed( LINK( pParent, ScCondFormatList, ColFormatTypeHdl ) );
+}
+
+ScDataBarFrmtEntry::~ScDataBarFrmtEntry()
+{
+}
+
+ScFormatEntry* ScDataBarFrmtEntry::GetEntry() const
+{
+ return createDatabarEntry();
+}
+
+void ScDataBarFrmtEntry::Init()
+{
+ mxLbDataBarMinType->connect_changed( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) );
+ mxLbDataBarMaxType->connect_changed( LINK( this, ScDataBarFrmtEntry, DataBarTypeSelectHdl ) );
+
+ mxBtOptions->connect_clicked( LINK( this, ScDataBarFrmtEntry, OptionBtnHdl ) );
+
+ if(!mpDataBarData)
+ {
+ mpDataBarData.reset(new ScDataBarFormatData());
+ mpDataBarData->mpUpperLimit.reset(new ScColorScaleEntry());
+ mpDataBarData->mpLowerLimit.reset(new ScColorScaleEntry());
+ mpDataBarData->mpLowerLimit->SetType(COLORSCALE_AUTO);
+ mpDataBarData->mpUpperLimit->SetType(COLORSCALE_AUTO);
+ mpDataBarData->maPositiveColor = 0x2a6099;
+ }
+}
+
+ScFormatEntry* ScDataBarFrmtEntry::createDatabarEntry() const
+{
+ SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *mxLbDataBarMinType,
+ *mxEdDataBarMin, mpDoc, maPos);
+ SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *mxLbDataBarMaxType,
+ *mxEdDataBarMax, mpDoc, maPos);
+ ScDataBarFormat* pDataBar = new ScDataBarFormat(mpDoc);
+ pDataBar->SetDataBarData(new ScDataBarFormatData(*mpDataBarData));
+ return pDataBar;
+}
+
+OUString ScDataBarFrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression( DATABAR, 0 );
+}
+
+void ScDataBarFrmtEntry::SetActive()
+{
+ mxLbColorFormat->show();
+
+ mxLbDataBarMinType->show();
+ mxLbDataBarMaxType->show();
+ mxEdDataBarMin->show();
+ mxEdDataBarMax->show();
+ mxBtOptions->show();
+
+ Select();
+}
+
+void ScDataBarFrmtEntry::SetInactive()
+{
+ mxLbColorFormat->hide();
+
+ mxLbDataBarMinType->hide();
+ mxLbDataBarMaxType->hide();
+ mxEdDataBarMin->hide();
+ mxEdDataBarMax->hide();
+ mxBtOptions->hide();
+
+ Deselect();
+}
+
+IMPL_LINK_NOARG( ScDataBarFrmtEntry, DataBarTypeSelectHdl, weld::ComboBox&, void )
+{
+ if (getSelectedType(*mxLbDataBarMinType) <= COLORSCALE_MAX)
+ mxEdDataBarMin->set_sensitive(false);
+ else
+ mxEdDataBarMin->set_sensitive(true);
+
+ if (getSelectedType(*mxLbDataBarMaxType) <= COLORSCALE_MAX)
+ mxEdDataBarMax->set_sensitive(false);
+ else
+ mxEdDataBarMax->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG( ScDataBarFrmtEntry, OptionBtnHdl, weld::Button&, void )
+{
+ SetColorScaleEntry(mpDataBarData->mpLowerLimit.get(), *mxLbDataBarMinType,
+ *mxEdDataBarMin, mpDoc, maPos);
+ SetColorScaleEntry(mpDataBarData->mpUpperLimit.get(), *mxLbDataBarMaxType,
+ *mxEdDataBarMax, mpDoc, maPos);
+ ScDataBarSettingsDlg aDlg(mpParent->GetFrameWeld(), *mpDataBarData, mpDoc, maPos);
+ if (aDlg.run() == RET_OK)
+ {
+ mpDataBarData.reset(aDlg.GetData());
+ SetDataBarEntryTypes(*mpDataBarData->mpLowerLimit, *mxLbDataBarMinType, *mxEdDataBarMin, mpDoc);
+ SetDataBarEntryTypes(*mpDataBarData->mpUpperLimit, *mxLbDataBarMaxType, *mxEdDataBarMax, mpDoc);
+ DataBarTypeSelectHdl(*mxLbDataBarMinType);
+ }
+}
+
+ScDateFrmtEntry::ScDateFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScCondDateFormatEntry* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, ScAddress())
+ , mxLbDateEntry(mxBuilder->weld_combo_box("datetype"))
+ , mxFtStyle(mxBuilder->weld_label("styleft"))
+ , mxLbStyle(mxBuilder->weld_combo_box("style"))
+ , mxWdPreviewWin(mxBuilder->weld_widget("previewwin"))
+ , mxWdPreview(new weld::CustomWeld(*mxBuilder, "preview", maWdPreview))
+ , mbIsInStyleCreate(false)
+{
+ mxLbDateEntry->set_size_request(CommonWidgetWidth, -1);
+ mxLbStyle->set_size_request(CommonWidgetWidth, -1);
+
+ mxWdPreview->set_size_request(mxLbStyle->get_preferred_size().Height(), -1);
+
+ Init();
+
+ StartListening(*pDoc->GetStyleSheetPool(), DuplicateHandling::Prevent);
+
+ if(pFormat)
+ {
+ sal_Int32 nPos = static_cast<sal_Int32>(pFormat->GetDateType());
+ mxLbDateEntry->set_active(nPos);
+
+ mxLbStyle->set_active_text(pFormat->GetStyleName());
+ }
+
+ StyleSelectHdl(*mxLbStyle);
+}
+
+ScDateFrmtEntry::~ScDateFrmtEntry()
+{
+}
+
+void ScDateFrmtEntry::Init()
+{
+ mxLbDateEntry->set_active(0);
+ mxLbType->set_active(3);
+
+ FillStyleListBox( mpDoc, *mxLbStyle );
+ mxLbStyle->connect_changed( LINK( this, ScDateFrmtEntry, StyleSelectHdl ) );
+ mxLbStyle->set_active(1);
+}
+
+void ScDateFrmtEntry::SetActive()
+{
+ mxLbDateEntry->show();
+ mxFtStyle->show();
+ mxWdPreviewWin->show();
+ mxLbStyle->show();
+
+ Select();
+}
+
+void ScDateFrmtEntry::SetInactive()
+{
+ mxLbDateEntry->hide();
+ mxFtStyle->hide();
+ mxWdPreviewWin->hide();
+ mxLbStyle->hide();
+
+ Deselect();
+}
+
+void ScDateFrmtEntry::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if(rHint.GetId() == SfxHintId::StyleSheetModified)
+ {
+ if(!mbIsInStyleCreate)
+ UpdateStyleList(*mxLbStyle, mpDoc);
+ }
+}
+
+ScFormatEntry* ScDateFrmtEntry::GetEntry() const
+{
+ ScCondDateFormatEntry* pNewEntry = new ScCondDateFormatEntry(mpDoc);
+ condformat::ScCondFormatDateType eType = static_cast<condformat::ScCondFormatDateType>(mxLbDateEntry->get_active());
+ pNewEntry->SetDateType(eType);
+ pNewEntry->SetStyleName(mxLbStyle->get_active_text());
+ return pNewEntry;
+}
+
+OUString ScDateFrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression(DATE, 0);
+}
+
+IMPL_LINK_NOARG( ScDateFrmtEntry, StyleSelectHdl, weld::ComboBox&, void )
+{
+ mbIsInStyleCreate = true;
+ StyleSelect(mpParent->GetFrameWeld(), *mxLbStyle, mpDoc, maWdPreview);
+ mbIsInStyleCreate = false;
+}
+
+class ScIconSetFrmtDataEntry
+{
+protected:
+ std::unique_ptr<weld::Builder> mxBuilder;
+private:
+ std::unique_ptr<weld::Container> mxGrid;
+ std::unique_ptr<weld::Image> mxImgIcon;
+ std::unique_ptr<weld::Label> mxFtEntry;
+ std::unique_ptr<weld::Entry> mxEdEntry;
+ std::unique_ptr<weld::ComboBox> mxLbEntryType;
+ weld::Container* mpContainer;
+
+public:
+ ScIconSetFrmtDataEntry(weld::Container* pParent, ScIconSetType eType, const ScDocument* pDoc,
+ sal_Int32 i, const ScColorScaleEntry* pEntry = nullptr);
+ ~ScIconSetFrmtDataEntry();
+ void Show() { mxGrid->show(); }
+ void Hide() { mxGrid->hide(); }
+ void set_grid_top_attach(int nTop)
+ {
+ mxGrid->set_grid_left_attach(0);
+ mxGrid->set_grid_top_attach(nTop);
+ }
+
+ ScColorScaleEntry* CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const;
+
+ void SetFirstEntry();
+};
+
+ScIconSetFrmtDataEntry::ScIconSetFrmtDataEntry(weld::Container* pParent, ScIconSetType eType, const ScDocument* pDoc, sal_Int32 i, const ScColorScaleEntry* pEntry)
+ : mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/conditionaliconset.ui"))
+ , mxGrid(mxBuilder->weld_container("ConditionalIconSet"))
+ , mxImgIcon(mxBuilder->weld_image("icon"))
+ , mxFtEntry(mxBuilder->weld_label("label"))
+ , mxEdEntry(mxBuilder->weld_entry("entry"))
+ , mxLbEntryType(mxBuilder->weld_combo_box("listbox"))
+ , mpContainer(pParent)
+{
+ mxImgIcon->set_from_icon_name(ScIconSetFormat::getIconName(eType, i));
+ if(pEntry)
+ {
+ switch(pEntry->GetType())
+ {
+ case COLORSCALE_VALUE:
+ mxLbEntryType->set_active(0);
+ mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc));
+ break;
+ case COLORSCALE_PERCENTILE:
+ mxLbEntryType->set_active(2);
+ mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc));
+ break;
+ case COLORSCALE_PERCENT:
+ mxLbEntryType->set_active(1);
+ mxEdEntry->set_text(convertNumberToString(pEntry->GetValue(), pDoc));
+ break;
+ case COLORSCALE_FORMULA:
+ mxLbEntryType->set_active(3);
+ mxEdEntry->set_text(pEntry->GetFormula(formula::FormulaGrammar::GRAM_DEFAULT));
+ break;
+ default:
+ assert(false);
+ }
+ }
+ else
+ {
+ mxLbEntryType->set_active(1);
+ }
+}
+
+ScIconSetFrmtDataEntry::~ScIconSetFrmtDataEntry()
+{
+ mpContainer->move(mxGrid.get(), nullptr);
+}
+
+ScColorScaleEntry* ScIconSetFrmtDataEntry::CreateEntry(ScDocument* pDoc, const ScAddress& rPos) const
+{
+ sal_Int32 nPos = mxLbEntryType->get_active();
+ OUString aText = mxEdEntry->get_text();
+ ScColorScaleEntry* pEntry = new ScColorScaleEntry();
+
+ sal_uInt32 nIndex = 0;
+ double nVal = 0;
+ SvNumberFormatter* pNumberFormatter = pDoc->GetFormatTable();
+ (void)pNumberFormatter->IsNumberFormat(aText, nIndex, nVal);
+ pEntry->SetValue(nVal);
+
+ switch(nPos)
+ {
+ case 0:
+ pEntry->SetType(COLORSCALE_VALUE);
+ break;
+ case 1:
+ pEntry->SetType(COLORSCALE_PERCENT);
+ break;
+ case 2:
+ pEntry->SetType(COLORSCALE_PERCENTILE);
+ break;
+ case 3:
+ pEntry->SetType(COLORSCALE_FORMULA);
+ pEntry->SetFormula(aText, pDoc, rPos, pDoc->GetGrammar());
+ break;
+ default:
+ assert(false);
+ }
+
+ return pEntry;
+}
+
+void ScIconSetFrmtDataEntry::SetFirstEntry()
+{
+ mxEdEntry->hide();
+ mxLbEntryType->hide();
+ mxFtEntry->hide();
+ mxEdEntry->set_text("0");
+ mxLbEntryType->set_active(1);
+}
+
+ScIconSetFrmtEntry::ScIconSetFrmtEntry(ScCondFormatList* pParent, ScDocument* pDoc, const ScAddress& rPos, const ScIconSetFormat* pFormat)
+ : ScCondFrmtEntry(pParent, pDoc, rPos)
+ , mxLbColorFormat(mxBuilder->weld_combo_box("colorformat"))
+ , mxLbIconSetType(mxBuilder->weld_combo_box("iconsettype"))
+ , mxIconParent(mxBuilder->weld_container("iconparent"))
+{
+ mxLbColorFormat->set_size_request(CommonWidgetWidth, -1);
+ mxLbIconSetType->set_size_request(CommonWidgetWidth, -1);
+
+ Init();
+ mxLbColorFormat->connect_changed(LINK(pParent, ScCondFormatList, ColFormatTypeHdl));
+
+ if(pFormat)
+ {
+ const ScIconSetFormatData* pIconSetFormatData = pFormat->GetIconSetData();
+ ScIconSetType eType = pIconSetFormatData->eIconSetType;
+ sal_Int32 nType = static_cast<sal_Int32>(eType);
+ mxLbIconSetType->set_active(nType);
+
+ for (size_t i = 0, n = pIconSetFormatData->m_Entries.size();
+ i < n; ++i)
+ {
+ maEntries.emplace_back(new ScIconSetFrmtDataEntry(
+ mxIconParent.get(), eType, pDoc, i, pIconSetFormatData->m_Entries[i].get()));
+ maEntries[i]->set_grid_top_attach(i);
+ }
+ maEntries[0]->SetFirstEntry();
+ }
+ else
+ IconSetTypeHdl(*mxLbIconSetType);
+}
+
+ScIconSetFrmtEntry::~ScIconSetFrmtEntry()
+{
+}
+
+void ScIconSetFrmtEntry::Init()
+{
+ mxLbColorFormat->set_active(3);
+ mxLbType->set_active(0);
+ mxLbIconSetType->set_active(0);
+
+ mxLbIconSetType->connect_changed(LINK(this, ScIconSetFrmtEntry, IconSetTypeHdl));
+}
+
+IMPL_LINK_NOARG( ScIconSetFrmtEntry, IconSetTypeHdl, weld::ComboBox&, void )
+{
+ const ScIconSetMap* pMap = ScIconSetFormat::g_IconSetMap;
+
+ sal_Int32 nPos = mxLbIconSetType->get_active();
+ sal_uInt32 nElements = pMap[nPos].nElements;
+
+ maEntries.clear();
+
+ for(size_t i = 0; i < nElements; ++i)
+ {
+ maEntries.emplace_back(new ScIconSetFrmtDataEntry(mxIconParent.get(), static_cast<ScIconSetType>(nPos), mpDoc, i));
+ maEntries[i]->set_grid_top_attach(i);
+ maEntries[i]->Show();
+ }
+ maEntries[0]->SetFirstEntry();
+}
+
+OUString ScIconSetFrmtEntry::GetExpressionString()
+{
+ return ScCondFormatHelper::GetExpression(ICONSET, 0);
+}
+
+void ScIconSetFrmtEntry::SetActive()
+{
+ mxLbColorFormat->show();
+ mxLbIconSetType->show();
+ for(auto& rxEntry : maEntries)
+ {
+ rxEntry->Show();
+ }
+
+ Select();
+}
+
+void ScIconSetFrmtEntry::SetInactive()
+{
+ mxLbColorFormat->hide();
+ mxLbIconSetType->hide();
+ for(auto& rxEntry : maEntries)
+ {
+ rxEntry->Hide();
+ }
+
+ Deselect();
+}
+
+ScFormatEntry* ScIconSetFrmtEntry::GetEntry() const
+{
+ ScIconSetFormat* pFormat = new ScIconSetFormat(mpDoc);
+
+ ScIconSetFormatData* pData = new ScIconSetFormatData;
+ pData->eIconSetType = static_cast<ScIconSetType>(mxLbIconSetType->get_active());
+ for(const auto& rxEntry : maEntries)
+ {
+ pData->m_Entries.emplace_back(rxEntry->CreateEntry(mpDoc, maPos));
+ }
+ pFormat->SetIconSetData(pData);
+
+ return pFormat;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/condformat/condformatdlgitem.cxx b/sc/source/ui/condformat/condformatdlgitem.cxx
new file mode 100644
index 000000000..b0bf511c3
--- /dev/null
+++ b/sc/source/ui/condformat/condformatdlgitem.cxx
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#include <utility>
+
+#include <scitems.hxx>
+#include <condformatdlgitem.hxx>
+
+ScCondFormatDlgItem::ScCondFormatDlgItem(std::shared_ptr<ScConditionalFormatList> pCondFormats,
+ sal_Int32 nItem, bool bManaged):
+ SfxPoolItem(SCITEM_CONDFORMATDLGDATA),
+ mpCondFormats(std::move(pCondFormats)),
+ mnItem(nItem),
+ meDialogType(condformat::dialog::CONDITION),
+ mbManaged(bManaged)
+{
+}
+
+ScCondFormatDlgItem::~ScCondFormatDlgItem()
+{
+}
+
+bool ScCondFormatDlgItem::operator==(const SfxPoolItem& rItem) const
+{
+ assert(SfxPoolItem::operator==(rItem)); (void)rItem;
+ return false;
+}
+
+ScCondFormatDlgItem* ScCondFormatDlgItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new ScCondFormatDlgItem(*this);
+}
+
+bool ScCondFormatDlgItem::IsManaged() const
+{
+ return mbManaged;
+}
+
+condformat::dialog::ScCondFormatDialogType ScCondFormatDlgItem::GetDialogType() const
+{
+ return meDialogType;
+}
+
+sal_Int32 ScCondFormatDlgItem::GetIndex() const
+{
+ return mnItem;
+}
+
+ScConditionalFormatList* ScCondFormatDlgItem::GetConditionalFormatList()
+{
+ return mpCondFormats.get();
+}
+
+void ScCondFormatDlgItem::SetDialogType(condformat::dialog::ScCondFormatDialogType eType)
+{
+ meDialogType = eType;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/condformat/condformathelper.cxx b/sc/source/ui/condformat/condformathelper.cxx
new file mode 100644
index 000000000..130785249
--- /dev/null
+++ b/sc/source/ui/condformat/condformathelper.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <condformathelper.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+#include <conditio.hxx>
+
+namespace {
+
+OUString getTextForType(ScCondFormatEntryType eType)
+{
+ switch(eType)
+ {
+ case CONDITION:
+ return ScResId(STR_COND_CONDITION);
+ case COLORSCALE:
+ return ScResId(STR_COND_COLORSCALE);
+ case DATABAR:
+ return ScResId(STR_COND_DATABAR);
+ case FORMULA:
+ return ScResId(STR_COND_FORMULA);
+ case ICONSET:
+ return ScResId(STR_COND_ICONSET);
+ case DATE:
+ return ScResId(STR_COND_DATE);
+ default:
+ break;
+ }
+
+ return OUString();
+}
+
+OUString getExpression(sal_Int32 nIndex)
+{
+ switch(nIndex)
+ {
+ case 0:
+ return "=";
+ case 1:
+ return "<";
+ case 2:
+ return ">";
+ case 3:
+ return "<=";
+ case 4:
+ return ">=";
+ case 5:
+ return "!=";
+ case 6:
+ return ScResId(STR_COND_BETWEEN);
+ case 7:
+ return ScResId(STR_COND_NOTBETWEEN);
+ case 8:
+ return ScResId(STR_COND_DUPLICATE);
+ case 9:
+ return ScResId(STR_COND_UNIQUE);
+
+ case 11:
+ return ScResId(STR_COND_TOP10);
+ case 12:
+ return ScResId(STR_COND_BOTTOM10);
+ case 13:
+ return ScResId(STR_COND_TOP_PERCENT);
+ case 14:
+ return ScResId(STR_COND_BOTTOM_PERCENT);
+ case 15:
+ return ScResId(STR_COND_ABOVE_AVERAGE);
+ case 16:
+ return ScResId(STR_COND_BELOW_AVERAGE);
+ case 17:
+ return ScResId(STR_COND_ABOVE_EQUAL_AVERAGE);
+ case 18:
+ return ScResId(STR_COND_BELOW_EQUAL_AVERAGE);
+ case 19:
+ return ScResId(STR_COND_ERROR);
+ case 20:
+ return ScResId(STR_COND_NOERROR);
+ case 21:
+ return ScResId(STR_COND_BEGINS_WITH);
+ case 22:
+ return ScResId(STR_COND_ENDS_WITH);
+ case 23:
+ return ScResId(STR_COND_CONTAINS);
+ case 24:
+ return ScResId(STR_COND_NOT_CONTAINS);
+
+ case 10:
+ assert(false);
+ }
+ return OUString();
+}
+
+OUString getDateString(sal_Int32 nIndex)
+{
+ const char* aCondStrs[] =
+ {
+ STR_COND_TODAY,
+ STR_COND_YESTERDAY,
+ STR_COND_TOMORROW,
+ STR_COND_LAST7DAYS,
+ STR_COND_THISWEEK,
+ STR_COND_LASTWEEK,
+ STR_COND_NEXTWEEK,
+ STR_COND_THISMONTH,
+ STR_COND_LASTMONTH,
+ STR_COND_NEXTMONTH,
+ STR_COND_THISYEAR,
+ STR_COND_LASTYEAR,
+ STR_COND_NEXTYEAR
+ };
+
+ if (nIndex >= 0 && o3tl::make_unsigned(nIndex) < SAL_N_ELEMENTS(aCondStrs))
+ return ScResId(aCondStrs[nIndex]);
+ assert(false);
+ return OUString();
+}
+
+}
+
+OUString ScCondFormatHelper::GetExpression(const ScConditionalFormat& rFormat, const ScAddress& rPos)
+{
+ OUStringBuffer aBuffer;
+ if(!rFormat.IsEmpty())
+ {
+ switch(rFormat.GetEntry(0)->GetType())
+ {
+ case ScFormatEntry::Type::Condition:
+ case ScFormatEntry::Type::ExtCondition:
+ {
+ const ScConditionEntry* pEntry = static_cast<const ScConditionEntry*>(rFormat.GetEntry(0));
+ ScConditionMode eMode = pEntry->GetOperation();
+ if(eMode == ScConditionMode::Direct)
+ {
+ aBuffer.append(getTextForType(FORMULA));
+ aBuffer.append(" ");
+ aBuffer.append(pEntry->GetExpression(rPos, 0));
+ }
+ else
+ {
+ aBuffer.append(getTextForType(CONDITION));
+ aBuffer.append(" ");
+ aBuffer.append(getExpression(static_cast<sal_Int32>(eMode)));
+ aBuffer.append(" ");
+ if(eMode == ScConditionMode::Between || eMode == ScConditionMode::NotBetween)
+ {
+ aBuffer.append(pEntry->GetExpression(rPos, 0));
+ aBuffer.append(" ");
+ aBuffer.append(ScResId(STR_COND_AND));
+ aBuffer.append(" ");
+ aBuffer.append(pEntry->GetExpression(rPos, 1));
+ }
+ else if(eMode <= ScConditionMode::NotEqual || eMode >= ScConditionMode::BeginsWith)
+ {
+ aBuffer.append(pEntry->GetExpression(rPos, 0));
+ }
+ }
+ }
+
+ break;
+ case ScFormatEntry::Type::Databar:
+ aBuffer.append(getTextForType(DATABAR));
+ break;
+ case ScFormatEntry::Type::Colorscale:
+ aBuffer.append(getTextForType(COLORSCALE));
+ break;
+ case ScFormatEntry::Type::Iconset:
+ aBuffer.append(getTextForType(ICONSET));
+ break;
+ case ScFormatEntry::Type::Date:
+ {
+ aBuffer.append(getTextForType(DATE));
+ aBuffer.append(" ");
+ sal_Int32 nDateEntry = static_cast<sal_Int32>(static_cast<const ScCondDateFormatEntry*>(rFormat.GetEntry(0))->GetDateType());
+ aBuffer.append(getDateString(nDateEntry));
+ }
+ break;
+ }
+ }
+ return aBuffer.makeStringAndClear();
+}
+
+OUString ScCondFormatHelper::GetExpression( ScCondFormatEntryType eType, sal_Int32 nIndex,
+ const OUString& aStr1, const OUString& aStr2 )
+{
+ OUStringBuffer aBuffer(getTextForType(eType));
+ aBuffer.append(" ");
+ if(eType == CONDITION)
+ {
+ // workaround missing FORMULA option in the conditions case
+ // FORMULA is handled later
+ if(nIndex > 9)
+ ++nIndex;
+ aBuffer.append(getExpression(nIndex));
+ if(nIndex <= 7 || nIndex >= 19)
+ {
+ aBuffer.append(" ").append(aStr1);
+ if(nIndex == 6 || nIndex == 7)
+ {
+ aBuffer.append(" ");
+ aBuffer.append(ScResId(STR_COND_AND));
+ aBuffer.append(" ");
+ aBuffer.append(aStr2);
+ }
+ }
+ }
+ else if(eType == FORMULA)
+ {
+ aBuffer.append(" ").append(aStr1);
+ }
+ else if(eType == DATE)
+ {
+ aBuffer.append(getDateString(nIndex));
+ }
+
+ return aBuffer.makeStringAndClear();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/condformat/condformatmgr.cxx b/sc/source/ui/condformat/condformatmgr.cxx
new file mode 100644
index 000000000..03e691ac2
--- /dev/null
+++ b/sc/source/ui/condformat/condformatmgr.cxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <condformatmgr.hxx>
+#include <condformathelper.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+#include <condformatdlg.hxx>
+#include <document.hxx>
+#include <conditio.hxx>
+
+ScCondFormatManagerWindow::ScCondFormatManagerWindow(weld::TreeView& rTreeView,
+ ScDocument* pDoc, ScConditionalFormatList* pFormatList)
+ : mrTreeView(rTreeView)
+ , mpDoc(pDoc)
+ , mpFormatList(pFormatList)
+{
+ mrTreeView.set_size_request(mrTreeView.get_approximate_digit_width() * 70,
+ mrTreeView.get_height_rows(20));
+ setColSizes();
+
+ Init();
+ mrTreeView.set_selection_mode(SelectionMode::Multiple);
+ mrTreeView.make_sorted();
+}
+
+void ScCondFormatManagerWindow::Init()
+{
+ mrTreeView.freeze();
+
+ if (mpFormatList)
+ {
+ int nRow = 0;
+ OUString sRangeStr;
+ for(const auto& rItem : *mpFormatList)
+ {
+ const ScRangeList& aRange = rItem->GetRange();
+ aRange.Format(sRangeStr, ScRefFlags::VALID, *mpDoc, mpDoc->GetAddressConvention());
+ mrTreeView.append(OUString::number(rItem->GetKey()), sRangeStr);
+ mrTreeView.set_text(nRow, ScCondFormatHelper::GetExpression(*rItem, aRange.GetTopLeftCorner()), 1);
+ ++nRow;
+ }
+ }
+
+ mrTreeView.thaw();
+
+ if (mpFormatList && !mpFormatList->empty())
+ mrTreeView.select(0);
+}
+
+void ScCondFormatManagerWindow::DeleteSelection()
+{
+ auto aSelectedRows = mrTreeView.get_selected_rows();
+ std::sort(aSelectedRows.begin(), aSelectedRows.end());
+ for (auto it = aSelectedRows.rbegin(); it != aSelectedRows.rend(); ++it)
+ {
+ sal_Int32 nIndex = mrTreeView.get_id(*it).toInt32();
+ mpFormatList->erase(nIndex);
+ mrTreeView.remove(*it);
+ }
+}
+
+ScConditionalFormat* ScCondFormatManagerWindow::GetSelection()
+{
+ int nEntry = mrTreeView.get_selected_index();
+ if (nEntry == -1)
+ return nullptr;
+
+ sal_Int32 nIndex = mrTreeView.get_id(nEntry).toInt32();
+ return mpFormatList->GetFormat(nIndex);
+}
+
+void ScCondFormatManagerWindow::setColSizes()
+{
+ std::vector<int> aWidths;
+ aWidths.push_back(mrTreeView.get_size_request().Width() / 2);
+ mrTreeView.set_column_fixed_widths(aWidths);
+}
+
+ScCondFormatManagerDlg::ScCondFormatManagerDlg(weld::Window* pParent, ScDocument* pDoc, const ScConditionalFormatList* pFormatList)
+ : GenericDialogController(pParent, "modules/scalc/ui/condformatmanager.ui", "CondFormatManager")
+ , m_bModified(false)
+ , m_xFormatList( pFormatList ? new ScConditionalFormatList(*pFormatList) : nullptr)
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnRemove(m_xBuilder->weld_button("remove"))
+ , m_xBtnEdit(m_xBuilder->weld_button("edit"))
+ , m_xTreeView(m_xBuilder->weld_tree_view("CONTAINER"))
+ , m_xCtrlManager(new ScCondFormatManagerWindow(*m_xTreeView, pDoc, m_xFormatList.get()))
+{
+ m_xBtnRemove->connect_clicked(LINK(this, ScCondFormatManagerDlg, RemoveBtnHdl));
+ m_xBtnEdit->connect_clicked(LINK(this, ScCondFormatManagerDlg, EditBtnClickHdl));
+ m_xBtnAdd->connect_clicked(LINK(this, ScCondFormatManagerDlg, AddBtnHdl));
+ m_xTreeView->connect_row_activated(LINK(this, ScCondFormatManagerDlg, EditBtnHdl));
+
+ UpdateButtonSensitivity();
+}
+
+ScCondFormatManagerDlg::~ScCondFormatManagerDlg()
+{
+}
+
+std::unique_ptr<ScConditionalFormatList> ScCondFormatManagerDlg::GetConditionalFormatList()
+{
+ return std::move(m_xFormatList);
+}
+
+void ScCondFormatManagerDlg::UpdateButtonSensitivity()
+{
+ bool bNewSensitivity = !m_xFormatList->empty();
+ m_xBtnRemove->set_sensitive(bNewSensitivity);
+ m_xBtnEdit->set_sensitive(bNewSensitivity);
+}
+
+// Get the current conditional format selected.
+//
+ScConditionalFormat* ScCondFormatManagerDlg::GetCondFormatSelected()
+{
+ return m_xCtrlManager->GetSelection();
+}
+
+IMPL_LINK_NOARG(ScCondFormatManagerDlg, RemoveBtnHdl, weld::Button&, void)
+{
+ m_xCtrlManager->DeleteSelection();
+ m_bModified = true;
+ UpdateButtonSensitivity();
+}
+
+IMPL_LINK_NOARG(ScCondFormatManagerDlg, EditBtnClickHdl, weld::Button&, void)
+{
+ EditBtnHdl(*m_xTreeView);
+}
+
+IMPL_LINK_NOARG(ScCondFormatManagerDlg, EditBtnHdl, weld::TreeView&, bool)
+{
+ ScConditionalFormat* pFormat = m_xCtrlManager->GetSelection();
+
+ if (!pFormat)
+ return true;
+
+ m_bModified = true;
+ m_xDialog->response( DLG_RET_EDIT );
+
+ return true;
+}
+
+IMPL_LINK_NOARG(ScCondFormatManagerDlg, AddBtnHdl, weld::Button&, void)
+{
+ m_bModified = true;
+ m_xDialog->response( DLG_RET_ADD );
+}
+
+void ScCondFormatManagerDlg::SetModified()
+{
+ m_bModified = true;
+ UpdateButtonSensitivity();
+}
+
+bool ScCondFormatManagerDlg::CondFormatsChanged() const
+{
+ return m_bModified;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */