include/vcl/menu.hxx | 4 + include/xmloff/xmltoken.hxx | 1 sc/inc/filterentries.hxx | 10 ++ sc/inc/queryentry.hxx | 14 +++- sc/inc/strings.hrc | 2 sc/qa/unit/data/ods/autofilter-colors.ods |binary sc/qa/unit/subsequent_export-test.cxx | 17 ++++ sc/source/core/data/column3.cxx | 28 ++++++-- sc/source/core/data/table3.cxx | 36 ++++++++++ sc/source/core/tool/queryentry.cxx | 24 +++++++ sc/source/filter/xml/XMLExportDatabaseRanges.cxx | 26 ++++++- sc/source/filter/xml/xmlfilti.cxx | 9 ++ sc/source/ui/cctrl/checklistmenu.cxx | 4 - sc/source/ui/inc/gridwin.hxx | 13 +++ sc/source/ui/view/gridwin.cxx | 41 ++++++++++++ schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng | 14 +++- vcl/source/window/menu.cxx | 12 +++ xmloff/source/core/xmltoken.cxx | 1 xmloff/source/token/tokens.txt | 1 19 files changed, 242 insertions(+), 15 deletions(-)
New commits: commit 1f201fd6ae64c97102a60dfdecda25e1dd32d49a Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Wed Apr 28 16:25:42 2021 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Mon Jun 28 09:51:30 2021 +0200 tdf#76258 Add ODF import/export XML looks like: <table:filter-condition table:field-number="0" loext:data-type="background-color" table:value="#ffd7d7" table:operator="="/> <table:filter-condition table:field-number="1" loext:data-type="text-color" table:value="#3465a4" table:operator="="/> Change-Id: Idcddf0ce436da69567e5a7e9dfd7d796dc872586 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114812 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> (cherry picked from commit e2bdd31c0231444f1ba1463bffb5656c230c3073) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115898 Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index a0e52903060a..5421a90da5cb 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -1889,6 +1889,7 @@ namespace xmloff { namespace token { XML_TEXT_BACKGROUND_COLOR, XML_TEXT_BLINKING, XML_TEXT_BOX, + XML_TEXT_COLOR, XML_TEXT_COMBINE, XML_TEXT_COMBINE_END_CHAR, XML_TEXT_COMBINE_START_CHAR, diff --git a/sc/qa/unit/data/ods/autofilter-colors.ods b/sc/qa/unit/data/ods/autofilter-colors.ods new file mode 100644 index 000000000000..d5a88e9299fb Binary files /dev/null and b/sc/qa/unit/data/ods/autofilter-colors.ods differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 61f6a46eba19..d2e1087acf55 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -201,6 +201,7 @@ public: void testTdf95640_ods_to_xlsx(); void testTdf95640_ods_to_xlsx_with_standard_list(); void testTdf95640_xlsx_to_xlsx(); + void testAutofilterColorsODF(); void testRefStringXLSX(); void testRefStringConfigXLSX(); @@ -337,6 +338,7 @@ public: CPPUNIT_TEST(testTdf95640_ods_to_xlsx); CPPUNIT_TEST(testTdf95640_ods_to_xlsx_with_standard_list); CPPUNIT_TEST(testTdf95640_xlsx_to_xlsx); + CPPUNIT_TEST(testAutofilterColorsODF); CPPUNIT_TEST(testRefStringXLSX); CPPUNIT_TEST(testRefStringConfigXLSX); @@ -4048,11 +4050,26 @@ void ScExportTest::testConditionalFormatContainsTextXLSX() CPPUNIT_ASSERT(xDocSh.is()); xmlDocPtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX); + CPPUNIT_ASSERT(pDoc); assertXPathContent(pDoc, "//x:conditionalFormatting/x:cfRule/x:formula", "NOT(ISERROR(SEARCH(\"test\",A1)))"); } +void ScExportTest::testAutofilterColorsODF() +{ + ScDocShellRef xDocSh = loadDoc(u"autofilter-colors.", FORMAT_ODS); + CPPUNIT_ASSERT(xDocSh.is()); + + xmlDocPtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "content.xml", FORMAT_ODS); + CPPUNIT_ASSERT(pDoc); + + assertXPath(pDoc, "//table:filter/table:filter-and/table:filter-condition[1]", "value", "#e8f2a1"); + assertXPath(pDoc, "//table:filter/table:filter-and/table:filter-condition[1][@loext:data-type='background-color']"); + assertXPath(pDoc, "//table:filter/table:filter-and/table:filter-condition[2]", "value", "#3465a4"); + assertXPath(pDoc, "//table:filter/table:filter-and/table:filter-condition[2][@loext:data-type='text-color']"); +} + void ScExportTest::testConditionalFormatPriorityCheckXLSX() { ScDocShellRef xDocSh = loadDoc("conditional_fmt_checkpriority.", FORMAT_XLSX); diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx index 937ac271db26..687168abe5cf 100644 --- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx +++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx @@ -435,16 +435,28 @@ private: return; } - mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(rEntry.nField - nFieldStart)); - if (bCaseSens) - mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); - if (rItems.size() == 1) { // Single item condition. const ScQueryEntry::Item& rItem = rItems.front(); if (rItem.meType == ScQueryEntry::ByString) mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString.getString()); + else if (rItem.meType == ScQueryEntry::ByTextColor + || rItem.meType == ScQueryEntry::ByBackgroundColor) + { + if (mrExport.getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) + { + if (rItem.meType == ScQueryEntry::ByTextColor) + mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_TYPE, XML_TEXT_COLOR); + else + mrExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_DATA_TYPE, + XML_BACKGROUND_COLOR); + } + + OUStringBuffer buffer; + sax::Converter::convertColor(buffer, rItem.maColor); + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, buffer.makeStringAndClear()); + } else { mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DATA_TYPE, XML_NUMBER); @@ -454,6 +466,9 @@ private: } mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, getOperatorXML(rEntry, eSearchType)); + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(rEntry.nField - nFieldStart)); + if (bCaseSens) + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true); } else @@ -465,6 +480,9 @@ private: const ScQueryEntry::Item& rItem = rItems.front(); mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_VALUE, rItem.maString.getString()); mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OPERATOR, OUString("=")); + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, OUString::number(rEntry.nField - nFieldStart)); + if (bCaseSens) + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_CASE_SENSITIVE, XML_TRUE); SvXMLElementExport aElemC(mrExport, XML_NAMESPACE_TABLE, XML_FILTER_CONDITION, true, true); std::for_each(rItems.begin(), rItems.end(), WriteSetItem(mrExport)); diff --git a/sc/source/filter/xml/xmlfilti.cxx b/sc/source/filter/xml/xmlfilti.cxx index 47fea817123c..000dbdfaf302 100644 --- a/sc/source/filter/xml/xmlfilti.cxx +++ b/sc/source/filter/xml/xmlfilti.cxx @@ -26,6 +26,7 @@ #include <document.hxx> #include <o3tl/safeint.hxx> +#include <sax/tools/converter.hxx> #include <svl/sharedstringpool.hxx> #include <xmloff/xmltoken.hxx> #include <xmloff/xmlnmspe.hxx> @@ -312,6 +313,7 @@ ScXMLConditionContext::ScXMLConditionContext( } break; case XML_ELEMENT( TABLE, XML_DATA_TYPE ): + case XML_ELEMENT( LO_EXT, XML_DATA_TYPE ): { sDataType = aIter.toString(); } @@ -437,6 +439,13 @@ void SAL_CALL ScXMLConditionContext::endFastElement( sal_Int32 /*nElement*/ ) rItem.mfVal = sConditionValue.toDouble(); rItem.meType = ScQueryEntry::ByValue; } + else if (IsXMLToken(sDataType, XML_TEXT_COLOR) + || IsXMLToken(sDataType, XML_BACKGROUND_COLOR)) + { + rItem.meType = IsXMLToken(sDataType, XML_TEXT_COLOR) ? ScQueryEntry::ByTextColor + : ScQueryEntry::ByBackgroundColor; + sax::Converter::convertColor(rItem.maColor, sConditionValue); + } else { svl::SharedStringPool& rPool = GetScImport().GetDocument()->GetSharedStringPool(); diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng index 69d43e510d44..47cacf855855 100644 --- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng +++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng @@ -29,7 +29,7 @@ basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR - FITNESS FOR A PARTICULAR PURPOSE. + FITNESS FOR A PARTICULAR PURPOSE. --> <rng:grammar xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:db="urn:oasis:names:tc:opendocument:xmlns:database:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:rng="http://relaxng.org/ns/structure/1.0" xmlns:script="urn:oa sis:names:tc:opendocument:xmlns:script:1.0" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" @@ -2412,4 +2412,16 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. </rng:optional> </rng:define> + <!-- TODO no proposal --> + <rng:define name="table-filter-condition-attlist" combine="interleave"> + <rng:optional> + <rng:attribute name="loext:data-type"> + <rng:choice> + <rng:value>background-color</rng:value> + <rng:value>text-color</rng:value> + </rng:choice> + </rng:attribute> + </rng:optional> + </rng:define> + </rng:grammar> diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 13f1415b8cc4..8c2276ab1251 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -1891,6 +1891,7 @@ namespace xmloff { namespace token { TOKEN( "text-background-color", XML_TEXT_BACKGROUND_COLOR ), TOKEN( "text-blinking", XML_TEXT_BLINKING ), TOKEN( "text-box", XML_TEXT_BOX ), + TOKEN( "text-color", XML_TEXT_COLOR ), TOKEN( "text-combine", XML_TEXT_COMBINE ), TOKEN( "text-combine-end-char", XML_TEXT_COMBINE_END_CHAR ), TOKEN( "text-combine-start-char", XML_TEXT_COMBINE_START_CHAR ), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index b2b95e956bd1..d2dd36122280 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -1806,6 +1806,7 @@ text-autospace text-background-color text-blinking text-box +text-color text-combine text-combine-end-char text-combine-start-char commit 8b5fe4be2a5293af34c27fe21c68be198a82b154 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Wed Apr 21 09:53:54 2021 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Mon Jun 28 09:51:16 2021 +0200 tdf#76258 Filter by colors UI/Logic implementation Change-Id: If7b48219caa466d8a3341bdc4e104d696e8988c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114385 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> (cherry picked from commit 5a4bd9bfbdb881368c202bc766f893a5c672621e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115869 Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx index 76a39c813eef..b787b43b31b7 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -22,6 +22,7 @@ #include <memory> #include <vcl/vclenum.hxx> +#include <tools/color.hxx> #include <tools/link.hxx> #include <vcl/dllapi.h> #include <vcl/keycod.hxx> @@ -306,6 +307,9 @@ public: void SetItemImage( sal_uInt16 nItemId, const Image& rImage ); Image GetItemImage( sal_uInt16 nItemId ) const; + // Instead of an image, draw a color + void SetItemColor( sal_uInt16 nItemId, const Color& rColor ); + void SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand ); OUString GetItemCommand( sal_uInt16 nItemId ) const; diff --git a/sc/inc/filterentries.hxx b/sc/inc/filterentries.hxx index 2a8dccd99cb3..6cbe4c43a929 100644 --- a/sc/inc/filterentries.hxx +++ b/sc/inc/filterentries.hxx @@ -13,12 +13,15 @@ #include <sal/config.h> #include "typedstrdata.hxx" #include <vector> +#include <tools/color.hxx> struct ScFilterEntries { std::vector<ScTypedStrData> maStrData; bool mbHasDates; bool mbHasEmpties; + std::set<Color> maTextColors; + std::set<Color> maBackgroundColors; ScFilterEntries() : mbHasDates(false), mbHasEmpties(false) {} @@ -32,6 +35,13 @@ struct ScFilterEntries bool empty() const { return maStrData.empty(); } void push_back( const ScTypedStrData& r ) { maStrData.push_back(r); } void push_back( ScTypedStrData&& r ) { maStrData.push_back(r); } + std::set<Color>& getTextColors() { return maTextColors; }; + void addTextColor(const Color& aTextColor) { maTextColors.emplace(aTextColor); } + std::set<Color>& getBackgroundColors() { return maBackgroundColors; }; + void addBackgroundColor(const Color& aBackgroundColor) + { + maBackgroundColors.emplace(aBackgroundColor); + } }; #endif diff --git a/sc/inc/queryentry.hxx b/sc/inc/queryentry.hxx index df858f08f339..848e55c3016d 100644 --- a/sc/inc/queryentry.hxx +++ b/sc/inc/queryentry.hxx @@ -23,6 +23,7 @@ #include "global.hxx" #include <svl/sharedstring.hxx> #include <unotools/textsearch.hxx> +#include <tools/color.hxx> #include <memory> #include <vector> @@ -32,7 +33,15 @@ */ struct SC_DLLPUBLIC ScQueryEntry { - enum QueryType { ByValue, ByString, ByDate, ByEmpty }; + enum QueryType + { + ByValue, + ByString, + ByDate, + ByEmpty, + ByTextColor, + ByBackgroundColor, + }; struct Item { @@ -40,6 +49,7 @@ struct SC_DLLPUBLIC ScQueryEntry double mfVal; svl::SharedString maString; bool mbMatchEmpty; + Color maColor; Item() : meType(ByValue), mfVal(0.0), mbMatchEmpty(false) {} @@ -70,6 +80,8 @@ struct SC_DLLPUBLIC ScQueryEntry bool IsQueryByNonEmpty() const; const Item& GetQueryItem() const; Item& GetQueryItem(); + void SetQueryByTextColor(Color color); + void SetQueryByBackgroundColor(Color color); void Clear(); ScQueryEntry& operator=( const ScQueryEntry& r ); bool operator==( const ScQueryEntry& r ) const; diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc index 9a44676ffbd3..95833ec5b2f2 100644 --- a/sc/inc/strings.hrc +++ b/sc/inc/strings.hrc @@ -35,6 +35,8 @@ #define SCSTR_TOP10FILTER NC_("SCSTR_TOP10FILTER", "Top 10") #define SCSTR_FILTER_EMPTY NC_("SCSTR_FILTER_EMPTY", "Empty") #define SCSTR_FILTER_NOTEMPTY NC_("SCSTR_FILTER_NOTEMPTY", "Not Empty") +#define SCSTR_FILTER_TEXT_COLOR NC_("SCSTR_FILTER_TEXT_COLOR", "Text color") +#define SCSTR_FILTER_BACKGROUND_COLOR NC_("SCSTR_FILTER_BACKGROUND_COLOR", "Background color") #define SCSTR_NONAME NC_("SCSTR_NONAME", "unnamed") // "%1 is replaced to column letter, such as 'Column A'" #define SCSTR_COLUMN NC_("SCSTR_COLUMN", "Column %1") diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 90a0dcec43aa..196369e54da8 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -44,6 +44,8 @@ #include <sharedformula.hxx> #include <listenercontext.hxx> #include <filterentries.hxx> +#include <editeng/brushitem.hxx> +#include <editeng/colritem.hxx> #include <com/sun/star/i18n/LocaleDataItem2.hpp> #include <com/sun/star/lang/IllegalArgumentException.hpp> @@ -2402,16 +2404,26 @@ class FilterEntriesHandler ScColumn& mrColumn; ScFilterEntries& mrFilterEntries; - void processCell(SCROW nRow, ScRefCellValue& rCell) + void processCell(ScColumn& rColumn, SCROW nRow, ScRefCellValue& rCell) { SvNumberFormatter* pFormatter = mrColumn.GetDoc()->GetFormatTable(); OUString aStr; sal_uLong nFormat = mrColumn.GetNumberFormat(mrColumn.GetDoc()->GetNonThreadedContext(), nRow); ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, mrColumn.GetDoc()); + // Colors + ScAddress aPos(rColumn.GetCol(), nRow, rColumn.GetTab()); + const SvxColorItem* pColor = rColumn.GetDoc()->GetAttr(aPos, ATTR_FONT_COLOR); + Color textColor = pColor->GetValue(); + + const SvxBrushItem* pBrush = rColumn.GetDoc()->GetAttr(aPos, ATTR_BACKGROUND); + Color backgroundColor = pBrush->GetColor(); + if (rCell.hasString()) { mrFilterEntries.push_back(ScTypedStrData(aStr)); + mrFilterEntries.addTextColor(textColor); + mrFilterEntries.addBackgroundColor(backgroundColor); return; } @@ -2434,6 +2446,8 @@ class FilterEntriesHandler if (!aErr.isEmpty()) { mrFilterEntries.push_back(ScTypedStrData(aErr)); + mrFilterEntries.addTextColor(textColor); + mrFilterEntries.addBackgroundColor(backgroundColor); return; } } @@ -2461,6 +2475,8 @@ class FilterEntriesHandler } // maybe extend ScTypedStrData enum is also an option here mrFilterEntries.push_back(ScTypedStrData(aStr, fVal, ScTypedStrData::Value,bDate)); + mrFilterEntries.addTextColor(textColor); + mrFilterEntries.addBackgroundColor(backgroundColor); } public: @@ -2470,25 +2486,25 @@ public: void operator() (size_t nRow, double fVal) { ScRefCellValue aCell(fVal); - processCell(nRow, aCell); + processCell(mrColumn, nRow, aCell); } void operator() (size_t nRow, const svl::SharedString& rStr) { ScRefCellValue aCell(&rStr); - processCell(nRow, aCell); + processCell(mrColumn, nRow, aCell); } void operator() (size_t nRow, const EditTextObject* p) { ScRefCellValue aCell(p); - processCell(nRow, aCell); + processCell(mrColumn, nRow, aCell); } void operator() (size_t nRow, const ScFormulaCell* p) { ScRefCellValue aCell(const_cast<ScFormulaCell*>(p)); - processCell(nRow, aCell); + processCell(mrColumn, nRow, aCell); } void operator() (const int nElemType, size_t nRow, size_t /* nDataSize */) @@ -2503,7 +2519,7 @@ public: return; } ScRefCellValue aCell = mrColumn.GetCellValue(nRow); - processCell(nRow, aCell); + processCell(mrColumn, nRow, aCell); } }; diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index c27c73fb88e1..60357a32d634 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -19,6 +19,8 @@ #include <comphelper/processfactory.hxx> #include <comphelper/random.hxx> +#include <editeng/brushitem.hxx> +#include <editeng/colritem.hxx> #include <unotools/textsearch.hxx> #include <svl/zforlist.hxx> #include <svl/zformat.hxx> @@ -2687,6 +2689,26 @@ public: return std::pair<bool,bool>(bOk, bTestEqual); } + std::pair<bool, bool> compareByTextColor(SCCOL nCol, SCROW nRow, SCTAB nTab, + const ScQueryEntry::Item& rItem) + { + ScAddress aPos(nCol, nRow, nTab); + const SvxColorItem* pColor = mrDoc.GetAttr(aPos, ATTR_FONT_COLOR); + Color color = pColor->GetValue(); + bool bMatch = rItem.maColor == color; + return std::pair<bool, bool>(bMatch, false); + } + + std::pair<bool, bool> compareByBackgroundColor(SCCOL nCol, SCROW nRow, SCTAB nTab, + const ScQueryEntry::Item& rItem) + { + ScAddress aPos(nCol, nRow, nTab); + const SvxBrushItem* pBrush = mrDoc.GetAttr(aPos, ATTR_BACKGROUND); + Color color = pBrush->GetColor(); + bool bMatch = rItem.maColor == color; + return std::pair<bool, bool>(bMatch, false); + } + // To be called only if both isQueryByValue() and isQueryByString() // returned false and range lookup is wanted! In range lookup comparison // numbers are less than strings. Nothing else is compared. @@ -2801,6 +2823,20 @@ bool ScTable::ValidQuery( aRes.first |= aThisRes.first; aRes.second |= aThisRes.second; } + if (rItem.meType == ScQueryEntry::ByTextColor) + { + std::pair<bool, bool> aThisRes + = aEval.compareByTextColor(nCol, nRow, nTab, rItem); + aRes.first |= aThisRes.first; + aRes.second |= aThisRes.second; + } + if (rItem.meType == ScQueryEntry::ByBackgroundColor) + { + std::pair<bool,bool> aThisRes = + aEval.compareByBackgroundColor(nCol, nRow, nTab, rItem); + aRes.first |= aThisRes.first; + aRes.second |= aThisRes.second; + } else if (rParam.mbRangeLookup) { std::pair<bool,bool> aThisRes = diff --git a/sc/source/core/tool/queryentry.cxx b/sc/source/core/tool/queryentry.cxx index ecc912b34c4a..581939748f86 100644 --- a/sc/source/core/tool/queryentry.cxx +++ b/sc/source/core/tool/queryentry.cxx @@ -29,6 +29,8 @@ #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 { @@ -115,6 +117,28 @@ bool ScQueryEntry::IsQueryByNonEmpty() const 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; +} + +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; +} + const ScQueryEntry::Item& ScQueryEntry::GetQueryItem() const { if (maQueryItems.size() > 1) diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index b9b5acca11c8..462051061e55 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -452,9 +452,9 @@ void ScMenuFloatingWindow::executeMenuItem(size_t nPos) // no action is defined. return; - terminateAllPopupMenus(); - maMenuItems[nPos].mpAction->execute(); + + terminateAllPopupMenus(); } void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu) diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index bd4ca07159c5..5ebb26241d10 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -302,7 +302,18 @@ protected: virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) override; public: - enum class AutoFilterMode { Normal, Top10, Custom, Empty, NonEmpty, SortAscending, SortDescending }; + enum class AutoFilterMode + { + Normal, + Top10, + Custom, + Empty, + NonEmpty, + TextColor, + BackgroundColor, + SortAscending, + SortDescending, + }; ScGridWindow( vcl::Window* pParent, ScViewData* pData, ScSplitPos eWhichPos ); virtual ~ScGridWindow() override; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 6d2c4ea19106..bb2a40368bfe 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -705,6 +705,11 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) mpAutoFilterPopup->addMenuItem( ScResId(SCSTR_FILTER_NOTEMPTY), new AutoFilterAction(this, AutoFilterMode::NonEmpty)); mpAutoFilterPopup->addSeparator(); + mpAutoFilterPopup->addMenuItem( + ScResId(SCSTR_FILTER_TEXT_COLOR), new AutoFilterAction(this, AutoFilterMode::TextColor)); + mpAutoFilterPopup->addMenuItem( + ScResId(SCSTR_FILTER_BACKGROUND_COLOR), new AutoFilterAction(this, AutoFilterMode::BackgroundColor)); + mpAutoFilterPopup->addSeparator(); mpAutoFilterPopup->addMenuItem( ScResId(SCSTR_STDFILTER), new AutoFilterAction(this, AutoFilterMode::Custom)); @@ -863,6 +868,42 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode) break; case AutoFilterMode::NonEmpty: pEntry->SetQueryByNonEmpty(); + break; + case AutoFilterMode::TextColor: + case AutoFilterMode::BackgroundColor: + { + ScFilterEntries aFilterEntries; + pDoc->GetFilterEntries(rPos.Col(), rPos.Row(), rPos.Tab(), aFilterEntries); + + VclPtr<PopupMenu> pColorMenu = VclPtr<PopupMenu>::Create(); + std::set<Color> aColors = eMode == AutoFilterMode::TextColor + ? aFilterEntries.getTextColors() + : aFilterEntries.getBackgroundColors(); + sal_Int32 i = 1; + for (auto& rColor : aColors) + { + pColorMenu->InsertItem(i, OUString(), MenuItemBits::CHECKABLE); + pColorMenu->SetItemColor(i, rColor); + i++; + } + + sal_uInt16 nSelected = pColorMenu->Execute(this, mpAutoFilterPopup->GetPosPixel()); + pColorMenu.disposeAndClear(); + + if (nSelected == 0) + break; + + // Get selected color from set + std::set<Color>::iterator it = aColors.begin(); + std::advance(it, nSelected - 1); + Color selectedColor = *it; + + if (eMode == AutoFilterMode::TextColor) + pEntry->SetQueryByTextColor(selectedColor); + else + pEntry->SetQueryByBackgroundColor(selectedColor); + } + break; default: // We don't know how to handle this! diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 1d25c089e976..918910444a70 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -21,6 +21,7 @@ #include <sal/log.hxx> #include <comphelper/lok.hxx> +#include <bitmapwriteaccess.hxx> #include <vcl/svapp.hxx> #include <vcl/mnemonic.hxx> #include <vcl/image.hxx> @@ -1010,6 +1011,17 @@ OUString Menu::GetItemText( sal_uInt16 nItemId ) const return OUString(); } +void Menu::SetItemColor(sal_uInt16 nItemId, const Color& rColor) +{ + Bitmap aBmp(Size(50, 50), 24); + BitmapWriteAccess aBmpAccess(aBmp); + aBmpAccess.SetFillColor(rColor); + aBmpAccess.FillRect(tools::Rectangle(0, 0, 49, 49)); + BitmapEx aBmpEx(aBmp); + Image aImage(aBmpEx); + SetItemImage(nItemId, aImage); +} + void Menu::SetItemImage( sal_uInt16 nItemId, const Image& rImage ) { size_t nPos; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits