LibreOffice Module sw (master)  1
bookmrk.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 <memory>
21 #include <bookmrk.hxx>
22 #include <IDocumentMarkAccess.hxx>
23 #include <IDocumentUndoRedo.hxx>
25 #include <IDocumentState.hxx>
26 #include <doc.hxx>
27 #include <ndtxt.hxx>
28 #include <pam.hxx>
29 #include <swserv.hxx>
30 #include <svl/listener.hxx>
31 #include <sfx2/linkmgr.hxx>
32 #include <swtypes.hxx>
33 #include <UndoBookmark.hxx>
34 #include <unobookmark.hxx>
35 #include <xmloff/odffields.hxx>
36 #include <libxml/xmlwriter.h>
37 #include <comphelper/random.hxx>
39 #include <sal/log.hxx>
40 #include <edtwin.hxx>
41 #include <DateFormFieldButton.hxx>
43 #include <svx/numfmtsh.hxx>
44 #include <ndtxt.hxx>
46 
47 using namespace ::sw::mark;
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::uno;
50 
51 namespace
52 {
53  void lcl_FixPosition(SwPosition& rPos)
54  {
55  // make sure the position has 1) the proper node, and 2) a proper index
56  SwTextNode* pTextNode = rPos.nNode.GetNode().GetTextNode();
57  if(pTextNode == nullptr && rPos.nContent.GetIndex() > 0)
58  {
59  SAL_INFO(
60  "sw.core",
61  "illegal position: " << rPos.nContent.GetIndex()
62  << " without proper TextNode");
63  rPos.nContent.Assign(nullptr, 0);
64  }
65  else if(pTextNode != nullptr && rPos.nContent.GetIndex() > pTextNode->Len())
66  {
67  SAL_INFO(
68  "sw.core",
69  "illegal position: " << rPos.nContent.GetIndex()
70  << " is beyond " << pTextNode->Len());
71  rPos.nContent.Assign(pTextNode, pTextNode->Len());
72  }
73  }
74 
75  void lcl_AssertFieldMarksSet(Fieldmark const * const pField,
76  const sal_Unicode aStartMark,
77  const sal_Unicode aEndMark)
78  {
79  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
80  {
81  SwPosition const& rStart(pField->GetMarkStart());
82  assert(rStart.nNode.GetNode().GetTextNode()->GetText()[rStart.nContent.GetIndex()] == aStartMark); (void) rStart; (void) aStartMark;
83  }
84  SwPosition const& rEnd(pField->GetMarkEnd());
85  assert(rEnd.nNode.GetNode().GetTextNode()->GetText()[rEnd.nContent.GetIndex() - 1] == aEndMark); (void) rEnd;
86  }
87 
88  void lcl_SetFieldMarks(Fieldmark* const pField,
89  SwDoc* const io_pDoc,
90  const sal_Unicode aStartMark,
91  const sal_Unicode aEndMark)
92  {
94 
95  SwPosition start = pField->GetMarkStart();
96  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
97  {
98  SwPaM aStartPaM(start);
99  io_pDoc->getIDocumentContentOperations().InsertString(aStartPaM, OUString(aStartMark));
100  --start.nContent; // restore, it was moved by InsertString
101  // do not manipulate via reference directly but call SetMarkStartPos
102  // which works even if start and end pos were the same
103  pField->SetMarkStartPos( start );
104  }
105 
106  SwPosition& rEnd = pField->GetMarkEnd();
107  if (aEndMark)
108  {
109  SwPaM aEndPaM(rEnd);
110  io_pDoc->getIDocumentContentOperations().InsertString(aEndPaM, OUString(aEndMark));
111  ++rEnd.nContent;
112  }
113 
115  };
116 
117  void lcl_RemoveFieldMarks(Fieldmark const * const pField,
118  SwDoc* const io_pDoc,
119  const sal_Unicode aStartMark,
120  const sal_Unicode aEndMark)
121  {
123 
124  const SwPosition& rStart = pField->GetMarkStart();
125  SwTextNode const*const pStartTextNode = rStart.nNode.GetNode().GetTextNode();
126  assert(pStartTextNode);
127  if (aEndMark != CH_TXT_ATR_FORMELEMENT)
128  {
129  (void) aStartMark;
130  (void) pStartTextNode;
131  assert(pStartTextNode->GetText()[rStart.nContent.GetIndex()] == aStartMark);
132  SwPaM aStart(rStart, rStart);
133  ++aStart.End()->nContent;
134  io_pDoc->getIDocumentContentOperations().DeleteRange(aStart);
135  }
136 
137  const SwPosition& rEnd = pField->GetMarkEnd();
138  SwTextNode const*const pEndTextNode = rEnd.nNode.GetNode().GetTextNode();
139  assert(pEndTextNode);
140  const sal_Int32 nEndPos = (rEnd == rStart)
141  ? rEnd.nContent.GetIndex()
142  : rEnd.nContent.GetIndex() - 1;
143  assert(pEndTextNode->GetText()[nEndPos] == aEndMark);
144  (void) pEndTextNode;
145  (void) nEndPos;
146  SwPaM aEnd(rEnd, rEnd);
147  if (aEnd.Start()->nContent > 0)
148  --aEnd.Start()->nContent;
150 
152  };
153 }
154 
155 namespace sw { namespace mark
156 {
158  const OUString& rName)
159  : m_pPos1(new SwPosition(*(aPaM.GetPoint())))
160  , m_aName(rName)
161  {
162  m_pPos1->nContent.SetMark(this);
163  lcl_FixPosition(*m_pPos1);
164  if (aPaM.HasMark() && (*aPaM.GetMark() != *aPaM.GetPoint()))
165  {
167  lcl_FixPosition(*m_pPos2);
168  }
169  }
170 
171  // For fieldmarks, the CH_TXT_ATR_FIELDSTART and CH_TXT_ATR_FIELDEND
172  // themselves are part of the covered range. This is guaranteed by
173  // TextFieldmark::InitDoc/lcl_AssureFieldMarksSet.
174  bool MarkBase::IsCoveringPosition(const SwPosition& rPos) const
175  {
176  return GetMarkStart() <= rPos && rPos < GetMarkEnd();
177  }
178 
179  void MarkBase::SetMarkPos(const SwPosition& rNewPos)
180  {
181  std::make_unique<SwPosition>(rNewPos).swap(m_pPos1);
182  m_pPos1->nContent.SetMark(this);
183  }
184 
186  {
187  std::make_unique<SwPosition>(rNewPos).swap(m_pPos2);
188  m_pPos2->nContent.SetMark(this);
189  }
190 
191  OUString MarkBase::ToString( ) const
192  {
193  return "Mark: ( Name, [ Node1, Index1 ] ): ( " + m_aName + ", [ "
194  + OUString::number( GetMarkPos().nNode.GetIndex( ) ) + ", "
195  + OUString::number( GetMarkPos().nContent.GetIndex( ) ) + " ] )";
196  }
197 
199  {
200  xmlTextWriterStartElement(pWriter, BAD_CAST("MarkBase"));
201  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(m_aName.toUtf8().getStr()));
202  xmlTextWriterStartElement(pWriter, BAD_CAST("markPos"));
203  GetMarkPos().dumpAsXml(pWriter);
204  xmlTextWriterEndElement(pWriter);
205  if (IsExpanded())
206  {
207  xmlTextWriterStartElement(pWriter, BAD_CAST("otherMarkPos"));
208  GetOtherMarkPos().dumpAsXml(pWriter);
209  xmlTextWriterEndElement(pWriter);
210  }
211  xmlTextWriterEndElement(pWriter);
212  }
213 
215  { }
216 
217  OUString MarkBase::GenerateNewName(const OUString& rPrefix)
218  {
219  static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != nullptr);
220 
221  if (bHack)
222  {
223  static sal_Int64 nIdCounter = SAL_CONST_INT64(6000000000);
224  return rPrefix + OUString::number(nIdCounter++);
225  }
226  else
227  {
228  static OUString sUniquePostfix;
229  static sal_Int32 nCount = SAL_MAX_INT32;
230  OUStringBuffer aResult(rPrefix);
231  if(nCount == SAL_MAX_INT32)
232  {
233  unsigned int const n(comphelper::rng::uniform_uint_distribution(0,
234  std::numeric_limits<unsigned int>::max()));
235  sUniquePostfix = "_" + OUString::number(n);
236  nCount = 0;
237  }
238  // putting the counter in front of the random parts will speed up string comparisons
239  return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear();
240  }
241  }
242 
243  void MarkBase::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
244  {
245  NotifyClients(pOld, pNew);
246  if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
247  { // invalidate cached uno object
248  SetXBookmark(uno::Reference<text::XTextContent>(nullptr));
249  }
250  }
251 
252  // TODO: everything else uses MarkBase::GenerateNewName ?
254  : MarkBase(rPaM, "__NavigatorReminder__")
255  { }
256 
257  UnoMark::UnoMark(const SwPaM& aPaM)
258  : MarkBase(aPaM, MarkBase::GenerateNewName("__UnoMark__"))
259  { }
260 
262  : MarkBase(aPaM, MarkBase::GenerateNewName("__DdeLink__"))
263  { }
264 
266  {
267  m_aRefObj = pObj;
268  }
269 
271  {
272  if(m_aRefObj.is())
274  }
275 
277  {
278  if( m_aRefObj.is() )
279  {
280  if(m_aRefObj->HasDataLinks())
281  {
283  p->SendDataChanged();
284  }
286  }
287  }
288 
290  const vcl::KeyCode& rCode,
291  const OUString& rName)
292  : DdeBookmark(aPaM)
293  , ::sfx2::Metadatable()
294  , m_aCode(rCode)
295  , m_bHidden(false)
296  {
297  m_aName = rName;
298  }
299 
300  void Bookmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const)
301  {
302  if (io_pDoc->GetIDocumentUndoRedo().DoesUndo())
303  {
304  io_pDoc->GetIDocumentUndoRedo().AppendUndo(
305  std::make_unique<SwUndoInsBookmark>(*this));
306  }
307  io_pDoc->getIDocumentState().SetModified();
308  }
309 
310  void Bookmark::DeregisterFromDoc(SwDoc* const io_pDoc)
311  {
313 
314  if (io_pDoc->GetIDocumentUndoRedo().DoesUndo())
315  {
316  io_pDoc->GetIDocumentUndoRedo().AppendUndo(
317  std::make_unique<SwUndoDeleteBookmark>(*this));
318  }
319  io_pDoc->getIDocumentState().SetModified();
320  }
321 
323  {
324  SwDoc *const pDoc( GetMarkPos().GetDoc() );
325  assert(pDoc);
326  return pDoc->GetXmlIdRegistry();
327  }
328 
330  {
331  SwDoc *const pDoc( GetMarkPos().GetDoc() );
332  assert(pDoc);
333  return pDoc->IsClipBoard();
334  }
335 
336  bool Bookmark::IsInUndo() const
337  {
338  return false;
339  }
340 
342  {
343  SwDoc *const pDoc( GetMarkPos().GetDoc() );
344  assert(pDoc);
345  return !pDoc->IsInHeaderFooter( GetMarkPos().nNode );
346  }
347 
348  uno::Reference< rdf::XMetadatable > Bookmark::MakeUnoObject()
349  {
350  SwDoc *const pDoc( GetMarkPos().GetDoc() );
351  assert(pDoc);
352  const uno::Reference< rdf::XMetadatable> xMeta(
353  SwXBookmark::CreateXBookmark(*pDoc, this), uno::UNO_QUERY);
354  return xMeta;
355  }
356 
358  : MarkBase(rPaM, MarkBase::GenerateNewName("__Fieldmark__"))
359  {
360  if(!IsExpanded())
362  }
363 
364  void Fieldmark::SetMarkStartPos( const SwPosition& rNewStartPos )
365  {
366  if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
367  return SetMarkPos( rNewStartPos );
368  else
369  return SetOtherMarkPos( rNewStartPos );
370  }
371 
372  void Fieldmark::SetMarkEndPos( const SwPosition& rNewEndPos )
373  {
374  if ( GetMarkPos( ) <= GetOtherMarkPos( ) )
375  return SetOtherMarkPos( rNewEndPos );
376  else
377  return SetMarkPos( rNewEndPos );
378  }
379 
380  OUString Fieldmark::ToString( ) const
381  {
382  return "Fieldmark: ( Name, Type, [ Nd1, Id1 ], [ Nd2, Id2 ] ): ( " + m_aName + ", "
383  + m_aFieldname + ", [ " + OUString::number( GetMarkPos().nNode.GetIndex( ) )
384  + ", " + OUString::number( GetMarkPos( ).nContent.GetIndex( ) ) + " ], ["
385  + OUString::number( GetOtherMarkPos().nNode.GetIndex( ) ) + ", "
386  + OUString::number( GetOtherMarkPos( ).nContent.GetIndex( ) ) + " ] ) ";
387  }
388 
390  {
391  // TODO: Does exist a better solution to trigger a format of the
392  // fieldmark portion? If yes, please use it.
393  SwPaM aPaM( GetMarkPos(), GetOtherMarkPos() );
394  aPaM.InvalidatePaM();
395  }
396 
398  {
399  xmlTextWriterStartElement(pWriter, BAD_CAST("Fieldmark"));
400  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("fieldname"), BAD_CAST(m_aFieldname.toUtf8().getStr()));
401  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("fieldHelptext"), BAD_CAST(m_aFieldHelptext.toUtf8().getStr()));
402  MarkBase::dumpAsXml(pWriter);
403  xmlTextWriterStartElement(pWriter, BAD_CAST("parameters"));
404  for (auto& rParam : m_vParams)
405  {
406  xmlTextWriterStartElement(pWriter, BAD_CAST("parameter"));
407  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("name"), BAD_CAST(rParam.first.toUtf8().getStr()));
408  xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(comphelper::anyToString(rParam.second).toUtf8().getStr()));
409  xmlTextWriterEndElement(pWriter);
410  }
411  xmlTextWriterEndElement(pWriter);
412  xmlTextWriterEndElement(pWriter);
413  }
414 
415  TextFieldmark::TextFieldmark(const SwPaM& rPaM, const OUString& rName)
416  : Fieldmark(rPaM)
417  {
418  if ( !rName.isEmpty() )
419  m_aName = rName;
420  }
421 
422  void TextFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
423  {
424  if (eMode == sw::mark::InsertMode::New)
425  {
426  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
427  }
428  else
429  {
430  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
431  }
432  }
433 
435  {
436  lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
437  }
438 
440  : Fieldmark(rPaM)
441  { }
442 
443  void NonTextFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
444  {
445  if (eMode == sw::mark::InsertMode::New)
446  {
447  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
448 
449  // For some reason the end mark is moved from 1 by the Insert:
450  // we don't want this for checkboxes
451  SwPosition aNewEndPos = GetMarkEnd();
452  aNewEndPos.nContent--;
453  SetMarkEndPos( aNewEndPos );
454  }
455  else
456  {
457  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
458  }
459  }
460 
462  {
463  lcl_RemoveFieldMarks(this, pDoc,
465  }
466 
467 
469  : NonTextFieldmark(rPaM)
470  { }
471 
472  void CheckboxFieldmark::SetChecked(bool checked)
473  {
474  if ( IsChecked() != checked )
475  {
476  (*GetParameters())[OUString(ODF_FORMCHECKBOX_RESULT)] <<= checked;
477  // mark document as modified
478  SwDoc *const pDoc( GetMarkPos().GetDoc() );
479  if ( pDoc )
480  pDoc->getIDocumentState().SetModified();
481  }
482  }
483 
485  {
486  bool bResult = false;
487  parameter_map_t::const_iterator pResult = GetParameters()->find(OUString(ODF_FORMCHECKBOX_RESULT));
488  if(pResult != GetParameters()->end())
489  pResult->second >>= bResult;
490  return bResult;
491  }
492 
494  : NonTextFieldmark(rPaM)
495  , m_pButton(nullptr)
496  {
497  }
498 
500  {
502  }
503 
505  {
506  if(m_pButton)
507  m_pButton->Show(false);
508  }
509 
511  {
512  if(m_pButton)
514  }
515 
518  {
519  }
520 
522  {
523  }
524 
526  {
527  if(pEditWin)
528  {
529  if(!m_pButton)
532  m_pButton->Show();
533  }
534  }
535 
536  void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
537  {
538  if(m_aPortionPaintArea == rPortionPaintArea &&
540  return;
541 
542  m_aPortionPaintArea = rPortionPaintArea;
543  if(m_pButton)
544  {
545  m_pButton->Show();
548  }
549  }
550 
553  , m_pNumberFormatter(nullptr)
554  , m_pDocumentContentOperationsManager(nullptr)
555  {
556  }
557 
559  {
560  }
561 
563  {
566  if (eMode == sw::mark::InsertMode::New)
567  {
568  lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
569  }
570  else
571  {
572  lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
573  }
574  }
575 
577  {
578  lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
579  }
580 
582  {
583  if(pEditWin)
584  {
585  if(!m_pButton)
588  m_pButton->Show();
589  }
590  }
591 
592  void DateFieldmark::SetPortionPaintAreaStart(const SwRect& rPortionPaintArea)
593  {
594  m_aPaintAreaStart = rPortionPaintArea;
596  }
597 
598  void DateFieldmark::SetPortionPaintAreaEnd(const SwRect& rPortionPaintArea)
599  {
600  if(m_aPaintAreaEnd == rPortionPaintArea &&
602  return;
603 
604  m_aPaintAreaEnd = rPortionPaintArea;
605  if(m_pButton)
606  {
607  m_pButton->Show();
609  m_pButton->CalcPosAndSize(aPaintArea);
611  }
613  }
614 
615  OUString DateFieldmark::GetContent() const
616  {
617  const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
618  const sal_Int32 nStart(GetMarkStart().nContent.GetIndex());
619  const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
620 
621  OUString sContent;
622  if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
623  nEnd > nStart + 2)
624  sContent = pTextNode->GetText().copy(nStart + 1, nEnd - nStart - 2);
625  return sContent;
626  }
627 
628  void DateFieldmark::ReplaceContent(const OUString& sNewContent)
629  {
631  return;
632 
633  const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
634  const sal_Int32 nStart(GetMarkStart().nContent.GetIndex());
635  const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
636 
637  if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
638  nEnd > nStart + 2)
639  {
640  SwPaM aFieldPam(GetMarkStart().nNode, nStart + 1,
641  GetMarkStart().nNode, nEnd - 1);
642  m_pDocumentContentOperationsManager->ReplaceRange(aFieldPam, sNewContent, false);
643  }
644  else
645  {
646  SwPaM aFieldStartPam(GetMarkStart().nNode, nStart + 1);
647  m_pDocumentContentOperationsManager->InsertString(aFieldStartPam, sNewContent);
648  }
649 
650  }
651 
652  std::pair<bool, double> DateFieldmark::GetCurrentDate() const
653  {
654  // Check current date param first
655  std::pair<bool, double> aResult = ParseCurrentDateParam();
656  if(aResult.first)
657  return aResult;
658 
660  bool bFoundValidDate = false;
661  double dCurrentDate = 0;
662  OUString sDateFormat;
663  auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
664  if (pResult != pParameters->end())
665  {
666  pResult->second >>= sDateFormat;
667  }
668 
669  OUString sLang;
670  pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
671  if (pResult != pParameters->end())
672  {
673  pResult->second >>= sLang;
674  }
675 
676  // Get current content of the field
677  OUString sContent = GetContent();
678 
679  sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
680  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
681  {
682  sal_Int32 nCheckPos = 0;
684  m_pNumberFormatter->PutEntry(sDateFormat,
685  nCheckPos,
686  nType,
687  nFormat,
688  LanguageTag(sLang).getLanguageType());
689  }
690 
691  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
692  {
693  bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sContent, nFormat, dCurrentDate);
694  }
695  return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
696  }
697 
698  void DateFieldmark::SetCurrentDate(double fDate)
699  {
700  // Replace current content with the selected date
702 
703  // Also save the current date in a standard format
705  (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= GetDateInStandardDateFormat(fDate);
706  }
707 
708  OUString DateFieldmark::GetDateInStandardDateFormat(double fDate) const
709  {
710  OUString sCurrentDate;
712  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
713  {
714  sal_Int32 nCheckPos = 0;
716  OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
717  m_pNumberFormatter->PutEntry(sFormat,
718  nCheckPos,
719  nType,
720  nFormat,
722  }
723 
724  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
725  {
726  Color* pCol = nullptr;
727  m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentDate, &pCol, false);
728  }
729  return sCurrentDate;
730  }
731 
732  std::pair<bool, double> DateFieldmark::ParseCurrentDateParam() const
733  {
734  bool bFoundValidDate = false;
735  double dCurrentDate = 0;
736 
738  auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
739  OUString sCurrentDate;
740  if (pResult != pParameters->end())
741  {
742  pResult->second >>= sCurrentDate;
743  }
744  if(!sCurrentDate.isEmpty())
745  {
747  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
748  {
749  sal_Int32 nCheckPos = 0;
751  OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
752  m_pNumberFormatter->PutEntry(sFormat,
753  nCheckPos,
754  nType,
755  nFormat,
757  }
758 
759  if(nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
760  {
761  bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate);
762  }
763  }
764  return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
765  }
766 
767 
768  OUString DateFieldmark::GetDateInCurrentDateFormat(double fDate) const
769  {
770  // Get current date format and language
771  OUString sDateFormat;
773  auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
774  if (pResult != pParameters->end())
775  {
776  pResult->second >>= sDateFormat;
777  }
778 
779  OUString sLang;
780  pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
781  if (pResult != pParameters->end())
782  {
783  pResult->second >>= sLang;
784  }
785 
786  // Fill the content with the specified format
787  OUString sCurrentContent;
788  sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
789  if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
790  {
791  sal_Int32 nCheckPos = 0;
793  OUString sFormat = sDateFormat;
794  m_pNumberFormatter->PutEntry(sFormat,
795  nCheckPos,
796  nType,
797  nFormat,
798  LanguageTag(sLang).getLanguageType());
799  }
800 
801  if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
802  {
803  Color* pCol = nullptr;
804  m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentContent, &pCol, false);
805  }
806  return sCurrentContent;
807  }
808 
810  {
811  std::pair<bool, double> aResult = ParseCurrentDateParam();
812  if(!aResult.first)
813  return;
814 
815  // Current date became invalid
816  if(GetDateInCurrentDateFormat(aResult.second) != GetContent())
817  {
819  (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
820  }
821  }
822 }}
823 
824 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetMarkStartPos(const SwPosition &rNewStartPos)
Definition: bookmrk.cxx:364
OUString m_aName
Definition: bookmrk.hxx:120
static OUString GenerateNewName(const OUString &rPrefix)
Definition: bookmrk.cxx:217
virtual std::pair< bool, double > GetCurrentDate() const override
Definition: bookmrk.cxx:652
bool is() const
DateFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:551
virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) override
Definition: bookmrk.cxx:243
std::map< OUString, css::uno::Any > parameter_map_t
Definition: IMark.hxx:94
Marks a position in the document model.
Definition: pam.hxx:35
OUString m_aFieldHelptext
Definition: bookmrk.hxx:238
bool IsChecked() const override
Definition: bookmrk.cxx:484
virtual void ShowButton(SwEditWin *pEditWin) override
Definition: bookmrk.cxx:525
const OUString & GetText() const
Definition: ndtxt.hxx:211
virtual bool IsInUndo() const override
Definition: bookmrk.cxx:336
virtual void ReplaceContent(const OUString &sNewContent) override
Definition: bookmrk.cxx:628
SvNumberFormatter * GetNumberFormatter(bool bCreate=true)
Definition: doc.hxx:1399
SwNodeIndex nNode
Definition: pam.hxx:37
void GetOutputString(const double &fOutNumber, sal_uInt32 nFIndex, OUString &sOutString, Color **ppColor, bool bUseStarFormat=false)
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:461
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:284
virtual void SetModified()=0
Must be called manually at changes of format.
void disposeAndClear()
const SwPosition * GetMark() const
Definition: pam.hxx:209
#define ODF_FORMDATE_CURRENTDATE
virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Closes undo block.
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: bookmrk.cxx:397
Definition: doc.hxx:185
#define ODF_FORMDATE_DATEFORMAT_LANGUAGE
virtual SwPosition & GetMarkStart() const override
Definition: bookmrk.hxx:65
IDocumentLinksAdministration const & getIDocumentLinksAdministration() const
Definition: doc.cxx:292
sw::DocumentContentOperationsManager * m_pDocumentContentOperationsManager
Definition: bookmrk.hxx:335
OUString m_aFieldname
Definition: bookmrk.hxx:237
void SetChecked(bool checked) override
Definition: bookmrk.cxx:472
virtual OUString ToString() const override
Definition: bookmrk.cxx:191
virtual void DeleteRange(SwPaM &)=0
Delete a range SwFlyFrameFormat.
SwNode & GetNode() const
Definition: ndindex.hxx:118
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:434
UnoMark(const SwPaM &rPaM)
Definition: bookmrk.cxx:257
virtual ::sfx2::IXmlIdRegistry & GetRegistry() override
Definition: bookmrk.cxx:322
virtual void ReleaseDoc(SwDoc *const pDoc) override
Definition: bookmrk.cxx:576
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:40
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:176
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
#define RES_REMOVE_UNO_OBJECT
Definition: hintids.hxx:304
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:347
void SetPortionPaintAreaEnd(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:598
virtual bool IsCoveringPosition(const SwPosition &rPos) const override
Definition: bookmrk.cxx:174
#define CH_TXT_ATR_FORMELEMENT
Definition: hintids.hxx:50
virtual ~DdeBookmark() override
Definition: bookmrk.cxx:276
bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND) override
Insert string into existing text node at position rRg.Point().
TextFieldmark(const SwPaM &rPaM, const OUString &rName)
Definition: bookmrk.cxx:415
#define ODF_FORMCHECKBOX_RESULT
bool IsInHeaderFooter(const SwNodeIndex &rIdx) const
Definition: doclay.cxx:1555
Fieldmark with a drop down button (e.g. this button opens the date picker for a date field) ...
Definition: bookmrk.hxx:273
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
void InvalidatePaM()
Definition: pam.cxx:1058
std::unique_ptr< SwPosition > m_pPos1
Definition: bookmrk.hxx:118
virtual bool IsExpanded() const override
Definition: bookmrk.hxx:83
#define ODF_FORMDATE_CURRENTDATE_LANGUAGE
virtual SwPosition & GetMarkEnd() const override
Definition: bookmrk.hxx:73
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode) override
Definition: bookmrk.cxx:422
sal_uInt16 sal_Unicode
FUNC_TYPE const nType
SwIndex nContent
Definition: pam.hxx:38
std::unique_ptr< SwPosition > m_pPos2
Definition: bookmrk.hxx:119
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode) override
Definition: bookmrk.cxx:443
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
virtual ~DropDownFieldmark() override
Definition: bookmrk.cxx:521
void RemoveServer(SvLinkSource *rObj)
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
std::pair< bool, double > ParseCurrentDateParam() const
Definition: bookmrk.cxx:732
::sfx2::IXmlIdRegistry & GetXmlIdRegistry()
Definition: docnew.cxx:806
OUString GetDateInCurrentDateFormat(double fDate) const
Definition: bookmrk.cxx:768
void InvalidateCurrentDateParam()
Definition: bookmrk.cxx:809
virtual parameter_map_t * GetParameters()=0
#define ODF_FORMDATE_CURRENTDATE_FORMAT
virtual bool DoesUndo() const =0
Is Undo enabled?
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW)
Bookmark(const SwPaM &rPaM, const vcl::KeyCode &rCode, const OUString &rName)
Definition: bookmrk.cxx:289
virtual void ShowButton(SwEditWin *pEditWin) override
Definition: bookmrk.cxx:581
void SetRefObject(SwServerObject *pObj)
Definition: bookmrk.cxx:265
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
void swap(cow_wrapper< T, P > &a, cow_wrapper< T, P > &b)
struct _xmlTextWriter * xmlTextWriterPtr
static css::uno::Reference< css::text::XTextContent > CreateXBookmark(SwDoc &rDoc,::sw::mark::IMark *pBookmark)
Definition: unobkm.cxx:156
T * get() const
virtual bool InsertString(const SwPaM &rRg, const OUString &, const SwInsertFlags nInsertMode=SwInsertFlags::EMPTYEXPAND)=0
Insert string into existing text node at position rRg.Point().
virtual void AppendUndo(std::unique_ptr< SwUndo > pUndo)=0
Add new Undo action.
virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const *const pRewriter)=0
Opens undo block.
#define SAL_MAX_INT32
const SwPosition * GetPoint() const
Definition: pam.hxx:207
void SetMarkEndPos(const SwPosition &rNewEndPos)
Definition: bookmrk.cxx:372
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:198
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: bookmrk.cxx:198
::sw::DocumentContentOperationsManager const & GetDocumentContentOperationsManager() const
Definition: doc.cxx:357
void CalcPosAndSize(const SwRect &rPortionPaintArea)
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
void SetNoServer()
Definition: swserv.cxx:252
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
virtual ~MarkBase() override
Definition: bookmrk.cxx:214
#define CH_TXT_ATR_FIELDSTART
Definition: hintids.hxx:52
SvNumberFormatter * m_pNumberFormatter
Definition: bookmrk.hxx:334
IDocumentState const & getIDocumentState() const
Definition: doc.cxx:426
DdeBookmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:261
virtual css::uno::Reference< css::rdf::XMetadatable > MakeUnoObject() override
Definition: bookmrk.cxx:348
SvNumFormatType
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber)
void SetPortionPaintAreaStart(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:592
#define ODF_FORMDATE_DATEFORMAT
DropDownFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:516
const Point BottomRight() const
Definition: swrect.cxx:180
virtual void InitDoc(SwDoc *const io_pDoc, sw::mark::InsertMode eMode) override
Definition: bookmrk.cxx:562
CheckboxFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:468
enumrange< T >::Iterator end(enumrange< T >)
virtual OUString ToString() const override
Definition: bookmrk.cxx:380
const Point TopLeft() const
Definition: swrect.cxx:177
virtual void DeregisterFromDoc(SwDoc *const io_pDoc) override
Definition: bookmrk.cxx:310
void NotifyClients(const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue)
Definition: calbck.cxx:167
bool HasDataLinks() const
NavigatorReminder(const SwPaM &rPaM)
Definition: bookmrk.cxx:253
NonTextFieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:439
virtual SwPosition & GetOtherMarkPos() const override
Definition: bookmrk.hxx:60
FieldmarkWithDropDownButton(const SwPaM &rPaM)
Definition: bookmrk.cxx:493
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
MarkBase(const SwPaM &rPaM, const OUString &rName)
Definition: bookmrk.cxx:157
void SetXBookmark(css::uno::Reference< css::text::XTextContent > const &xBkmk)
Definition: bookmrk.hxx:110
virtual bool IsInContent() const override
Definition: bookmrk.cxx:341
bool IsVisible() const
virtual bool IsInClipboard() const override
Definition: bookmrk.cxx:329
#define SAL_INFO(area, stream)
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsClipBoard() const
Definition: doc.hxx:954
virtual SwPosition & GetMarkPos() const override
Definition: bookmrk.hxx:56
static VclPtr< reference_type > Create(Arg &&...arg)
virtual void SetMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:179
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: pam.cxx:183
void SetPortionPaintArea(const SwRect &rPortionPaintArea)
Definition: bookmrk.cxx:536
IFieldmark::parameter_map_t m_vParams
Definition: bookmrk.hxx:239
virtual const SwPosition & GetMarkEnd() const =0
virtual ~DateFieldmark() override
Definition: bookmrk.cxx:558
#define CH_TXT_ATR_FIELDEND
Definition: hintids.hxx:53
virtual void SetCurrentDate(double fDate) override
Definition: bookmrk.cxx:698
sal_uInt32 GetEntryKey(const OUString &sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
virtual OUString GetContent() const override
Definition: bookmrk.cxx:615
Fieldmark(const SwPaM &rPaM)
Definition: bookmrk.cxx:357
virtual sfx2::LinkManager & GetLinkManager()=0
virtual void InitDoc(SwDoc *const io_Doc, sw::mark::InsertMode eMode) override
Definition: bookmrk.cxx:300
virtual void DeregisterFromDoc(SwDoc *const pDoc)
Definition: bookmrk.cxx:270
tools::SvRef< SwServerObject > m_aRefObj
Definition: bookmrk.hxx:157
virtual const SwPosition & GetMarkStart() const =0
bool ReplaceRange(SwPaM &rPam, const OUString &rNewStr, const bool bRegExReplace) override
Replace selected range in a TextNode with string.
InsertMode
Definition: IMark.hxx:31
virtual void SetOtherMarkPos(const SwPosition &rNewPos)
Definition: bookmrk.cxx:185
virtual ~FieldmarkWithDropDownButton() override
Definition: bookmrk.cxx:499
sal_uInt16 Which() const
virtual void Invalidate() override
Definition: bookmrk.cxx:389
VclPtr< FormFieldButton > m_pButton
Definition: bookmrk.hxx:285
virtual IFieldmark::parameter_map_t * GetParameters() override
Definition: bookmrk.hxx:216
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:843
OUString anyToString(uno::Any const &value)
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo
virtual OUString GetDateInStandardDateFormat(double fDate) const override
Definition: bookmrk.cxx:708