From 979ee566e7adba689fad7760b7a25db1216d438f Mon Sep 17 00:00:00 2001 From: Mavridis Philippe Date: Fri, 5 Apr 2024 20:19:23 +0300 Subject: [PATCH] KSpread: Add natural comparison operators. Natural comparison does not depend on the type of data (whether it's a string or a number). Based on Calligra Sheets code originally from revision 551470. Signed-off-by: Mavridis Philippe (cherry picked from commit 4f21f4038f558fa330c307cc3745d6c3568b8b56) --- kspread/valuecalc.cpp | 65 +++++++++++++++++++++++++++++++++++++++++-- kspread/valuecalc.h | 17 ++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/kspread/valuecalc.cpp b/kspread/valuecalc.cpp index 3a1182e54..2f6b4b8dd 100644 --- a/kspread/valuecalc.cpp +++ b/kspread/valuecalc.cpp @@ -433,9 +433,70 @@ bool ValueCalc::approxEqual (const Value &a, const Value &b) return (x < 0.0 ? -x : x) < ((aa < 0.0 ? -aa : aa) * DBL_EPSILON); } -bool ValueCalc::strEqual (const Value &a, const Value &b) +bool ValueCalc::strEqual (const Value &a, const Value &b, bool CS) { - return (converter->asString (a).asString() == converter->asString (b).asString()); + TQString aa = converter->asString(a).asString(); + TQString bb = converter->asString(b).asString(); + if (!CS) { + aa = aa.lower(); + bb = bb.lower(); + } + return (aa == bb); +} + +bool ValueCalc::strGreater (const Value &a, const Value &b, bool CS) +{ + TQString aa = converter->asString(a).asString(); + TQString bb = converter->asString(b).asString(); + if (!CS) { + aa = aa.lower(); + bb = bb.lower(); + } + return (aa > bb); +} + +bool ValueCalc::strGequal (const Value &a, const Value &b, bool CS) +{ + TQString aa = converter->asString(a).asString(); + TQString bb = converter->asString(b).asString(); + if (!CS) { + aa = aa.lower(); + bb = bb.lower(); + } + return (aa >= bb); +} + +bool ValueCalc::strLower (const Value &a, const Value &b, bool CS) +{ + return strGreater (b, a, CS); +} + +bool ValueCalc::naturalEqual (const Value &a, const Value &b, bool CS) +{ + if (a.isNumber() && b.isNumber()) + return approxEqual(a, b); + if (a.allowComparison(b)) + return a.equal(b); + return strEqual(a, b, CS); +} + +bool ValueCalc::naturalGreater (const Value &a, const Value &b, bool CS) +{ + if (a.isNumber() && b.isNumber()) + return greater(a, b); + if (a.allowComparison(b)) + return a.greater(b); + return strGreater(a, b, CS); +} + +bool ValueCalc::naturalGequal (const Value &a, const Value &b, bool CS) +{ + return naturalGreater(a, b, CS) || naturalEqual(a, b, CS); +} + +bool ValueCalc::naturalLower (const Value &a, const Value &b, bool CS) +{ + return naturalGreater(b, a, CS); } bool ValueCalc::greater (const Value &a, const Value &b) diff --git a/kspread/valuecalc.h b/kspread/valuecalc.h index 2d78211b2..5157fa4c6 100644 --- a/kspread/valuecalc.h +++ b/kspread/valuecalc.h @@ -106,7 +106,22 @@ class ValueCalc { /** numerical comparison */ bool lower (const Value &a, const Value &b); /** string comparison */ - bool strEqual (const Value &a, const Value &b); + bool strEqual (const Value &a, const Value &b, bool CS = true); + /** string comparison */ + bool strGreater (const Value &a, const Value &b, bool CS = true); + /** string comparison - greater or equal */ + bool strGequal (const Value &a, const Value &b, bool CS = true); + /** string comparison */ + bool strLower (const Value &a, const Value &b, bool CS = true); + /** string or numerical comparison */ + bool naturalEqual (const Value &a, const Value &b, bool CS = true); + /** string or numerical comparison */ + bool naturalGreater (const Value &a, const Value &b, bool CS = true); + /** string or numerical comparison - greater or equal */ + bool naturalGequal (const Value &a, const Value &b, bool CS = true); + /** string or numerical comparison */ + bool naturalLower (const Value &a, const Value &b, bool CS = true); + int sign (const Value &a); /** rounding */