22 #include <unonames.hxx>
24 #include <document.hxx>
30 #include <com/sun/star/uno/Reference.h>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/sheet/XSheetCondition.hpp>
33 #include <com/sun/star/sheet/TableValidationVisibility.hpp>
38 #include <osl/diagnose.h>
51 aAlertStyle(
sheet::ValidationAlertStyle_STOP),
52 aValidationType(
sheet::ValidationType_ANY),
53 aOperator(
sheet::ConditionOperator_NONE),
55 bShowErrorMessage(false),
56 bShowInputMessage(false),
99 sal_Int32& nValidationIndex)
101 uno::Reference<beans::XPropertySet> xPropertySet(aTempAny, uno::UNO_QUERY);
102 if (!xPropertySet.is())
105 OUString sErrorMessage;
106 xPropertySet->getPropertyValue(
gsERRMESS) >>= sErrorMessage;
107 OUString sErrorTitle;
108 xPropertySet->getPropertyValue(
gsERRTITLE) >>= sErrorTitle;
109 OUString sInputMessage;
110 xPropertySet->getPropertyValue(
gsINPMESS) >>= sInputMessage;
111 OUString sInputTitle;
112 xPropertySet->getPropertyValue(
gsINPTITLE) >>= sInputTitle;
113 bool bShowErrorMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(
gsSHOWERR));
114 bool bShowInputMessage = ::cppu::any2bool(xPropertySet->getPropertyValue(
gsSHOWINP));
115 sheet::ValidationType aValidationType;
116 xPropertySet->getPropertyValue(
gsTYPE) >>= aValidationType;
117 if (!bShowErrorMessage && !bShowInputMessage && aValidationType == sheet::ValidationType_ANY &&
118 sErrorMessage.isEmpty() && sErrorTitle.isEmpty() && sInputMessage.isEmpty() && sInputTitle.isEmpty())
132 uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
135 aValidation.
sFormula1 = xCondition->getFormula1();
136 aValidation.
sFormula2 = xCondition->getFormula2();
137 aValidation.
aOperator = xCondition->getOperator();
138 table::CellAddress aCellAddress= xCondition->getSourcePosition();
139 aValidation.
aBaseCell =
ScAddress( static_cast<SCCOL>(aCellAddress.Column), static_cast<SCROW>(aCellAddress.Row), aCellAddress.Sheet );
142 bool bEqualFound(
false);
145 while (i <
nCount && !bEqualFound)
152 nValidationIndex = i;
155 sal_Int32 nNameIndex(
nCount + 1);
156 OUString sCount(OUString::number(nNameIndex));
157 aValidation.
sName +=
"val";
158 aValidation.
sName += sCount;
160 nValidationIndex =
nCount;
176 case sheet::ValidationType_DATE :
177 sCondition +=
"cell-content-is-date()";
179 case sheet::ValidationType_DECIMAL :
180 sCondition +=
"cell-content-is-decimal-number()";
182 case sheet::ValidationType_LIST :
183 sCondition +=
"cell-content-is-in-list(" + aValidation.
sFormula1 +
")";
185 case sheet::ValidationType_TEXT_LEN :
186 if (aValidation.
aOperator != sheet::ConditionOperator_BETWEEN &&
187 aValidation.
aOperator != sheet::ConditionOperator_NOT_BETWEEN)
188 sCondition +=
"cell-content-text-length()";
190 case sheet::ValidationType_TIME :
191 sCondition +=
"cell-content-is-time()";
193 case sheet::ValidationType_WHOLE :
194 sCondition +=
"cell-content-is-whole-number()";
196 case sheet::ValidationType_CUSTOM :
197 sCondition +=
"is-true-formula(" + aValidation.
sFormula1 +
")";
207 ((aValidation.
aOperator == sheet::ConditionOperator_BETWEEN ||
208 aValidation.
aOperator == sheet::ConditionOperator_NOT_BETWEEN) &&
212 sCondition +=
" and ";
213 if (aValidation.
aOperator != sheet::ConditionOperator_BETWEEN &&
214 aValidation.
aOperator != sheet::ConditionOperator_NOT_BETWEEN)
217 sCondition +=
"cell-content()";
220 case sheet::ConditionOperator_EQUAL :
223 case sheet::ConditionOperator_GREATER :
226 case sheet::ConditionOperator_GREATER_EQUAL :
229 case sheet::ConditionOperator_LESS :
232 case sheet::ConditionOperator_LESS_EQUAL :
235 case sheet::ConditionOperator_NOT_EQUAL :
249 if (aValidation.
aOperator == sheet::ConditionOperator_BETWEEN)
250 sCondition +=
"cell-content-text-length-is-between(";
252 sCondition +=
"cell-content-text-length-is-not-between(";
256 if (aValidation.
aOperator == sheet::ConditionOperator_BETWEEN)
257 sCondition +=
"cell-content-is-between(";
259 sCondition +=
"cell-content-is-not-between(";
268 if (!sCondition.isEmpty())
286 const OUString& sTitle,
const OUString& sOUMessage,
287 const bool bShowMessage,
const bool bIsHelpMessage)
289 if (!sTitle.isEmpty())
295 std::unique_ptr<SvXMLElementExport> pMessage;
300 if (sOUMessage.isEmpty())
304 OUStringBuffer sTemp;
306 bool bPrevCharWasSpace(
true);
307 while(i < sText.getLength())
309 if( sText[i] ==
'\n')
313 bPrevCharWasSpace =
true;
316 sTemp.append(sText[i]);
319 if (!sTemp.isEmpty())
335 OUString sCondition(
GetCondition(rExport, rValidation));
336 if (!sCondition.isEmpty())
339 if (rValidation.bIgnoreBlanks)
343 if (rValidation.aValidationType == sheet::ValidationType_LIST)
345 switch (rValidation.nShowList)
347 case sheet::TableValidationVisibility::INVISIBLE:
350 case sheet::TableValidationVisibility::UNSORTED:
353 case sheet::TableValidationVisibility::SORTEDASCENDING:
357 OSL_FAIL(
"unknown ListType");
363 if (rValidation.bShowInputMessage || !rValidation.sInputMessage.isEmpty() || !rValidation.sInputTitle.isEmpty())
365 WriteMessage(rExport, rValidation.sInputTitle, rValidation.sInputMessage, rValidation.bShowInputMessage,
true);
367 if (rValidation.bShowErrorMessage || !rValidation.sErrorMessage.isEmpty() || !rValidation.sErrorTitle.isEmpty())
369 switch (rValidation.aAlertStyle)
371 case sheet::ValidationAlertStyle_INFO :
374 WriteMessage(rExport, rValidation.sErrorTitle, rValidation.sErrorMessage, rValidation.bShowErrorMessage,
false);
377 case sheet::ValidationAlertStyle_WARNING :
380 WriteMessage(rExport, rValidation.sErrorTitle, rValidation.sErrorMessage, rValidation.bShowErrorMessage,
false);
383 case sheet::ValidationAlertStyle_STOP :
386 WriteMessage(rExport, rValidation.sErrorTitle, rValidation.sErrorMessage, rValidation.bShowErrorMessage,
false);
389 case sheet::ValidationAlertStyle_MACRO :
393 if (rValidation.bShowErrorMessage)
405 const OUString
sScript(
"Script");
407 {
"EventType",
uno::Any(bScriptURL ? sScript : OUString(
"StarBasic")) },
408 {
"Library",
uno::Any(OUString()) },
409 { bScriptURL ? sScript : OUString(
"MacroName"),
uno::Any(rValidation.sErrorTitle) }
432 const sal_Int32 nTable,
const sal_Int32 nPos,
433 const sal_Int32 i,
bool& bIsAutoStyle)
439 const sal_Int32 nLastRow,
const sal_Int32 nLastCol,
451 bool bPrevAutoStyle(
false);
453 sal_Int32 nPrevIndex(0);
454 sal_Int32 nRepeat(0);
455 for (sal_Int32
i = nLastCol;
i >= 0; --
i)
457 pDoc->
GetColDefault(nTab, static_cast<SCCOL>(
i), static_cast<SCROW>(nLastRow), nPos);
461 (*pDefaults)[
i].nIndex = nPrevIndex;
462 (*pDefaults)[
i].bIsAutoStyle = bPrevAutoStyle;
468 if ((nIndex != nPrevIndex) || (bIsAutoStyle != bPrevAutoStyle))
472 (*pDefaults)[
i].nIndex = nPrevIndex;
473 (*pDefaults)[
i].bIsAutoStyle = bPrevAutoStyle;
477 (*pDefaults)[
i].nIndex = nPrevIndex;
478 (*pDefaults)[
i].bIsAutoStyle = bPrevAutoStyle;
481 (*pDefaults)[
i].nRepeat = nRepeat;
492 nValidationIndex(-1),
503 : aRowFormatRanges(),
504 pColDefaults(nullptr),
510 : aRowFormatRanges(pRanges->aRowFormatRanges),
511 pColDefaults(pRanges->pColDefaults),
512 nSize(pRanges->nSize)
530 if ((nPrevIndex != rFormatRange.
nIndex) ||
532 nIndex = rFormatRange.
nIndex;
534 bool bInserted(
false);
538 if ((nPrevStartCol == (rRange.nStartColumn + rRange.nRepeatColumns))
539 && (rRange.bIsAutoStyle == rFormatRange.
bIsAutoStyle) && (rRange.nIndex == nIndex)
544 rRange.nRepeatColumns += nRepeat;
567 sal_Int32 nPrevIndex = -1;
568 bool bPrevAutoStyle =
true;
571 OSL_ENSURE( static_cast<size_t>(nPrevStartCol) <
pColDefaults->size(),
"nPrevStartCol out of bounds");
573 if (static_cast<size_t>(nPrevStartCol) <
pColDefaults->size())
575 nRepeat = (*pColDefaults)[nPrevStartCol].nRepeat;
576 nPrevIndex = (*pColDefaults)[nPrevStartCol].nIndex;
577 bPrevAutoStyle = (*pColDefaults)[nPrevStartCol].bIsAutoStyle;
587 bPrevAutoStyle =
false;
591 nRepeat = (*pColDefaults)[
pColDefaults->size()-1].nRepeat;
592 nPrevIndex = (*pColDefaults)[
pColDefaults->size()-1].nIndex;
593 bPrevAutoStyle = (*pColDefaults)[
pColDefaults->size()-1].bIsAutoStyle;
597 for(sal_uInt32
i = nPrevStartCol + nRepeat;
i < nEnd &&
i <
pColDefaults->size();
i += (*pColDefaults)[
i].nRepeat)
599 OSL_ENSURE(sal_uInt32(nPrevStartCol + nRepeat) <= nEnd,
"something went wrong");
603 AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
605 nRepeat = (*pColDefaults)[
i].nRepeat;
606 nPrevIndex = (*pColDefaults)[
i].nIndex;
607 bPrevAutoStyle = (*pColDefaults)[
i].bIsAutoStyle;
610 nRepeat += (*pColDefaults)[
i].nRepeat;
612 if (sal_uInt32(nPrevStartCol + nRepeat) > nEnd)
613 nRepeat = nEnd - nPrevStartCol;
614 AddRange(nPrevStartCol, nRepeat, nPrevIndex, bPrevAutoStyle, rFormatRange);
623 aFormatRange = *aItr;
633 sal_Int32 nMaxRows(0);
638 nMaxRows = (*aItr).nRepeatRows;
642 OSL_FAIL(
"no ranges found");
653 : nStyleNameIndex(-1)
654 , nValidationIndex(-1)
675 pColDefaults(nullptr)
685 sal_Int32 nSize =
aTables.size() - 1;
687 for (sal_Int32
i = nSize;
i < nTable; ++
i)
706 while ((i >= 0) && (!bFound))
729 sal_Int32 nPrefixLength(rPrefix.getLength());
730 OUString sTemp(rString.copy(nPrefixLength));
731 sal_Int32
nIndex(sTemp.toInt32());
750 bIsAutoStyle =
false;
775 const sal_Int32 nColumn,
const sal_Int32 nRow,
bool& bIsAutoStyle)
const
782 if ((rFormatRange.aRangeAddress.StartColumn <= nColumn) &&
783 (rFormatRange.aRangeAddress.EndColumn >= nColumn) &&
784 (rFormatRange.aRangeAddress.StartRow <= nRow) &&
785 (rFormatRange.aRangeAddress.EndRow >= nRow))
787 bIsAutoStyle = rFormatRange.bIsAutoStyle;
788 return rFormatRange.nStyleNameIndex;
795 bool& bIsAutoStyle, sal_Int32& nValidationIndex, sal_Int32& nNumberFormat,
const sal_Int32 nRemoveBeforeRow)
801 ScMyFormatRangeAddresses::iterator aItr(rFormatRanges.begin());
802 ScMyFormatRangeAddresses::iterator aEndItr(rFormatRanges.end());
803 while (aItr != aEndItr)
805 if (((*aItr).aRangeAddress.StartColumn <= nColumn) &&
806 ((*aItr).aRangeAddress.EndColumn >= nColumn) &&
807 ((*aItr).aRangeAddress.StartRow <= nRow) &&
808 ((*aItr).aRangeAddress.EndRow >= nRow))
810 bIsAutoStyle = aItr->bIsAutoStyle;
811 nValidationIndex = aItr->nValidationIndex;
812 nNumberFormat = aItr->nNumberFormat;
815 ((*pColDefaults)[nColumn].nIndex != -1) &&
816 ((*
pColDefaults)[nColumn].nIndex == (*aItr).nStyleNameIndex) &&
817 ((*
pColDefaults)[nColumn].bIsAutoStyle == (*aItr).bIsAutoStyle))
820 return (*aItr).nStyleNameIndex;
824 if ((*aItr).aRangeAddress.EndRow < nRemoveBeforeRow)
825 aItr = rFormatRanges.erase(aItr);
836 sal_Int32 nTotalColumns(nEndColumn - nStartColumn + 1);
839 ScMyFormatRangeAddresses::iterator aItr(rFormatRanges.begin());
840 ScMyFormatRangeAddresses::iterator aEndItr(rFormatRanges.end());
841 sal_Int32 nColumns = 0;
842 while (aItr != aEndItr && nColumns < nTotalColumns)
844 if (((*aItr).aRangeAddress.StartRow <= nRow) &&
845 ((*aItr).aRangeAddress.EndRow >= nRow))
847 if ((((*aItr).aRangeAddress.StartColumn <= nStartColumn) &&
848 ((*aItr).aRangeAddress.EndColumn >= nStartColumn)) ||
849 (((*aItr).aRangeAddress.StartColumn <= nEndColumn) &&
850 ((*aItr).aRangeAddress.EndColumn >= nEndColumn)) ||
851 (((*aItr).aRangeAddress.StartColumn >= nStartColumn) &&
852 ((*aItr).aRangeAddress.EndColumn <= nEndColumn)))
855 aRange.
nIndex = aItr->nStyleNameIndex;
858 if ((aItr->aRangeAddress.StartColumn < nStartColumn) &&
859 (aItr->aRangeAddress.EndColumn >= nStartColumn))
861 if (aItr->aRangeAddress.EndColumn >= nEndColumn)
864 aRange.
nRepeatColumns = aItr->aRangeAddress.EndColumn - nStartColumn + 1;
867 else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
868 (aItr->aRangeAddress.EndColumn <= nEndColumn))
870 aRange.
nRepeatColumns = aItr->aRangeAddress.EndColumn - aItr->aRangeAddress.StartColumn + 1;
873 else if ((aItr->aRangeAddress.StartColumn >= nStartColumn) &&
874 (aItr->aRangeAddress.StartColumn <= nEndColumn) &&
875 (aItr->aRangeAddress.EndColumn > nEndColumn))
877 aRange.
nRepeatColumns = nEndColumn - aItr->aRangeAddress.StartColumn + 1;
880 aRange.
nRepeatRows = aItr->aRangeAddress.EndRow - nRow + 1;
887 if(aItr->aRangeAddress.EndRow < nRow)
888 aItr = rFormatRanges.erase(aItr);
892 pRowFormatRanges->
Sort();
896 const sal_Int32 nStringIndex,
const bool bIsAutoStyle,
const sal_Int32 nValidationIndex,
897 const sal_Int32 nNumberFormat)
907 rFormatRanges.push_back(aFormatRange);
941 sal_Int32 nPrefixLength(rPrefix.getLength());
942 OUString sTemp(rString.copy(nPrefixLength));
943 sal_Int32
nIndex(sTemp.toInt32());
981 sal_Int32 nSize(
aTables.size() - 1);
983 for (sal_Int32
i = nSize;
i < nTable; ++
i)
996 bIsVisible =
aTables[nTable][nField].bIsVisible;
997 return aTables[nTable][nField].nIndex;
1001 bIsVisible =
aTables[nTable][
aTables[nTable].size() - 1].bIsVisible;
1007 const sal_Int32 nStringIndex,
const bool bIsVisible)
1012 aStyle.
nIndex = nStringIndex;
1014 if (
aTables[nTable].
size() == static_cast<sal_uInt32>(nField))
1015 aTables[nTable].push_back(aStyle);
1016 aTables[nTable][nField] = aStyle;
1024 return mnTable == nTable &&
mnStart <= nField && nField <
mnEnd;
1038 sal_Int32 nSize(
aTables.size() - 1);
1040 for (sal_Int32
i = nSize;
i < nTable; ++
i)
1042 aTables.push_back(std::make_unique<StylesType>(0, nFields+1, -1));
1057 if (!r.is_tree_valid())
1059 sal_Int32 nStyle(0);
1060 sal_Int32 nStart(0), nEnd(0);
1061 if (r.search_tree(nField, nStyle, &nStart, &nEnd).second)
1075 const sal_Int32 nStringIndex)
1079 r.insert_back(nField, nField+1, nStringIndex);
1083 const sal_Int32 nStringIndex,
const sal_Int32 nEndField)
1085 OSL_ENSURE( nStartField <= nEndField,
"bad field range");
1088 r.insert_back(nStartField, nEndField+1, nStringIndex);
static bool IsXScriptURL(const OUString &rScriptURL)
sal_Int32 GetIndexOfStyleName(const OUString &rString, const OUString &rPrefix)
constexpr OUStringLiteral gsINPTITLE(u""SC_UNONAME_INPTITLE)
#define SC_UNONAME_INPMESS
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
constexpr OUStringLiteral gsSHOWERR(u""SC_UNONAME_SHOWERR)
constexpr OUStringLiteral gsSHOWLIST(u""SC_UNONAME_SHOWLIST)
static OUString GetBaseCellAddress(const ScDocument *pDoc, const ScAddress &aCell)
constexpr sal_uInt16 XML_NAMESPACE_OOOC
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex, const bool bIsVisible)
static void WriteMessage(ScXMLExport &rExport, const OUString &sTitle, const OUString &sMessage, const bool bShowMessage, const bool bIsHelpMessage)
virtual ~ScColumnStyles() override
#define SC_UNONAME_SHOWINP
constexpr OUStringLiteral gsIGNOREBL(u""SC_UNONAME_IGNOREBL)
#define SC_UNONAME_ERRMESS
sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField, bool &bIsVisible)
css::sheet::ConditionOperator aOperator
constexpr OUStringLiteral gsERRTITLE(u""SC_UNONAME_ERRTITLE)
css::sheet::ValidationAlertStyle aAlertStyle
#define SC_UNONAME_ERRTITLE
static void GetStringFromAddress(OUString &rString, const ScAddress &rAddress, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
Range to String core.
ScMyValidationsContainer()
exports com.sun.star. sheet
#define SC_UNONAME_IGNOREBL
#define SC_UNONAME_ERRALSTY
constexpr OUStringLiteral gsTYPE(u""SC_UNONAME_TYPE)
~ScMyValidationsContainer()
#define SC_UNONAME_SHOWERR
void AddAttribute(sal_uInt16 nPrefix, const char *pName, const OUString &rValue)
void AddFieldStyleName(const sal_Int32 nTable, const sal_Int32 nField, const sal_Int32 nStringIndex)
void AddValidation(const css::uno::Any &aAny, sal_Int32 &nValidationIndex)
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
sal_Int32 AddStyleName(const OUString &rString)
bool hasCache(sal_Int32 nTable, sal_Int32 nField) const
std::vector< ScColumnStyle > ScMyColumnStyleVec
::mdds::flat_segment_tree< sal_Int32, sal_Int32 > StylesType
ScMyDefaultStyleList maColDefaults
css::sheet::ValidationType aValidationType
constexpr OUStringLiteral gsSHOWINP(u""SC_UNONAME_SHOWINP)
virtual ~ScRowStyles() override
void GetColDefault(SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW &nDefault)
constexpr OUStringLiteral gsERRALSTY(u""SC_UNONAME_ERRALSTY)
XMLEventExport & GetEventExport()
constexpr sal_uInt16 XML_NAMESPACE_TEXT
void ExportSingleEvent(css::uno::Sequence< css::beans::PropertyValue > &rEventValues, const OUString &rApiEventName, bool bUseWhitespace=true)
void WriteValidations(ScXMLExport &rExport)
std::vector< OUString > aStyleNames
constexpr OUStringLiteral gsERRMESS(u""SC_UNONAME_ERRMESS)
sal_Int32 GetStyleNameIndex(const sal_Int32 nTable, const sal_Int32 nField)
static OUString GetCondition(ScXMLExport &rExport, const ScMyValidation &aValidation)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) override
void CreateColumnIfNotExists(SCTAB nTab, SCCOL nCol)
constexpr OUStringLiteral gsINPMESS(u""SC_UNONAME_INPMESS)
void FillDefaultStyles(const sal_Int32 nTable, const sal_Int32 nLastRow, const sal_Int32 nLastCol, const ScFormatRangeStyles *pCellStyles, ScDocument *pDoc)
formula::FormulaGrammar::Grammar GetStorageGrammar() const
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
static sal_Int32 GetStyleNameIndex(const ScFormatRangeStyles *pCellStyles, const sal_Int32 nTable, const sal_Int32 nPos, const sal_Int32 i, bool &bIsAutoStyle)
const SvXMLNamespaceMap & GetNamespaceMap() const
const OUString & GetValidationName(const sal_Int32 nIndex)
std::vector< ScMyValidation > aValidationVec
ScDocument * GetDocument()
constexpr sal_uInt16 XML_NAMESPACE_TABLE
constexpr OUStringLiteral sScript
virtual void AddNewTable(const sal_Int32 nTable, const sal_Int32 nFields) override
#define SC_UNONAME_SHOWLIST
Sequence< sal_Int8 > aSeq
constexpr sal_uInt16 XML_NAMESPACE_OF
OUString & GetStyleNameByIndex(const sal_Int32 nIndex)
#define SC_UNONAME_INPTITLE
std::vector< std::unique_ptr< StylesType > > aTables
bool IsEqual(const ScMyValidation &aVal) const
if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
virtual ~ScColumnRowStylesBase()
std::vector< ScMyDefaultStyle > ScMyDefaultStyleList
ScMyColumnVectorVec aTables