[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 29 commits - include/xmloff officecfg/registry sw/inc sw/Library_sw.mk sw/Library_swui.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk writerfilter/source
Tamás Zolnai (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 17 09:41:38 UTC 2019
dev/null |binary
include/xmloff/odffields.hxx | 7
officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu | 8
sw/Library_sw.mk | 2
sw/Library_swui.mk | 1
sw/UIConfig_swriter.mk | 1
sw/inc/IDocumentMarkAccess.hxx | 3
sw/inc/IMark.hxx | 19
sw/inc/cmdid.h | 2
sw/inc/swabstdlg.hxx | 5
sw/qa/extras/globalfilter/data/date_form_field.odt |binary
sw/qa/extras/globalfilter/data/date_form_field_char_formatting.odt |binary
sw/qa/extras/globalfilter/globalfilter.cxx | 169 +++++
sw/qa/extras/ooxmlexport/data/invalid_date_form_field.docx |binary
sw/qa/extras/ooxmlexport/data/n820509.docx |binary
sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 11
sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 80 ++
sw/qa/extras/ooxmlexport/ooxmlexport4.cxx | 7
sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 42 -
sw/qa/extras/ooxmlimport/ooxmlimport2.cxx | 39 +
sw/qa/extras/uiwriter/uiwriter2.cxx | 197 +++++
sw/sdi/_textsh.sdi | 6
sw/sdi/swriter.sdi | 18
sw/source/core/crsr/DateFormFieldButton.cxx | 103 +++
sw/source/core/crsr/DropDownFormFieldButton.cxx | 123 ---
sw/source/core/crsr/FormFieldButton.cxx | 155 ++++
sw/source/core/crsr/bookmrk.cxx | 336 +++++++++-
sw/source/core/doc/docbm.cxx | 68 +-
sw/source/core/inc/DateFormFieldButton.hxx | 47 +
sw/source/core/inc/DropDownFormFieldButton.hxx | 19
sw/source/core/inc/FormFieldButton.hxx | 56 +
sw/source/core/inc/MarkManager.hxx | 6
sw/source/core/inc/bookmrk.hxx | 79 +-
sw/source/core/text/itrform2.cxx | 17
sw/source/core/text/porfld.cxx | 21
sw/source/core/text/porfld.hxx | 19
sw/source/core/unocore/unobkm.cxx | 6
sw/source/filter/ww8/docxattributeoutput.cxx | 145 ++--
sw/source/filter/ww8/docxattributeoutput.hxx | 3
sw/source/filter/ww8/docxexport.cxx | 3
sw/source/filter/ww8/fields.hxx | 3
sw/source/filter/ww8/wrtw8nds.cxx | 121 ++-
sw/source/ui/dialog/swdlgfact.cxx | 9
sw/source/ui/dialog/swdlgfact.hxx | 8
sw/source/ui/dialog/swuiexp.cxx | 1
sw/source/ui/fldui/DateFormFieldDialog.cxx | 129 +++
sw/source/uibase/docvw/edtwin.cxx | 2
sw/source/uibase/inc/DateFormFieldDialog.hxx | 53 +
sw/source/uibase/shells/textfld.cxx | 39 +
sw/source/uibase/shells/textsh1.cxx | 16
sw/uiconfig/swriter/menubar/mscompatibleformsmenu.xml | 2
sw/uiconfig/swriter/ui/dateformfielddialog.ui | 124 +++
writerfilter/source/dmapper/DomainMapper.cxx | 111 +--
writerfilter/source/dmapper/DomainMapper_Impl.cxx | 4
writerfilter/source/dmapper/DomainMapper_Impl.hxx | 1
writerfilter/source/dmapper/SdtHelper.cxx | 128 +--
writerfilter/source/dmapper/SdtHelper.hxx | 12
57 files changed, 2079 insertions(+), 507 deletions(-)
New commits:
commit 08684d4fc6796804612fd0800c719bd1716f34e4
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Tue Jul 16 11:14:45 2019 +0100
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:01 2019 +0200
tdf#126414: MSForms: fix flickering of date field button on Windows
Need to ignore empty paint area parameters.
Change-Id: I195d7bf9b3914199984f4a732d7616520d51dbba
Reviewed-on: https://gerrit.libreoffice.org/75708
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit 13a2db4941447001b81b077ee587903ae84cfc91)
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 88fa37c0e1f1..14fab9d32da5 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -585,19 +585,26 @@ namespace sw { namespace mark
{
if(!m_pButton)
m_pButton = VclPtr<DateFormFieldButton>::Create(pEditWin, *this, m_pNumberFormatter);
- m_pButton->CalcPosAndSize(m_aPaintAreaEnd);
+ SwRect aPaintArea(m_aPaintAreaStart.TopLeft(), m_aPaintAreaEnd.BottomRight());
+ m_pButton->CalcPosAndSize(aPaintArea);
m_pButton->Show();
}
}
void DateFieldmark::SetPortionPaintAreaStart(const SwRect& rPortionPaintArea)
{
+ if (rPortionPaintArea.IsEmpty())
+ return;
+
m_aPaintAreaStart = rPortionPaintArea;
InvalidateCurrentDateParam();
}
void DateFieldmark::SetPortionPaintAreaEnd(const SwRect& rPortionPaintArea)
{
+ if (rPortionPaintArea.IsEmpty())
+ return;
+
if(m_aPaintAreaEnd == rPortionPaintArea &&
m_pButton && m_pButton->IsVisible())
return;
commit 5adee770c8c42419a50970391c611acb8bf2e7c6
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Jul 15 10:26:51 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:01 2019 +0200
Disable testDateFormFieldCurrentDateInvalidation test only for Windows
Reviewed-on: https://gerrit.libreoffice.org/75613
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit f74fbba22e435852c1ee37abf4384be7db6d8607)
Change-Id: Id267d118b509177f93f3c440a03d05feb532cd34
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 669887e03d62..ddaa4894af2e 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -90,7 +90,9 @@ public:
void testDateFormFieldInsertion();
void testDateFormFieldContentOperations();
void testDateFormFieldCurrentDateHandling();
- //void testDateFormFieldCurrentDateInvalidation();
+#if !defined(_WIN32)
+ void testDateFormFieldCurrentDateInvalidation();
+#endif
CPPUNIT_TEST_SUITE(SwUiWriterTest2);
CPPUNIT_TEST(testRedlineMoveInsertInDelete);
@@ -125,7 +127,9 @@ public:
CPPUNIT_TEST(testDateFormFieldInsertion);
CPPUNIT_TEST(testDateFormFieldContentOperations);
CPPUNIT_TEST(testDateFormFieldCurrentDateHandling);
- //CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
+#if !defined(_WIN32)
+ CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
+#endif
CPPUNIT_TEST_SUITE_END();
private:
@@ -1466,7 +1470,8 @@ void SwUiWriterTest2::testDateFormFieldCurrentDateHandling()
CPPUNIT_ASSERT_EQUAL(OUString("2031-06-01"), sCurrentDate);
}
-/*void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
+#if !defined(_WIN32)
+void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
{
SwDoc* pDoc = createDoc();
CPPUNIT_ASSERT(pDoc);
@@ -1522,7 +1527,8 @@ void SwUiWriterTest2::testDateFormFieldCurrentDateHandling()
pResult->second >>= sCurrentDate;
}
CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate);
-}*/
+}
+#endif
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
commit ddee85404ae42d1dbc4501d2ee33f8b60ef9a67e
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sun Jul 14 14:00:24 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:00 2019 +0200
Disable testDateFormFieldCurrentDateInvalidation() test
It hangs on Windows.
(cherry picked from commit b55d5e3fd2cc92661b06ab4edf8d5956d461a166)
Change-Id: If1e0054327212e5c2bf691c51f419677a4a15739
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 15b960a50fee..669887e03d62 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -90,7 +90,7 @@ public:
void testDateFormFieldInsertion();
void testDateFormFieldContentOperations();
void testDateFormFieldCurrentDateHandling();
- void testDateFormFieldCurrentDateInvalidation();
+ //void testDateFormFieldCurrentDateInvalidation();
CPPUNIT_TEST_SUITE(SwUiWriterTest2);
CPPUNIT_TEST(testRedlineMoveInsertInDelete);
@@ -125,7 +125,7 @@ public:
CPPUNIT_TEST(testDateFormFieldInsertion);
CPPUNIT_TEST(testDateFormFieldContentOperations);
CPPUNIT_TEST(testDateFormFieldCurrentDateHandling);
- CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
+ //CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
CPPUNIT_TEST_SUITE_END();
private:
@@ -1466,7 +1466,7 @@ void SwUiWriterTest2::testDateFormFieldCurrentDateHandling()
CPPUNIT_ASSERT_EQUAL(OUString("2031-06-01"), sCurrentDate);
}
-void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
+/*void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
{
SwDoc* pDoc = createDoc();
CPPUNIT_ASSERT(pDoc);
@@ -1522,7 +1522,7 @@ void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
pResult->second >>= sCurrentDate;
}
CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate);
-}
+}*/
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
commit e339e224c02c8ad2bc658660c6f848985d52fce5
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Jul 11 17:20:59 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:00 2019 +0200
MSForms: Test date fieldmark's content and current date related methods
These methods are used by the field's properties dialog,
it's drop-down button and DOCX export.
Reviewed-on: https://gerrit.libreoffice.org/75463
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit d0ff1090762ac61ce08f54bc76685232699d98a0)
Change-Id: I2b75e69b452a736cc72785d251516f3b3bf1d1f1
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 0af09b335d5b..15b960a50fee 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -88,6 +88,9 @@ public:
void testTdf124261();
void testShapePageMove();
void testDateFormFieldInsertion();
+ void testDateFormFieldContentOperations();
+ void testDateFormFieldCurrentDateHandling();
+ void testDateFormFieldCurrentDateInvalidation();
CPPUNIT_TEST_SUITE(SwUiWriterTest2);
CPPUNIT_TEST(testRedlineMoveInsertInDelete);
@@ -120,6 +123,9 @@ public:
CPPUNIT_TEST(testTdf124261);
CPPUNIT_TEST(testShapePageMove);
CPPUNIT_TEST(testDateFormFieldInsertion);
+ CPPUNIT_TEST(testDateFormFieldContentOperations);
+ CPPUNIT_TEST(testDateFormFieldCurrentDateHandling);
+ CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
CPPUNIT_TEST_SUITE_END();
private:
@@ -1372,6 +1378,152 @@ void SwUiWriterTest2::testDateFormFieldInsertion()
CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
}
+void SwUiWriterTest2::testDateFormFieldContentOperations()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a date form field
+ lcl_dispatchCommand(mxComponent, ".uno:DatePickerFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IDateFieldmark* pFieldmark
+ = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+
+ // Check the default content added by insertion
+ uno::Reference<text::XTextRange> xPara = getParagraph(1);
+ sal_Unicode vEnSpaces[5] = { 8194, 8194, 8194, 8194, 8194 };
+ CPPUNIT_ASSERT_EQUAL(OUString(vEnSpaces, 5), pFieldmark->GetContent());
+
+ // Set content to empty string
+ pFieldmark->ReplaceContent("");
+ CPPUNIT_ASSERT_EQUAL(OUString(""), pFieldmark->GetContent());
+
+ // Replace empty string with a valid content
+ pFieldmark->ReplaceContent("2019-10-23");
+ CPPUNIT_ASSERT_EQUAL(OUString("2019-10-23"), pFieldmark->GetContent());
+}
+
+void SwUiWriterTest2::testDateFormFieldCurrentDateHandling()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a date form field
+ lcl_dispatchCommand(mxComponent, ".uno:DatePickerFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IDateFieldmark* pFieldmark
+ = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+
+ // The default content is not a valid date
+ uno::Reference<text::XTextRange> xPara = getParagraph(1);
+ sal_Unicode vEnSpaces[5] = { 8194, 8194, 8194, 8194, 8194 };
+ CPPUNIT_ASSERT_EQUAL(OUString(vEnSpaces, 5), pFieldmark->GetContent());
+ std::pair<bool, double> aResult = pFieldmark->GetCurrentDate();
+ CPPUNIT_ASSERT(!aResult.first);
+
+ // Check empty string
+ pFieldmark->ReplaceContent("");
+ aResult = pFieldmark->GetCurrentDate();
+ CPPUNIT_ASSERT(!aResult.first);
+
+ // Check valid date
+ // Set date format first
+ sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldmark->GetParameters();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= OUString("YYYY/MM/DD");
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= OUString("en-US");
+
+ // Set date value and check whether the content is formatted correctly
+ pFieldmark->SetCurrentDate(48000.0);
+ aResult = pFieldmark->GetCurrentDate();
+ CPPUNIT_ASSERT(aResult.first);
+ CPPUNIT_ASSERT_EQUAL(48000.0, aResult.second);
+ CPPUNIT_ASSERT_EQUAL(OUString("2031/06/01"), pFieldmark->GetContent());
+ // Current date param contains date in a "standard format"
+ OUString sCurrentDate;
+ auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sCurrentDate;
+ }
+ CPPUNIT_ASSERT_EQUAL(OUString("2031-06-01"), sCurrentDate);
+}
+
+void SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
+{
+ SwDoc* pDoc = createDoc();
+ CPPUNIT_ASSERT(pDoc);
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+ CPPUNIT_ASSERT(pMarkAccess);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+
+ // Insert a date form field
+ lcl_dispatchCommand(mxComponent, ".uno:DatePickerFormField", {});
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Check whether the fieldmark is created
+ auto aIter = pMarkAccess->getAllMarksBegin();
+ CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
+ ::sw::mark::IDateFieldmark* pFieldmark
+ = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+
+ // Set a date first
+ sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldmark->GetParameters();
+ pFieldmark->SetCurrentDate(48000.0);
+ std::pair<bool, double> aResult = pFieldmark->GetCurrentDate();
+ CPPUNIT_ASSERT(aResult.first);
+ CPPUNIT_ASSERT_EQUAL(48000.0, aResult.second);
+
+ // Do the layouting to trigger invalidation
+ // Since we have the current date consistent with the field content
+ // This invalidation won't change anything
+ calcLayout();
+ Scheduler::ProcessEventsToIdle();
+
+ // Current date param contains date in a "standard format"
+ OUString sCurrentDate;
+ auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sCurrentDate;
+ }
+ // We have the current date parameter set
+ CPPUNIT_ASSERT_EQUAL(OUString("2031-06-01"), sCurrentDate);
+
+ // Now change the content of the field
+ pFieldmark->ReplaceContent("[select date]");
+ // Do the layouting to trigger invalidation
+ calcLayout();
+ Scheduler::ProcessEventsToIdle();
+
+ sCurrentDate.clear();
+ pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sCurrentDate;
+ }
+ CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 8a95852f9379c56a6a033815266583318eda444e
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Jul 10 12:07:09 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:00 2019 +0200
MSForms: date field: handle replacing empty content
It occurs when the date field is empty and the user trying to
set a date with the date picker.
Change-Id: I182930258b05071d861c2b326c139c73e2339af9
Reviewed-on: https://gerrit.libreoffice.org/75461
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
Tested-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit fcb36a995dde68456b862db8a931b98176f9eca7)
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 393e7b5cfa69..88fa37c0e1f1 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -635,12 +635,18 @@ namespace sw { namespace mark
const sal_Int32 nStart(GetMarkStart().nContent.GetIndex());
const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
- if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength())
+ if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
+ nEnd > nStart + 2)
{
SwPaM aFieldPam(GetMarkStart().nNode, nStart + 1,
GetMarkStart().nNode, nEnd - 1);
m_pDocumentContentOperationsManager->ReplaceRange(aFieldPam, sNewContent, false);
}
+ else
+ {
+ SwPaM aFieldStartPam(GetMarkStart().nNode, nStart + 1);
+ m_pDocumentContentOperationsManager->InsertString(aFieldStartPam, sNewContent);
+ }
}
commit 28e8c673b71e1f49a47ea6251c2d813c40f0a70e
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Jul 10 18:23:48 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:00 2019 +0200
MSForms: Test import / export of character formatting for date field
* With the rework, now the character formatting is fully supported.
* Remove the other related test, which tested only a interop
grabbag implementation.
Reviewed-on: https://gerrit.libreoffice.org/75460
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit 01f6c6ad6ba1adce817daa782bf3520fafc512a0)
Change-Id: I598a21691c08a161933a5fef659e7ca21092dd0c
diff --git a/sw/qa/extras/globalfilter/data/date_form_field_char_formatting.odt b/sw/qa/extras/globalfilter/data/date_form_field_char_formatting.odt
new file mode 100644
index 000000000000..eb770262056a
Binary files /dev/null and b/sw/qa/extras/globalfilter/data/date_form_field_char_formatting.odt differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index f511df98f698..9df6e2ee8d55 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -29,6 +29,7 @@
#include <IDocumentMarkAccess.hxx>
#include <IMark.hxx>
#include <bookmrk.hxx>
+#include <com/sun/star/awt/FontWeight.hpp>
class Test : public SwModelTestBase
{
@@ -53,6 +54,7 @@ public:
void testCheckBoxFormField();
void testDropDownFormField();
void testDateFormField();
+ void testDateFormFieldCharacterFormatting();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testEmbeddedGraphicRoundtrip);
@@ -72,6 +74,7 @@ public:
CPPUNIT_TEST(testCheckBoxFormField);
CPPUNIT_TEST(testDropDownFormField);
CPPUNIT_TEST(testDateFormField);
+ CPPUNIT_TEST(testDateFormFieldCharacterFormatting);
CPPUNIT_TEST_SUITE_END();
};
@@ -1358,6 +1361,54 @@ void Test::testDateFormField()
}
}
+void Test::testDateFormFieldCharacterFormatting()
+{
+ const OUString aFilterNames[] = {
+ "writer8",
+ "Office Open XML Text",
+ };
+
+ for (const OUString& rFilterName : aFilterNames)
+ {
+ if (mxComponent.is())
+ mxComponent->dispose();
+ mxComponent = loadFromDesktop(m_directories.getURLFromSrc("/sw/qa/extras/globalfilter/data/date_form_field_char_formatting.odt"), "com.sun.star.text.TextDocument");
+
+ const OString sFailedMessage = OString("Failed on filter: ") + rFilterName.toUtf8();
+
+ // Export the document and import again for a check
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= rFilterName;
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+ uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY);
+ xComponent->dispose();
+ mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+
+ // Check the document after round trip
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pTextDoc);
+ SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
+ IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
+
+ // Check that we have the field at the right place
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(1), pMarkAccess->getAllMarksCount());
+ ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(pMarkAccess->getAllMarksBegin()->get());
+ CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0), pFieldmark->GetMarkStart().nContent.GetIndex());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(10), pFieldmark->GetMarkEnd().nContent.GetIndex());
+
+ // We have one date field, first half of the field has bold character weight and second part has red character color
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::BOLD, getProperty<float>(getRun(getParagraph(1), 2), "CharWeight"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(COL_AUTO), getProperty<sal_Int32>(getRun(getParagraph(1), 2), "CharColor"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), awt::FontWeight::NORMAL, getProperty<float>(getRun(getParagraph(1), 3), "CharWeight"));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(0xff0000), getProperty<sal_Int32>(getRun(getParagraph(1), 3), "CharColor"));
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/ooxmlexport/data/sdt-date-charformat.docx b/sw/qa/extras/ooxmlexport/data/sdt-date-charformat.docx
deleted file mode 100644
index 22c4d4e1f8c3..000000000000
Binary files a/sw/qa/extras/ooxmlexport/data/sdt-date-charformat.docx and /dev/null differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 029228cb3fcb..b9be20c37146 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -72,17 +72,6 @@ DECLARE_OOXMLEXPORT_TEST(testSdtAlias, "sdt-alias.docx")
assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:alias", "val", "Subtitle");
}
-/*DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx")
-{
- if (xmlDocPtr pXmlDoc = parseExport())
- {
- // character formatting (bold) was missing, this was 0
- assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:rPr/w:b", 1);
- // alias was also missing.
- assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:alias", 1);
- }
-}*/
-
DECLARE_OOXMLEXPORT_TEST(testFooterBodyDistance, "footer-body-distance.docx")
{
if (xmlDocPtr pXmlDoc = parseExport())
commit 047220d82b3eefa5fdeec186752b70205a16369b
Author: Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Jul 10 18:22:31 2019 +0200
Commit: Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Wed Jul 17 11:40:00 2019 +0200
MSForms: Rework text-based date form field's representation
* Better to represent it similar to text form field with two
marking characters selecting a text range
* So the text between the two marks can be anything (not only
a well formatted date) and also have any character formatting.
* With this we handle the case when the user needs a placeholder
text in the date field or when the user needs time values (hour,
minute, sec) next to the date.
Reviewed-on: https://gerrit.libreoffice.org/75459
Tested-by: Jenkins
Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
(cherry picked from commit 68e1be4ccbb90ee9a788962219a88312c4ffbea2)
Change-Id: Id60a50a2028058f8a6a080e265c0730d88b98543
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index ee021ad7c4e4..c26f0ab10461 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -258,7 +258,7 @@ class IDocumentMarkAccess
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0;
virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
- virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
+ virtual ::sw::mark::IFieldmark* changeFormFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
virtual void NotifyCursorUpdate(const SwCursorShell& rCursorShell) = 0;
virtual void ClearFieldActivation() = 0;
diff --git a/sw/inc/IMark.hxx b/sw/inc/IMark.hxx
index ba49320040bd..2592c2e6817d 100644
--- a/sw/inc/IMark.hxx
+++ b/sw/inc/IMark.hxx
@@ -156,6 +156,25 @@ namespace sw { namespace mark
}
};
+ class SW_DLLPUBLIC IDateFieldmark
+ : virtual public IFieldmark
+ {
+ protected:
+ IDateFieldmark() = default;
+
+ public:
+ virtual OUString GetContent() const = 0;
+ virtual void ReplaceContent(const OUString& sNewContent) = 0;
+
+ virtual std::pair<bool, double> GetCurrentDate() const = 0;
+ virtual void SetCurrentDate(double fDate) = 0;
+ virtual OUString GetDateInStandardDateFormat(double fDate) const = 0;
+
+ private:
+ IDateFieldmark(ICheckboxFieldmark const &) = delete;
+ IDateFieldmark &operator =(ICheckboxFieldmark const&) = delete;
+ };
+
OUString ExpandFieldmark(IFieldmark* pBM);
}}
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index efa7375e0f11..2347116e172c 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -78,7 +78,7 @@ namespace com{namespace sun{namespace star{
}}}
-namespace sw { namespace mark { class IFieldmark; } }
+namespace sw { namespace mark { class IFieldmark; class IDateFieldmark; } }
typedef void (*SwLabDlgMethod) (css::uno::Reference< css::frame::XModel> const & xModel, const SwLabItem& rItem);
@@ -393,7 +393,7 @@ public:
SwField* pField, bool bPrevButton, bool bNextButton) = 0;
virtual VclPtr<VclAbstractDialog> CreateDropDownFormFieldDialog(weld::Window* pParent, sw::mark::IFieldmark* pDropDownField) = 0;
- virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc) = 0;
+ virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IDateFieldmark* pDateField, SwDoc* pDoc) = 0;
virtual VclPtr<SfxAbstractTabDialog> CreateSwEnvDlg(weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert) = 0;
virtual VclPtr<AbstractSwLabDlg> CreateSwLabDlg(weld::Window* pParent, const SfxItemSet& rSet,
diff --git a/sw/qa/extras/globalfilter/data/date_form_field.odt b/sw/qa/extras/globalfilter/data/date_form_field.odt
index 8e15793c2d59..2b786a414658 100644
Binary files a/sw/qa/extras/globalfilter/data/date_form_field.odt and b/sw/qa/extras/globalfilter/data/date_form_field.odt differ
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index de14efc78018..f511df98f698 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -1274,19 +1274,12 @@ void Test::testDateFormField()
SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
- if(rFilterName == "Office Open XML Text")
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(6), pMarkAccess->getAllMarksCount());
- else
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(3), pMarkAccess->getAllMarksCount());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pMarkAccess->getAllMarksCount());
int nIndex = 0;
for(auto aIter = pMarkAccess->getAllMarksBegin(); aIter != pMarkAccess->getAllMarksEnd(); ++aIter)
{
- ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(aIter->get());
-
- if(!pFieldmark)
- continue;
-
+ ::sw::mark::IDateFieldmark* pFieldmark = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
@@ -1306,20 +1299,16 @@ void Test::testDateFormField()
pResult->second >>= sLang;
}
- OUString sCurrentDate;
- pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
- if (pResult != pParameters->end())
- {
- pResult->second >>= sCurrentDate;
- }
+ OUString sCurrentDate = pFieldmark->GetContent();
- // The first one is empty
+ // The first one has the default field content
if(nIndex == 0)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(""), sCurrentDate);
+ sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(vEnSpaces, 5), sCurrentDate);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(5), pFieldmark->GetMarkStart().nContent.GetIndex());
@@ -1328,24 +1317,44 @@ void Test::testDateFormField()
{
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-12"), sCurrentDate);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("06/12/19"), sCurrentDate);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(13), pFieldmark->GetMarkStart().nContent.GetIndex());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(19), pFieldmark->GetMarkStart().nContent.GetIndex());
}
- else // The third one has special format
+ else if (nIndex == 2) // The third one has special format
{
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[NatNum12 MMMM=abbreviation]YYYY\". \"MMMM D."), sDateFormat);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("hu-HU"), sLang);
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019-06-11"), sCurrentDate);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("2019. febr. 12."), sCurrentDate);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(38), pFieldmark->GetMarkStart().nContent.GetIndex());
+
+ }
+ else if (nIndex == 3) // The fourth one has placeholder text
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("D, MMM YY"), sDateFormat);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("bm-ML"), sLang);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("[select date]"), sCurrentDate);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(59), pFieldmark->GetMarkStart().nContent.GetIndex());
+
+ }
+ else // The last one is really empty
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("MM/DD/YY"), sDateFormat);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString("en-US"), sLang);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(""), sCurrentDate);
CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(23), pFieldmark->GetMarkStart().nContent.GetIndex());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(78), pFieldmark->GetMarkStart().nContent.GetIndex());
}
++nIndex;
}
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(3), nIndex);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(5), nIndex);
}
}
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 9b5828ff688a..d0250213ccd1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -263,7 +263,7 @@ DECLARE_OOXMLIMPORT_TEST(testInvalidDateFormField, "invalid_date_form_field.docx
CPPUNIT_ASSERT_EQUAL(OUString("2019.06.34"), sCurrentDate);
CPPUNIT_ASSERT_EQUAL(sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
- CPPUNIT_ASSERT_EQUAL(sal_Int32(13), pFieldmark->GetMarkStart().nContent.GetIndex());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(14), pFieldmark->GetMarkStart().nContent.GetIndex());
}
else // The third one has wrong local
{
@@ -272,7 +272,7 @@ DECLARE_OOXMLIMPORT_TEST(testInvalidDateFormField, "invalid_date_form_field.docx
CPPUNIT_ASSERT_EQUAL(OUString("2019.06.11"), sCurrentDate);
CPPUNIT_ASSERT_EQUAL(sal_uLong(9), pFieldmark->GetMarkStart().nNode.GetIndex());
- CPPUNIT_ASSERT_EQUAL(sal_Int32(23), pFieldmark->GetMarkStart().nContent.GetIndex());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(33), pFieldmark->GetMarkStart().nContent.GetIndex());
}
++nIndex;
}
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 8af12404dbb3..03a884a2cd3d 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -22,6 +22,9 @@
#include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp>
#include <com/sun/star/embed/Aspects.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
+#include <xmloff/odffields.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <IMark.hxx>
class Test : public SwModelTestBase
{
@@ -40,16 +43,38 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108545_embeddedDocxIcon, "tdf108545_embeddedDocx
DECLARE_OOXMLIMPORT_TEST(testTdf121203, "tdf121203.docx")
{
- // Make sure that the date SDT's content is imported as plain text, as
- // the field has no fullDate attribute which we can use to find out the actual date.
- CPPUNIT_ASSERT_EQUAL(OUString("17-Oct-2018 09:00"), getRun(getParagraph(1), 1)->getString());
-
- // Make sure we did not import a date field.
+ // We imported the date field
SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
CPPUNIT_ASSERT(pTextDoc);
SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
- CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMarkAccess->getAllMarksCount());
+
+ // Custom sdt date content is imported correctly
+ ::sw::mark::IDateFieldmark* pFieldmark
+ = dynamic_cast<::sw::mark::IDateFieldmark*>(pMarkAccess->getAllMarksBegin()->get());
+ CPPUNIT_ASSERT(pFieldmark);
+ CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+
+ const sw::mark::IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
+ OUString sDateFormat;
+ auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sDateFormat;
+ }
+
+ OUString sLang;
+ pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sLang;
+ }
+
+ OUString sCurrentDate = pFieldmark->GetContent();
+ CPPUNIT_ASSERT_EQUAL(OUString("dd-MMM-yy"), sDateFormat);
+ CPPUNIT_ASSERT_EQUAL(OUString("en-GB"), sLang);
+ CPPUNIT_ASSERT_EQUAL(OUString("17-Oct-2018 09:00"), sCurrentDate);
}
DECLARE_OOXMLIMPORT_TEST(testTdf109053, "tdf109053.docx")
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 1706323f6088..0af09b335d5b 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1354,6 +1354,11 @@ void SwUiWriterTest2::testDateFormFieldInsertion()
CPPUNIT_ASSERT(pFieldmark);
CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
+ // The date form field has the placeholder text in it
+ uno::Reference<text::XTextRange> xPara = getParagraph(1);
+ sal_Unicode vEnSpaces[5] = { 8194, 8194, 8194, 8194, 8194 };
+ CPPUNIT_ASSERT_EQUAL(OUString(vEnSpaces, 5), xPara->getString());
+
// Undo insertion
lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), pMarkAccess->getAllMarksCount());
diff --git a/sw/source/core/crsr/DateFormFieldButton.cxx b/sw/source/core/crsr/DateFormFieldButton.cxx
index 360db4055710..0fdcf842dc30 100644
--- a/sw/source/core/crsr/DateFormFieldButton.cxx
+++ b/sw/source/core/crsr/DateFormFieldButton.cxx
@@ -28,19 +28,19 @@ class SwDatePickerDialog : public FloatingWindow
{
private:
VclPtr<Calendar> m_pCalendar;
- sw::mark::IFieldmark* m_pFieldmark;
+ sw::mark::DateFieldmark* m_pFieldmark;
SvNumberFormatter* m_pNumberFormatter;
DECL_LINK(ImplSelectHdl, Calendar*, void);
public:
- SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark,
+ SwDatePickerDialog(SwEditWin* parent, sw::mark::DateFieldmark* pFieldmark,
SvNumberFormatter* pNumberFormatter);
virtual ~SwDatePickerDialog() override;
virtual void dispose() override;
};
-SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark,
+SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::DateFieldmark* pFieldmark,
SvNumberFormatter* pNumberFormatter)
: FloatingWindow(parent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW)
, m_pCalendar(VclPtr<Calendar>::Create(this, WB_TABSTOP))
@@ -49,33 +49,11 @@ SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark*
{
if (m_pFieldmark != nullptr)
{
- sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters();
-
- auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
- if (pResult != pParameters->end())
+ std::pair<bool, double> aResult = m_pFieldmark->GetCurrentDate();
+ if (aResult.first)
{
- OUString sDateString;
- pResult->second >>= sDateString;
-
- sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
- m_pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- }
-
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- double dCurrentDate = 0;
- m_pNumberFormatter->IsNumberFormat(sDateString, nFormat, dCurrentDate);
-
- const Date& rNullDate = m_pNumberFormatter->GetNullDate();
- m_pCalendar->SetCurDate(rNullDate + sal_Int32(dCurrentDate));
- }
+ const Date& rNullDate = m_pNumberFormatter->GetNullDate();
+ m_pCalendar->SetCurDate(rNullDate + sal_Int32(aResult.second));
}
}
m_pCalendar->SetSelectHdl(LINK(this, SwDatePickerDialog, ImplSelectHdl));
@@ -98,30 +76,9 @@ IMPL_LINK(SwDatePickerDialog, ImplSelectHdl, Calendar*, pCalendar, void)
{
if (m_pFieldmark != nullptr)
{
- sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
- m_pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- }
-
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- Color* pCol = nullptr;
- OUString sOutput;
-
- const Date& rNullDate = m_pNumberFormatter->GetNullDate();
- double dDate = pCalendar->GetFirstSelectedDate() - rNullDate;
-
- m_pNumberFormatter->GetOutputString(dDate, nFormat, sOutput, &pCol, false);
-
- sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters();
- (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= sOutput;
- }
+ const Date& rNullDate = m_pNumberFormatter->GetNullDate();
+ double dDate = pCalendar->GetFirstSelectedDate() - rNullDate;
+ m_pFieldmark->SetCurrentDate(dDate);
}
EndPopupMode();
}
@@ -138,8 +95,9 @@ DateFormFieldButton::~DateFormFieldButton() { disposeOnce(); }
void DateFormFieldButton::InitPopup()
{
+ sw::mark::DateFieldmark* pDateFieldmark = dynamic_cast<sw::mark::DateFieldmark*>(&m_rFieldmark);
m_pFieldPopup = VclPtr<SwDatePickerDialog>::Create(static_cast<SwEditWin*>(GetParent()),
- &m_rFieldmark, m_pNumberFormatter);
+ pDateFieldmark, m_pNumberFormatter);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 0035f7375a68..393e7b5cfa69 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -41,6 +41,8 @@
#include <DateFormFieldButton.hxx>
#include <DropDownFormFieldButton.hxx>
#include <svx/numfmtsh.hxx>
+#include <ndtxt.hxx>
+#include <DocumentContentOperationsManager.hxx>
using namespace ::sw::mark;
using namespace ::com::sun::star;
@@ -500,21 +502,6 @@ namespace sw { namespace mark
m_pButton.disposeAndClear();
}
- void FieldmarkWithDropDownButton::SetPortionPaintArea(const SwRect& rPortionPaintArea)
- {
- if(m_aPortionPaintArea == rPortionPaintArea &&
- m_pButton && m_pButton->IsVisible())
- return;
-
- m_aPortionPaintArea = rPortionPaintArea;
- if(m_pButton)
- {
- m_pButton->Show();
- m_pButton->CalcPosAndSize(m_aPortionPaintArea);
- m_pButton->Invalidate();
- }
- }
-
void FieldmarkWithDropDownButton::HideButton()
{
if(m_pButton)
@@ -547,8 +534,25 @@ namespace sw { namespace mark
}
}
+ void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea)
+ {
+ if(m_aPortionPaintArea == rPortionPaintArea &&
+ m_pButton && m_pButton->IsVisible())
+ return;
+
+ m_aPortionPaintArea = rPortionPaintArea;
+ if(m_pButton)
+ {
+ m_pButton->Show();
+ m_pButton->CalcPosAndSize(m_aPortionPaintArea);
+ m_pButton->Invalidate();
+ }
+ }
+
DateFieldmark::DateFieldmark(const SwPaM& rPaM)
: FieldmarkWithDropDownButton(rPaM)
+ , m_pNumberFormatter(nullptr)
+ , m_pDocumentContentOperationsManager(nullptr)
{
}
@@ -559,7 +563,20 @@ namespace sw { namespace mark
void DateFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode)
{
m_pNumberFormatter = io_pDoc->GetNumberFormatter();
- NonTextFieldmark::InitDoc(io_pDoc, eMode);
+ m_pDocumentContentOperationsManager = &io_pDoc->GetDocumentContentOperationsManager();
+ if (eMode == sw::mark::InsertMode::New)
+ {
+ lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
+ }
+ else
+ {
+ lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
+ }
+ }
+
+ void DateFieldmark::ReleaseDoc(SwDoc* const pDoc)
+ {
+ lcl_RemoveFieldMarks(this, pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
}
void DateFieldmark::ShowButton(SwEditWin* pEditWin)
@@ -568,10 +585,235 @@ namespace sw { namespace mark
{
if(!m_pButton)
m_pButton = VclPtr<DateFormFieldButton>::Create(pEditWin, *this, m_pNumberFormatter);
- m_pButton->CalcPosAndSize(m_aPortionPaintArea);
+ m_pButton->CalcPosAndSize(m_aPaintAreaEnd);
m_pButton->Show();
}
}
+
+ void DateFieldmark::SetPortionPaintAreaStart(const SwRect& rPortionPaintArea)
+ {
+ m_aPaintAreaStart = rPortionPaintArea;
+ InvalidateCurrentDateParam();
+ }
+
+ void DateFieldmark::SetPortionPaintAreaEnd(const SwRect& rPortionPaintArea)
+ {
+ if(m_aPaintAreaEnd == rPortionPaintArea &&
+ m_pButton && m_pButton->IsVisible())
+ return;
+
+ m_aPaintAreaEnd = rPortionPaintArea;
+ if(m_pButton)
+ {
+ m_pButton->Show();
+ SwRect aPaintArea(m_aPaintAreaStart.TopLeft(), m_aPaintAreaEnd.BottomRight());
+ m_pButton->CalcPosAndSize(aPaintArea);
+ m_pButton->Invalidate();
+ }
+ InvalidateCurrentDateParam();
+ }
+
+ OUString DateFieldmark::GetContent() const
+ {
+ const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
+ const sal_Int32 nStart(GetMarkStart().nContent.GetIndex());
+ const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
+
+ OUString sContent;
+ if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength() &&
+ nEnd > nStart + 2)
+ sContent = pTextNode->GetText().copy(nStart + 1, nEnd - nStart - 2);
+ return sContent;
+ }
+
+ void DateFieldmark::ReplaceContent(const OUString& sNewContent)
+ {
+ if(!m_pDocumentContentOperationsManager)
+ return;
+
+ const SwTextNode* const pTextNode = GetMarkEnd().nNode.GetNode().GetTextNode();
+ const sal_Int32 nStart(GetMarkStart().nContent.GetIndex());
+ const sal_Int32 nEnd (GetMarkEnd().nContent.GetIndex());
+
+ if(nStart + 1 < pTextNode->GetText().getLength() && nEnd <= pTextNode->GetText().getLength())
+ {
+ SwPaM aFieldPam(GetMarkStart().nNode, nStart + 1,
+ GetMarkStart().nNode, nEnd - 1);
+ m_pDocumentContentOperationsManager->ReplaceRange(aFieldPam, sNewContent, false);
+ }
+
+ }
+
+ std::pair<bool, double> DateFieldmark::GetCurrentDate() const
+ {
+ // Check current date param first
+ std::pair<bool, double> aResult = ParseCurrentDateParam();
+ if(aResult.first)
+ return aResult;
+
+ const sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
+ bool bFoundValidDate = false;
+ double dCurrentDate = 0;
+ OUString sDateFormat;
+ auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sDateFormat;
+ }
+
+ OUString sLang;
+ pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sLang;
+ }
+
+ // Get current content of the field
+ OUString sContent = GetContent();
+
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ m_pNumberFormatter->PutEntry(sDateFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+
+ if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sContent, nFormat, dCurrentDate);
+ }
+ return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
+ }
+
+ void DateFieldmark::SetCurrentDate(double fDate)
+ {
+ // Replace current content with the selected date
+ ReplaceContent(GetDateInCurrentDateFormat(fDate));
+
+ // Also save the current date in a standard format
+ sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
+ (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= GetDateInStandardDateFormat(fDate);
+ }
+
+ OUString DateFieldmark::GetDateInStandardDateFormat(double fDate) const
+ {
+ OUString sCurrentDate;
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
+ m_pNumberFormatter->PutEntry(sFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ ODF_FORMDATE_CURRENTDATE_LANGUAGE);
+ }
+
+ if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ Color* pCol = nullptr;
+ m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentDate, &pCol, false);
+ }
+ return sCurrentDate;
+ }
+
+ std::pair<bool, double> DateFieldmark::ParseCurrentDateParam() const
+ {
+ bool bFoundValidDate = false;
+ double dCurrentDate = 0;
+
+ const sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
+ auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
+ OUString sCurrentDate;
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sCurrentDate;
+ }
+ if(!sCurrentDate.isEmpty())
+ {
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
+ m_pNumberFormatter->PutEntry(sFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ ODF_FORMDATE_CURRENTDATE_LANGUAGE);
+ }
+
+ if(nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ bFoundValidDate = m_pNumberFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate);
+ }
+ }
+ return std::pair<bool, double>(bFoundValidDate, dCurrentDate);
+ }
+
+
+ OUString DateFieldmark::GetDateInCurrentDateFormat(double fDate) const
+ {
+ // Get current date format and language
+ OUString sDateFormat;
+ const sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
+ auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sDateFormat;
+ }
+
+ OUString sLang;
+ pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sLang;
+ }
+
+ // Fill the content with the specified format
+ OUString sCurrentContent;
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ OUString sFormat = sDateFormat;
+ m_pNumberFormatter->PutEntry(sFormat,
+ nCheckPos,
+ nType,
+ nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+
+ if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ Color* pCol = nullptr;
+ m_pNumberFormatter->GetOutputString(fDate, nFormat, sCurrentContent, &pCol, false);
+ }
+ return sCurrentContent;
+ }
+
+ void DateFieldmark::InvalidateCurrentDateParam()
+ {
+ std::pair<bool, double> aResult = ParseCurrentDateParam();
+ if(!aResult.first)
+ return;
+
+ // Current date became invalid
+ if(GetDateInCurrentDateFormat(aResult.second) != GetContent())
+ {
+ sw::mark::IFieldmark::parameter_map_t* pParameters = GetParameters();
+ (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
+ }
+ }
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 3c000747d512..8d61b4272d5e 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -510,9 +510,19 @@ namespace sw { namespace mark
bool bUndoIsEnabled = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
m_pDoc->GetIDocumentUndoRedo().DoUndo(false);
- sw::mark::IMark* pMark = makeMark( rPaM, rName,
- IDocumentMarkAccess::MarkType::TEXT_FIELDMARK,
- sw::mark::InsertMode::New);
+ sw::mark::IMark* pMark = nullptr;
+ if(rType == ODF_FORMDATE)
+ {
+ pMark = makeMark(rPaM, rName,
+ IDocumentMarkAccess::MarkType::DATE_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
+ else
+ {
+ pMark = makeMark(rPaM, rName,
+ IDocumentMarkAccess::MarkType::TEXT_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
if (pFieldMark)
pFieldMark->SetFieldname( rType );
@@ -1120,23 +1130,29 @@ namespace sw { namespace mark
deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
}
- ::sw::mark::IFieldmark* MarkManager::changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType)
+ ::sw::mark::IFieldmark* MarkManager::changeFormFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType)
{
bool bActualChange = false;
if(rNewType == ODF_FORMDROPDOWN)
{
if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
bActualChange = true;
+ if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
+ return nullptr;
}
else if(rNewType == ODF_FORMCHECKBOX)
{
if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
bActualChange = true;
+ if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) // only allowed converting between checkbox <-> dropdown
+ return nullptr;
}
else if(rNewType == ODF_FORMDATE)
{
if (!dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark))
bActualChange = true;
+ if (!dynamic_cast<::sw::mark::TextFieldmark*>(pFieldmark)) // only allowed converting between date field <-> text field
+ return nullptr;
}
if (!bActualChange)
@@ -1147,13 +1163,20 @@ namespace sw { namespace mark
SwPaM aPaM(pFieldmark->GetMarkPos());
// Remove the old fieldmark and create a new one with the new type
- if(aPaM.GetPoint()->nContent > 0)
+ if(aPaM.GetPoint()->nContent > 0 && (rNewType == ODF_FORMDROPDOWN || rNewType == ODF_FORMCHECKBOX))
{
--aPaM.GetPoint()->nContent;
SwPosition aNewPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
deleteFieldmarkAt(aNewPos);
return makeNoTextFieldBookmark(aPaM, sName, rNewType);
}
+ else if(rNewType == ODF_FORMDATE)
+ {
+ SwPosition aPos (aPaM.GetPoint()->nNode, aPaM.GetPoint()->nContent);
+ SwPaM aNewPaM(pFieldmark->GetMarkStart(), pFieldmark->GetMarkEnd());
+ deleteFieldmarkAt(aPos);
+ return makeFieldBookmark(aNewPaM, sName, rNewType);
+ }
return nullptr;
}
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index 6e05a171ce34..0bf8f1e97cdc 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -91,7 +91,7 @@ namespace sw {
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override;
virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
- virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
+ virtual ::sw::mark::IFieldmark* changeFormFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
virtual void NotifyCursorUpdate(const SwCursorShell& rCursorShell) override;
virtual void ClearFieldActivation() override;
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index c658d22a2585..2107b3640616 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -278,15 +278,11 @@ namespace sw {
FieldmarkWithDropDownButton(const SwPaM& rPaM);
virtual ~FieldmarkWithDropDownButton() override;
- // This method should be called only by the portion so we can now the portion's painting area
- void SetPortionPaintArea(const SwRect& rPortionPaintArea);
-
virtual void ShowButton(SwEditWin* pEditWin) = 0;
void HideButton();
void RemoveButton();
protected:
- SwRect m_aPortionPaintArea;
VclPtr<FormFieldButton> m_pButton;
};
@@ -299,22 +295,47 @@ namespace sw {
virtual ~DropDownFieldmark() override;
virtual void ShowButton(SwEditWin* pEditWin) override;
+
+ // This method should be called only by the portion so we can now the portion's painting area
+ void SetPortionPaintArea(const SwRect& rPortionPaintArea);
+
+ private:
+ SwRect m_aPortionPaintArea;
};
/// Fieldmark representing a date form field.
class DateFieldmark
- : public FieldmarkWithDropDownButton
+ : virtual public IDateFieldmark
+ , public FieldmarkWithDropDownButton
{
public:
DateFieldmark(const SwPaM& rPaM);
virtual ~DateFieldmark() override;
virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override;
+ virtual void ReleaseDoc(SwDoc* const pDoc) override;
virtual void ShowButton(SwEditWin* pEditWin) override;
+ void SetPortionPaintAreaStart(const SwRect& rPortionPaintArea);
+ void SetPortionPaintAreaEnd(const SwRect& rPortionPaintArea);
+
+ virtual OUString GetContent() const override;
+ virtual void ReplaceContent(const OUString& sNewContent) override;
+
+ virtual std::pair<bool, double> GetCurrentDate() const override;
+ virtual void SetCurrentDate(double fDate) override;
+ virtual OUString GetDateInStandardDateFormat(double fDate) const override;
+
private:
+ OUString GetDateInCurrentDateFormat(double fDate) const;
+ std::pair<bool, double> ParseCurrentDateParam() const;
+ void InvalidateCurrentDateParam();
+
SvNumberFormatter* m_pNumberFormatter;
+ sw::DocumentContentOperationsManager* m_pDocumentContentOperationsManager;
+ SwRect m_aPaintAreaStart;
+ SwRect m_aPaintAreaEnd;
};
}
}
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 013dabd267ff..7c61314b6a1b 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -864,78 +864,6 @@ namespace sw { namespace mark {
sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
return OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH);
}
-
- static OUString ExpandDateFieldmark(IFieldmark* pBM, SvNumberFormatter* pFormatter)
- {
- OUString sDateFormat;
- mark::IFieldmark::parameter_map_t* pParameters = pBM->GetParameters();
- auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
- if (pResult != pParameters->end())
- {
- pResult->second >>= sDateFormat;
- }
-
- OUString sLang;
- pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
- if (pResult != pParameters->end())
- {
- pResult->second >>= sLang;
- }
-
- double dCurrentDate = 0.0;
- bool bHasCurrentDate = false;
- pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE);
- if (pResult != pParameters->end())
- {
- OUString sFormattedDate;
- pResult->second >>= sFormattedDate;
-
- sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
- pFormatter->PutEntry(sFormat,
- nCheckPos,
- nType,
- nFormat,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- }
-
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- pFormatter->IsNumberFormat(sFormattedDate, nFormat, dCurrentDate);
- bHasCurrentDate = true;
- }
- }
-
- if (!sDateFormat.isEmpty() && !sLang.isEmpty() && bHasCurrentDate)
- {
- sal_uInt32 nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- pFormatter->PutEntry(sDateFormat,
- nCheckPos,
- nType,
- nFormat,
- LanguageTag(sLang).getLanguageType());
- }
-
- OUString sOutput;
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- Color* pCol = nullptr;
- pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false);
- }
- return sOutput;
- }
-
- sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
- return OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH);
- }
} }
SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
@@ -962,16 +890,24 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
// Only at the End!
// If pCurr does not have a width, it can however already have content.
// E.g. for non-displayable characters
+
auto const ch(rInf.GetText()[sal_Int32(rInf.GetIdx())]);
- if (ch == CH_TXT_ATR_FIELDSTART)
+ SwTextFrame const*const pFrame(rInf.GetTextFrame());
+ SwPosition aPosition(pFrame->MapViewToModelPos(rInf.GetIdx()));
+ sw::mark::IFieldmark *pBM = pFrame->GetDoc().getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
+ if(pBM != nullptr && pBM->GetFieldname( ) == ODF_FORMDATE)
+ {
+ if (ch == CH_TXT_ATR_FIELDSTART)
+ pPor = new SwFieldFormDatePortion(pBM, true);
+ else if (ch == CH_TXT_ATR_FIELDEND)
+ pPor = new SwFieldFormDatePortion(pBM, false);
+ }
+ else if (ch == CH_TXT_ATR_FIELDSTART)
pPor = new SwFieldMarkPortion();
else if (ch == CH_TXT_ATR_FIELDEND)
pPor = new SwFieldMarkPortion();
else if (ch == CH_TXT_ATR_FORMELEMENT)
{
- SwTextFrame const*const pFrame(rInf.GetTextFrame());
- SwPosition aPosition(pFrame->MapViewToModelPos(rInf.GetIdx()));
- sw::mark::IFieldmark *pBM = pFrame->GetDoc().getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
OSL_ENSURE(pBM != nullptr, "Where is my form field bookmark???");
if (pBM != nullptr)
{
@@ -983,11 +919,6 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
{
pPor = new SwFieldFormDropDownPortion(pBM, sw::mark::ExpandFieldmark(pBM));
}
- else if (pBM->GetFieldname( ) == ODF_FORMDATE)
- {
- SvNumberFormatter* pFormatter = const_cast<SvNumberFormatter*>(GetTextFrame()->GetDoc().GetNumberFormatter());
- pPor = new SwFieldFormDatePortion(pBM, sw::mark::ExpandDateFieldmark(pBM, pFormatter));
- }
/* we need to check for ODF_FORMTEXT for scenario having FormFields inside FORMTEXT.
* Otherwise file will crash on open.
*/
diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index 6147cff76219..b4a81868cff6 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -1328,9 +1328,9 @@ void SwFieldFormDropDownPortion::Paint( const SwTextPaintInfo &rInf ) const
}
}
-SwFieldPortion *SwFieldFormDatePortion::Clone(const OUString &rExpand) const
+SwFieldPortion *SwFieldFormDatePortion::Clone(const OUString &/*rExpand*/) const
{
- return new SwFieldFormDatePortion(m_pFieldMark, rExpand);
+ return new SwFieldFormDatePortion(m_pFieldMark, m_bStart);
}
void SwFieldFormDatePortion::Paint( const SwTextPaintInfo &rInf ) const
@@ -1342,7 +1342,10 @@ void SwFieldFormDatePortion::Paint( const SwTextPaintInfo &rInf ) const
{
SwRect aPaintArea;
rInf.CalcRect( *this, &aPaintArea );
- pDateField->SetPortionPaintArea(aPaintArea);
+ if(m_bStart)
+ pDateField->SetPortionPaintAreaStart(aPaintArea);
+ else
+ pDateField->SetPortionPaintAreaEnd(aPaintArea);
}
}
diff --git a/sw/source/core/text/porfld.hxx b/sw/source/core/text/porfld.hxx
index 5d10b24c028d..973fc9146a6e 100644
--- a/sw/source/core/text/porfld.hxx
+++ b/sw/source/core/text/porfld.hxx
@@ -235,18 +235,20 @@ private:
class SwFieldFormDatePortion : public SwFieldPortion
{
public:
- explicit SwFieldFormDatePortion(sw::mark::IFieldmark *pFieldMark, const OUString &rExpand)
- : SwFieldPortion(rExpand)
+ explicit SwFieldFormDatePortion(sw::mark::IFieldmark *pFieldMark, bool bStart)
+ : SwFieldPortion("")
, m_pFieldMark(pFieldMark)
+ , m_bStart(bStart)
{
}
// Field cloner for SplitGlue
- virtual SwFieldPortion *Clone( const OUString &rExpand ) const override;
+ virtual SwFieldPortion *Clone( const OUString &rExpand) const override;
virtual void Paint( const SwTextPaintInfo &rInf ) const override;
private:
sw::mark::IFieldmark* m_pFieldMark;
+ bool m_bStart;
};
#endif
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index c6a7f31c1efe..e3e7ad203b10 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -629,7 +629,7 @@ void SwXFieldmark::setFieldType(const OUString & fieldType)
{
if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX || fieldType == ODF_FORMDATE)
{
- ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeNonTextFieldmarkType(pBkm, fieldType);
+ ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeFormFieldmarkType(pBkm, fieldType);
if (pNewFieldmark)
{
registerInMark(*this, pNewFieldmark);
@@ -676,7 +676,7 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark))
pXBkmk = new SwXFieldmark(true, &rDoc);
else if (dynamic_cast< ::sw::mark::DateFieldmark* >(pMark))
- pXBkmk = new SwXFieldmark(true, &rDoc);
+ pXBkmk = new SwXFieldmark(false, &rDoc);
else
pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index ffee31224bf8..5254c445d7f1 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1919,21 +1919,18 @@ void DocxAttributeOutput::WriteFFData( const FieldInfos& rInfos )
}
}
-void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang)
+void DocxAttributeOutput::WriteFormDateStart(const OUString& sFullDate, const OUString& sDateFormat, const OUString& sLang)
{
m_pSerializer->startElementNS(XML_w, XML_sdt, FSEND);
m_pSerializer->startElementNS(XML_w, XML_sdtPr, FSEND);
- if (!sCurrentDate.isEmpty())
- {
- OString sDate = sCurrentDate.toUtf8() + "T00:00:00Z";
- m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), sDate, FSEND);
- }
+ if(!sFullDate.isEmpty())
+ m_pSerializer->startElementNS(XML_w, XML_date, FSNS(XML_w, XML_fullDate), sFullDate.toUtf8(), FSEND);
else
m_pSerializer->startElementNS(XML_w, XML_date, FSEND);
- OString sUTF8DateFormat = sDateFormat.toUtf8();
// Replace quotation mark used for marking static strings in date format
+ OString sUTF8DateFormat = sDateFormat.toUtf8();
sUTF8DateFormat = sUTF8DateFormat.replaceAll("\"", "'");
m_pSerializer->singleElementNS(XML_w, XML_dateFormat,
FSNS(XML_w, XML_val), sUTF8DateFormat, FSEND);
@@ -1948,59 +1945,11 @@ void DocxAttributeOutput::WriteFormDate(const OUString& sCurrentDate, const OUSt
m_pSerializer->endElementNS(XML_w, XML_sdtPr);
m_pSerializer->startElementNS(XML_w, XML_sdtContent, FSEND);
- m_pSerializer->startElementNS(XML_w, XML_r, FSEND);
-
- // Convert the current date to the right format
- if (!sCurrentDate.isEmpty())
- {
- SvNumberFormatter* pFormatter = m_rExport.m_pDoc->GetNumberFormatter();
-
- double dCurrentDate = 0.0;
- // First get the date internal double representation
- sal_uInt32 nFormat = pFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT;
- pFormatter->PutEntry(sFormat,
- nCheckPos,
- nType,
- nFormat,
- ODF_FORMDATE_CURRENTDATE_LANGUAGE);
- }
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- pFormatter->IsNumberFormat(sCurrentDate, nFormat, dCurrentDate);
- }
-
- // Then convert the date to a fromatter string
- nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType());
- if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- sal_Int32 nCheckPos = 0;
- SvNumFormatType nType;
- OUString sNonConstDateFormat = sDateFormat;
- pFormatter->PutEntry(sNonConstDateFormat,
- nCheckPos,
- nType,
- nFormat,
- LanguageTag(sLang).getLanguageType());
- }
-
- OUString sOutput;
- if (nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
- {
- Color* pCol = nullptr;
- pFormatter->GetOutputString(dCurrentDate, nFormat, sOutput, &pCol, false);
- }
-
- RunText(sOutput);
- }
+}
- m_pSerializer->endElementNS(XML_w, XML_r);
+void DocxAttributeOutput::WriteFormDateEnd()
+{
m_pSerializer->endElementNS(XML_w, XML_sdtContent);
-
m_pSerializer->endElementNS(XML_w, XML_sdt);
}
@@ -2013,17 +1962,31 @@ void DocxAttributeOutput::StartField_Impl( const SwTextNode* pNode, sal_Int32 nP
}
else if ( rInfos.eType == ww::eFORMDATE )
{
- const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
- FieldMarkParamsHelper params( rFieldmark );
+ const sw::mark::IDateFieldmark* const pFieldmark = dynamic_cast<const sw::mark::IDateFieldmark* const>(rInfos.pFieldmark);
+ FieldMarkParamsHelper params( *pFieldmark );
+ OUString sFullDate;
OUString sCurrentDate;
params.extractParam( ODF_FORMDATE_CURRENTDATE, sCurrentDate );
+ if(!sCurrentDate.isEmpty())
+ {
+ sFullDate = sCurrentDate + "T00:00:00Z";
+ }
+ else
+ {
+ std::pair<bool, double> aResult = pFieldmark->GetCurrentDate();
+ if(aResult.first)
+ {
+ sFullDate = pFieldmark->GetDateInStandardDateFormat(aResult.second) + "T00:00:00Z";
+ }
+ }
+
OUString sDateFormat;
params.extractParam( ODF_FORMDATE_DATEFORMAT, sDateFormat );
OUString sLang;
params.extractParam( ODF_FORMDATE_DATEFORMAT_LANGUAGE, sLang );
- WriteFormDate( sCurrentDate, sDateFormat, sLang );
+ WriteFormDateStart( sFullDate, sDateFormat, sLang );
}
else if ( rInfos.eType != ww::eNONE ) // HYPERLINK fields are just commands
{
@@ -2254,6 +2217,12 @@ void DocxAttributeOutput::DoWriteFieldRunProperties( const SwTextNode * pNode, s
void DocxAttributeOutput::EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos )
{
+ if ( rInfos.eType == ww::eFORMDATE )
+ {
+ WriteFormDateEnd();
+ return;
+ }
+
// The command has to be written before for the hyperlinks
if ( rInfos.pField )
{
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 28ff7dcfb03f..201d0f1a31d6 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -706,7 +706,8 @@ private:
/// Closes a currently open SDT block.
void EndSdtBlock();
- void WriteFormDate(const OUString& sCurrentDate, const OUString& sDateFormat, const OUString& sLang);
+ void WriteFormDateStart(const OUString& sFullDate, const OUString& sDateFormat, const OUString& sLang);
+ void WriteFormDateEnd();
void StartField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos const & rInfos, bool bWriteRun = false );
void DoWriteCmd( const OUString& rCmd );
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 5a9d99888019..0c1e9e5fc378 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -157,6 +157,9 @@ void DocxExport::AppendBookmarks( const SwTextNode& rNode, sal_Int32 nCurrentPos
const sal_Int32 nStart = pMark->GetMarkStart().nContent.GetIndex();
const sal_Int32 nEnd = pMark->GetMarkEnd().nContent.GetIndex();
+ if (dynamic_cast<sw::mark::IDateFieldmark*>(pMark))
+ continue;
+
if ( nStart == nCurrentPos )
aStarts.push_back( pMark->GetName() );
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 058b30e0ad11..8dfbc01423a4 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2332,49 +2332,64 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
- if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT
- && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
+ // Date field is exported as content control, not as a simple field
+ if(pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMDATE)
{
- AppendBookmark( pFieldmark->GetName() );
+ if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
+ {
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ),
+ lcl_getFieldCode( pFieldmark ),
+ FieldFlags::Start | FieldFlags::CmdStart );
+ WriteFormData( *pFieldmark );
+ }
}
- ww::eField eFieldId = lcl_getFieldId( pFieldmark );
- OUString sCode = lcl_getFieldCode( pFieldmark );
- if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
+ else
{
- IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
- if ( it != pFieldmark->GetParameters()->end() )
+
+ if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT
+ && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
{
- OUString sFieldId;
- it->second >>= sFieldId;
- eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ AppendBookmark( pFieldmark->GetName() );
}
-
- it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
- if ( it != pFieldmark->GetParameters()->end() )
+ ww::eField eFieldId = lcl_getFieldId( pFieldmark );
+ OUString sCode = lcl_getFieldCode( pFieldmark );
+ if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
{
- it->second >>= sCode;
+ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
+ if ( it != pFieldmark->GetParameters()->end() )
+ {
+ OUString sFieldId;
+ it->second >>= sFieldId;
+ eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ }
+
+ it = pFieldmark->GetParameters()->find( ODF_CODE_PARAM );
+ if ( it != pFieldmark->GetParameters()->end() )
+ {
+ it->second >>= sCode;
+ }
}
- }
- OutputField( nullptr, eFieldId, sCode, FieldFlags::Start | FieldFlags::CmdStart );
+ OutputField( nullptr, eFieldId, sCode, FieldFlags::Start | FieldFlags::CmdStart );
- if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
- WriteFormData( *pFieldmark );
- else if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
- WriteHyperlinkData( *pFieldmark );
- OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::CmdEnd );
+ if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMTEXT)
+ WriteFormData( *pFieldmark );
+ else if ( pFieldmark && pFieldmark->GetFieldname( ) == ODF_HYPERLINK )
+ WriteHyperlinkData( *pFieldmark );
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::CmdEnd );
- if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
- {
- // Check for the presence of a linked OLE object
- IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
- if ( it != pFieldmark->GetParameters()->end() )
+ if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
{
- OUString sOleId;
- uno::Any aValue = it->second;
- aValue >>= sOleId;
- if ( !sOleId.isEmpty() )
- OutputLinkedOLE( sOleId );
+ // Check for the presence of a linked OLE object
+ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
+ if ( it != pFieldmark->GetParameters()->end() )
+ {
+ OUString sOleId;
+ uno::Any aValue = it->second;
+ aValue >>= sOleId;
+ if ( !sOleId.isEmpty() )
+ OutputLinkedOLE( sOleId );
+ }
}
}
}
@@ -2385,24 +2400,34 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDEND??" );
- ww::eField eFieldId = lcl_getFieldId( pFieldmark );
- if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
+ if(pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMDATE)
{
- IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
- if ( it != pFieldmark->GetParameters()->end() )
+ if(GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
{
- OUString sFieldId;
- it->second >>= sFieldId;
- eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ OutputField( nullptr, ww::eFORMDATE, OUString(), FieldFlags::Close );
}
}
+ else
+ {
+ ww::eField eFieldId = lcl_getFieldId( pFieldmark );
+ if ( pFieldmark && pFieldmark->GetFieldname() == ODF_UNHANDLED )
+ {
+ IFieldmark::parameter_map_t::const_iterator it = pFieldmark->GetParameters()->find( ODF_ID_PARAM );
+ if ( it != pFieldmark->GetParameters()->end() )
+ {
+ OUString sFieldId;
+ it->second >>= sFieldId;
+ eFieldId = static_cast<ww::eField>(sFieldId.toInt32());
+ }
+ }
- OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
+ OutputField( nullptr, eFieldId, OUString(), FieldFlags::Close );
- if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT
- && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
- {
- AppendBookmark( pFieldmark->GetName() );
+ if ( pFieldmark && pFieldmark->GetFieldname() == ODF_FORMTEXT
+ && GetExportFormat() != MSWordExportBase::ExportFormat::DOCX )
+ {
+ AppendBookmark( pFieldmark->GetName() );
+ }
}
}
else if ( ch == CH_TXT_ATR_FORMELEMENT )
@@ -2410,30 +2435,18 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos ) );
::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
- // Date field is exported as content control, not as a simple field
- if(pFieldmark && pFieldmark->GetFieldname( ) == ODF_FORMDATE &&
- GetExportFormat() == MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
- {
- OutputField( nullptr, lcl_getFieldId( pFieldmark ),
- lcl_getFieldCode( pFieldmark ),
- FieldFlags::Start | FieldFlags::CmdStart );
+ bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
+ pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
+ if ( isDropdownOrCheckbox )
+ AppendBookmark( pFieldmark->GetName() );
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ),
+ lcl_getFieldCode( pFieldmark ),
+ FieldFlags::Start | FieldFlags::CmdStart );
+ if ( isDropdownOrCheckbox )
WriteFormData( *pFieldmark );
- }
- else
- {
- bool isDropdownOrCheckbox = pFieldmark && (pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
- pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
- if ( isDropdownOrCheckbox )
- AppendBookmark( pFieldmark->GetName() );
- OutputField( nullptr, lcl_getFieldId( pFieldmark ),
- lcl_getFieldCode( pFieldmark ),
- FieldFlags::Start | FieldFlags::CmdStart );
- if ( isDropdownOrCheckbox )
- WriteFormData( *pFieldmark );
- OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close );
- if ( isDropdownOrCheckbox )
- AppendBookmark( pFieldmark->GetName() );
- }
+ OutputField( nullptr, lcl_getFieldId( pFieldmark ), OUString(), FieldFlags::Close );
+ if ( isDropdownOrCheckbox )
+ AppendBookmark( pFieldmark->GetName() );
}
nLen -= ofs;
diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx
index 11e611f0ceb6..970d83e40d38 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -877,7 +877,7 @@ VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDropDownFormFieldD
return VclPtr<AbstractDropDownFormFieldDialog_Impl>::Create(o3tl::make_unique<sw::DropDownFormFieldDialog>(pParent, pDropDownField));
}
-VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc)
+VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDateFormFieldDialog(sw::mark::IDateFieldmark* pDateField, SwDoc* pDoc)
{
VclPtr<sw::DateFormFieldDialog> pDlg = VclPtr<sw::DateFormFieldDialog>::Create(nullptr, pDateField, pDoc);
return VclPtr<AbstractDateFormFieldDialog_Impl>::Create(pDlg);
diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx
index 9421f71e903f..3a31db3546da 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -644,7 +644,7 @@ public:
virtual VclPtr<AbstractDropDownFieldDialog> CreateDropDownFieldDialog(weld::Window* pParent, SwWrtShell &rSh,
SwField* pField, bool bPrevButton, bool bNextButton) override;
virtual VclPtr<VclAbstractDialog> CreateDropDownFormFieldDialog(weld::Window* pParent, sw::mark::IFieldmark* pDropDownField) override;
- virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc) override;
+ virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IDateFieldmark* pDateField, SwDoc* pDoc) override;
virtual VclPtr<SfxAbstractTabDialog> CreateSwEnvDlg(weld::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert) override;
virtual VclPtr<AbstractSwLabDlg> CreateSwLabDlg(weld::Window* pParent, const SfxItemSet& rSet,
diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx
index 421654d42b90..82c6e0e9a0d9 100644
--- a/sw/source/ui/fldui/DateFormFieldDialog.cxx
+++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx
@@ -18,7 +18,7 @@
namespace sw
{
-DateFormFieldDialog::DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* pDateField,
+DateFormFieldDialog::DateFormFieldDialog(vcl::Window* pParent, mark::IDateFieldmark* pDateField,
SwDoc* pDoc)
: SvxStandardDialog(pParent, "DateFormFieldDialog", "modules/swriter/ui/dateformfielddialog.ui")
, m_pDateField(pDateField)
@@ -46,12 +46,28 @@ void DateFormFieldDialog::Apply()
{
if (m_pDateField != nullptr)
{
- const SvNumberformat* pFormat = m_pNumberFormatter->GetEntry(m_xFormatLB->GetFormat());
+ // Try to find out the current date value and replace the content
+ // with the right formatted date string
sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters();
+ const SvNumberformat* pFormat = m_pNumberFormatter->GetEntry(m_xFormatLB->GetFormat());
+
+ // Get date value first
+ std::pair<bool, double> aResult = m_pDateField->GetCurrentDate();
+
+ // Then set the date format
(*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE]
+ <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
- LanguageType aLang = pFormat->GetLanguage();
- (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= LanguageTag(aLang).getBcp47();
+ // Update current date
+ if (aResult.first)
+ {
+ m_pDateField->SetCurrentDate(aResult.second);
+ }
+ else
+ {
+ (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
+ }
}
}
@@ -78,16 +94,16 @@ void DateFormFieldDialog::InitControls()
if (!sFormatString.isEmpty() && !sLang.isEmpty())
{
LanguageType aLangType = LanguageTag(sLang).getLanguageType();
- sal_uInt32 nFormatKey = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType);
- if (nFormatKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
{
sal_Int32 nCheckPos = 0;
SvNumFormatType nType;
- m_pNumberFormatter->PutEntry(sFormatString, nCheckPos, nType, nFormatKey,
+ m_pNumberFormatter->PutEntry(sFormatString, nCheckPos, nType, nFormat,
LanguageTag(sLang).getLanguageType());
}
- if (aLangType != LANGUAGE_DONTKNOW && nFormatKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ if (aLangType != LANGUAGE_DONTKNOW && nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
{
if (m_xFormatLB->GetCurLanguage() == aLangType)
{
@@ -102,7 +118,7 @@ void DateFormFieldDialog::InitControls()
m_xFormatLB->SetFormatType(SvNumFormatType::ALL);
m_xFormatLB->SetFormatType(SvNumFormatType::DATE);
}
- m_xFormatLB->SetDefFormat(nFormatKey);
+ m_xFormatLB->SetDefFormat(nFormat);
}
}
}
diff --git a/sw/source/uibase/inc/DateFormFieldDialog.hxx b/sw/source/uibase/inc/DateFormFieldDialog.hxx
index b62cb0009865..7c64e4df20c8 100644
--- a/sw/source/uibase/inc/DateFormFieldDialog.hxx
+++ b/sw/source/uibase/inc/DateFormFieldDialog.hxx
@@ -21,7 +21,7 @@ namespace sw
{
namespace mark
{
-class IFieldmark;
+class IDateFieldmark;
}
} // namespace sw
@@ -31,7 +31,7 @@ namespace sw
class DateFormFieldDialog : public SvxStandardDialog
{
private:
- mark::IFieldmark* m_pDateField;
+ sw::mark::IDateFieldmark* m_pDateField;
SvNumberFormatter* m_pNumberFormatter;
VclPtr<NumFormatListBox> m_xFormatLB;
@@ -40,7 +40,8 @@ private:
void InitControls();
public:
- DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* pDateField, SwDoc* pDoc);
+ DateFormFieldDialog(vcl::Window* pParent, mark::IDateFieldmark* pDateField, SwDoc* pDoc);
+
virtual ~DateFormFieldDialog() override;
virtual void dispose() override;
};
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index 050a97420d8f..795cb38866ae 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -724,17 +724,25 @@ FIELD_INSERT:
SwPaM* pCursorPos = rSh.GetCursor();
if(pCursorPos)
{
- IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
- sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMDATE);
-
- // Use a default date format and language
- sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldBM->GetParameters();
- SvNumberFormatter* pFormatter = rSh.GetDoc()->GetNumberFormatter();
- sal_uInt32 nStandardFormat = pFormatter->GetStandardFormat(SvNumFormatType::DATE);
- const SvNumberformat* pFormat = pFormatter->GetEntry(nStandardFormat);
-
- (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
- (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
+ // Insert five enspaces into the text field so the field has extent
+ sal_Unicode vEnSpaces[ODF_FORMFIELD_DEFAULT_LENGTH] = {8194, 8194, 8194, 8194, 8194};
+ bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH));
+ if(bSuccess)
+ {
+ IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess();
+ SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()-5,
+ pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex());
+ sw::mark::IFieldmark* pFieldBM = pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), ODF_FORMDATE);
+
+ // Use a default date format and language
+ sw::mark::IFieldmark::parameter_map_t* pParameters = pFieldBM->GetParameters();
+ SvNumberFormatter* pFormatter = rSh.GetDoc()->GetNumberFormatter();
+ sal_uInt32 nStandardFormat = pFormatter->GetStandardFormat(SvNumFormatType::DATE);
+ const SvNumberformat* pFormat = pFormatter->GetEntry(nStandardFormat);
+
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
+ }
}
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr);
diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index 07ffe50535ba..3a6966bb967f 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -1367,7 +1367,8 @@ void SwTextShell::Execute(SfxRequest &rReq)
else if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDATE )
{
SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
- ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(pFieldBM, GetView().GetDocShell()->GetDoc()));
+ sw::mark::DateFieldmark* pDateField = dynamic_cast<sw::mark::DateFieldmark*>(pFieldBM);
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(pDateField, GetView().GetDocShell()->GetDoc()));
if (pDlg->Execute() == RET_OK)
{
pFieldBM->Invalidate();
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index b542d43bc2c0..95bd864fc63a 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list