LibreOffice Module vcl (master)  1
fmtfield.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 <tools/debug.hxx>
22 #include <comphelper/string.hxx>
24 #include <vcl/event.hxx>
25 #include <vcl/settings.hxx>
26 #include <vcl/commandevent.hxx>
27 #include <svl/zformat.hxx>
28 #include <vcl/fmtfield.hxx>
29 #include <vcl/weld.hxx>
31 #include <unotools/syslocale.hxx>
32 #include <map>
33 #include <rtl/math.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <sal/log.hxx>
36 #include <osl/diagnose.h>
37 
38 using namespace ::com::sun::star::lang;
39 using namespace ::com::sun::star::util;
40 
41 // hmm. No support for regular expression. Well, I always (not really :) wanted to write a finite automat
42 // so here comes a finite automat ...
43 
44 namespace validation
45 {
46  namespace {
47 
48  // the states of our automat.
49  enum State
50  {
51  START, // at the very start of the string
52  NUM_START, // the very start of the number
53 
54  DIGIT_PRE_COMMA, // some pre-comma digits are read, perhaps including some thousand separators
55 
56  DIGIT_POST_COMMA, // reading digits after the comma
57  EXPONENT_START, // at the very start of the exponent value
58  // (means: not including the "e" which denotes the exponent)
59  EXPONENT_DIGIT, // currently reading the digits of the exponent
60 
61  END // reached the end of the string
62  };
63 
64  }
65 
66  // a row in the transition table (means the set of states to be reached from a given state)
67  typedef ::std::map< sal_Unicode, State > StateTransitions;
68 
69  // a single transition
70  typedef StateTransitions::value_type Transition;
71 
72  // the complete transition table
73  typedef ::std::map< State, StateTransitions > TransitionTable;
74 
75  // the validator class
77  {
78  private:
79  TransitionTable m_aTransitions;
80 
81  public:
82  NumberValidator( const sal_Unicode _cThSep, const sal_Unicode _cDecSep );
83 
84  bool isValidNumericFragment( const OUString& _rText );
85 
86  private:
87  bool implValidateNormalized( const OUString& _rText );
88  };
89 
90  static void lcl_insertStopTransition( StateTransitions& _rRow )
91  {
92  _rRow.insert( Transition( '_', END ) );
93  }
94 
95  static void lcl_insertStartExponentTransition( StateTransitions& _rRow )
96  {
97  _rRow.insert( Transition( 'e', EXPONENT_START ) );
98  }
99 
100  static void lcl_insertSignTransitions( StateTransitions& _rRow, const State eNextState )
101  {
102  _rRow.insert( Transition( '-', eNextState ) );
103  _rRow.insert( Transition( '+', eNextState ) );
104  }
105 
106  static void lcl_insertDigitTransitions( StateTransitions& _rRow, const State eNextState )
107  {
108  for ( sal_Unicode aChar = '0'; aChar <= '9'; ++aChar )
109  _rRow.insert( Transition( aChar, eNextState ) );
110  }
111 
112  static void lcl_insertCommonPreCommaTransitions( StateTransitions& _rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep )
113  {
114  // digits are allowed
115  lcl_insertDigitTransitions( _rRow, DIGIT_PRE_COMMA );
116 
117  // the thousand separator is allowed
118  _rRow.insert( Transition( _cThSep, DIGIT_PRE_COMMA ) );
119 
120  // a comma is allowed
121  _rRow.insert( Transition( _cDecSep, DIGIT_POST_COMMA ) );
122  }
123 
125  {
126  // build up our transition table
127 
128  // how to proceed from START
129  {
130  StateTransitions& rRow = m_aTransitions[ START ];
131  rRow.insert( Transition( '_', NUM_START ) );
132  // if we encounter the normalizing character, we want to proceed with the number
133  }
134 
135  // how to proceed from NUM_START
136  {
137  StateTransitions& rRow = m_aTransitions[ NUM_START ];
138 
139  // a sign is allowed
140  lcl_insertSignTransitions( rRow, DIGIT_PRE_COMMA );
141 
142  // common transitions for the two pre-comma states
143  lcl_insertCommonPreCommaTransitions( rRow, _cThSep, _cDecSep );
144 
145  // the exponent may start here
146  // (this would mean string like "_+e10_", but this is a valid fragment, though no valid number)
148  }
149 
150  // how to proceed from DIGIT_PRE_COMMA
151  {
152  StateTransitions& rRow = m_aTransitions[ DIGIT_PRE_COMMA ];
153 
154  // common transitions for the two pre-comma states
155  lcl_insertCommonPreCommaTransitions( rRow, _cThSep, _cDecSep );
156 
157  // the exponent may start here
159 
160  // the final transition indicating the end of the string
161  // (if there is no comma and no post-comma, then the string may end here)
162  lcl_insertStopTransition( rRow );
163  }
164 
165  // how to proceed from DIGIT_POST_COMMA
166  {
167  StateTransitions& rRow = m_aTransitions[ DIGIT_POST_COMMA ];
168 
169  // there might be digits, which would keep the state at DIGIT_POST_COMMA
170  lcl_insertDigitTransitions( rRow, DIGIT_POST_COMMA );
171 
172  // the exponent may start here
174 
175  // the string may end here
176  lcl_insertStopTransition( rRow );
177  }
178 
179  // how to proceed from EXPONENT_START
180  {
181  StateTransitions& rRow = m_aTransitions[ EXPONENT_START ];
182 
183  // there may be a sign
184  lcl_insertSignTransitions( rRow, EXPONENT_DIGIT );
185 
186  // there may be digits
187  lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
188 
189  // the string may end here
190  lcl_insertStopTransition( rRow );
191  }
192 
193  // how to proceed from EXPONENT_DIGIT
194  {
195  StateTransitions& rRow = m_aTransitions[ EXPONENT_DIGIT ];
196 
197  // there may be digits
198  lcl_insertDigitTransitions( rRow, EXPONENT_DIGIT );
199 
200  // the string may end here
201  lcl_insertStopTransition( rRow );
202  }
203 
204  // how to proceed from END
205  {
206  /*StateTransitions& rRow =*/ m_aTransitions[ EXPONENT_DIGIT ];
207  // no valid transition to leave this state
208  // (note that we, for consistency, nevertheless want to have a row in the table)
209  }
210  }
211 
212  bool NumberValidator::implValidateNormalized( const OUString& _rText )
213  {
214  const sal_Unicode* pCheckPos = _rText.getStr();
215  State eCurrentState = START;
216 
217  while ( END != eCurrentState )
218  {
219  // look up the transition row for the current state
220  TransitionTable::const_iterator aRow = m_aTransitions.find( eCurrentState );
221  DBG_ASSERT( m_aTransitions.end() != aRow,
222  "NumberValidator::implValidateNormalized: invalid transition table (row not found)!" );
223 
224  if ( m_aTransitions.end() != aRow )
225  {
226  // look up the current character in this row
227  StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos );
228  if ( aRow->second.end() != aTransition )
229  {
230  // there is a valid transition for this character
231  eCurrentState = aTransition->second;
232  ++pCheckPos;
233  continue;
234  }
235  }
236 
237  // if we're here, there is no valid transition
238  break;
239  }
240 
241  DBG_ASSERT( ( END != eCurrentState ) || ( 0 == *pCheckPos ),
242  "NumberValidator::implValidateNormalized: inconsistency!" );
243  // if we're at END, then the string should be done, too - the string should be normalized, means ending
244  // a "_" and not containing any other "_" (except at the start), and "_" is the only possibility
245  // to reach the END state
246 
247  // the string is valid if and only if we reached the final state
248  return ( END == eCurrentState );
249  }
250 
251  bool NumberValidator::isValidNumericFragment( const OUString& _rText )
252  {
253  if ( _rText.isEmpty() )
254  // empty strings are always allowed
255  return true;
256 
257  // normalize the string
258  OUString sNormalized = "_" + _rText + "_";
259 
260  return implValidateNormalized( sNormalized );
261  }
262 }
263 
266 
268 {
269  if (!s_cFormatter)
270  {
271  // get the Office's locale and translate
272  LanguageType eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
275  eSysLanguage);
276  }
277  return s_cFormatter;
278 }
279 
281 {
282  ++s_nReferences;
283 }
284 
286 {
287  if (--s_nReferences == 0)
288  {
289  delete s_cFormatter;
290  s_cFormatter = nullptr;
291  }
292 }
293 
294 
296  :SpinField(pParent, nStyle)
297  ,m_aLastSelection(0,0)
298  ,m_dMinValue(0)
299  ,m_dMaxValue(0)
300  ,m_bHasMin(false)
301  ,m_bHasMax(false)
302  ,m_bStrictFormat(true)
303  ,m_bEnableEmptyField(true)
304  ,m_bAutoColor(false)
305  ,m_bEnableNaN(false)
308  ,m_dCurrentValue(0)
309  ,m_dDefaultValue(0)
310  ,m_nFormatKey(0)
311  ,m_pFormatter(nullptr)
312  ,m_dSpinSize(1)
313  ,m_dSpinFirst(-1000000)
314  ,m_dSpinLast(1000000)
315  ,m_bTreatAsNumber(true)
316  ,m_pLastOutputColor(nullptr)
318 {
319 }
320 
321 void FormattedField::SetText(const OUString& rStr)
322 {
323 
324  SpinField::SetText(rStr);
326 }
327 
328 void FormattedField::SetText( const OUString& rStr, const Selection& rNewSelection )
329 {
330 
331  SpinField::SetText( rStr, rNewSelection );
333 }
334 
335 void FormattedField::SetTextFormatted(const OUString& rStr)
336 {
337  SAL_INFO_IF(ImplGetFormatter()->IsTextFormat(m_nFormatKey), "svtools",
338  "FormattedField::SetTextFormatted : valid only with text formats !");
339 
340  m_sCurrentTextValue = rStr;
341 
342  OUString sFormatted;
343  double dNumber = 0.0;
344  // IsNumberFormat changes the format key parameter
345  sal_uInt32 nTempFormatKey = static_cast< sal_uInt32 >( m_nFormatKey );
347  ImplGetFormatter()->IsNumberFormat(m_sCurrentTextValue, nTempFormatKey, dNumber) )
348  {
349  ImplGetFormatter()->GetInputLineString(dNumber, m_nFormatKey, sFormatted);
350  }
351  else
352  {
354  m_nFormatKey,
355  sFormatted,
357  }
358 
359  // calculate the new selection
360  Selection aSel(GetSelection());
361  Selection aNewSel(aSel);
362  aNewSel.Justify();
363  sal_Int32 nNewLen = sFormatted.getLength();
364  sal_Int32 nCurrentLen = GetText().getLength();
365  if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen))
366  { // the new text is longer and the cursor was behind the last char (of the old text)
367  if (aNewSel.Min() == 0)
368  { // the whole text was selected -> select the new text on the whole, too
369  aNewSel.Max() = nNewLen;
370  if (!nCurrentLen)
371  { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
373  if (nSelOptions & SelectionOptions::ShowFirst)
374  { // selection should be from right to left -> swap min and max
375  aNewSel.Min() = aNewSel.Max();
376  aNewSel.Max() = 0;
377  }
378  }
379  }
380  else if (aNewSel.Max() == aNewSel.Min())
381  { // there was no selection -> set the cursor behind the new last char
382  aNewSel.Max() = nNewLen;
383  aNewSel.Min() = nNewLen;
384  }
385  }
386  else if (aNewSel.Max() > nNewLen)
387  aNewSel.Max() = nNewLen;
388  else
389  aNewSel = aSel; // don't use the justified version
390  SpinField::SetText(sFormatted, aNewSel);
392 }
393 
394 OUString const & FormattedField::GetTextValue() const
395 {
396  if (m_ValueState != valueString )
397  {
398  const_cast<FormattedField*>(this)->m_sCurrentTextValue = GetText();
399  const_cast<FormattedField*>(this)->m_ValueState = valueString;
400  }
401  return m_sCurrentTextValue;
402 }
403 
404 void FormattedField::EnableNotANumber( bool _bEnable )
405 {
406  if ( m_bEnableNaN == _bEnable )
407  return;
408 
409  m_bEnableNaN = _bEnable;
410 }
411 
412 void FormattedField::SetAutoColor(bool _bAutomatic)
413 {
414  if (_bAutomatic == m_bAutoColor)
415  return;
416 
417  m_bAutoColor = _bAutomatic;
418  if (m_bAutoColor)
419  { // if auto color is switched on, adjust the current text color, too
420  if (m_pLastOutputColor)
422  else
424  }
425 }
426 
427 void FormattedField::impl_Modify(bool makeValueDirty)
428 {
429 
430  if (!IsStrictFormat())
431  {
432  if(makeValueDirty)
435  return;
436  }
437 
438  OUString sCheck = GetText();
439  if (CheckText(sCheck))
440  {
441  m_sLastValidText = sCheck;
443  if(makeValueDirty)
445  }
446  else
447  {
449  }
450 
452 }
453 
455 {
456 
457  impl_Modify();
458 }
459 
460 void FormattedField::ImplSetTextImpl(const OUString& rNew, Selection const * pNewSel)
461 {
462 
463  if (m_bAutoColor)
464  {
465  if (m_pLastOutputColor)
467  else
469  }
470 
471  if (pNewSel)
472  SpinField::SetText(rNew, *pNewSel);
473  else
474  {
475  Selection aSel(GetSelection());
476  aSel.Justify();
477 
478  sal_Int32 nNewLen = rNew.getLength();
479  sal_Int32 nCurrentLen = GetText().getLength();
480 
481  if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen))
482  { // new text is longer and the cursor is behind the last char
483  if (aSel.Min() == 0)
484  {
485  if (!nCurrentLen)
486  { // there wasn't really a previous selection (as there was no previous text)
487  aSel.Max() = 0;
488  }
489  else
490  { // the whole text was selected -> select the new text on the whole, too
491  aSel.Max() = nNewLen;
492  }
493  }
494  else if (aSel.Max() == aSel.Min())
495  { // there was no selection -> set the cursor behind the new last char
496  aSel.Max() = nNewLen;
497  aSel.Min() = nNewLen;
498  }
499  }
500  else if (aSel.Max() > nNewLen)
501  aSel.Max() = nNewLen;
502  SpinField::SetText(rNew, aSel);
503  }
504 
505  m_ValueState = valueDirty; // not always necessary, but better re-evaluate for safety reasons
506 }
507 
509 {
510  if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT)
512  return SpinField::PreNotify(rNEvt);
513 }
514 
516 {
517 
518  m_nFormatKey = nFormatKey;
519  bool bNeedFormatter = (m_pFormatter == nullptr) && (nFormatKey != 0);
520  if (bNeedFormatter)
521  {
522  ImplGetFormatter(); // this creates a standard formatter
523 
524  // It might happen that the standard formatter makes no sense here, but it takes a default
525  // format. Thus, it is possible to set one of the other standard keys (which are spanning
526  // across multiple formatters).
527  m_nFormatKey = nFormatKey;
528  // When calling SetFormatKey without a formatter, the key must be one of the standard values
529  // that is available for all formatters (and, thus, also in this new one).
530  DBG_ASSERT(m_pFormatter->GetEntry(nFormatKey) != nullptr, "FormattedField::ImplSetFormatKey : invalid format key !");
531  }
532 }
533 
535 {
536  bool bNoFormatter = (m_pFormatter == nullptr);
537  ImplSetFormatKey(nFormatKey);
539 }
540 
541 void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, bool bResetFormat)
542 {
543 
544  if (bResetFormat)
545  {
546  m_pFormatter = pFormatter;
547 
548  // calc the default format key from the Office's UI locale
549  if ( m_pFormatter )
550  {
551  // get the Office's locale and translate
552  LanguageType eSysLanguage = SvtSysLocale().GetLanguageTag().getLanguageType( false);
553  // get the standard numeric format for this language
554  m_nFormatKey = m_pFormatter->GetStandardFormat( SvNumFormatType::NUMBER, eSysLanguage );
555  }
556  else
557  m_nFormatKey = 0;
558  }
559  else
560  {
561  LanguageType aOldLang;
562  OUString sOldFormat = GetFormat(aOldLang);
563 
564  sal_uInt32 nDestKey = pFormatter->TestNewString(sOldFormat);
565  if (nDestKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
566  {
567  // language of the new formatter
568  const SvNumberformat* pDefaultEntry = pFormatter->GetEntry(0);
569  LanguageType aNewLang = pDefaultEntry ? pDefaultEntry->GetLanguage() : LANGUAGE_DONTKNOW;
570 
571  // convert the old format string into the new language
572  sal_Int32 nCheckPos;
574  pFormatter->PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang, true);
575  m_nFormatKey = nDestKey;
576  }
577  m_pFormatter = pFormatter;
578  }
579 
581 }
582 
584 {
585  const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
586  DBG_ASSERT(pFormatEntry != nullptr, "FormattedField::GetFormat: no number format for the given format key.");
587  OUString sFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : OUString();
588  eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW;
589 
590  return sFormatString;
591 }
592 
593 bool FormattedField::SetFormat(const OUString& rFormatString, LanguageType eLang)
594 {
595  sal_uInt32 nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang);
596  if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
597  {
598  sal_Int32 nCheckPos;
600  OUString rFormat(rFormatString);
601  if (!ImplGetFormatter()->PutEntry(rFormat, nCheckPos, nType, nNewKey, eLang))
602  return false;
603  DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "FormattedField::SetFormatString : PutEntry returned an invalid key !");
604  }
605 
606  if (nNewKey != m_nFormatKey)
607  SetFormatKey(nNewKey);
608  return true;
609 }
610 
612 {
613  DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
614  "FormattedField::GetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
615 
616  bool bThousand, IsRed;
617  sal_uInt16 nPrecision, nLeadingCnt;
618  ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt);
619 
620  return bThousand;
621 }
622 
623 void FormattedField::SetThousandsSep(bool _bUseSeparator)
624 {
625  DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
626  "FormattedField::SetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
627 
628  // get the current settings
629  bool bThousand, IsRed;
630  sal_uInt16 nPrecision, nLeadingCnt;
631  ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt);
632  if (bThousand == _bUseSeparator)
633  return;
634 
635  // we need the language for the following
636  LanguageType eLang;
637  GetFormat(eLang);
638 
639  // generate a new format ...
640  OUString sFmtDescription = ImplGetFormatter()->GenerateFormat(m_nFormatKey, eLang, _bUseSeparator, IsRed, nPrecision, nLeadingCnt);
641  // ... and introduce it to the formatter
642  sal_Int32 nCheckPos = 0;
643  sal_uInt32 nNewKey;
645  ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
646 
647  // set the new key
648  ImplSetFormatKey(nNewKey);
650 }
651 
653 {
654  DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
655  "FormattedField::GetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
656 
657  bool bThousand, IsRed;
658  sal_uInt16 nPrecision, nLeadingCnt;
659  ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt);
660 
661  return nPrecision;
662 }
663 
664 void FormattedField::SetDecimalDigits(sal_uInt16 _nPrecision)
665 {
666  DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
667  "FormattedField::SetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
668 
669  // get the current settings
670  bool bThousand, IsRed;
671  sal_uInt16 nPrecision, nLeadingCnt;
672  ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nLeadingCnt);
673  if (nPrecision == _nPrecision)
674  return;
675 
676  // we need the language for the following
677  LanguageType eLang;
678  GetFormat(eLang);
679 
680  // generate a new format ...
681  OUString sFmtDescription = ImplGetFormatter()->GenerateFormat(m_nFormatKey, eLang, bThousand, IsRed, _nPrecision, nLeadingCnt);
682  // ... and introduce it to the formatter
683  sal_Int32 nCheckPos = 0;
684  sal_uInt32 nNewKey;
686  ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
687 
688  // set the new key
689  ImplSetFormatKey(nNewKey);
691 }
692 
694 {
695  m_pLastOutputColor = nullptr;
696 
697  if ( (_nWhat == FORMAT_CHANGE_TYPE::FORMATTER) && m_pFormatter )
699 
700  ReFormat();
701 }
702 
704 {
705  // remember the old text
706  OUString sOld( GetText() );
707 
708  // do the reformat
709  ReFormat();
710 
711  // did the text change?
712  if ( GetText() != sOld )
713  { // consider the field as modified,
714  // but we already have the most recent value;
715  // don't reparse it from the text
716  // (can lead to data loss when the format is lossy,
717  // as is e.g. our default date format: 2-digit year!)
718  impl_Modify(false);
719  }
720 }
721 
723 {
724  if (!IsEmptyFieldEnabled() || !GetText().isEmpty())
725  {
726  if (TreatingAsNumber())
727  {
728  double dValue = GetValue();
729  if ( m_bEnableNaN && ::rtl::math::isNan( dValue ) )
730  return;
731  ImplSetValue( dValue, true );
732  }
733  else
735  }
736 }
737 
739 {
740 
741  if ((rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !IsReadOnly())
742  {
743  const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
744  sal_uInt16 nMod = rKEvt.GetKeyCode().GetModifier();
745  switch ( rKEvt.GetKeyCode().GetCode() )
746  {
747  case KEY_UP:
748  case KEY_DOWN:
749  case KEY_PAGEUP:
750  case KEY_PAGEDOWN:
751  if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
752  {
753  // the base class would translate this into calls to Up/Down/First/Last,
754  // but we don't want this if we are text-formatted
755  return true;
756  }
757  }
758  }
759 
760  if ((rNEvt.GetType() == MouseNotifyEvent::COMMAND) && !IsReadOnly())
761  {
762  const CommandEvent* pCommand = rNEvt.GetCommandEvent();
763  if (pCommand->GetCommand() == CommandEventId::Wheel)
764  {
765  const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
767  {
768  // same as above : prevent the base class from doing Up/Down-calls
769  // (normally I should put this test into the Up/Down methods itself, shouldn't I ?)
770  // FS - 71553 - 19.01.00
771  return true;
772  }
773  }
774  }
775 
776  if (rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS)
777  {
778  // special treatment for empty texts
779  if (GetText().isEmpty())
780  {
781  if (!IsEmptyFieldEnabled())
782  {
783  if (TreatingAsNumber())
784  {
786  Modify();
788  }
789  else
790  {
791  OUString sNew = GetTextValue();
792  if (!sNew.isEmpty())
793  SetTextFormatted(sNew);
794  else
797  }
798  }
799  }
800  else
801  {
802  Commit();
803  }
804  }
805 
806  return SpinField::EventNotify( rNEvt );
807 }
808 
810 {
811  DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !");
812 
813  m_dMinValue = dMin;
814  m_bHasMin = true;
815  // for checking the current value at the new border -> ImplSetValue
816  ReFormat();
817 }
818 
820 {
821  DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !");
822 
823  m_dMaxValue = dMax;
824  m_bHasMax = true;
825  // for checking the current value at the new border -> ImplSetValue
826  ReFormat();
827 }
828 
829 void FormattedField::SetTextValue(const OUString& rText)
830 {
831  SetText(rText);
832  ReFormat();
833 }
834 
836 {
837  if (bEnable == m_bEnableEmptyField)
838  return;
839 
840  m_bEnableEmptyField = bEnable;
841  if (!m_bEnableEmptyField && GetText().isEmpty())
843 }
844 
845 void FormattedField::ImplSetValue(double dVal, bool bForce)
846 {
847 
848  if (m_bHasMin && (dVal<m_dMinValue))
849  dVal = m_dMinValue;
850  if (m_bHasMax && (dVal>m_dMaxValue))
851  dVal = m_dMaxValue;
852  if (!bForce && (dVal == GetValue()))
853  return;
854 
855  DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplSetValue : can't set a value without a formatter !");
856 
858  m_dCurrentValue = dVal;
859 
860  if (!m_aOutputHdl.IsSet() || !m_aOutputHdl.Call(*this))
861  {
862  OUString sNewText;
864  {
865  // first convert the number as string in standard format
866  OUString sTemp;
868  // then encode the string in the corresponding text format
870  }
871  else
872  {
874  {
876  }
877  else
878  {
880  }
881  }
882  ImplSetTextImpl(sNewText, nullptr);
883  DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
884  }
885 
887 }
888 
889 bool FormattedField::ImplGetValue(double& dNewVal)
890 {
891  dNewVal = m_dCurrentValue;
892  if (m_ValueState == valueDouble)
893  return true;
894 
895  dNewVal = m_dDefaultValue;
896  OUString sText(GetText());
897  if (sText.isEmpty())
898  return true;
899 
900  bool bUseExternalFormatterValue = false;
901  if (m_aInputHdl.IsSet())
902  {
903  sal_Int64 nResult;
904  auto eState = m_aInputHdl.Call(&nResult);
905  bUseExternalFormatterValue = eState != TRISTATE_INDET;
906  if (bUseExternalFormatterValue)
907  {
908  if (eState == TRISTATE_TRUE)
909  {
910  dNewVal = nResult;
912  }
913  else
914  dNewVal = m_dCurrentValue;
915  }
916  }
917 
918  if (!bUseExternalFormatterValue)
919  {
920  DBG_ASSERT(ImplGetFormatter() != nullptr, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
921 
922  sal_uInt32 nFormatKey = m_nFormatKey; // IsNumberFormat changes the FormatKey!
923 
924  if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
925  // for detection of values like "1,1" in fields that are formatted as text
926  nFormatKey = 0;
927 
928  // special treatment for percentage formatting
929  if (ImplGetFormatter()->GetType(m_nFormatKey) == SvNumFormatType::PERCENT)
930  {
931  // the language of our format
933  // the default number format for this language
934  sal_uLong nStandardNumericFormat = m_pFormatter->GetStandardFormat(SvNumFormatType::NUMBER, eLanguage);
935 
936  sal_uInt32 nTempFormat = nStandardNumericFormat;
937  double dTemp;
938  if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
939  SvNumFormatType::NUMBER == m_pFormatter->GetType(nTempFormat))
940  // the string is equivalent to a number formatted one (has no % sign) -> append it
941  sText += "%";
942  // (with this, an input of '3' becomes '3%', which then by the formatter is translated
943  // into 0.03. Without this, the formatter would give us the double 3 for an input '3',
944  // which equals 300 percent.
945  }
946  if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
947  return false;
948  }
949 
950  if (m_bHasMin && (dNewVal<m_dMinValue))
951  dNewVal = m_dMinValue;
952  if (m_bHasMax && (dNewVal>m_dMaxValue))
953  dNewVal = m_dMaxValue;
954  return true;
955 }
956 
957 void FormattedField::SetValue(double dVal)
958 {
960 }
961 
963 {
964 
965  if ( !ImplGetValue( m_dCurrentValue ) )
966  {
967  if ( m_bEnableNaN )
968  ::rtl::math::setNan( &m_dCurrentValue );
969  else
971  }
972 
974  return m_dCurrentValue;
975 }
976 
978 {
980 }
981 
982 bool FormattedField::set_property(const OString &rKey, const OUString &rValue)
983 {
984  if (rKey == "digits")
985  SetDecimalDigits(rValue.toInt32());
986  else
987  return SpinField::set_property(rKey, rValue);
988  return true;
989 }
990 
992 {
994 
995  sal_Int64 nValue = std::round(GetValue() * nScale);
996  sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale);
997  sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize;
998  if (nValue >= 0)
999  nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue + nSpinSize - nRemainder;
1000  else
1001  nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue - nRemainder;
1002 
1003  // setValue handles under- and overflows (min/max) automatically
1004  SetValue(static_cast<double>(nValue) / nScale);
1005  SetModifyFlag();
1006  Modify();
1007 
1008  SpinField::Up();
1009 }
1010 
1012 {
1014 
1015  sal_Int64 nValue = std::round(GetValue() * nScale);
1016  sal_Int64 nSpinSize = std::round(m_dSpinSize * nScale);
1017  sal_Int64 nRemainder = m_bDisableRemainderFactor ? 0 : nValue % nSpinSize;
1018  if (nValue >= 0)
1019  nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nRemainder;
1020  else
1021  nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nSpinSize - nRemainder;
1022 
1023  // setValue handles under- and overflows (min/max) automatically
1024  SetValue(static_cast<double>(nValue) / nScale);
1025  SetModifyFlag();
1026  Modify();
1027 
1028  SpinField::Down();
1029 }
1030 
1032 {
1033  if (m_bHasMin)
1034  {
1036  SetModifyFlag();
1037  Modify();
1038  }
1039 
1040  SpinField::First();
1041 }
1042 
1044 {
1045  if (m_bHasMax)
1046  {
1048  SetModifyFlag();
1049  Modify();
1050  }
1051 
1052  SpinField::Last();
1053 }
1054 
1056 {
1058 }
1059 
1061  : FormattedField(pParent, nStyle)
1062 {
1064 }
1065 
1067 
1069 {
1072 }
1073 
1074 bool DoubleNumericField::CheckText(const OUString& sText) const
1075 {
1076  // We'd like to implement this using the NumberFormatter::IsNumberFormat, but unfortunately, this doesn't
1077  // recognize fragments of numbers (like, for instance "1e", which happens during entering e.g. "1e10")
1078  // Thus, the roundabout way via a regular expression
1079  return m_pNumberValidator->isValidNumericFragment( sText );
1080 }
1081 
1083 {
1084  // the thousands and the decimal separator are language dependent
1085  const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
1086 
1087  sal_Unicode cSeparatorThousand = ',';
1088  sal_Unicode cSeparatorDecimal = '.';
1089  if (pFormatEntry)
1090  {
1091  LocaleDataWrapper aLocaleInfo( LanguageTag( pFormatEntry->GetLanguage()) );
1092 
1093  OUString sSeparator = aLocaleInfo.getNumThousandSep();
1094  if (!sSeparator.isEmpty())
1095  cSeparatorThousand = sSeparator[0];
1096 
1097  sSeparator = aLocaleInfo.getNumDecimalSep();
1098  if (!sSeparator.isEmpty())
1099  cSeparatorDecimal = sSeparator[0];
1100  }
1101 
1102  m_pNumberValidator.reset(new validation::NumberValidator( cSeparatorThousand, cSeparatorDecimal ));
1103 }
1104 
1106  :FormattedField(pParent, nStyle)
1107  ,m_bChangingFormat(false)
1108 {
1109  m_bPrependCurrSym = false;
1110 
1111  // initialize with a system currency format
1114 }
1115 
1117 {
1118  if (m_bChangingFormat)
1119  {
1121  return;
1122  }
1123 
1124  switch (nWhat)
1125  {
1129  // the aspects which changed don't take our currency settings into account (in fact, they most probably
1130  // destroyed them)
1132  break;
1134  OSL_FAIL("DoubleCurrencyField::FormatChanged : somebody modified my key !");
1135  // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.).
1136  // Nobody but ourself should modify the format key directly!
1137  break;
1138  default: break;
1139  }
1140 
1142 }
1143 
1144 void DoubleCurrencyField::setCurrencySymbol(const OUString& rSymbol)
1145 {
1146  if (m_sCurrencySymbol == rSymbol)
1147  return;
1148 
1149  m_sCurrencySymbol = rSymbol;
1152 }
1153 
1155 {
1156  if (m_bPrependCurrSym == _bPrepend)
1157  return;
1158 
1159  m_bPrependCurrSym = _bPrepend;
1162 }
1163 
1165 {
1166  // the old settings
1167  LanguageType eLanguage;
1168  GetFormat(eLanguage);
1169  bool bThSep = GetThousandsSep();
1170  sal_uInt16 nDigits = GetDecimalDigits();
1171 
1172  // build a new format string with the base class' and my own settings
1173 
1174  /* Strangely with gcc 4.6.3 this needs a temporary LanguageTag, otherwise
1175  * there's
1176  * error: request for member 'getNumThousandSep' in 'aLocaleInfo', which is
1177  * of non-class type 'LocaleDataWrapper(LanguageTag)' */
1178  LanguageTag aLanguageTag( eLanguage);
1179  LocaleDataWrapper aLocaleInfo( aLanguageTag );
1180 
1181  OUStringBuffer sNewFormat;
1182  if (bThSep)
1183  {
1184  sNewFormat.append('#');
1185  sNewFormat.append(aLocaleInfo.getNumThousandSep());
1186  sNewFormat.append("##0");
1187  }
1188  else
1189  sNewFormat.append('0');
1190 
1191  if (nDigits)
1192  {
1193  sNewFormat.append(aLocaleInfo.getNumDecimalSep());
1194 
1195  OUStringBuffer sTemp;
1196  comphelper::string::padToLength(sTemp, nDigits, '0');
1197  sNewFormat.append(sTemp);
1198  }
1199 
1200  if (getPrependCurrSym())
1201  {
1202  OUString sSymbol = getCurrencySymbol();
1203  sSymbol = comphelper::string::stripStart(sSymbol, ' ');
1204  sSymbol = comphelper::string::stripEnd(sSymbol, ' ');
1205 
1206  OUStringBuffer sTemp("[$");
1207  sTemp.append(sSymbol);
1208  sTemp.append("] ");
1209  sTemp.append(sNewFormat);
1210 
1211  // for negative values : $ -0.00, not -$ 0.00...
1212  // (the real solution would be a possibility to choose a "positive currency format" and a "negative currency format"...
1213  // But not now... (and hey, you could take a formatted field for this...))
1214  // FS - 31.03.00 74642
1215  sTemp.append(";[$");
1216  sTemp.append(sSymbol);
1217  sTemp.append("] -");
1218  sTemp.append(sNewFormat);
1219 
1220  sNewFormat = sTemp;
1221  }
1222  else
1223  {
1224  OUString sTemp = getCurrencySymbol();
1225  sTemp = comphelper::string::stripStart(sTemp, ' ');
1226  sTemp = comphelper::string::stripEnd(sTemp, ' ');
1227 
1228  sNewFormat.append(" [$");
1229  sNewFormat.append(sTemp);
1230  sNewFormat.append(']');
1231  }
1232 
1233  // set this new basic format
1234  m_bChangingFormat = true;
1235  SetFormat(sNewFormat.makeStringAndClear(), eLanguage);
1236  m_bChangingFormat = false;
1237 }
1238 
1239 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool SetFormat(const OUString &rFormatString, LanguageType eLang)
Definition: fmtfield.cxx:593
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: fmtfield.cxx:982
bool m_bEnableNaN
Definition: fmtfield.hxx:72
OString stripEnd(const OString &rIn, sal_Char c)
bool isValidNumericFragment(const OUString &_rText)
Definition: fmtfield.cxx:251
bool m_bStrictFormat
Definition: fmtfield.hxx:68
bool IsEmptyFieldEnabled() const
Definition: fmtfield.hxx:121
virtual ~DoubleNumericField() override
virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat) override
Definition: fmtfield.cxx:1068
static void lcl_insertStopTransition(StateTransitions &_rRow)
Definition: fmtfield.cxx:90
static void lcl_insertStartExponentTransition(StateTransitions &_rRow)
Definition: fmtfield.cxx:95
#define KEY_PAGEDOWN
Definition: keycodes.hxx:117
SvNumberFormatter * ImplGetFormatter() const
Definition: fmtfield.hxx:255
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:318
void SetFormatter(SvNumberFormatter *pFormatter, bool bResetFormat=true)
Definition: fmtfield.cxx:541
#define KEY_PAGEUP
Definition: keycodes.hxx:116
LanguageType getLanguageType(bool bResolveSystem=true) const
SelectionOptions GetSelectionOptions() const
SelectionOptions
Definition: settings.hxx:184
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, Color **ppColor, bool bUseStarFormat=false)
FORMAT_CHANGE_TYPE
Definition: fmtfield.hxx:30
sal_uIntPtr sal_uLong
#define SAL_INFO_IF(condition, area, stream)
const StyleSettings & GetStyleSettings() const
static VCL_DLLPUBLIC SvNumberFormatter * GetFormatter()
Definition: fmtfield.cxx:267
Link< sal_Int64 *, TriState > m_aInputHdl
Definition: fmtfield.hxx:262
virtual void Last() override
Definition: fmtfield.cxx:1043
SvNumFormatType GetType(sal_uInt32 nFIndex) const
OUString m_sDefaultText
Definition: fmtfield.hxx:92
::std::map< sal_Unicode, State > StateTransitions
Definition: fmtfield.cxx:67
sal_uInt16 GetCode() const
Definition: keycod.hxx:53
void ReFormat()
Definition: fmtfield.cxx:722
virtual void SetText(const OUString &rStr) override
Definition: fmtfield.cxx:321
const KeyEvent * GetKeyEvent() const
Definition: event.hxx:302
sal_uInt32 TestNewString(const OUString &sFormatString, LanguageType eLnge=LANGUAGE_DONTKNOW)
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: edit.cxx:176
virtual void First() override
Definition: fmtfield.cxx:1031
OUString m_sCurrencySymbol
Definition: fmtfield.hxx:298
virtual void Up()
Definition: spinfld.cxx:359
const CommandWheelData * GetWheelData() const
TransitionTable m_aTransitions
Definition: fmtfield.cxx:79
double m_dDefaultValue
Definition: fmtfield.hxx:77
void SetMaxValue(double dMax)
Definition: fmtfield.cxx:819
TRISTATE_TRUE
static sal_uLong s_nReferences
Definition: fmtfield.hxx:48
bool IsUsingInputStringForFormatting() const
Definition: fmtfield.hxx:234
const OUString & GetFormatstring() const
bool m_bUseInputStringForFormatting
Definition: fmtfield.hxx:97
sal_Int64 WinBits
sal_uInt16 sal_Unicode
const LocaleDataWrapper & GetLocaleData() const
double m_dCurrentValue
Definition: fmtfield.hxx:76
double m_dMinValue
Definition: fmtfield.hxx:63
StateTransitions::value_type Transition
Definition: fmtfield.cxx:70
void SetTextFormatted(const OUString &rText)
Definition: fmtfield.cxx:335
virtual bool CheckText(const OUString &sText) const override
Definition: fmtfield.cxx:1074
virtual void Up() override
Definition: fmtfield.cxx:991
double m_dSpinFirst
Definition: fmtfield.hxx:84
std::unique_ptr< validation::NumberValidator > m_pNumberValidator
Definition: fmtfield.hxx:278
static void lcl_insertSignTransitions(StateTransitions &_rRow, const State eNextState)
Definition: fmtfield.cxx:100
OUString const & GetTextValue() const
Definition: fmtfield.cxx:394
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
virtual void SetModifyFlag()
Definition: edit.cxx:2588
virtual const Selection & GetSelection() const
Definition: edit.cxx:2468
sal_uInt16 GetModifier() const
Definition: keycod.hxx:56
DoubleCurrencyField(vcl::Window *pParent, WinBits nStyle)
Definition: fmtfield.cxx:1105
void ImplSetTextImpl(const OUString &rNew, Selection const *pNewSel)
Definition: fmtfield.cxx:460
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: fmtfield.cxx:738
void GetFormatSpecialInfo(sal_uInt32 nFormat, bool &bThousand, bool &IsRed, sal_uInt16 &nPrecision, sal_uInt16 &nLeadingCnt)
void SetAutoColor(bool _bAutomatic)
Definition: fmtfield.cxx:412
virtual void Down()
Definition: spinfld.cxx:364
void SetTextValue(const OUString &rText)
Definition: fmtfield.cxx:829
static unsigned int Power10(unsigned int n)
Definition: builder.cxx:206
TRISTATE_INDET
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW)
void ImplSetValue(double dValue, bool bForce)
Definition: fmtfield.cxx:845
static SvNumberFormatter * s_cFormatter
Definition: fmtfield.hxx:47
void SetDecimalDigits(sal_uInt16 _nPrecision)
Definition: fmtfield.cxx:664
void EnableEmptyField(bool bEnable)
Definition: fmtfield.cxx:835
virtual void Modify() override
Definition: fmtfield.cxx:454
Color * m_pLastOutputColor
Definition: fmtfield.hxx:95
double GetValue()
Definition: fmtfield.cxx:962
Selection m_aLastSelection
Definition: fmtfield.hxx:61
END
const OUString & getNumDecimalSep() const
long Min() const
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: spinfld.cxx:490
void Justify()
OUString m_sCurrentTextValue
Definition: fmtfield.hxx:91
Link< Edit &, bool > m_aOutputHdl
Definition: fmtfield.hxx:261
sal_uLong m_nFormatKey
Definition: fmtfield.hxx:79
#define DBG_ASSERT(sCon, aError)
virtual void Down() override
Definition: fmtfield.cxx:1011
bool PutandConvertEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge, LanguageType eNewLnge, bool bConvertDateOrder)
bool IsStrictFormat() const
Definition: fmtfield.hxx:156
void UseInputStringForFormatting()
When being set to true, the strings in the field are formatted using the InputLine format...
Definition: fmtfield.cxx:1055
bool ImplGetValue(double &dNewVal)
Definition: fmtfield.cxx:889
bool IsTextFormat(sal_uInt32 nFIndex) const
void SetControlForeground()
Definition: window2.cxx:457
CommandWheelMode GetMode() const
QPRO_FUNC_TYPE const nType
double m_dSpinSize
Definition: fmtfield.hxx:83
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, sal_Char cFill= '\0')
virtual OUString GetText() const override
Definition: edit.cxx:2564
OString stripStart(const OString &rIn, sal_Char c)
CommandEventId GetCommand() const
virtual void Modify()
Definition: edit.cxx:2305
void setPrependCurrSym(bool _bPrepend)
Definition: fmtfield.cxx:1154
void SetEvalDateFormat(NfEvalDateFormat eEDF)
#define LANGUAGE_DONTKNOW
SvNumFormatType
MouseNotifyEvent GetType() const
Definition: event.hxx:294
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber)
bool m_bAutoColor
Definition: fmtfield.hxx:71
bool implValidateNormalized(const OUString &_rText)
Definition: fmtfield.cxx:212
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
bool PreNotify(NotifyEvent &rNEvt) override
Definition: fmtfield.cxx:508
void SetValue(double dVal)
Definition: fmtfield.cxx:957
void GetInputLineString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &rOutString)
void SetMinValue(double dMin)
Definition: fmtfield.cxx:809
bool GetThousandsSep() const
Definition: fmtfield.cxx:611
bool m_bDisableRemainderFactor
Definition: fmtfield.hxx:73
SvNumberFormatter * m_pFormatter
Definition: fmtfield.hxx:80
void ImplSetFormatKey(sal_uLong nFormatKey)
Definition: fmtfield.cxx:515
void Commit()
reformats the current text.
Definition: fmtfield.cxx:703
virtual bool CheckText(const OUString &) const
Definition: fmtfield.hxx:242
const OUString & getCurrSymbol() const
double m_dSpinLast
Definition: fmtfield.hxx:85
static void lcl_insertDigitTransitions(StateTransitions &_rRow, const State eNextState)
Definition: fmtfield.cxx:106
OUString GenerateFormat(sal_uInt32 nIndex, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bThousand=false, bool IsRed=false, sal_uInt16 nPrecision=0, sal_uInt16 nLeadingCnt=1)
void UpdateCurrencyFormat()
Definition: fmtfield.cxx:1164
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:53
virtual void First()
Definition: spinfld.cxx:369
OUString m_sLastValidText
Definition: fmtfield.hxx:58
#define KEY_DOWN
Definition: keycodes.hxx:110
void SetFormatKey(sal_uLong nFormatKey)
Definition: fmtfield.cxx:534
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
void DisableRemainderFactor()
Definition: fmtfield.cxx:977
DoubleNumericField(vcl::Window *pParent, WinBits nStyle)
Definition: fmtfield.cxx:1060
sal_uInt16 GetDecimalDigits() const
Definition: fmtfield.cxx:652
State
NumberValidator(const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
Definition: fmtfield.cxx:124
const OUString & getCurrencySymbol() const
Definition: fmtfield.hxx:287
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
bool m_bTreatAsNumber
Definition: fmtfield.hxx:89
void ResetConformanceTester()
Definition: fmtfield.cxx:1082
virtual void Last()
Definition: spinfld.cxx:374
virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat) override
Definition: fmtfield.cxx:1116
Reference< XComponentContext > getProcessComponentContext()
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: spinfld.cxx:835
const OUString & getNumThousandSep() const
WindowType GetType() const
Definition: window2.cxx:963
bool getPrependCurrSym() const
Definition: fmtfield.hxx:290
double m_dMaxValue
Definition: fmtfield.hxx:64
virtual void FormatChanged(FORMAT_CHANGE_TYPE nWhat)
Definition: fmtfield.cxx:693
const LanguageTag & GetLanguageTag() const
valueState m_ValueState
Definition: fmtfield.hxx:75
long Max() const
virtual bool IsReadOnly() const
Definition: edit.hxx:181
virtual void SetText(const OUString &rStr) override
Definition: edit.cxx:2545
NF_EVALDATEFORMAT_FORMAT_INTL
void setCurrencySymbol(const OUString &rSymbol)
Definition: fmtfield.cxx:1144
bool TreatingAsNumber() const
Definition: fmtfield.hxx:179
FormattedField(vcl::Window *pParent, WinBits nStyle)
Definition: fmtfield.cxx:295
void impl_Modify(bool makeValueDirty=true)
Definition: fmtfield.cxx:427
void SetThousandsSep(bool _bUseSeparator)
Definition: fmtfield.cxx:623
bool m_bEnableEmptyField
Definition: fmtfield.hxx:70
void EnableNotANumber(bool _bEnable)
enables handling of not-a-number value.
Definition: fmtfield.cxx:404
::std::map< State, StateTransitions > TransitionTable
Definition: fmtfield.cxx:73
LanguageType GetLanguage() const
OUString GetFormat(LanguageType &eLang) const
Definition: fmtfield.cxx:583
#define KEY_UP
Definition: keycodes.hxx:111
static void lcl_insertCommonPreCommaTransitions(StateTransitions &_rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
Definition: fmtfield.cxx:112