diff options
author | Ashod Nakashian <ashod.nakashian@collabora.co.uk> | 2022-12-23 13:02:57 -0500 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2023-01-29 13:22:28 +0000 |
commit | e2d646665c4cb4c7eeb0a73cb5f460838589bef0 (patch) | |
tree | 42987bdec2a8e09af3b6cf70ad2b244c01d92136 | |
parent | e3e259d551c0c8b7c106191f2c258e5929db1b29 (diff) |
lok: support per-user timezone
This adds support for user-specific timezone.
When none is provided during loading, the
system default is used.
Signed-off-by: Ashod Nakashian <ashod.nakashian@collabora.co.uk>
Change-Id: Ie863450687eb82bc475268a09c9112e9fd50020f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144816
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
(cherry picked from commit abaf8c0af1c6c7fe01276fdf2ae62419c7b0f654)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146211
Tested-by: Jenkins
Reviewed-by: Andras Timar <andras.timar@collabora.com>
-rw-r--r-- | comphelper/source/misc/lok.cxx | 19 | ||||
-rw-r--r-- | desktop/qa/desktop_lib/test_desktop_lib.cxx | 4 | ||||
-rw-r--r-- | desktop/source/lib/init.cxx | 49 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.h | 3 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.hxx | 11 | ||||
-rw-r--r-- | include/comphelper/lok.hxx | 3 | ||||
-rw-r--r-- | include/sfx2/lokhelper.hxx | 11 | ||||
-rw-r--r-- | include/sfx2/viewsh.hxx | 17 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun6.cxx | 19 | ||||
-rw-r--r-- | sfx2/source/view/lokhelper.cxx | 42 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 4 |
11 files changed, 181 insertions, 1 deletions
diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx index b11bf4e83582..1f07cd2614eb 100644 --- a/comphelper/source/misc/lok.cxx +++ b/comphelper/source/misc/lok.cxx @@ -8,6 +8,7 @@ */ #include <comphelper/lok.hxx> +#include <osl/process.h> #include <i18nlangtag/languagetag.hxx> #include <sal/log.hxx> @@ -255,6 +256,24 @@ bool isAllowlistedLanguage(const OUString& lang) #endif } +void setTimezone(bool isSet, const OUString& rTimezone) +{ + if (isSet) + { + // Set the given timezone, even if empty. + osl_setEnvironment(OUString("TZ").pData, rTimezone.pData); + } + else + { + // Unset and empty aren't the same. + // When unset, it means default to the system configured timezone. + osl_clearEnvironment(OUString("TZ").pData); + } + + // Update the timezone data. + ::tzset(); +} + static void (*pStatusIndicatorCallback)(void *data, statusIndicatorCallbackType type, int percent, const char* pText)(nullptr); static void *pStatusIndicatorCallbackData(nullptr); diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx index 98c734c8190a..a5560dd6be8d 100644 --- a/desktop/qa/desktop_lib/test_desktop_lib.cxx +++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx @@ -3629,10 +3629,12 @@ void DesktopLOKTest::testABI() CPPUNIT_ASSERT_EQUAL(documentClassOffset(65), offsetof(struct _LibreOfficeKitDocumentClass, getSelectionTypeAndText)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(66), offsetof(struct _LibreOfficeKitDocumentClass, getDataArea)); CPPUNIT_ASSERT_EQUAL(documentClassOffset(67), offsetof(struct _LibreOfficeKitDocumentClass, getEditMode)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), + offsetof(struct _LibreOfficeKitDocumentClass, setViewTimezone)); // Extending is fine, update this, and add new assert for the offsetof the // new method - CPPUNIT_ASSERT_EQUAL(documentClassOffset(68), sizeof(struct _LibreOfficeKitDocumentClass)); + CPPUNIT_ASSERT_EQUAL(documentClassOffset(69), sizeof(struct _LibreOfficeKitDocumentClass)); } CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 97d74bc4682d..db9a9632e4c3 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <sfx2/lokhelper.hxx> #include <config_buildconfig.h> #include <config_features.h> @@ -1203,6 +1204,8 @@ static bool doc_renderSearchResult(LibreOfficeKitDocument* pThis, static void doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const char* pArguments); +static void doc_setViewTimezone(LibreOfficeKitDocument* pThis, int nId, const char* timezone); + } // extern "C" namespace { @@ -1353,6 +1356,8 @@ LibLODocument_Impl::LibLODocument_Impl(uno::Reference <css::lang::XComponent> xC m_pDocumentClass->sendContentControlEvent = doc_sendContentControlEvent; + m_pDocumentClass->setViewTimezone = doc_setViewTimezone; + gDocumentClass = m_pDocumentClass; } pClass = m_pDocumentClass.get(); @@ -2600,6 +2605,27 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, SvNumberFormatter::resetTheCurrencyTable(); } + // Set the timezone, if not empty. + const OUString aTimezone = extractParameter(aOptions, u"Timezone"); + if (!aTimezone.isEmpty()) + { + SfxLokHelper::setDefaultTimezone(true, aTimezone); + } + else + { + // Default to the TZ envar, if set. + const char* tz = ::getenv("TZ"); + if (tz) + { + SfxLokHelper::setDefaultTimezone(true, + OStringToOUString(tz, RTL_TEXTENCODING_UTF8)); + } + else + { + SfxLokHelper::setDefaultTimezone(false, OUString()); + } + } + const OUString aDeviceFormFactor = extractParameter(aOptions, u"DeviceFormFactor"); SfxLokHelper::setDeviceFormFactor(aDeviceFormFactor); @@ -6598,6 +6624,22 @@ static void doc_sendContentControlEvent(LibreOfficeKitDocument* pThis, const cha pDoc->executeContentControlEvent(aMap); } +static void doc_setViewTimezone(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pThis*/, int nId, + const char* pTimezone) +{ + comphelper::ProfileZone aZone("doc_setViewTimezone"); + + SolarMutexGuard aGuard; + SetLastExceptionMsg(); + + // Leave the default if we get a null timezone. + if (pTimezone) + { + OUString sTimezone = OStringToOUString(pTimezone, RTL_TEXTENCODING_UTF8); + SfxLokHelper::setViewTimezone(nId, true, sTimezone); + } +} + static char* lo_getError (LibreOfficeKit *pThis) { comphelper::ProfileZone aZone("lo_getError"); @@ -7065,8 +7107,15 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char comphelper::ProfileZone aZone("lok-init"); if (eStage == PRE_INIT) + { rtl_alloc_preInit(true); + // Set the default timezone to the TZ envar, if set. + const char* tz = ::getenv("TZ"); + SfxLokHelper::setDefaultTimezone(!!tz, tz ? OStringToOUString(tz, RTL_TEXTENCODING_UTF8) + : OUString()); + } + if (eStage != SECOND_INIT) comphelper::LibreOfficeKit::setActive(); diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h index 61a68f632209..74c2100ab18c 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.h +++ b/include/LibreOfficeKit/LibreOfficeKit.h @@ -493,6 +493,9 @@ struct _LibreOfficeKitDocumentClass /// @see lok::Document::getEditMode(). int (*getEditMode) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::setViewTimezone(). + void (*setViewTimezone) (LibreOfficeKitDocument* pThis, int nId, const char* timezone); + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx index d70e4eb44d39..2ac398edd497 100644 --- a/include/LibreOfficeKit/LibreOfficeKit.hxx +++ b/include/LibreOfficeKit/LibreOfficeKit.hxx @@ -875,6 +875,17 @@ public: mpDoc->pClass->sendContentControlEvent(mpDoc, pArguments); } + /** + * Set the timezone of the window with the specified nId. + * + * @param nId a view ID, returned by createView(). + * @param timezone a timezone in the tzfile(5) format (e.g. Pacific/Auckland). + */ + void setViewTimezone(int nId, const char* timezone) + { + mpDoc->pClass->setViewTimezone(mpDoc, nId, timezone); + } + #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY }; diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx index 66784e8e4892..4cfdb70a09d3 100644 --- a/include/comphelper/lok.hxx +++ b/include/comphelper/lok.hxx @@ -102,6 +102,9 @@ COMPHELPER_DLLPUBLIC const LanguageTag& getLanguageTag(); /// If the language name should be used for this LOK instance. COMPHELPER_DLLPUBLIC bool isAllowlistedLanguage(const OUString& lang); +/// Update the current LOK's timezone. +COMPHELPER_DLLPUBLIC void setTimezone(bool isSet, const OUString& rTimezone); + // Status indicator handling. Even if in theory there could be several status indicators active at // the same time, in practice there is only one at a time, so we don't handle any identification of // status indicator in this API. diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx index c3b05b7927e5..90ddd52d01a4 100644 --- a/include/sfx2/lokhelper.hxx +++ b/include/sfx2/lokhelper.hxx @@ -91,6 +91,17 @@ public: /// Set the device form factor that should be used for a new view. static void setDeviceFormFactor(std::u16string_view rDeviceFormFactor); + /// Set timezone of the given view. + /// @isSet true to use @rTimezone, even if it's empty. Otherwise, no timezone. + /// @rTimezone the value to set (which could be empty). + static void setDefaultTimezone(bool isSet, const OUString& rTimezone); + /// Get timezone of the given view. See @setDefaultTimezone. + static std::pair<bool, OUString> getDefaultTimezone(); + /// Set the timezone of the given view. + static void setViewTimezone(int nId, bool isSet, const OUString& rTimezone); + /// Get the timezone of the given view. + static std::pair<bool, OUString> getViewTimezone(int nId); + /// Iterate over any view shell, except pThisViewShell, passing it to the f function. template<typename ViewShellType, typename FunctionType> static void forEachOtherView(ViewShellType* pThisViewShell, FunctionType f); diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx index 8efa98a13e4f..a948f0f5baea 100644 --- a/include/sfx2/viewsh.hxx +++ b/include/sfx2/viewsh.hxx @@ -171,6 +171,8 @@ friend class SfxPrinterController; LanguageTag maLOKLocale; LOKDeviceFormFactor maLOKDeviceFormFactor; std::unordered_set<OUString> mvLOKBlockedCommandList; + OUString maLOKTimezone; + bool maLOKIsTimezoneSet; /// Used to set the DocId at construction time. See SetCurrentDocId. static ViewShellDocId mnCurrentDocId; @@ -403,6 +405,21 @@ public: /// Get the LibreOfficeKit language of this view. const LanguageTag& GetLOKLanguageTag() const { return maLOKLanguageTag; } + /// Get the LibreOfficeKit timezone of this view. See @SetLOKTimezone. + std::pair<bool, OUString> GetLOKTimezone() const + { + return { maLOKIsTimezoneSet, maLOKTimezone }; + } + + /// Set the LibreOfficeKit timezone of this view. + /// @isSet true to use @rTimezone, even if it's empty. Otherwise, no timezone. + /// @rTimezone the value to set (which could be empty). + void SetLOKTimezone(bool isSet, const OUString& rTimezone) + { + maLOKIsTimezoneSet = isSet; + maLOKTimezone = rTimezone; + } + /// Set the LibreOfficeKit locale of this view. void SetLOKLocale(const OUString& rBcp47LanguageTag); /// Get the LibreOfficeKit locale of this view. diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx index 160ee6ce5882..2a68f730b9bf 100644 --- a/sc/source/ui/view/viewfun6.cxx +++ b/sc/source/ui/view/viewfun6.cxx @@ -21,6 +21,7 @@ #include <svx/svdocapt.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> +#include <sfx2/lokhelper.hxx> #include <svl/stritem.hxx> #include <svl/numformat.hxx> #include <svl/zforlist.hxx> @@ -47,6 +48,7 @@ #include <tabvwsh.hxx> #include <scmod.hxx> #include <postit.hxx> +#include <comphelper/scopeguard.hxx> #include <vector> @@ -286,6 +288,23 @@ void ScViewFunc::InsertCurrentTime(SvNumFormatType nReqFmt, const OUString& rUnd const SvNumFormatType nCurNumFormatType = (pCurNumFormatEntry ? pCurNumFormatEntry->GetMaskedType() : SvNumFormatType::UNDEFINED); + const int nView(comphelper::LibreOfficeKit::isActive() ? SfxLokHelper::getView() : -1); + if (nView >= 0) + { + const auto [isTimezoneSet, aTimezone] = SfxLokHelper::getViewTimezone(nView); + comphelper::LibreOfficeKit::setTimezone(isTimezoneSet, aTimezone); + } + + comphelper::ScopeGuard aAutoUserTimezone( + [nView]() + { + if (nView >= 0) + { + const auto [isTimezoneSet, aTimezone] = SfxLokHelper::getDefaultTimezone(); + comphelper::LibreOfficeKit::setTimezone(isTimezoneSet, aTimezone); + } + }); + if (bInputMode) { double fVal = 0.0; diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx index 794dcc00b300..53c2abace8b5 100644 --- a/sfx2/source/view/lokhelper.cxx +++ b/sfx2/source/view/lokhelper.cxx @@ -76,6 +76,8 @@ namespace LanguageTag g_defaultLanguageTag("en-US", true); LanguageTag g_loadLanguageTag("en-US", true); //< The language used to load. LOKDeviceFormFactor g_deviceFormFactor = LOKDeviceFormFactor::UNKNOWN; +bool g_isDefaultTimezoneSet = false; +OUString g_DefaultTimezone; } int SfxLokHelper::createView(SfxViewFrame* pViewFrame, ViewShellDocId docId) @@ -339,6 +341,46 @@ void SfxLokHelper::setDeviceFormFactor(std::u16string_view rDeviceFormFactor) g_deviceFormFactor = LOKDeviceFormFactor::UNKNOWN; } +void SfxLokHelper::setDefaultTimezone(bool isSet, const OUString& rTimezone) +{ + g_isDefaultTimezoneSet = isSet; + g_DefaultTimezone = rTimezone; +} + +std::pair<bool, OUString> SfxLokHelper::getDefaultTimezone() +{ + return { g_isDefaultTimezoneSet, g_DefaultTimezone }; +} + +void SfxLokHelper::setViewTimezone(int nId, bool isSet, const OUString& rTimezone) +{ + std::vector<SfxViewShell*>& rViewArr = SfxGetpApp()->GetViewShells_Impl(); + + for (SfxViewShell* pViewShell : rViewArr) + { + if (pViewShell->GetViewShellId() == ViewShellId(nId)) + { + pViewShell->SetLOKTimezone(isSet, rTimezone); + return; + } + } +} + +std::pair<bool, OUString> SfxLokHelper::getViewTimezone(int nId) +{ + std::vector<SfxViewShell*>& rViewArr = SfxGetpApp()->GetViewShells_Impl(); + + for (SfxViewShell* pViewShell : rViewArr) + { + if (pViewShell->GetViewShellId() == ViewShellId(nId)) + { + return pViewShell->GetLOKTimezone(); + } + } + + return {}; +} + /* * Used for putting a whole JSON string into a string value * e.g { key: "{JSON}" } diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx index 1d494878a0a2..cd4ffe676f2b 100644 --- a/sfx2/source/view/viewsh.cxx +++ b/sfx2/source/view/viewsh.cxx @@ -1083,6 +1083,10 @@ SfxViewShell::SfxViewShell maLOKLanguageTag = SfxLokHelper::getDefaultLanguage(); maLOKLocale = SfxLokHelper::getDefaultLanguage(); + const auto [isTimezoneSet, aTimezone] = SfxLokHelper::getDefaultTimezone(); + maLOKIsTimezoneSet = isTimezoneSet; + maLOKTimezone = aTimezone; + maLOKDeviceFormFactor = SfxLokHelper::getDeviceFormFactor(); vcl::Window* pFrameWin = pViewFrame->GetWindow().GetFrameWindow(); |