include/xmloff/odffields.hxx | 7 + sw/inc/swabstdlg.hxx | 3 sw/qa/extras/globalfilter/data/date_form_field.odt |binary sw/qa/extras/globalfilter/globalfilter.cxx | 97 +++++++++++++++++++++ sw/source/core/crsr/DateFormFieldButton.cxx | 61 +++++++++++-- sw/source/core/crsr/bookmrk.cxx | 9 + sw/source/core/doc/docbm.cxx | 6 - sw/source/core/inc/DateFormFieldButton.hxx | 7 + sw/source/core/inc/bookmrk.hxx | 6 + sw/source/core/text/itrform2.cxx | 66 +++++++++++++- sw/source/ui/dialog/swdlgfact.cxx | 4 sw/source/ui/dialog/swdlgfact.hxx | 2 sw/source/ui/fldui/DateFormFieldDialog.cxx | 52 +++++++++-- sw/source/uibase/inc/DateFormFieldDialog.hxx | 6 + sw/source/uibase/shells/textfld.cxx | 17 +++ sw/source/uibase/shells/textsh1.cxx | 2 xmloff/source/text/XMLTextMarkImportContext.cxx | 5 - 17 files changed, 316 insertions(+), 34 deletions(-)
New commits: commit 9137e880a24dd532201c7c4455b3ae90d0c8a6a3 Author: Tamás Zolnai <[email protected]> AuthorDate: Fri Jun 21 17:56:30 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Jul 14 00:16:18 2019 +0200 MSForms: ODF import / export of text-based date field Reviewed-on: https://gerrit.libreoffice.org/75445 Tested-by: Jenkins Reviewed-by: Tamás Zolnai <[email protected]> (cherry picked from commit 46a59d10dbbe3cb9bb9962df93e5a79a5318dcfd) Change-Id: Ib535f1ce065a7f298fcccf95e82d1ffab4d1e1e2 Reviewed-on: https://gerrit.libreoffice.org/75538 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/sw/qa/extras/globalfilter/data/date_form_field.odt b/sw/qa/extras/globalfilter/data/date_form_field.odt new file mode 100644 index 000000000000..8e15793c2d59 Binary files /dev/null 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 d762a8d5f8cd..74491b787503 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -48,6 +48,7 @@ public: void testTextFormField(); void testCheckBoxFormField(); void testDropDownFormField(); + void testDateFormField(); CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testSwappedOutImageExport); @@ -65,6 +66,7 @@ public: CPPUNIT_TEST(testTextFormField); CPPUNIT_TEST(testCheckBoxFormField); CPPUNIT_TEST(testDropDownFormField); + CPPUNIT_TEST(testDateFormField); CPPUNIT_TEST_SUITE_END(); }; @@ -1112,6 +1114,101 @@ void Test::testDropDownFormField() } } +void Test::testDateFormField() +{ + const OUString aFilterNames[] = { + "writer8", + //"MS Word 97", + //"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.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(); + + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), sal_Int32(3), 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; + + CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), pFieldmark); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), OUString(ODF_FORMDATE), pFieldmark->GetFieldname()); + + // Check date form field's parameters. + 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; + pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); + if (pResult != pParameters->end()) + { + pResult->second >>= sCurrentDate; + } + + // The first one is empty + 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); + } + else if (nIndex == 1) // The second has the default format + { + 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); + } + else // 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); + } + ++nIndex; + } + CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), int(3), nIndex); + } +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 5b74a410bf79..985904e27a56 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1126,17 +1126,17 @@ namespace sw { namespace mark bool bActualChange = false; if(rNewType == ODF_FORMDROPDOWN) { - if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) + if (!dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) bActualChange = true; } else if(rNewType == ODF_FORMCHECKBOX) { - if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark)) + if (!dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark)) bActualChange = true; } else if(rNewType == ODF_FORMDATE) { - if (dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark)) + if (!dynamic_cast<::sw::mark::DateFieldmark*>(pFieldmark)) bActualChange = true; } diff --git a/xmloff/source/text/XMLTextMarkImportContext.cxx b/xmloff/source/text/XMLTextMarkImportContext.cxx index 379ecbe6385a..a168788b7c9d 100644 --- a/xmloff/source/text/XMLTextMarkImportContext.cxx +++ b/xmloff/source/text/XMLTextMarkImportContext.cxx @@ -135,6 +135,8 @@ static const char *lcl_getFormFieldmarkName(OUString const &name) else if (name == ODF_FORMDROPDOWN || name == "ecma.office-open-xml.field.FORMDROPDOWN") return ODF_FORMDROPDOWN; + else if (name == ODF_FORMDATE) + return ODF_FORMDATE; else return nullptr; } @@ -321,7 +323,8 @@ void XMLTextMarkImportContext::EndElement() OUString const type(m_rHelper.getCurrentFieldType()); fieldmarkTypeName = lcl_getFieldmarkName(type); if (fieldmarkTypeName == ODF_FORMCHECKBOX || - fieldmarkTypeName == ODF_FORMDROPDOWN) + fieldmarkTypeName == ODF_FORMDROPDOWN || + fieldmarkTypeName == ODF_FORMDATE) { // sw can't handle checkbox with start+end SAL_INFO("xmloff.text", "invalid fieldmark-start/fieldmark-end ignored"); isInvalid = true; commit a34de129dc627e74fc2b3c3e56f384794d5944dc Author: Tamás Zolnai <[email protected]> AuthorDate: Fri Jul 12 18:06:47 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Jul 14 00:16:06 2019 +0200 MSForms: Implement calculation of the displayed text in date form field * Change ODF_FORMDATE_DATEFORMAT to store the date format in a standard way (e.g. "MM.DD.YY") * Also add a new attribute called ODF_FORMDATE_DATEFORMAT_LANGUAGE to store the language for the date format. * Set a default date format and language by insertion. * Display the date in the field using the set format. * Store the current date in a specific format, which will make import / export easier (MSO DOCX format). Reviewed-on: https://gerrit.libreoffice.org/75444 Tested-by: Jenkins Reviewed-by: Tamás Zolnai <[email protected]> (cherry picked from commit 1df055ba2a01a4c83d90c7c64998e7950ca8d795) Change-Id: I852975bbf81556f0e21f8f85d1c293707fdf672e Reviewed-on: https://gerrit.libreoffice.org/75537 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/include/xmloff/odffields.hxx b/include/xmloff/odffields.hxx index fc119fe0a295..8b5fc6dc7bcb 100644 --- a/include/xmloff/odffields.hxx +++ b/include/xmloff/odffields.hxx @@ -34,8 +34,11 @@ #define ODF_FORMDROPDOWN_RESULT "Dropdown_Selected" #define ODF_FORMDATE "vnd.oasis.opendocument.field.FORMDATE" -#define ODF_FORMDATE_DATEFORMAT "DateField_DateFormat" -#define ODF_FORMDATE_CURRENTDATE "DateField_CurrentDate" +#define ODF_FORMDATE_DATEFORMAT "DateField_DateFormat" // e.g. "MM.DD.YY" +#define ODF_FORMDATE_DATEFORMAT_LANGUAGE "DateField_DateFormat_Language" // e.g. "en-US", "hu-HU" +#define ODF_FORMDATE_CURRENTDATE "DateField_CurrentDate" // date string in a specific format +#define ODF_FORMDATE_CURRENTDATE_FORMAT "YYYY-MM-DD" // Coming from MSO +#define ODF_FORMDATE_CURRENTDATE_LANGUAGE LANGUAGE_ENGLISH_US #define ODF_TOC "vnd.oasis.opendocument.field.TOC" diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx index cdf3cbe96506..b1342d55dee8 100644 --- a/sw/inc/swabstdlg.hxx +++ b/sw/inc/swabstdlg.hxx @@ -51,6 +51,7 @@ class SwField; class SwLabFormatPage; class SwLabRec; class SwAsciiOptions; +class SwDoc; class SwDocShell; class SvStream; class SwWrtShell; @@ -417,7 +418,7 @@ public: virtual VclPtr<SfxAbstractTabDialog> CreateSwEnvDlg ( vcl::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert ) = 0; - virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField) = 0; + virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc) = 0; virtual VclPtr<AbstractSwLabDlg> CreateSwLabDlg(const SfxItemSet& rSet, SwDBManager* pDBManager, bool bLabel) = 0; diff --git a/sw/source/core/crsr/DateFormFieldButton.cxx b/sw/source/core/crsr/DateFormFieldButton.cxx index d2f2267e0d46..cd309ae7ab69 100644 --- a/sw/source/core/crsr/DateFormFieldButton.cxx +++ b/sw/source/core/crsr/DateFormFieldButton.cxx @@ -22,35 +22,57 @@ #include <strings.hrc> #include <svtools/calendar.hxx> #include <tools/date.hxx> +#include <svx/numfmtsh.hxx> class SwDatePickerDialog : public FloatingWindow { private: VclPtr<Calendar> m_pCalendar; sw::mark::IFieldmark* m_pFieldmark; + SvNumberFormatter* m_pNumberFormatter; DECL_LINK(ImplSelectHdl, Calendar*, void); public: - SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark); + SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark, + SvNumberFormatter* pNumberFormatter); virtual ~SwDatePickerDialog() override; virtual void dispose() override; }; -SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark) +SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark, + SvNumberFormatter* pNumberFormatter) : FloatingWindow(parent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW) , m_pCalendar(VclPtr<Calendar>::Create(this, WB_TABSTOP)) , m_pFieldmark(pFieldmark) + , m_pNumberFormatter(pNumberFormatter) { 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()) { - sal_Int32 nCurrentDate = 0; - pResult->second >>= nCurrentDate; - m_pCalendar->SetCurDate(Date(nCurrentDate)); + OUString sDateString; + pResult->second >>= sDateString; + + double dCurrentDate = 0; + sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + short nType; + OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; + m_pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + + m_pNumberFormatter->IsNumberFormat(sDateString, nFormat, dCurrentDate); + + const Date& rNullDate = m_pNumberFormatter->GetNullDate(); + m_pCalendar->SetCurDate(rNullDate + sal_Int32(dCurrentDate)); } } m_pCalendar->SetSelectHdl(LINK(this, SwDatePickerDialog, ImplSelectHdl)); @@ -73,16 +95,35 @@ IMPL_LINK(SwDatePickerDialog, ImplSelectHdl, Calendar*, pCalendar, void) { if (m_pFieldmark != nullptr) { + Color* pCol = nullptr; + OUString sOutput; + sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(ODF_FORMDATE_CURRENTDATE_FORMAT, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + short nType; + OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; + m_pNumberFormatter->PutEntry(sFormat, nCheckPos, nType, nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + + 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] - <<= pCalendar->GetFirstSelectedDate().GetDate(); + (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= sOutput; } EndPopupMode(); } } -DateFormFieldButton::DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldmark) +DateFormFieldButton::DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldmark, + SvNumberFormatter* pNumberFormatter) : FormFieldButton(pEditWin, rFieldmark) + , m_pNumberFormatter(pNumberFormatter) { } @@ -90,8 +131,8 @@ DateFormFieldButton::~DateFormFieldButton() { disposeOnce(); } void DateFormFieldButton::InitPopup() { - m_pFieldPopup - = VclPtr<SwDatePickerDialog>::Create(static_cast<SwEditWin*>(GetParent()), &m_rFieldmark); + m_pFieldPopup = VclPtr<SwDatePickerDialog>::Create(static_cast<SwEditWin*>(GetParent()), + &m_rFieldmark, 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 d8467b4ce0c3..a0c9afd4f756 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -39,6 +39,7 @@ #include <edtwin.hxx> #include <DateFormFieldButton.hxx> #include <DropDownFormFieldButton.hxx> +#include <svx/numfmtsh.hxx> using namespace ::sw::mark; using namespace ::com::sun::star; @@ -554,12 +555,18 @@ 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); + } + void DateFieldmark::ShowButton(SwEditWin* pEditWin) { if(pEditWin) { if(!m_pButton) - m_pButton = VclPtr<DateFormFieldButton>::Create(pEditWin, *this); + m_pButton = VclPtr<DateFormFieldButton>::Create(pEditWin, *this, m_pNumberFormatter); m_pButton->CalcPosAndSize(m_aPortionPaintArea); m_pButton->Show(); } diff --git a/sw/source/core/inc/DateFormFieldButton.hxx b/sw/source/core/inc/DateFormFieldButton.hxx index ff677b610b3d..4c38f1a5779b 100644 --- a/sw/source/core/inc/DateFormFieldButton.hxx +++ b/sw/source/core/inc/DateFormFieldButton.hxx @@ -16,6 +16,7 @@ class SwEditWin; class FloatingWindow; +class SvNumberFormatter; namespace sw { namespace mark @@ -31,10 +32,14 @@ class DateFieldmark; class DateFormFieldButton : public FormFieldButton { public: - DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldMark); + DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldMark, + SvNumberFormatter* pNumberFormatter); virtual ~DateFormFieldButton() override; virtual void InitPopup() override; + +private: + SvNumberFormatter* m_pNumberFormatter; }; #endif diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx index 0c7d7f8fda7d..75cd7b1b5c64 100644 --- a/sw/source/core/inc/bookmrk.hxx +++ b/sw/source/core/inc/bookmrk.hxx @@ -44,6 +44,7 @@ namespace com { struct SwPosition; // fwd Decl. wg. UI class SwDoc; class SwEditWin; +class SvNumberFormatter; namespace sw { namespace mark { @@ -297,7 +298,12 @@ namespace sw { DateFieldmark(const SwPaM& rPaM); virtual ~DateFieldmark() override; + virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override; + virtual void ShowButton(SwEditWin* pEditWin) override; + + private: + SvNumberFormatter* m_pNumberFormatter; }; } } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index c55195faa8eb..ce8302a1c8ad 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -57,6 +57,9 @@ #include <unotools/charclass.hxx> #include <xmloff/odffields.hxx> #include <IDocumentSettingAccess.hxx> +#include <IMark.hxx> +#include <IDocumentMarkAccess.hxx> +#include <svl/zforlist.hxx> #include <vector> @@ -861,8 +864,66 @@ namespace sw { namespace mark { return OUString(vEnSpaces, ODF_FORMFIELD_DEFAULT_LENGTH); } - static OUString ExpandDateFieldmark(IFieldmark* /*pBM*/) + 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) + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + short nType; + OUString sFormat = ODF_FORMDATE_CURRENTDATE_FORMAT; + pFormatter->PutEntry(sFormat, + nCheckPos, + nType, + nFormat, + ODF_FORMDATE_CURRENTDATE_LANGUAGE); + } + pFormatter->IsNumberFormat(sFormattedDate, nFormat, dCurrentDate); + bHasCurrentDate = true; + } + + Color* pCol = nullptr; + if (!sDateFormat.isEmpty() && !sLang.isEmpty() && bHasCurrentDate) + { + OUString sOutput; + sal_uInt32 nFormat = pFormatter->GetEntryKey(sDateFormat, LanguageTag(sLang).getLanguageType()); + if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) + { + sal_Int32 nCheckPos = 0; + short nType; + pFormatter->PutEntry(sDateFormat, + nCheckPos, + nType, + nFormat, + LanguageTag(sLang).getLanguageType()); + } + 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); } @@ -916,7 +977,8 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const } else if (pBM->GetFieldname( ) == ODF_FORMDATE) { - pPor = new SwFieldFormDatePortion(pBM, sw::mark::ExpandDateFieldmark(pBM)); + SvNumberFormatter* pFormatter = const_cast<SvNumberFormatter*>(doc->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/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx index 0c87c82c68b8..08221eb9d7e8 100644 --- a/sw/source/ui/dialog/swdlgfact.cxx +++ b/sw/source/ui/dialog/swdlgfact.cxx @@ -783,9 +783,9 @@ VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDropDownFormFieldD return VclPtr<VclAbstractDialog_Impl>::Create( pDlg ); } -VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField) +VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc) { - VclPtr<sw::DateFormFieldDialog> pDlg = VclPtr<sw::DateFormFieldDialog>::Create(nullptr, pDateField); + VclPtr<sw::DateFormFieldDialog> pDlg = VclPtr<sw::DateFormFieldDialog>::Create(nullptr, pDateField, pDoc); return VclPtr<VclAbstractDialog_Impl>::Create( pDlg ); } diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx index af097968c438..f86653e3204d 100644 --- a/sw/source/ui/dialog/swdlgfact.hxx +++ b/sw/source/ui/dialog/swdlgfact.hxx @@ -416,7 +416,7 @@ public: virtual VclPtr<AbstractDropDownFieldDialog> CreateDropDownFieldDialog(SwWrtShell &rSh, SwField* pField, bool bPrevButton, bool bNextButton) override; virtual VclPtr<VclAbstractDialog> CreateDropDownFormFieldDialog(sw::mark::IFieldmark* pDropDownField) override; - virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField) override; + virtual VclPtr<VclAbstractDialog> CreateDateFormFieldDialog(sw::mark::IFieldmark* pDateField, SwDoc* pDoc) override; virtual VclPtr<SfxAbstractTabDialog> CreateSwEnvDlg ( vcl::Window* pParent, const SfxItemSet& rSet, SwWrtShell* pWrtSh, Printer* pPrt, bool bInsert ) override; virtual VclPtr<AbstractSwLabDlg> CreateSwLabDlg(const SfxItemSet& rSet, SwDBManager* pDBManager, bool bLabel) override; diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx index 8a74b1537954..8321acd24875 100644 --- a/sw/source/ui/fldui/DateFormFieldDialog.cxx +++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx @@ -11,17 +11,24 @@ #include <vcl/event.hxx> #include <IMark.hxx> #include <xmloff/odffields.hxx> +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <svx/numfmtsh.hxx> +#include <doc.hxx> namespace sw { -DateFormFieldDialog::DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* pDateField) +DateFormFieldDialog::DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* pDateField, + SwDoc* pDoc) : SvxStandardDialog(pParent, "DateFormFieldDialog", "modules/swriter/ui/dateformfielddialog.ui") , m_pDateField(pDateField) + , m_pNumberFormatter(pDoc->GetNumberFormatter()) { get(m_xFormatLB, "date_formats_treeview"); m_xFormatLB->SetFormatType(css::util::NumberFormat::DATE); m_xFormatLB->SetShowLanguageControl(true); m_xFormatLB->SetAutomaticLanguage(true); + m_xFormatLB->SetShowLanguageControl(true); m_xFormatLB->SetOneArea(true); InitControls(); @@ -39,8 +46,12 @@ void DateFormFieldDialog::Apply() { if (m_pDateField != nullptr) { - mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters(); - (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= m_xFormatLB->GetFormat(); + const SvNumberformat* pFormat = m_pNumberFormatter->GetEntry(m_xFormatLB->GetFormat()); + sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters(); + (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring(); + + LanguageType aLang = pFormat->GetLanguage(); + (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE] <<= LanguageTag(aLang).getBcp47(); } } @@ -48,14 +59,41 @@ void DateFormFieldDialog::InitControls() { if (m_pDateField != nullptr) { - mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters(); + sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters(); + OUString sFormatString; auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT); if (pResult != pParameters->end()) { - sal_uInt32 nDateFormat = 0; - pResult->second >>= nDateFormat; - m_xFormatLB->SetDefFormat(nDateFormat); + pResult->second >>= sFormatString; + } + + OUString sLang; + pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE); + if (pResult != pParameters->end()) + { + pResult->second >>= sLang; + } + + if (!sFormatString.isEmpty() && !sLang.isEmpty()) + { + LanguageType aLangType = LanguageTag(sLang).getLanguageType(); + sal_uInt32 nFormatKey = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType); + + if (m_xFormatLB->GetCurLanguage() == aLangType) + { + m_xFormatLB->SetAutomaticLanguage(true); + } + else + { + m_xFormatLB->SetAutomaticLanguage(false); + m_xFormatLB->SetLanguage(aLangType); + + // Change format and change back for regenerating the list + m_xFormatLB->SetFormatType(css::util::NumberFormat::ALL); + m_xFormatLB->SetFormatType(css::util::NumberFormat::DATE); + } + m_xFormatLB->SetDefFormat(nFormatKey); } } } diff --git a/sw/source/uibase/inc/DateFormFieldDialog.hxx b/sw/source/uibase/inc/DateFormFieldDialog.hxx index b79673ee584b..b62cb0009865 100644 --- a/sw/source/uibase/inc/DateFormFieldDialog.hxx +++ b/sw/source/uibase/inc/DateFormFieldDialog.hxx @@ -14,6 +14,9 @@ #include "actctrl.hxx" #include "numfmtlb.hxx" +class SvNumberFormatter; +class SwDoc; + namespace sw { namespace mark @@ -29,6 +32,7 @@ class DateFormFieldDialog : public SvxStandardDialog { private: mark::IFieldmark* m_pDateField; + SvNumberFormatter* m_pNumberFormatter; VclPtr<NumFormatListBox> m_xFormatLB; @@ -36,7 +40,7 @@ private: void InitControls(); public: - DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* pDateField); + DateFormFieldDialog(vcl::Window* pParent, mark::IFieldmark* 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 278ad3212282..be599349a86f 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -75,6 +75,12 @@ #include <xmloff/odffields.hxx> #include <IDocumentContentOperations.hxx> #include <IDocumentUndoRedo.hxx> +#include <svx/numfmtsh.hxx> +#include <svl/zforlist.hxx> +#include <svl/zformat.hxx> +#include <IMark.hxx> +#include <xmloff/odffields.hxx> + using namespace nsSwDocInfoSubType; @@ -728,7 +734,16 @@ FIELD_INSERT: if(pCursorPos) { IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); - pMarksAccess->makeNoTextFieldBookmark(*pCursorPos, OUString(), ODF_FORMDATE); + 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(css::util::NumberFormat::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 cda646cde90d..28f59f61e9f7 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -1414,7 +1414,7 @@ void SwTextShell::Execute(SfxRequest &rReq) else if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDATE ) { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(pFieldBM)); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateDateFormFieldDialog(pFieldBM, GetView().GetDocShell()->GetDoc())); if (pDlg->Execute() == RET_OK) { pFieldBM->Invalidate(); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
