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