forked from amazingfate/loongoffice
Fix regression of a series of commits that, intended for filter
queries, unconditionally round numeric values as shown under
ScTable::ValidQuery() and compareByValue() without having taken
into account that the same query and compare functions are used by
the interpreter for all functions that use query criteria,
possibly delivering completely wrong results including in
backports to 7.2.0.0
commit f6b143a57d9bd8f5d7b29febcb4e01ee1eb2ff1d
CommitDate: Wed Jul 7 17:44:46 2021 +0200
tdf#142910 sc filter: fix "greater than" or "smaller than" etc
commit 51375b48378915b6e95c1ac26b2ccf8e39880f7e
CommitDate: Tue Sep 21 11:06:35 2021 +0200
tdf#144253 tdf#144324 sc filter: use formatted values in filters
Several related and intertwined commits in filter context make
assumptions about these queries always being executed rounded, so
the only clean solution is to make that depend on the
ScQueryEntry::Item being passed. Its mbRoundForFilter value is set
to true for all items of all queries executed via ScTable::Query()
and ScTable::GetFilteredFilterEntries(). It might be not all are
necessary (or some even still harmful?) and unnecessarily
obtaining number formats and calling RoundValueAsShown() is still
a bottle neck for those, but that should be addressed and reworked
independently. The important part is calculations work as before.
Also, moved obtaining number formats for calling RoundValueAsShown()
into logic that calls them only if necessary.
Note the TODO in compareByValue() about suspicious rounding of
rItem.mfVal in filter context that is to be addressed.
Change-Id: Ieb178ad1ea15a635caeb1ba698c2f4b7ad676d57
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122729
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
208 lines
5.5 KiB
C++
208 lines
5.5 KiB
C++
/* -*- 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/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <queryentry.hxx>
|
|
|
|
#include <unotools/textsearch.hxx>
|
|
|
|
/*
|
|
* dialog returns the special field values "empty"/"not empty"
|
|
* as constants SC_EMPTYFIELDS and SC_NONEMPTYFIELDS respectively in nVal in
|
|
* conjunctions with the flag bQueryByString = FALSE.
|
|
*/
|
|
|
|
#define SC_EMPTYFIELDS (double(0x0042))
|
|
#define SC_NONEMPTYFIELDS (double(0x0043))
|
|
#define SC_TEXTCOLOR (double(0x0044))
|
|
#define SC_BACKGROUNDCOLOR (double(0x0045))
|
|
|
|
bool ScQueryEntry::Item::operator== (const Item& r) const
|
|
{
|
|
return meType == r.meType && mfVal == r.mfVal && maString == r.maString && mbMatchEmpty == r.mbMatchEmpty
|
|
&& mbRoundForFilter == r.mbRoundForFilter;
|
|
}
|
|
|
|
ScQueryEntry::ScQueryEntry() :
|
|
bDoQuery(false),
|
|
nField(0),
|
|
eOp(SC_EQUAL),
|
|
eConnect(SC_AND),
|
|
maQueryItems(1)
|
|
{
|
|
}
|
|
|
|
ScQueryEntry::ScQueryEntry(const ScQueryEntry& r) :
|
|
bDoQuery(r.bDoQuery),
|
|
nField(r.nField),
|
|
eOp(r.eOp),
|
|
eConnect(r.eConnect),
|
|
maQueryItems(r.maQueryItems)
|
|
{
|
|
}
|
|
|
|
ScQueryEntry::~ScQueryEntry()
|
|
{
|
|
}
|
|
|
|
ScQueryEntry& ScQueryEntry::operator=( const ScQueryEntry& r )
|
|
{
|
|
bDoQuery = r.bDoQuery;
|
|
eOp = r.eOp;
|
|
eConnect = r.eConnect;
|
|
nField = r.nField;
|
|
maQueryItems = r.maQueryItems;
|
|
|
|
pSearchParam.reset();
|
|
pSearchText.reset();
|
|
|
|
return *this;
|
|
}
|
|
|
|
void ScQueryEntry::SetQueryByEmpty()
|
|
{
|
|
eOp = SC_EQUAL;
|
|
maQueryItems.resize(1);
|
|
Item& rItem = maQueryItems[0];
|
|
rItem.meType = ByEmpty;
|
|
rItem.maString = svl::SharedString();
|
|
rItem.mfVal = SC_EMPTYFIELDS;
|
|
}
|
|
|
|
bool ScQueryEntry::IsQueryByEmpty() const
|
|
{
|
|
if (maQueryItems.size() != 1)
|
|
return false;
|
|
|
|
const Item& rItem = maQueryItems[0];
|
|
return eOp == SC_EQUAL &&
|
|
rItem.meType == ByEmpty &&
|
|
rItem.maString.isEmpty() &&
|
|
rItem.mfVal == SC_EMPTYFIELDS;
|
|
}
|
|
|
|
void ScQueryEntry::SetQueryByNonEmpty()
|
|
{
|
|
eOp = SC_EQUAL;
|
|
maQueryItems.resize(1);
|
|
Item& rItem = maQueryItems[0];
|
|
rItem.meType = ByEmpty;
|
|
rItem.maString = svl::SharedString();
|
|
rItem.mfVal = SC_NONEMPTYFIELDS;
|
|
}
|
|
|
|
bool ScQueryEntry::IsQueryByNonEmpty() const
|
|
{
|
|
if (maQueryItems.size() != 1)
|
|
return false;
|
|
|
|
const Item& rItem = maQueryItems[0];
|
|
return eOp == SC_EQUAL &&
|
|
rItem.meType == ByEmpty &&
|
|
rItem.maString.isEmpty() &&
|
|
rItem.mfVal == SC_NONEMPTYFIELDS;
|
|
}
|
|
|
|
void ScQueryEntry::SetQueryByTextColor(Color color)
|
|
{
|
|
eOp = SC_EQUAL;
|
|
maQueryItems.resize(1);
|
|
Item& rItem = maQueryItems[0];
|
|
rItem.meType = ByTextColor;
|
|
rItem.maString = svl::SharedString();
|
|
rItem.mfVal = SC_TEXTCOLOR;
|
|
rItem.maColor = color;
|
|
}
|
|
|
|
bool ScQueryEntry::IsQueryByTextColor() const
|
|
{
|
|
if (maQueryItems.size() != 1)
|
|
return false;
|
|
|
|
const Item& rItem = maQueryItems[0];
|
|
return eOp == SC_EQUAL &&
|
|
rItem.meType == ByTextColor;
|
|
}
|
|
|
|
void ScQueryEntry::SetQueryByBackgroundColor(Color color)
|
|
{
|
|
eOp = SC_EQUAL;
|
|
maQueryItems.resize(1);
|
|
Item& rItem = maQueryItems[0];
|
|
rItem.meType = ByBackgroundColor;
|
|
rItem.maString = svl::SharedString();
|
|
rItem.mfVal = SC_BACKGROUNDCOLOR;
|
|
rItem.maColor = color;
|
|
}
|
|
|
|
bool ScQueryEntry::IsQueryByBackgroundColor() const
|
|
{
|
|
if (maQueryItems.size() != 1)
|
|
return false;
|
|
|
|
const Item& rItem = maQueryItems[0];
|
|
return eOp == SC_EQUAL &&
|
|
rItem.meType == ByBackgroundColor;
|
|
}
|
|
|
|
ScQueryEntry::Item& ScQueryEntry::GetQueryItemImpl() const
|
|
{
|
|
if (maQueryItems.size() != 1)
|
|
// Reset to a single query mode.
|
|
maQueryItems.resize(1);
|
|
return maQueryItems[0];
|
|
}
|
|
|
|
void ScQueryEntry::Clear()
|
|
{
|
|
bDoQuery = false;
|
|
eOp = SC_EQUAL;
|
|
eConnect = SC_AND;
|
|
nField = 0;
|
|
maQueryItems.clear();
|
|
maQueryItems.emplace_back();
|
|
|
|
pSearchParam.reset();
|
|
pSearchText.reset();
|
|
}
|
|
|
|
bool ScQueryEntry::operator==( const ScQueryEntry& r ) const
|
|
{
|
|
return bDoQuery == r.bDoQuery
|
|
&& eOp == r.eOp
|
|
&& eConnect == r.eConnect
|
|
&& nField == r.nField
|
|
&& maQueryItems == r.maQueryItems;
|
|
// do not compare pSearchParam and pSearchText!
|
|
}
|
|
|
|
utl::TextSearch* ScQueryEntry::GetSearchTextPtr( utl::SearchParam::SearchType eSearchType, bool bCaseSens,
|
|
bool bWildMatchSel ) const
|
|
{
|
|
if ( !pSearchParam )
|
|
{
|
|
OUString aStr = maQueryItems[0].maString.getString();
|
|
pSearchParam.reset(new utl::SearchParam(
|
|
aStr, eSearchType, bCaseSens, '~', bWildMatchSel));
|
|
pSearchText.reset(new utl::TextSearch( *pSearchParam, ScGlobal::getCharClass() ));
|
|
}
|
|
return pSearchText.get();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|