LibreOffice Module sc (master) 1
validat.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <config_features.h>
21
22#include <validat.hxx>
23#include <com/sun/star/sheet/TableValidationVisibility.hpp>
24
25#include <sfx2/app.hxx>
26#include <sfx2/objsh.hxx>
27#include <sfx2/viewsh.hxx>
28#include <basic/sbmeth.hxx>
29#include <basic/sbmod.hxx>
30#include <basic/sbstar.hxx>
31#include <basic/sberrors.hxx>
32
33#include <basic/sbx.hxx>
34#include <svl/numformat.hxx>
36#include <vcl/svapp.hxx>
37#include <vcl/weld.hxx>
38#include <rtl/math.hxx>
39#include <osl/diagnose.h>
40
41#include <document.hxx>
42#include <formulacell.hxx>
43#include <patattr.hxx>
44#include <globstr.hrc>
45#include <scresid.hxx>
46#include <rangenam.hxx>
47#include <dbdata.hxx>
48#include <typedstrdata.hxx>
49#include <editutil.hxx>
50#include <tokenarray.hxx>
51#include <scmatrix.hxx>
52#include <cellvalue.hxx>
53#include <comphelper/lok.hxx>
54#include <simpleformulacalc.hxx>
55
56#include <math.h>
57#include <memory>
58
59using namespace formula;
60
61// Entries for validation (with only one condition)
62
64 const OUString& rExpr1, const OUString& rExpr2,
65 ScDocument& rDocument, const ScAddress& rPos,
66 const OUString& rExprNmsp1, const OUString& rExprNmsp2,
68 FormulaGrammar::Grammar eGrammar2 )
69 : ScConditionEntry( eOper, rExpr1, rExpr2, rDocument, rPos, rExprNmsp1,
70 rExprNmsp2, eGrammar1, eGrammar2 )
71 , nKey( 0 )
72 , eDataMode( eMode )
73 , bShowInput(false)
74 , bShowError(false)
75 , eErrorStyle( SC_VALERR_STOP )
76 , mnListType( css::sheet::TableValidationVisibility::UNSORTED )
77{
78}
79
81 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
82 ScDocument& rDocument, const ScAddress& rPos )
83 : ScConditionEntry( eOper, pArr1, pArr2, rDocument, rPos )
84 , nKey( 0 )
85 , eDataMode( eMode )
86 , bShowInput(false)
87 , bShowError(false)
88 , eErrorStyle( SC_VALERR_STOP )
89 , mnListType( css::sheet::TableValidationVisibility::UNSORTED )
90{
91}
92
94 : ScConditionEntry( r )
95 , nKey( r.nKey )
96 , eDataMode( r.eDataMode )
97 , bShowInput( r.bShowInput )
98 , bShowError( r.bShowError )
99 , eErrorStyle( r.eErrorStyle )
100 , mnListType( r.mnListType )
101 , aInputTitle( r.aInputTitle )
102 , aInputMessage( r.aInputMessage )
103 , aErrorTitle( r.aErrorTitle )
104 , aErrorMessage( r.aErrorMessage )
105{
106 // Formulae copied by RefCount
107}
108
110 : ScConditionEntry( rDocument, r )
111 , nKey( r.nKey )
112 , eDataMode( r.eDataMode )
113 , bShowInput( r.bShowInput )
114 , bShowError( r.bShowError )
115 , eErrorStyle( r.eErrorStyle )
116 , mnListType( r.mnListType )
117 , aInputTitle( r.aInputTitle )
118 , aInputMessage( r.aInputMessage )
119 , aErrorTitle( r.aErrorTitle )
120 , aErrorMessage( r.aErrorMessage )
121{
122 // Formulae really copied
123}
124
126{
127}
128
130{
132 return EqualEntries( aDefault );
133}
134
136{
137 // test same parameters (excluding Key)
138
140 eDataMode == r.eDataMode &&
141 bShowInput == r.bShowInput &&
142 bShowError == r.bShowError &&
144 mnListType == r.mnListType &&
149}
150
152{
153 bShowInput = false;
154}
155
157{
158 bShowError = false;
159}
160
161void ScValidationData::SetInput( const OUString& rTitle, const OUString& rMsg )
162{
163 bShowInput = true;
164 aInputTitle = rTitle;
165 aInputMessage = rMsg;
166}
167
168void ScValidationData::SetError( const OUString& rTitle, const OUString& rMsg,
169 ScValidErrorStyle eStyle )
170{
171 bShowError = true;
172 eErrorStyle = eStyle;
173 aErrorTitle = rTitle;
174 aErrorMessage = rMsg;
175}
176
177bool ScValidationData::GetErrMsg( OUString& rTitle, OUString& rMsg,
178 ScValidErrorStyle& rStyle ) const
179{
180 rTitle = aErrorTitle;
181 rMsg = aErrorMessage;
182 rStyle = eErrorStyle;
183 return bShowError;
184}
185
186bool ScValidationData::DoScript( const ScAddress& rPos, const OUString& rInput,
187 ScFormulaCell* pCell, weld::Window* pParent ) const
188{
189 ScDocument* pDocument = GetDocument();
190 SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
191 if ( !pDocSh )
192 return false;
193
194 bool bScriptReturnedFalse = false; // default: do not abort
195
196 // 1) entered or calculated value
197 css::uno::Any aParam0(rInput);
198 if ( pCell ) // if cell exists, call interpret
199 {
200 if ( pCell->IsValue() )
201 aParam0 <<= pCell->GetValue();
202 else
203 aParam0 <<= pCell->GetString().getString();
204 }
205
206 // 2) Position of the cell
207 OUString aPosStr(rPos.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, pDocument, pDocument->GetAddressConvention()));
208
209 // Set up parameters
210 css::uno::Sequence< css::uno::Any > aParams{ aParam0, css::uno::Any(aPosStr) };
211
212 // use link-update flag to prevent closing the document
213 // while the macro is running
214 bool bWasInLinkUpdate = pDocument->IsInLinkUpdate();
215 if ( !bWasInLinkUpdate )
216 pDocument->SetInLinkUpdate( true );
217
218 if ( pCell )
219 pDocument->LockTable( rPos.Tab() );
220
221 css::uno::Any aRet;
222 css::uno::Sequence< sal_Int16 > aOutArgsIndex;
223 css::uno::Sequence< css::uno::Any > aOutArgs;
224
225 ErrCode eRet = pDocSh->CallXScript(
226 aErrorTitle, aParams, aRet, aOutArgsIndex, aOutArgs );
227
228 if ( pCell )
229 pDocument->UnlockTable( rPos.Tab() );
230
231 if ( !bWasInLinkUpdate )
232 pDocument->SetInLinkUpdate( false );
233
234 // Check the return value from the script
235 // The contents of the cell get reset if the script returns false
236 bool bTmp = false;
237 if ( eRet == ERRCODE_NONE &&
238 aRet.getValueType() == cppu::UnoType<bool>::get() &&
239 ( aRet >>= bTmp ) &&
240 !bTmp )
241 {
242 bScriptReturnedFalse = true;
243 }
244
245 if ( eRet == ERRCODE_BASIC_METHOD_NOT_FOUND && !pCell )
246 // Macro not found (only with input)
247 {
248 //TODO: different error message, if found, but not bAllowed ??
249 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
250 VclMessageType::Warning, VclButtonsType::Ok,
251 ScResId(STR_VALID_MACRONOTFOUND)));
252 xBox->run();
253 }
254
255 return bScriptReturnedFalse;
256}
257
258 // true -> abort
259
260bool ScValidationData::DoMacro( const ScAddress& rPos, const OUString& rInput,
261 ScFormulaCell* pCell, weld::Window* pParent ) const
262{
264 {
265 return DoScript( rPos, rInput, pCell, pParent );
266 }
267
268 ScDocument* pDocument = GetDocument();
269 SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
270 if ( !pDocSh )
271 return false;
272
273 bool bDone = false;
274 bool bRet = false; // default: do not abort
275
276 // If the Doc was loaded during a Basic-Calls,
277 // the Sbx-object may not be created (?)
278// pDocSh->GetSbxObject();
279
280#if HAVE_FEATURE_SCRIPTING
281 // no security check ahead (only CheckMacroWarn), that happens in CallBasic
282
283 // Function search by their simple name,
284 // then assemble aBasicStr, aMacroStr for SfxObjectShell::CallBasic
285
286 StarBASIC* pRoot = pDocSh->GetBasic();
287 SbxVariable* pVar = pRoot->Find( aErrorTitle, SbxClassType::Method );
288 if (SbMethod* pMethod = dynamic_cast<SbMethod*>(pVar))
289 {
290 SbModule* pModule = pMethod->GetModule();
291 SbxObject* pObject = pModule->GetParent();
292 OUString aMacroStr(
293 pObject->GetName() + "." + pModule->GetName() + "." + pMethod->GetName());
294 OUString aBasicStr;
295
296 // the distinction between document- and app-basic has to be done
297 // by checking the parent (as in ScInterpreter::ScMacro), not by looping
298 // over all open documents, because this may be called from within loading,
299 // when SfxObjectShell::GetFirst/GetNext won't find the document.
300
301 if ( pObject->GetParent() )
302 aBasicStr = pObject->GetParent()->GetName(); // Basic of document
303 else
304 aBasicStr = SfxGetpApp()->GetName(); // Basic of application
305
306 // Parameter for Macro
307 SbxArrayRef refPar = new SbxArray;
308
309 // 1) entered or calculated value
310 OUString aValStr = rInput;
311 double nValue = 0.0;
312 bool bIsValue = false;
313 if ( pCell ) // if cell set, called from interpret
314 {
315 bIsValue = pCell->IsValue();
316 if ( bIsValue )
317 nValue = pCell->GetValue();
318 else
319 aValStr = pCell->GetString().getString();
320 }
321 if ( bIsValue )
322 refPar->Get(1)->PutDouble(nValue);
323 else
324 refPar->Get(1)->PutString(aValStr);
325
326 // 2) Position of the cell
327 OUString aPosStr(rPos.Format(ScRefFlags::VALID | ScRefFlags::TAB_3D, pDocument, pDocument->GetAddressConvention()));
328 refPar->Get(2)->PutString(aPosStr);
329
330 // use link-update flag to prevent closing the document
331 // while the macro is running
332 bool bWasInLinkUpdate = pDocument->IsInLinkUpdate();
333 if ( !bWasInLinkUpdate )
334 pDocument->SetInLinkUpdate( true );
335
336 if ( pCell )
337 pDocument->LockTable( rPos.Tab() );
338 SbxVariableRef refRes = new SbxVariable;
339 ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, refPar.get(), refRes.get() );
340 if ( pCell )
341 pDocument->UnlockTable( rPos.Tab() );
342
343 if ( !bWasInLinkUpdate )
344 pDocument->SetInLinkUpdate( false );
345
346 // Interrupt input if Basic macro returns false
347 if ( eRet == ERRCODE_NONE && refRes->GetType() == SbxBOOL && !refRes->GetBool() )
348 bRet = true;
349 bDone = true;
350 }
351#endif
352 if ( !bDone && !pCell ) // Macro not found (only with input)
353 {
354 //TODO: different error message, if found, but not bAllowed ??
355 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
356 VclMessageType::Warning, VclButtonsType::Ok,
357 ScResId(STR_VALID_MACRONOTFOUND)));
358 xBox->run();
359 }
360
361 return bRet;
362}
363
365{
367 DoMacro( pCell->aPos, OUString(), pCell, nullptr );
368}
369
371{
372 return SfxViewShell::Current();
373}
374
375 // true -> abort
376
377bool ScValidationData::DoError(weld::Window* pParent, const OUString& rInput,
378 const ScAddress& rPos) const
379{
381 return DoMacro(rPos, rInput, nullptr, pParent);
382
383 // Output error message
384
385 OUString aTitle = aErrorTitle;
386 if (aTitle.isEmpty())
387 aTitle = ScResId( STR_MSSG_DOSUBTOTALS_0 ); // application title
388 OUString aMessage = aErrorMessage;
389 if (aMessage.isEmpty())
390 aMessage = ScResId( STR_VALID_DEFERROR );
391
392 VclButtonsType eStyle = VclButtonsType::Ok;
393 VclMessageType eType = VclMessageType::Error;
394 switch (eErrorStyle)
395 {
396 case SC_VALERR_INFO:
397 eType = VclMessageType::Info;
398 eStyle = VclButtonsType::OkCancel;
399 break;
401 eType = VclMessageType::Warning;
402 eStyle = VclButtonsType::OkCancel;
403 break;
404 default:
405 break;
406 }
407
408 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent, eType,
409 eStyle, aMessage, SfxViewShell::Current()));
410 xBox->set_title(aTitle);
411 xBox->SetInstallLOKNotifierHdl(LINK(nullptr, ScValidationData, InstallLOKNotifierHdl));
412
413 switch (eErrorStyle)
414 {
415 case SC_VALERR_INFO:
416 xBox->set_default_response(RET_OK);
417 break;
419 xBox->set_default_response(RET_CANCEL);
420 break;
421 default:
422 break;
423 }
424
425 short nRet = xBox->run();
426
427 return ( eErrorStyle == SC_VALERR_STOP || nRet == RET_CANCEL );
428}
429
431 const OUString& rTest,
432 const ScPatternAttr& rPattern,
433 const ScAddress& rPos,
434 const CustomValidationPrivateAccess& ) const
435{
436 OSL_ENSURE(GetDataMode() == SC_VALID_CUSTOM,
437 "ScValidationData::IsDataValidCustom invoked for a non-custom validation");
438
439 if (rTest.isEmpty()) // check whether empty cells are allowed
440 return IsIgnoreBlank();
441
442 SvNumberFormatter* pFormatter = nullptr;
443 sal_uInt32 nFormat = 0;
444 double nVal = 0.0;
445 OUString rStrResult = "";
446 bool bIsVal = false;
447
448 if (rTest[0] == '=')
449 {
450 if (!isFormulaResultsValidatable(rTest, rPos, pFormatter, rStrResult, nVal, nFormat, bIsVal))
451 return false;
452
453 // check whether empty cells are allowed
454 if (rStrResult.isEmpty())
455 return IsIgnoreBlank();
456 }
457 else
458 {
459 pFormatter = GetDocument()->GetFormatTable();
460
461 // get the value if any
462 nFormat = rPattern.GetNumberFormat(pFormatter);
463 bIsVal = pFormatter->IsNumberFormat(rTest, nFormat, nVal);
464 rStrResult = rTest;
465 }
466
467 ScRefCellValue aTmpCell;
469 if (bIsVal)
470 {
471 aTmpCell = ScRefCellValue(nVal);
472 }
473 else
474 {
475 aSS = mpDoc->GetSharedStringPool().intern(rStrResult);
476 aTmpCell = ScRefCellValue(&aSS);
477 }
478
479 ScCellValue aOriginalCellValue(ScRefCellValue(*GetDocument(), rPos));
480
481 aTmpCell.commit(*GetDocument(), rPos);
482 bool bRet = IsCellValid(aTmpCell, rPos);
483 aOriginalCellValue.commit(*GetDocument(), rPos);
484
485 return bRet;
486}
487
494{
496 double mfVal;
497 sal_uInt32 mnFormat;
498
499 ScValidationDataIsNumeric( double fVal, SvNumberFormatter* pFormatter = nullptr, sal_uInt32 nFormat = 0 )
500 : mpFormatter(pFormatter), mfVal(fVal), mnFormat(nFormat)
501 {
502 }
503
504 void init( const ScDocument& rDoc, const ScAddress& rPos )
505 {
506 const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab());
509 }
510};
511
512bool ScValidationData::IsDataValidTextLen( std::u16string_view rTest, const ScAddress& rPos,
513 ScValidationDataIsNumeric* pDataNumeric ) const
514{
515 sal_Int32 nLen;
516 if (!pDataNumeric)
517 nLen = rTest.size();
518 else
519 {
520 if (!pDataNumeric->mpFormatter)
521 pDataNumeric->init( *GetDocument(), rPos);
522
523 // For numeric values use the resulting input line string to
524 // determine length, otherwise an once accepted value maybe could
525 // not be edited again, for example abbreviated dates or leading
526 // zeros or trailing zeros after decimal separator change length.
527 OUString aStr;
528 pDataNumeric->mpFormatter->GetInputLineString( pDataNumeric->mfVal, pDataNumeric->mnFormat, aStr);
529 nLen = aStr.getLength();
530 }
531 ScRefCellValue aTmpCell( static_cast<double>(nLen));
532 return IsCellValid( aTmpCell, rPos);
533}
534
536 const OUString& rTest, const ScPatternAttr& rPattern, const ScAddress& rPos ) const
537{
538 if ( eDataMode == SC_VALID_ANY ) // check if any cell content is allowed
539 return true;
540
541 if (rTest.isEmpty()) // check whether empty cells are allowed
542 return IsIgnoreBlank();
543
544 SvNumberFormatter* pFormatter = nullptr;
545 sal_uInt32 nFormat = 0;
546 double nVal = 0.0;
547 OUString rStrResult = "";
548 bool bIsVal = false;
549
550 if (rTest[0] == '=')
551 {
552 if (!isFormulaResultsValidatable(rTest, rPos, pFormatter, rStrResult, nVal, nFormat, bIsVal))
553 return false;
554
555 // check whether empty cells are allowed
556 if (rStrResult.isEmpty())
557 return IsIgnoreBlank();
558 }
559 else
560 {
561 pFormatter = GetDocument()->GetFormatTable();
562
563 // get the value if any
564 nFormat = rPattern.GetNumberFormat(pFormatter);
565 bIsVal = pFormatter->IsNumberFormat(rTest, nFormat, nVal);
566 rStrResult = rTest;
567 }
568
569 bool bRet;
571 {
572 if (!bIsVal)
573 bRet = IsDataValidTextLen( rStrResult, rPos, nullptr);
574 else
575 {
576 ScValidationDataIsNumeric aDataNumeric( nVal, pFormatter, nFormat);
577 bRet = IsDataValidTextLen( rStrResult, rPos, &aDataNumeric);
578 }
579 }
580 else
581 {
582 if (bIsVal)
583 {
584 ScRefCellValue aTmpCell(nVal);
585 bRet = IsDataValid(aTmpCell, rPos);
586 }
587 else
588 {
589 svl::SharedString aSS = mpDoc->GetSharedStringPool().intern( rStrResult );
590 ScRefCellValue aTmpCell(&aSS);
591 bRet = IsDataValid(aTmpCell, rPos);
592 }
593 }
594
595 return bRet;
596}
597
599{
600 if( eDataMode == SC_VALID_LIST )
601 return IsListValid(rCell, rPos);
602
603 if ( eDataMode == SC_VALID_CUSTOM )
604 return IsCellValid(rCell, rPos);
605
606 double nVal = 0.0;
607 OUString aString;
608 bool bIsVal = true;
609
610 switch (rCell.getType())
611 {
612 case CELLTYPE_VALUE:
613 nVal = rCell.getDouble();
614 break;
615 case CELLTYPE_STRING:
616 aString = rCell.getSharedString()->getString();
617 bIsVal = false;
618 break;
619 case CELLTYPE_EDIT:
620 if (rCell.getEditText())
621 aString = ScEditUtil::GetString(*rCell.getEditText(), GetDocument());
622 bIsVal = false;
623 break;
624 case CELLTYPE_FORMULA:
625 {
626 ScFormulaCell* pFCell = rCell.getFormula();
627 bIsVal = pFCell->IsValue();
628 if ( bIsVal )
629 nVal = pFCell->GetValue();
630 else
631 aString = pFCell->GetString().getString();
632 }
633 break;
634 default: // Notes, Broadcaster
635 return IsIgnoreBlank(); // as set
636 }
637
638 bool bOk = true;
639 switch (eDataMode)
640 {
641 // SC_VALID_ANY already above
642
643 case SC_VALID_WHOLE:
644 case SC_VALID_DECIMAL:
645 case SC_VALID_DATE: // Date/Time is only formatting
646 case SC_VALID_TIME:
647 bOk = bIsVal;
648 if ( bOk && eDataMode == SC_VALID_WHOLE )
649 bOk = ::rtl::math::approxEqual( nVal, floor(nVal+0.5) ); // integers
650 if ( bOk )
651 bOk = IsCellValid(rCell, rPos);
652 break;
653
654 case SC_VALID_TEXTLEN:
655 if (!bIsVal)
656 bOk = IsDataValidTextLen( aString, rPos, nullptr);
657 else
658 {
659 ScValidationDataIsNumeric aDataNumeric( nVal);
660 bOk = IsDataValidTextLen( aString, rPos, &aDataNumeric);
661 }
662 break;
663
664 default:
665 OSL_FAIL("not yet done");
666 break;
667 }
668
669 return bOk;
670}
671
672bool ScValidationData::isFormulaResultsValidatable(const OUString& rTest, const ScAddress& rPos, SvNumberFormatter* pFormatter,
673 OUString& rStrResult, double& nVal, sal_uInt32& nFormat, bool& bIsVal) const
674{
675 std::optional<ScSimpleFormulaCalculator> pFCell(std::in_place, *mpDoc, rPos, rTest, true);
676 pFCell->SetLimitString(true);
677
678 bool bColRowName = pFCell->HasColRowName();
679 if (bColRowName)
680 {
681 // ColRowName from RPN-Code?
682 if (pFCell->GetCode()->GetCodeLen() <= 1)
683 { // ==1: area
684 // ==0: would be an area if...
685 OUString aBraced = "(" + rTest + ")";
686 pFCell.emplace(*mpDoc, rPos, aBraced, true);
687 pFCell->SetLimitString(true);
688 }
689 else
690 bColRowName = false;
691 }
692
693 FormulaError nErrCode = pFCell->GetErrCode();
694 if (nErrCode == FormulaError::NONE || pFCell->IsMatrix())
695 {
696 pFormatter = mpDoc->GetFormatTable();
697 const Color* pColor;
698 if (pFCell->IsMatrix())
699 {
700 rStrResult = pFCell->GetString().getString();
701 }
702 else if (pFCell->IsValue())
703 {
704 nVal = pFCell->GetValue();
705 nFormat = pFormatter->GetStandardFormat(nVal, 0,
706 pFCell->GetFormatType(), ScGlobal::eLnge);
707 pFormatter->GetOutputString(nVal, nFormat, rStrResult, &pColor);
708 bIsVal = true;
709 }
710 else
711 {
712 nFormat = pFormatter->GetStandardFormat(
713 pFCell->GetFormatType(), ScGlobal::eLnge);
714 pFormatter->GetOutputString(pFCell->GetString().getString(), nFormat,
715 rStrResult, &pColor);
716 // Indicate it's a string, so a number string doesn't look numeric.
717 // Escape embedded quotation marks first by doubling them, as
718 // usual. Actually the result can be copy-pasted from the result
719 // box as literal into a formula expression.
720 rStrResult = "\"" + rStrResult.replaceAll("\"", "\"\"") + "\"";
721 }
722
723 ScRange aTestRange;
724 if (bColRowName || (aTestRange.Parse(rTest, *mpDoc) & ScRefFlags::VALID))
725 rStrResult += " ...";
726 // area
727
728 return true;
729 }
730 else
731 {
732 return false;
733 }
734}
735
736namespace {
737
741class ScStringTokenIterator
742{
743public:
744 explicit ScStringTokenIterator( const ScTokenArray& rTokArr ) :
745 maIter( rTokArr ), mbOk( true ) {}
746
748 rtl_uString* First();
750 rtl_uString* Next();
751
753 bool Ok() const { return mbOk; }
754
755private:
756 svl::SharedString maCurString;
758 bool mbOk;
759};
760
761rtl_uString* ScStringTokenIterator::First()
762{
763 maIter.Reset();
764 mbOk = true;
765 return Next();
766}
767
768rtl_uString* ScStringTokenIterator::Next()
769{
770 if( !mbOk )
771 return nullptr;
772
773 // seek to next non-separator token
774 const FormulaToken* pToken = maIter.NextNoSpaces();
775 while( pToken && (pToken->GetOpCode() == ocSep) )
776 pToken = maIter.NextNoSpaces();
777
778 mbOk = !pToken || (pToken->GetType() == formula::svString);
779
780 maCurString = svl::SharedString(); // start with invalid string.
781 if (mbOk && pToken)
782 maCurString = pToken->GetString();
783
784 // string found but empty -> get next token; otherwise return it
785 return (maCurString.isValid() && maCurString.isEmpty()) ? Next() : maCurString.getData();
786}
787
789sal_uLong lclGetCellFormat( const ScDocument& rDoc, const ScAddress& rPos )
790{
791 const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() );
792 if( !pPattern )
793 pPattern = rDoc.GetDefPattern();
794 return pPattern->GetNumberFormat( rDoc.GetFormatTable() );
795}
796
797} // namespace
798
800{
801 return (eDataMode == SC_VALID_LIST) && (mnListType != css::sheet::TableValidationVisibility::INVISIBLE);
802}
803
805 std::vector<ScTypedStrData>* pStrings, ScRefCellValue& rCell, const ScAddress& rPos,
806 const ScTokenArray& rTokArr, int& rMatch) const
807{
808 bool bOk = true;
809
810 // pDoc is private in condition, use an accessor and a long winded name.
811 ScDocument* pDocument = GetDocument();
812 if( nullptr == pDocument )
813 return false;
814
815 ScFormulaCell aValidationSrc(
817
818 // Make sure the formula gets interpreted and a result is delivered,
819 // regardless of the AutoCalc setting.
820 aValidationSrc.Interpret();
821
822 ScMatrixRef xMatRef;
823 const ScMatrix *pValues = aValidationSrc.GetMatrix();
824 if (!pValues)
825 {
826 // The somewhat nasty case of either an error occurred, or the
827 // dereferenced value of a single cell reference or an immediate result
828 // is stored as a single value.
829
830 // Use an interim matrix to create the TypedStrData below.
831 xMatRef = new ScMatrix(1, 1, 0.0);
832
833 FormulaError nErrCode = aValidationSrc.GetErrCode();
834 if (nErrCode != FormulaError::NONE)
835 {
836 /* TODO : to use later in an alert box?
837 * OUString rStrResult = "...";
838 * rStrResult += ScGlobal::GetLongErrorString(nErrCode);
839 */
840
841 xMatRef->PutError( nErrCode, 0, 0);
842 bOk = false;
843 }
844 else if (aValidationSrc.IsValue())
845 xMatRef->PutDouble( aValidationSrc.GetValue(), 0);
846 else
847 {
848 svl::SharedString aStr = aValidationSrc.GetString();
849 xMatRef->PutString(aStr, 0);
850 }
851
852 pValues = xMatRef.get();
853 }
854
855 // which index matched. We will want it eventually to pre-select that item.
856 rMatch = -1;
857
859 sal_uInt32 nDestFormat = pDocument->GetNumberFormat(rPos.Col(), rPos.Row(), rPos.Tab());
860
861 SCSIZE nCol, nRow, nCols, nRows, n = 0;
862 pValues->GetDimensions( nCols, nRows );
863
864 bool bRef = false;
865 ScRange aRange;
866
867 ScTokenArray* pArr = const_cast<ScTokenArray*>(&rTokArr);
868 if (pArr->GetLen() == 1)
869 {
872 if (t)
873 {
874 OpCode eOpCode = t->GetOpCode();
875 if (eOpCode == ocDBArea || eOpCode == ocTableRef)
876 {
877 if (const ScDBData* pDBData = pDocument->GetDBCollection()->getNamedDBs().findByIndex(t->GetIndex()))
878 {
879 pDBData->GetArea(aRange);
880 bRef = true;
881 }
882 }
883 else if (eOpCode == ocName)
884 {
885 const ScRangeData* pName = pDocument->FindRangeNameBySheetAndIndex( t->GetSheet(), t->GetIndex());
886 if (pName && pName->IsReference(aRange))
887 {
888 bRef = true;
889 }
890 }
891 else if (t->GetType() != svIndex)
892 {
893 if (pArr->IsValidReference(aRange, rPos))
894 {
895 bRef = true;
896 }
897 }
898 }
899 }
900
901 bool bHaveEmpty = false;
902 svl::SharedStringPool& rSPool = pDocument->GetSharedStringPool();
903
904 /* XL artificially limits things to a single col or row in the UI but does
905 * not list the constraint in MOOXml. If a defined name or INDIRECT
906 * resulting in 1D is entered in the UI and the definition later modified
907 * to 2D, it is evaluated fine and also stored and loaded. Lets get ahead
908 * of the curve and support 2d. In XL, values are listed row-wise, do the
909 * same. */
910 for( nRow = 0; nRow < nRows ; nRow++ )
911 {
912 for( nCol = 0; nCol < nCols ; nCol++ )
913 {
914 ScTokenArray aCondTokArr(*pDocument);
915 std::unique_ptr<ScTypedStrData> pEntry;
916 OUString aValStr;
917 ScMatrixValue nMatVal = pValues->Get( nCol, nRow);
918
919 // strings and empties
920 if( ScMatrix::IsNonValueType( nMatVal.nType ) )
921 {
922 aValStr = nMatVal.GetString().getString();
923
924 // Do not add multiple empty strings to the validation list,
925 // especially not if they'd bloat the tail with a million empty
926 // entries for a column range, fdo#61520
927 if (aValStr.isEmpty())
928 {
929 if (bHaveEmpty)
930 continue;
931 bHaveEmpty = true;
932 }
933
934 if( nullptr != pStrings )
935 pEntry.reset(new ScTypedStrData(aValStr, 0.0, 0.0, ScTypedStrData::Standard));
936
937 if (!rCell.isEmpty() && rMatch < 0)
938 aCondTokArr.AddString(rSPool.intern(aValStr));
939 }
940 else
941 {
942 FormulaError nErr = nMatVal.GetError();
943
944 if( FormulaError::NONE != nErr )
945 {
946 aValStr = ScGlobal::GetErrorString( nErr );
947 }
948 else
949 {
950 // FIXME FIXME FIXME
951 // Feature regression. Date formats are lost passing through the matrix
952 //pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr );
953 //For external reference and a formula that results in an area or array, date formats are still lost.
954 if ( bRef )
955 {
956 aValStr = pDocument->GetInputString(static_cast<SCCOL>(nCol+aRange.aStart.Col()),
957 static_cast<SCROW>(nRow+aRange.aStart.Row()), aRange.aStart.Tab());
958 }
959 else
960 {
961 pFormatter->GetInputLineString( nMatVal.fVal, nDestFormat, aValStr );
962 }
963 }
964
965 if (!rCell.isEmpty() && rMatch < 0)
966 {
967 // I am not sure errors will work here, but a user can no
968 // manually enter an error yet so the point is somewhat moot.
969 aCondTokArr.AddDouble( nMatVal.fVal );
970 }
971 if( nullptr != pStrings )
972 pEntry.reset(new ScTypedStrData(aValStr, nMatVal.fVal, nMatVal.fVal, ScTypedStrData::Value));
973 }
974
975 if (rMatch < 0 && !rCell.isEmpty() && IsEqualToTokenArray(rCell, rPos, aCondTokArr))
976 {
977 rMatch = n;
978 // short circuit on the first match if not filling the list
979 if( nullptr == pStrings )
980 return true;
981 }
982
983 if( pEntry )
984 {
985 assert(pStrings);
986 pStrings->push_back(*pEntry);
987 n++;
988 }
989 }
990 }
991
992 // In case of no match needed and an error occurred, return that error
993 // entry as valid instead of silently failing.
994 return bOk || rCell.isEmpty();
995}
996
997bool ScValidationData::FillSelectionList(std::vector<ScTypedStrData>& rStrColl, const ScAddress& rPos) const
998{
999 bool bOk = false;
1000
1001 if( HasSelectionList() )
1002 {
1003 std::unique_ptr<ScTokenArray> pTokArr( CreateFlatCopiedTokenArray(0) );
1004
1005 // *** try if formula is a string list ***
1006
1007 sal_uInt32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
1008 ScStringTokenIterator aIt( *pTokArr );
1009 for (rtl_uString* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next())
1010 {
1011 double fValue;
1012 OUString aStr(pString);
1013 bool bIsValue = GetDocument()->GetFormatTable()->IsNumberFormat(aStr, nFormat, fValue);
1014 rStrColl.emplace_back(
1015 aStr, fValue, fValue, bIsValue ? ScTypedStrData::Value : ScTypedStrData::Standard);
1016 }
1017 bOk = aIt.Ok();
1018
1019 // *** if not a string list, try if formula results in a cell range or
1020 // anything else we recognize as valid ***
1021
1022 if (!bOk)
1023 {
1024 int nMatch;
1025 ScRefCellValue aEmptyCell;
1026 bOk = GetSelectionFromFormula(&rStrColl, aEmptyCell, rPos, *pTokArr, nMatch);
1027 }
1028 }
1029
1030 return bOk;
1031}
1032
1033bool ScValidationData::IsEqualToTokenArray( ScRefCellValue& rCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const
1034{
1035 // create a condition entry that tests on equality and set the passed token array
1036 ScConditionEntry aCondEntry( ScConditionMode::Equal, &rTokArr, nullptr, *GetDocument(), rPos );
1037 return aCondEntry.IsCellValid(rCell, rPos);
1038}
1039
1041{
1042 bool bIsValid = false;
1043
1044 /* Compare input cell with all supported tokens from the formula.
1045 Currently a formula may contain:
1046 1) A list of strings (at least one string).
1047 2) A single cell or range reference.
1048 3) A single defined name (must contain a cell/range reference, another
1049 name, or DB range, or a formula resulting in a cell/range reference
1050 or matrix/array).
1051 4) A single database range.
1052 5) A formula resulting in a cell/range reference or matrix/array.
1053 */
1054
1055 std::unique_ptr< ScTokenArray > pTokArr( CreateFlatCopiedTokenArray( 0 ) );
1056
1057 // *** try if formula is a string list ***
1058
1060 sal_uInt32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
1061 ScStringTokenIterator aIt( *pTokArr );
1062 for (rtl_uString* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next())
1063 {
1064 /* Do not break the loop, if a valid string has been found.
1065 This is to find invalid tokens following in the formula. */
1066 if( !bIsValid )
1067 {
1068 // create a formula containing a single string or number
1069 ScTokenArray aCondTokArr(*GetDocument());
1070 double fValue;
1071 OUString aStr(pString);
1072 if (GetDocument()->GetFormatTable()->IsNumberFormat(aStr, nFormat, fValue))
1073 aCondTokArr.AddDouble( fValue );
1074 else
1075 aCondTokArr.AddString(rSPool.intern(aStr));
1076
1077 bIsValid = IsEqualToTokenArray(rCell, rPos, aCondTokArr);
1078 }
1079 }
1080
1081 if( !aIt.Ok() )
1082 bIsValid = false;
1083
1084 // *** if not a string list, try if formula results in a cell range or
1085 // anything else we recognize as valid ***
1086
1087 if (!bIsValid)
1088 {
1089 int nMatch;
1090 bIsValid = GetSelectionFromFormula(nullptr, rCell, rPos, *pTokArr, nMatch);
1091 bIsValid = bIsValid && nMatch >= 0;
1092 }
1093
1094 return bIsValid;
1095}
1096
1098{
1099 // for Ref-Undo - real copy with new tokens!
1100
1101 for (const auto& rxItem : rList)
1102 {
1103 InsertNew( std::unique_ptr<ScValidationData>(rxItem->Clone()) );
1104 }
1105
1106 //TODO: faster insert for sorted entries from rList ???
1107}
1108
1110 const ScValidationDataList& rList)
1111{
1112 // for new documents - real copy with new tokens!
1113
1114 for (const auto& rxItem : rList)
1115 {
1116 InsertNew( std::unique_ptr<ScValidationData>(rxItem->Clone(&rNewDoc)) );
1117 }
1118
1119 //TODO: faster insert for sorted entries from rList ???
1120}
1121
1123{
1124 //TODO: binary search
1125
1126 for( iterator it = begin(); it != end(); ++it )
1127 if( (*it)->GetKey() == nKey )
1128 return it->get();
1129
1130 OSL_FAIL("ScValidationDataList: Entry not found");
1131 return nullptr;
1132}
1133
1135{
1136 for( iterator it = begin(); it != end(); ++it )
1137 (*it)->CompileXML();
1138}
1139
1141{
1142 for( iterator it = begin(); it != end(); ++it )
1143 (*it)->UpdateReference(rCxt);
1144}
1145
1147{
1148 for (iterator it = begin(); it != end(); ++it)
1149 (*it)->UpdateInsertTab(rCxt);
1150}
1151
1153{
1154 for (iterator it = begin(); it != end(); ++it)
1155 (*it)->UpdateDeleteTab(rCxt);
1156}
1157
1159{
1160 for (iterator it = begin(); it != end(); ++it)
1161 (*it)->UpdateMoveTab(rCxt);
1162}
1163
1165{
1166 return maData.begin();
1167}
1168
1170{
1171 return maData.begin();
1172}
1173
1175{
1176 return maData.end();
1177}
1178
1180{
1181 return maData.end();
1182}
1183
1184/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
XPropertyListType t
const char * pName
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:44
std::vector< Reference< XAnimationNode > >::iterator maIter
SfxApplication * SfxGetpApp()
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
const SbxObject * GetParent() const
const OUString & GetName(SbxNameType=SbxNameType::NONE) const
SCTAB Tab() const
Definition: address.hxx:283
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
ScDocument * GetDocument() const
Definition: conditio.hxx:413
std::unique_ptr< ScTokenArray > CreateFlatCopiedTokenArray(sal_uInt16 nPos) const
Create a flat copy using ScTokenArray copy-ctor with shared tokens.
Definition: conditio.cxx:1302
bool IsIgnoreBlank() const
Definition: conditio.hxx:371
bool IsCellValid(ScRefCellValue &rCell, const ScAddress &rPos) const
Definition: conditio.cxx:1240
ScDBData * findByIndex(sal_uInt16 nIndex)
Definition: dbdata.cxx:1214
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:324
SC_DLLPUBLIC sal_uInt32 GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3640
SC_DLLPUBLIC ScPatternAttr * GetDefPattern() const
Definition: document.cxx:6045
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
Definition: documen3.cxx:492
ScRangeData * FindRangeNameBySheetAndIndex(SCTAB nTab, sal_uInt16 nIndex) const
Find a named expression / range name in either global or a local scope.
Definition: documen3.cxx:269
bool IsInLinkUpdate() const
Definition: documen8.cxx:784
void SetInLinkUpdate(bool bSet)
Definition: documen8.cxx:776
SC_DLLPUBLIC OUString GetInputString(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bForceSystemLocale=false) const
Definition: document.cxx:3549
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:827
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1083
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:467
void LockTable(SCTAB nTab)
Definition: document.cxx:5297
void UnlockTable(SCTAB nTab)
Definition: document.cxx:5307
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4719
static SC_DLLPUBLIC OUString GetString(const EditTextObject &rEditText, const ScDocument *pDoc)
Retrieves string with paragraphs delimited by new lines (' ').
Definition: editutil.cxx:119
ScDocument * mpDoc
Definition: conditio.hxx:256
bool operator==(const ScFormatEntry &) const
Definition: conditio.cxx:56
double GetValue()
const svl::SharedString & GetString()
FormulaError GetErrCode()
const ScMatrix * GetMatrix()
ScAddress aPos
bool Interpret(SCROW nStartOffset=-1, SCROW nEndOffset=-1)
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:560
static OUString GetErrorString(FormulaError nErrNumber)
Definition: global.cxx:315
Matrix data type that can store values of mixed types.
Definition: scmatrix.hxx:101
static bool IsNonValueType(ScMatValType nType)
String, empty or empty path, but not value nor boolean.
Definition: scmatrix.hxx:179
sal_uInt32 GetNumberFormat(SvNumberFormatter *) const
Definition: patattr.cxx:1398
ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1700
ScAddress aStart
Definition: address.hxx:497
bool IsValidReference(ScRange &rRange, const ScAddress &rPos) const
Exactly and only one valid range (no #REF!s)
Definition: token.cxx:1862
ScValidationDataListDataType::iterator iterator
Definition: validat.hxx:223
ScValidationDataListDataType maData
Definition: validat.hxx:216
void UpdateDeleteTab(sc::RefUpdateDeleteTabContext &rCxt)
Definition: validat.cxx:1152
void UpdateReference(sc::RefUpdateContext &rCxt)
Definition: validat.cxx:1140
void UpdateMoveTab(sc::RefUpdateMoveTabContext &rCxt)
Definition: validat.cxx:1158
void InsertNew(std::unique_ptr< ScValidationData > pNew)
Definition: validat.hxx:231
void UpdateInsertTab(sc::RefUpdateInsertTabContext &rCxt)
Definition: validat.cxx:1146
ScValidationData * GetData(sal_uInt32 nKey)
Definition: validat.cxx:1122
ScValidationDataListDataType::const_iterator const_iterator
Definition: validat.hxx:224
bool IsListValid(ScRefCellValue &rCell, const ScAddress &rPos) const
Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list.
Definition: validat.cxx:1040
sal_Int16 mnListType
Definition: validat.hxx:71
bool IsEmpty() const
Definition: validat.cxx:129
bool IsDataValidCustom(const OUString &rTest, const ScPatternAttr &rPattern, const ScAddress &rPos, const CustomValidationPrivateAccess &) const
Definition: validat.cxx:430
bool isFormulaResultsValidatable(const OUString &rTest, const ScAddress &rPos, SvNumberFormatter *pFormatter, OUString &rStrResult, double &nVal, sal_uInt32 &nFormat, bool &bIsVal) const
Test, if formula is valid.
Definition: validat.cxx:672
OUString aErrorTitle
Definition: validat.hxx:74
OUString aInputTitle
Definition: validat.hxx:72
bool IsDataValidTextLen(std::u16string_view rTest, const ScAddress &rPos, ScValidationDataIsNumeric *pDataNumeric) const
Tests, if string or numeric data has valid text length.
Definition: validat.cxx:512
bool DoScript(const ScAddress &rPos, const OUString &rInput, ScFormulaCell *pCell, weld::Window *pParent) const
Definition: validat.cxx:186
ScValidationData(ScValidationMode eMode, ScConditionMode eOper, const OUString &rExpr1, const OUString &rExpr2, ScDocument &rDocument, const ScAddress &rPos, const OUString &rExprNmsp1=OUString(), const OUString &rExprNmsp2=OUString(), formula::FormulaGrammar::Grammar eGrammar1=formula::FormulaGrammar::GRAM_DEFAULT, formula::FormulaGrammar::Grammar eGrammar2=formula::FormulaGrammar::GRAM_DEFAULT)
Definition: validat.cxx:63
bool IsDataValid(const OUString &rTest, const ScPatternAttr &rPattern, const ScAddress &rPos) const
Definition: validat.cxx:535
ScValidationMode GetDataMode() const
Definition: validat.hxx:118
ScValidationMode eDataMode
Definition: validat.hxx:67
bool GetSelectionFromFormula(std::vector< ScTypedStrData > *pStrings, ScRefCellValue &rCell, const ScAddress &rPos, const ScTokenArray &rTokArr, int &rMatch) const
Tries to fill the passed collection with list validation entries.
Definition: validat.cxx:804
ScValidErrorStyle eErrorStyle
Definition: validat.hxx:70
bool EqualEntries(const ScValidationData &r) const
Definition: validat.cxx:135
void DoCalcError(ScFormulaCell *pCell) const
Definition: validat.cxx:364
OUString aErrorMessage
Definition: validat.hxx:75
bool FillSelectionList(std::vector< ScTypedStrData > &rStrings, const ScAddress &rPos) const
Tries to fill the passed collection with list validation entries.
Definition: validat.cxx:997
bool GetErrMsg(OUString &rTitle, OUString &rMsg, ScValidErrorStyle &rStyle) const
Definition: validat.cxx:177
void SetInput(const OUString &rTitle, const OUString &rMsg)
Definition: validat.cxx:161
bool HasSelectionList() const
Returns true, if the validation cell will show a selection list.
Definition: validat.cxx:799
void ResetInput()
Definition: validat.cxx:151
virtual ~ScValidationData() override
Definition: validat.cxx:125
bool IsEqualToTokenArray(ScRefCellValue &rCell, const ScAddress &rPos, const ScTokenArray &rTokArr) const
Tests, if pCell is equal to what the passed token array represents.
Definition: validat.cxx:1033
void SetError(const OUString &rTitle, const OUString &rMsg, ScValidErrorStyle eStyle)
Definition: validat.cxx:168
void ResetError()
Definition: validat.cxx:156
bool DoMacro(const ScAddress &rPos, const OUString &rInput, ScFormulaCell *pCell, weld::Window *pParent) const
Definition: validat.cxx:260
OUString aInputMessage
Definition: validat.hxx:73
bool DoError(weld::Window *pParent, const OUString &rInput, const ScAddress &rPos) const
Definition: validat.cxx:377
static bool IsXScriptURL(const OUString &rScriptURL)
ErrCode CallXScript(const OUString &rScriptURL, const css::uno::Sequence< css::uno::Any > &aParams, css::uno::Any &aRet, css::uno::Sequence< sal_Int16 > &aOutParamIndex, css::uno::Sequence< css::uno::Any > &aOutParam, bool bRaiseError=true, const css::uno::Any *aCaller=nullptr)
StarBASIC * GetBasic() const
ErrCode CallBasic(std::u16string_view rMacro, std::u16string_view rBasicName, SbxArray *pArgs, SbxValue *pRet=nullptr)
const OUString & GetName() const
static SAL_WARN_UNUSED_RESULT SfxViewShell * Current()
virtual SbxVariable * Find(const OUString &, SbxClassType) override
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, const Color **ppColor, bool bUseStarFormat=false)
void GetInputLineString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &rOutString, bool bFiltering=false, bool bForceSystemLocale=false)
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
sal_uInt16 GetLen() const
FormulaToken * AddDouble(double fVal)
FormulaToken * AddString(const svl::SharedString &rStr)
OpCode GetOpCode() const
StackVar GetType() const
virtual const svl::SharedString & GetString() const
SharedString intern(const OUString &rStr)
const OUString & getString() const
T * get() const
ScConditionMode
Definition: conditio.hxx:60
EmbeddedObjectRef * pObject
#define ERRCODE_NONE
FormulaError
DocumentType eType
sal_Int16 nValue
@ CELLTYPE_EDIT
Definition: global.hxx:277
@ CELLTYPE_STRING
Definition: global.hxx:275
@ CELLTYPE_FORMULA
Definition: global.hxx:276
@ CELLTYPE_VALUE
Definition: global.hxx:274
Mode eMode
sal_Int64 n
aStr
svIndex
OpCode
ocTableRef
ocDBArea
ocName
#define ERRCODE_BASIC_METHOD_NOT_FOUND
SbxBOOL
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
sal_uIntPtr sal_uLong
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:32
void commit(ScDocument &rDoc, const ScAddress &rPos) const
Set cell value at specified position in specified document.
Definition: cellvalue.cxx:426
Try NOT to use this struct.
Definition: scmatrix.hxx:53
ScMatValType nType
Definition: scmatrix.hxx:56
FormulaError GetError() const
Only valid if ScMatrix methods indicate that this is no string!
Definition: scmatrix.hxx:62
double fVal
Definition: scmatrix.hxx:54
const svl::SharedString & GetString() const
Only valid if ScMatrix methods indicate so!
Definition: scmatrix.hxx:59
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
const EditTextObject * getEditText() const
Definition: cellvalue.hxx:136
double getDouble() const
Definition: cellvalue.hxx:134
bool isEmpty() const
Definition: cellvalue.cxx:667
void commit(ScDocument &rDoc, const ScAddress &rPos) const
Set cell value at specified position in specified document.
Definition: cellvalue.cxx:589
const svl::SharedString * getSharedString() const
Definition: cellvalue.hxx:135
CellType getType() const
Definition: cellvalue.hxx:133
To test numeric data text length in IsDataValidTextLen().
Definition: validat.cxx:494
ScValidationDataIsNumeric(double fVal, SvNumberFormatter *pFormatter=nullptr, sal_uInt32 nFormat=0)
Definition: validat.cxx:499
SvNumberFormatter * mpFormatter
Definition: validat.cxx:495
void init(const ScDocument &rDoc, const ScAddress &rPos)
Definition: validat.cxx:504
Context for reference update during shifting, moving or copying of cell ranges.
sal_Int16 SCCOL
Definition: types.hxx:21
::boost::intrusive_ptr< ScMatrix > ScMatrixRef
Definition: types.hxx:25
sal_Int32 SCROW
Definition: types.hxx:17
IMPL_STATIC_LINK_NOARG(ScValidationData, InstallLOKNotifierHdl, void *, vcl::ILibreOfficeKitNotifier *)
Definition: validat.cxx:370
ScValidationMode
Definition: validat.hxx:41
@ SC_VALID_TEXTLEN
Definition: validat.hxx:47
@ SC_VALID_TIME
Definition: validat.hxx:46
@ SC_VALID_CUSTOM
Definition: validat.hxx:49
@ SC_VALID_ANY
Definition: validat.hxx:42
@ SC_VALID_DECIMAL
Definition: validat.hxx:44
@ SC_VALID_WHOLE
Definition: validat.hxx:43
@ SC_VALID_DATE
Definition: validat.hxx:45
@ SC_VALID_LIST
Definition: validat.hxx:48
ScValidErrorStyle
Definition: validat.hxx:53
@ SC_VALERR_MACRO
Definition: validat.hxx:57
@ SC_VALERR_STOP
Definition: validat.hxx:54
@ SC_VALERR_WARNING
Definition: validat.hxx:55
@ SC_VALERR_INFO
Definition: validat.hxx:56
RET_OK
RET_CANCEL
VclMessageType
VclButtonsType