/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* 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 <docfunc.hxx>
#include <condformateasydlg.hxx>
#include <stlpool.hxx>
#include <viewdata.hxx>
#include <reffact.hxx>
#include <scresid.hxx>
#include <svl/style.hxx>
#include <strings.hrc>
#include <condformathelper.hxx>
namespace
{
condformat::ScCondFormatDateType GetScCondFormatDateType(ScConditionMode mode)
{
switch (mode)
{
case ScConditionMode::Today:
return condformat::ScCondFormatDateType::TODAY;
case ScConditionMode::Yesterday:
return condformat::ScCondFormatDateType::YESTERDAY;
case ScConditionMode::Tomorrow:
return condformat::ScCondFormatDateType::TOMORROW;
case ScConditionMode::Last7days:
return condformat::ScCondFormatDateType::LAST7DAYS;
case ScConditionMode::ThisWeek:
return condformat::ScCondFormatDateType::THISWEEK;
case ScConditionMode::LastWeek:
return condformat::ScCondFormatDateType::LASTWEEK;
case ScConditionMode::NextWeek:
return condformat::ScCondFormatDateType::NEXTWEEK;
case ScConditionMode::ThisMonth:
return condformat::ScCondFormatDateType::THISMONTH;
case ScConditionMode::LastMonth:
return condformat::ScCondFormatDateType::LASTMONTH;
case ScConditionMode::NextMonth:
return condformat::ScCondFormatDateType::NEXTMONTH;
case ScConditionMode::ThisYear:
return condformat::ScCondFormatDateType::THISYEAR;
case ScConditionMode::LastYear:
return condformat::ScCondFormatDateType::LASTYEAR;
case ScConditionMode::NextYear:
return condformat::ScCondFormatDateType::NEXTYEAR;
default:
return condformat::ScCondFormatDateType::TODAY;
}
}
}
namespace sc
{
void ConditionalFormatEasyDialog::SetDescription(std::u16string_view rCondition)
{
mxDescription->set_label(mxDescription->get_label().replaceAll("%1", rCondition));
}
ConditionalFormatEasyDialog::ConditionalFormatEasyDialog(SfxBindings* pBindings,
SfxChildWindow* pChildWindow,
weld::Window* pParent,
ScViewData* pViewData)
: ScAnyRefDlgController(pBindings, pChildWindow, pParent,
u"modules/scalc/ui/conditionaleasydialog.ui"_ustr,
u"CondFormatEasyDlg"_ustr)
, mpParent(pParent)
, mpViewData(pViewData)
, mpDocument(&mpViewData->GetDocument())
, mbIsManaged(false)
, mnFormatKey(0)
, mnEntryIndex(0)
, mxNumberEntry(m_xBuilder->weld_entry(u"entryNumber"_ustr))
, mxNumberEntry2(m_xBuilder->weld_entry(u"entryNumber2"_ustr))
, mxAllInputs(m_xBuilder->weld_container(u"allInputs"_ustr))
, mxWarningLabel(m_xBuilder->weld_label(u"warning"_ustr))
, mxRangeEntry(new formula::RefEdit(m_xBuilder->weld_entry(u"entryRange"_ustr)))
, mxButtonRangeEdit(new formula::RefButton(m_xBuilder->weld_button(u"rbassign"_ustr)))
, mxStyles(m_xBuilder->weld_combo_box(u"themeCombo"_ustr))
, mxWdPreviewWin(m_xBuilder->weld_widget(u"previewwin"_ustr))
, mxWdPreview(new weld::CustomWeld(*m_xBuilder, "preview", maWdPreview))
, mxDescription(m_xBuilder->weld_label(u"description"_ustr))
, mxButtonOk(m_xBuilder->weld_button(u"ok"_ustr))
, mxButtonCancel(m_xBuilder->weld_button(u"cancel"_ustr))
{
mxButtonRangeEdit->SetReferences(this, mxRangeEntry.get());
const ScConditionEasyDialogData CurrentData
= pViewData->GetDocument().GetEasyConditionalFormatDialogData();
if (!CurrentData.Mode)
{
SAL_WARN(
"sc",
"Condition mode not set for easy conditional format dialog, this should not happen");
meMode = ScConditionMode::Greater;
}
else
{
meMode = *CurrentData.Mode;
mbIsManaged = CurrentData.IsManaged;
msFormula = CurrentData.Formula;
mnFormatKey = CurrentData.FormatKey;
mnEntryIndex = CurrentData.EntryIndex;
}
mxNumberEntry2->hide();
switch (meMode)
{
case ScConditionMode::Equal:
SetDescription(ScResId(STR_CONDITION_EQUAL));
break;
case ScConditionMode::Less:
SetDescription(ScResId(STR_CONDITION_LESS));
break;
case ScConditionMode::Greater:
SetDescription(ScResId(STR_CONDITION_GREATER));
break;
case ScConditionMode::EqLess:
SetDescription(ScResId(STR_CONDITION_EQLESS));
break;
case ScConditionMode::EqGreater:
SetDescription(ScResId(STR_CONDITION_EQGREATER));
break;
case ScConditionMode::NotEqual:
SetDescription(ScResId(STR_CONDITION_NOT_EQUAL));
break;
case ScConditionMode::Between:
SetDescription(ScResId(STR_CONDITION_BETWEEN));
mxNumberEntry2->show();
break;
case ScConditionMode::NotBetween:
SetDescription(ScResId(STR_CONDITION_NOT_BETWEEN));
mxNumberEntry2->show();
break;
case ScConditionMode::Duplicate:
SetDescription(ScResId(STR_CONDITION_DUPLICATE));
mxAllInputs->hide();
break;
case ScConditionMode::NotDuplicate:
SetDescription(ScResId(STR_CONDITION_NOT_DUPLICATE));
mxAllInputs->hide();
break;
// TODO: Direct
case ScConditionMode::Top10:
SetDescription(ScResId(STR_CONDITION_TOP_N_ELEMENTS));
break;
case ScConditionMode::Bottom10:
SetDescription(ScResId(STR_CONDITION_BOTTOM_N_ELEMENTS));
break;
case ScConditionMode::TopPercent:
SetDescription(ScResId(STR_CONDITION_TOP_N_PERCENT));
break;
case ScConditionMode::BottomPercent:
SetDescription(ScResId(STR_CONDITION_BOTTOM_N_PERCENT));
break;
case ScConditionMode::AboveAverage:
SetDescription(ScResId(STR_CONDITION_ABOVE_AVERAGE));
mxAllInputs->hide();
break;
case ScConditionMode::BelowAverage:
SetDescription(ScResId(STR_CONDITION_BELOW_AVERAGE));
mxAllInputs->hide();
break;
case ScConditionMode::AboveEqualAverage:
SetDescription(ScResId(STR_CONDITION_ABOVE_OR_EQUAL_AVERAGE));
mxAllInputs->hide();
break;
case ScConditionMode::BelowEqualAverage:
SetDescription(ScResId(STR_CONDITION_BELOW_OR_EQUAL_AVERAGE));
mxAllInputs->hide();
break;
case ScConditionMode::Error:
SetDescription(ScResId(STR_CONDITION_ERROR));
break;
case ScConditionMode::NoError:
SetDescription(ScResId(STR_CONDITION_NOERROR));
break;
case ScConditionMode::BeginsWith:
SetDescription(ScResId(STR_CONDITION_BEGINS_WITH));
break;
case ScConditionMode::EndsWith:
SetDescription(ScResId(STR_CONDITION_ENDS_WITH));
break;
case ScConditionMode::ContainsText:
SetDescription(ScResId(STR_CONDITION_CONTAINS_TEXT));
break;
case ScConditionMode::NotContainsText:
SetDescription(ScResId(STR_CONDITION_NOT_CONTAINS_TEXT));
break;
case ScConditionMode::Formula:
SetDescription(ScResId(STR_CONDITION_FORMULA));
mxAllInputs->hide();
break;
case ScConditionMode::Today:
SetDescription(ScResId(STR_CONDITION_TODAY));
mxAllInputs->hide();
break;
case ScConditionMode::Yesterday:
SetDescription(ScResId(STR_CONDITION_YESTERDAY));
mxAllInputs->hide();
break;
case ScConditionMode::Tomorrow:
SetDescription(ScResId(STR_CONDITION_TOMORROW));
mxAllInputs->hide();
break;
case ScConditionMode::Last7days:
SetDescription(ScResId(STR_CONDITION_LAST7DAYS));
mxAllInputs->hide();
break;
case ScConditionMode::ThisWeek:
SetDescription(ScResId(STR_CONDITION_THISWEEK));
mxAllInputs->hide();
break;
case ScConditionMode::LastWeek:
SetDescription(ScResId(STR_CONDITION_LASTWEEK));
mxAllInputs->hide();
break;
case ScConditionMode::NextWeek:
SetDescription(ScResId(STR_CONDITION_NEXTWEEK));
mxAllInputs->hide();
break;
case ScConditionMode::ThisMonth:
SetDescription(ScResId(STR_CONDITION_THISMONTH));
mxAllInputs->hide();
break;
case ScConditionMode::LastMonth:
SetDescription(ScResId(STR_CONDITION_LASTMONTH));
mxAllInputs->hide();
break;
case ScConditionMode::NextMonth:
SetDescription(ScResId(STR_CONDITION_NEXTMONTH));
mxAllInputs->hide();
break;
case ScConditionMode::ThisYear:
SetDescription(ScResId(STR_CONDITION_THISYEAR));
mxAllInputs->hide();
break;
case ScConditionMode::LastYear:
SetDescription(ScResId(STR_CONDITION_LASTYEAR));
mxAllInputs->hide();
break;
case ScConditionMode::NextYear:
SetDescription(ScResId(STR_CONDITION_NEXTYEAR));
mxAllInputs->hide();
break;
default:
SAL_WARN("sc",
"ConditionalFormatEasyDialog::ConditionalFormatEasyDialog: invalid format");
break;
}
mxButtonOk->connect_clicked(LINK(this, ConditionalFormatEasyDialog, ButtonPressed));
mxButtonCancel->connect_clicked(LINK(this, ConditionalFormatEasyDialog, ButtonPressed));
mxStyles->connect_changed(LINK(this, ConditionalFormatEasyDialog, StyleSelectHdl));
mxNumberEntry->connect_changed(LINK(this, ConditionalFormatEasyDialog, OnEdChanged));
mxNumberEntry2->connect_changed(LINK(this, ConditionalFormatEasyDialog, OnEdChanged));
ScRangeList aRange;
mpViewData->GetMarkData().FillRangeListWithMarks(&aRange, false);
ScConditionalFormat* format
= mpDocument->GetCondFormList(mpViewData->GetTabNo())->GetFormat(mnFormatKey);
if (aRange.empty() && mnFormatKey != -1 && mnEntryIndex != -1)
{
aRange = format->GetRangeList();
}
else if (aRange.empty())
{
ScAddress aPosition(mpViewData->GetCurX(), mpViewData->GetCurY(), mpViewData->GetTabNo());
aRange.push_back(ScRange(aPosition));
}
maPosition = aRange.GetTopLeftCorner();
// FIX me: Tab is always 0 in some cases
// Refer to test tdf100793
maPosition.SetTab(mpViewData->GetTabNo());
OUString sRangeString;
aRange.Format(sRangeString, ScRefFlags::VALID, *mpDocument, mpDocument->GetAddressConvention());
mxRangeEntry->SetText(sRangeString);
OUString sStyleName;
if (format)
{
const ScFormatEntry* entry = format->GetEntry(mnEntryIndex);
if (!entry)
return;
ScFormatEntry::Type type = entry->GetType();
if (type == ScFormatEntry::Type::Condition)
{
const ScCondFormatEntry* condEntry = static_cast<const ScCondFormatEntry*>(entry);
sStyleName = condEntry->GetStyle();
if (mxNumberEntry->get_visible())
mxNumberEntry->set_text(condEntry->GetExpression(aRange.GetTopLeftCorner(), 0));
if (mxNumberEntry2->get_visible())
mxNumberEntry2->set_text(condEntry->GetExpression(aRange.GetTopLeftCorner(), 1));
}
else if (type == ScFormatEntry::Type::Date)
{
const ScCondDateFormatEntry* dateEntry
= static_cast<const ScCondDateFormatEntry*>(entry);
sStyleName = dateEntry->GetStyleName();
}
}
StartListening(*mpDocument->GetStyleSheetPool(), DuplicateHandling::Prevent);
ScCondFormatHelper::FillStyleListBox(mpDocument, *mxStyles);
mxStyles->set_active_text(sStyleName);
StyleSelectHdl(*mxStyles);
mxWdPreviewWin->show();
}
ConditionalFormatEasyDialog::~ConditionalFormatEasyDialog()
{
if (mbIsManaged)
{
GetBindings().GetDispatcher()->Execute(SID_OPENDLG_CONDFRMT_MANAGER,
SfxCallMode::ASYNCHRON);
}
}
void ConditionalFormatEasyDialog::Notify(SfxBroadcaster&, const SfxHint& rHint)
{
if (rHint.GetId() == SfxHintId::StyleSheetModified
|| rHint.GetId() == SfxHintId::StyleSheetModifiedExtended)
ScCondFormatHelper::UpdateStyleList(*mxStyles, mpDocument);
}
void ConditionalFormatEasyDialog::SetReference(const ScRange& rRange, ScDocument&)
{
formula::RefEdit* pEdit = mxRangeEntry.get();
if (rRange.aStart != rRange.aEnd)
RefInputStart(pEdit);
ScRefFlags nFlags = ScRefFlags::RANGE_ABS;
const ScDocument& rDoc = mpViewData->GetDocument();
OUString sRange(
rRange.Format(rDoc, nFlags, ScAddress::Details(mpDocument->GetAddressConvention(), 0, 0)));
pEdit->SetRefString(sRange);
maPosition = rRange.aStart;
}
void ConditionalFormatEasyDialog::SetActive()
{
mxRangeEntry->GrabFocus();
RefInputDone();
}
void ConditionalFormatEasyDialog::Close()
{
DoClose(ConditionalFormatEasyDialogWrapper::GetChildWindowId());
}
IMPL_LINK(ConditionalFormatEasyDialog, ButtonPressed, weld::Button&, rButton, void)
{
if (&rButton == mxButtonOk.get())
{
if (mnEntryIndex != -1 && mnFormatKey != -1) // isEdit
mpDocument->GetCondFormList(maPosition.Tab())
->GetFormat(mnFormatKey)
->RemoveEntry(mnEntryIndex);
std::unique_ptr<ScConditionalFormat> pFormat(new ScConditionalFormat(0, mpDocument));
OUString sExpression1 = (mxNumberEntry->get_visible() && mxAllInputs->get_visible()
? mxNumberEntry->get_text()
: u""_ustr);
OUString sExpression2 = (mxNumberEntry2->get_visible() && mxAllInputs->get_visible()
? mxNumberEntry2->get_text()
: u""_ustr);
switch (meMode)
{
case ScConditionMode::ContainsText:
case ScConditionMode::NotContainsText:
case ScConditionMode::BeginsWith:
case ScConditionMode::EndsWith:
sExpression1 = "\"" + sExpression1 + "\"";
sExpression2 = "\"" + sExpression2 + "\"";
break;
default:
break;
}
std::unique_ptr<ScFormatEntry> xEntry;
if (meMode < ScConditionMode::Formula)
{
xEntry.reset(new ScCondFormatEntry(meMode, sExpression1, sExpression2, *mpDocument,
maPosition, mxStyles->get_active_text()));
}
else if (meMode >= ScConditionMode::Today && meMode < ScConditionMode::NONE)
{
ScCondDateFormatEntry entry(mpDocument);
entry.SetDateType(GetScCondFormatDateType(meMode));
entry.SetStyleName(mxStyles->get_active_text());
xEntry.reset(new ScCondDateFormatEntry(mpDocument, entry));
}
else if (meMode == ScConditionMode::Formula)
{
xEntry.reset(new ScCondFormatEntry(ScConditionMode::Direct, msFormula, OUString(),
*mpDocument, maPosition,
mxStyles->get_active_text()));
}
else
{
DBG_ASSERT(false, "Invalid condition type selected.");
return;
}
ScRangeList aRange;
ScRefFlags nFlags
= aRange.Parse(mxRangeEntry->GetText(), mpViewData->GetDocument(),
mpViewData->GetDocument().GetAddressConvention(), maPosition.Tab());
if ((nFlags & ScRefFlags::VALID) && !aRange.empty())
{
pFormat->AddEntry(xEntry.release());
pFormat->SetRange(aRange);
auto& rRangeList = pFormat->GetRange();
mpViewData->GetDocShell()->GetDocFunc().ReplaceConditionalFormat(
0, std::move(pFormat), maPosition.Tab(), rRangeList);
}
m_xDialog->response(RET_OK);
}
else if (&rButton == mxButtonCancel.get())
m_xDialog->response(RET_CANCEL);
}
IMPL_LINK_NOARG(ConditionalFormatEasyDialog, StyleSelectHdl, weld::ComboBox&, void)
{
ScCondFormatHelper::StyleSelect(mpParent, *mxStyles, &(mpViewData->GetDocument()), maWdPreview);
}
IMPL_LINK(ConditionalFormatEasyDialog, OnEdChanged, weld::Entry&, rEntry, void)
{
ScCondFormatHelper::ValidateInputField(rEntry, *mxWarningLabel, mpDocument, maPosition);
if (!mxWarningLabel->get_label().isEmpty())
mxWarningLabel->show();
else
mxWarningLabel->hide();
}
} // namespace sc
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
↑ V530 The return value of function 'Execute' is required to be utilized.
↑ V595 The 'format' pointer was utilized before it was verified against nullptr. Check lines: 270, 287.