/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include using namespace utl; using namespace com::sun::star::uno; // ScAppOptions - Application Options ScAppOptions::ScAppOptions() { SetDefaults(); } ScAppOptions::ScAppOptions( const ScAppOptions& rCpy ) { *this = rCpy; } ScAppOptions::~ScAppOptions() { } void ScAppOptions::SetDefaults() { if ( ScOptionsUtil::IsMetricSystem() ) eMetric = FieldUnit::CM; // default for countries with metric system else eMetric = FieldUnit::INCH; // default for others nZoom = 100; eZoomType = SvxZoomType::PERCENT; bSynchronizeZoom = true; nStatusFunc = ( 1 << SUBTOTAL_FUNC_SUM ); bAutoComplete = true; bDetectiveAuto = true; pLRUList.reset( new sal_uInt16[5] ); // sensible initialization pLRUList[0] = SC_OPCODE_SUM; pLRUList[1] = SC_OPCODE_AVERAGE; pLRUList[2] = SC_OPCODE_MIN; pLRUList[3] = SC_OPCODE_MAX; pLRUList[4] = SC_OPCODE_IF; nLRUFuncCount = 5; nTrackContentColor = COL_TRANSPARENT; nTrackInsertColor = COL_TRANSPARENT; nTrackDeleteColor = COL_TRANSPARENT; nTrackMoveColor = COL_TRANSPARENT; eLinkMode = LM_ON_DEMAND; nDefaultObjectSizeWidth = 8000; nDefaultObjectSizeHeight = 5000; mbShowSharedDocumentWarning = true; meKeyBindingType = ScOptionsUtil::KEY_DEFAULT; } ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) { eMetric = rCpy.eMetric; eZoomType = rCpy.eZoomType; bSynchronizeZoom = rCpy.bSynchronizeZoom; nZoom = rCpy.nZoom; SetLRUFuncList( rCpy.pLRUList.get(), rCpy.nLRUFuncCount ); nStatusFunc = rCpy.nStatusFunc; bAutoComplete = rCpy.bAutoComplete; bDetectiveAuto = rCpy.bDetectiveAuto; nTrackContentColor = rCpy.nTrackContentColor; nTrackInsertColor = rCpy.nTrackInsertColor; nTrackDeleteColor = rCpy.nTrackDeleteColor; nTrackMoveColor = rCpy.nTrackMoveColor; eLinkMode = rCpy.eLinkMode; nDefaultObjectSizeWidth = rCpy.nDefaultObjectSizeWidth; nDefaultObjectSizeHeight = rCpy.nDefaultObjectSizeHeight; mbShowSharedDocumentWarning = rCpy.mbShowSharedDocumentWarning; meKeyBindingType = rCpy.meKeyBindingType; return *this; } void ScAppOptions::SetLRUFuncList( const sal_uInt16* pList, const sal_uInt16 nCount ) { nLRUFuncCount = nCount; if ( nLRUFuncCount > 0 ) { pLRUList.reset( new sal_uInt16[nLRUFuncCount] ); for ( sal_uInt16 i=0; i aSeq( nCount ); sal_Int32* pArray = aSeq.getArray(); for (tools::Long i=0; i(0); // empty } static void lcl_GetSortList( Any& rDest ) { const ScUserList* pUserList = ScGlobal::GetUserList(); if (pUserList) { size_t nCount = pUserList->size(); Sequence aSeq( nCount ); OUString* pArray = aSeq.getArray(); for (size_t i=0; i(i)].GetString(); rDest <<= aSeq; } else rDest <<= Sequence(0); // empty } constexpr OUStringLiteral CFGPATH_LAYOUT = u"Office.Calc/Layout"; #define SCLAYOUTOPT_MEASURE 0 #define SCLAYOUTOPT_STATUSBAR 1 #define SCLAYOUTOPT_ZOOMVAL 2 #define SCLAYOUTOPT_ZOOMTYPE 3 #define SCLAYOUTOPT_SYNCZOOM 4 #define SCLAYOUTOPT_STATUSBARMULTI 5 constexpr OUStringLiteral CFGPATH_INPUT = u"Office.Calc/Input"; #define SCINPUTOPT_LASTFUNCS 0 #define SCINPUTOPT_AUTOINPUT 1 #define SCINPUTOPT_DET_AUTO 2 constexpr OUStringLiteral CFGPATH_REVISION = u"Office.Calc/Revision/Color"; #define SCREVISOPT_CHANGE 0 #define SCREVISOPT_INSERTION 1 #define SCREVISOPT_DELETION 2 #define SCREVISOPT_MOVEDENTRY 3 constexpr OUStringLiteral CFGPATH_CONTENT = u"Office.Calc/Content/Update"; #define SCCONTENTOPT_LINK 0 constexpr OUStringLiteral CFGPATH_SORTLIST = u"Office.Calc/SortList"; #define SCSORTLISTOPT_LIST 0 constexpr OUStringLiteral CFGPATH_MISC = u"Office.Calc/Misc"; #define SCMISCOPT_DEFOBJWIDTH 0 #define SCMISCOPT_DEFOBJHEIGHT 1 #define SCMISCOPT_SHOWSHAREDDOCWARN 2 constexpr OUStringLiteral CFGPATH_COMPAT = u"Office.Calc/Compatibility"; #define SCCOMPATOPT_KEY_BINDING 0 // Default value of Layout/Other/StatusbarMultiFunction #define SCLAYOUTOPT_STATUSBARMULTI_DEFAULTVAL 514 // Default value of Layout/Other/StatusbarFunction #define SCLAYOUTOPT_STATUSBAR_DEFAULTVAL 1 // Legacy default value of Layout/Other/StatusbarFunction // prior to multiple statusbar functions feature addition #define SCLAYOUTOPT_STATUSBAR_DEFAULTVAL_LEGACY 9 static sal_uInt32 lcl_ConvertStatusBarFuncSetToSingle( sal_uInt32 nFuncSet ) { if ( !nFuncSet ) return 0; for ( sal_uInt32 nFunc = 1; nFunc < 32; ++nFunc ) if ( nFuncSet & ( 1U << nFunc ) ) return nFunc; return 0; } Sequence ScAppCfg::GetLayoutPropertyNames() { const bool bIsMetric = ScOptionsUtil::IsMetricSystem(); return {(bIsMetric ? OUString("Other/MeasureUnit/Metric") : OUString("Other/MeasureUnit/NonMetric")), // SCLAYOUTOPT_MEASURE "Other/StatusbarFunction", // SCLAYOUTOPT_STATUSBAR "Zoom/Value", // SCLAYOUTOPT_ZOOMVAL "Zoom/Type", // SCLAYOUTOPT_ZOOMTYPE "Zoom/Synchronize", // SCLAYOUTOPT_SYNCZOOM "Other/StatusbarMultiFunction"}; // SCLAYOUTOPT_STATUSBARMULTI } Sequence ScAppCfg::GetInputPropertyNames() { return {"LastFunctions", // SCINPUTOPT_LASTFUNCS "AutoInput", // SCINPUTOPT_AUTOINPUT "DetectiveAuto"}; // SCINPUTOPT_DET_AUTO } Sequence ScAppCfg::GetRevisionPropertyNames() { return {"Change", // SCREVISOPT_CHANGE "Insertion", // SCREVISOPT_INSERTION "Deletion", // SCREVISOPT_DELETION "MovedEntry"}; // SCREVISOPT_MOVEDENTRY } Sequence ScAppCfg::GetContentPropertyNames() { return {"Link"}; // SCCONTENTOPT_LINK } Sequence ScAppCfg::GetSortListPropertyNames() { return {"List"}; // SCSORTLISTOPT_LIST } Sequence ScAppCfg::GetMiscPropertyNames() { return {"DefaultObjectSize/Width", // SCMISCOPT_DEFOBJWIDTH "DefaultObjectSize/Height", // SCMISCOPT_DEFOBJHEIGHT "SharedDocument/ShowWarning"}; // SCMISCOPT_SHOWSHAREDDOCWARN } Sequence ScAppCfg::GetCompatPropertyNames() { return {"KeyBindings/BaseGroup"}; // SCCOMPATOPT_KEY_BINDING } ScAppCfg::ScAppCfg() : aLayoutItem( CFGPATH_LAYOUT ), aInputItem( CFGPATH_INPUT ), aRevisionItem( CFGPATH_REVISION ), aContentItem( CFGPATH_CONTENT ), aSortListItem( CFGPATH_SORTLIST ), aMiscItem( CFGPATH_MISC ), aCompatItem( CFGPATH_COMPAT ) { aLayoutItem.EnableNotification(GetLayoutPropertyNames()); ReadLayoutCfg(); aLayoutItem.SetCommitLink( LINK( this, ScAppCfg, LayoutCommitHdl ) ); aLayoutItem.SetNotifyLink( LINK( this, ScAppCfg, LayoutNotifyHdl ) ); aInputItem.EnableNotification(GetInputPropertyNames()); ReadInputCfg(); aInputItem.SetCommitLink( LINK( this, ScAppCfg, InputCommitHdl ) ); aInputItem.SetNotifyLink( LINK( this, ScAppCfg, InputNotifyHdl ) ); aRevisionItem.EnableNotification(GetRevisionPropertyNames()); ReadRevisionCfg(); aRevisionItem.SetCommitLink( LINK( this, ScAppCfg, RevisionCommitHdl ) ); aRevisionItem.SetNotifyLink( LINK( this, ScAppCfg, RevisionNotifyHdl ) ); aContentItem.EnableNotification(GetContentPropertyNames()); ReadContentCfg(); aContentItem.SetCommitLink( LINK( this, ScAppCfg, ContentCommitHdl ) ); aContentItem.SetNotifyLink( LINK( this, ScAppCfg, ContentNotifyHdl ) ); aSortListItem.EnableNotification(GetSortListPropertyNames()); ReadSortListCfg(); aSortListItem.SetCommitLink( LINK( this, ScAppCfg, SortListCommitHdl ) ); aSortListItem.SetNotifyLink( LINK( this, ScAppCfg, SortListNotifyHdl ) ); aMiscItem.EnableNotification(GetMiscPropertyNames()); ReadMiscCfg(); aMiscItem.SetCommitLink( LINK( this, ScAppCfg, MiscCommitHdl ) ); aMiscItem.SetNotifyLink( LINK( this, ScAppCfg, MiscNotifyHdl ) ); aCompatItem.EnableNotification(GetCompatPropertyNames()); ReadCompatCfg(); aCompatItem.SetCommitLink( LINK(this, ScAppCfg, CompatCommitHdl) ); aCompatItem.SetNotifyLink( LINK(this, ScAppCfg, CompatNotifyHdl) ); } void ScAppCfg::ReadLayoutCfg() { const Sequence aNames = GetLayoutPropertyNames(); const Sequence aValues = aLayoutItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; sal_uInt32 nStatusBarFuncSingle = 0; sal_uInt32 nStatusBarFuncMulti = 0; if (sal_Int32 nIntVal; aValues[SCLAYOUTOPT_MEASURE] >>= nIntVal) SetAppMetric(static_cast(nIntVal)); if (sal_uInt32 nUIntVal; aValues[SCLAYOUTOPT_STATUSBAR] >>= nUIntVal) nStatusBarFuncSingle = nUIntVal; if (sal_uInt32 nUIntVal; aValues[SCLAYOUTOPT_STATUSBARMULTI] >>= nUIntVal) nStatusBarFuncMulti = nUIntVal; if (sal_Int32 nIntVal; aValues[SCLAYOUTOPT_ZOOMVAL] >>= nIntVal) SetZoom(static_cast(nIntVal)); if (sal_Int32 nIntVal; aValues[SCLAYOUTOPT_ZOOMTYPE] >>= nIntVal) SetZoomType(static_cast(nIntVal)); SetSynchronizeZoom(ScUnoHelpFunctions::GetBoolFromAny(aValues[SCLAYOUTOPT_SYNCZOOM])); if (nStatusBarFuncMulti != SCLAYOUTOPT_STATUSBARMULTI_DEFAULTVAL) SetStatusFunc(nStatusBarFuncMulti); else if (nStatusBarFuncSingle != SCLAYOUTOPT_STATUSBAR_DEFAULTVAL && nStatusBarFuncSingle != SCLAYOUTOPT_STATUSBAR_DEFAULTVAL_LEGACY) { if (nStatusBarFuncSingle) SetStatusFunc(1 << nStatusBarFuncSingle); else SetStatusFunc(0); } else SetStatusFunc(SCLAYOUTOPT_STATUSBARMULTI_DEFAULTVAL); } void ScAppCfg::ReadInputCfg() { const Sequence aNames = GetInputPropertyNames(); const Sequence aValues = aInputItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; if (Sequence aSeq; aValues[SCINPUTOPT_LASTFUNCS] >>= aSeq) { sal_Int32 nCount = aSeq.getLength(); if (nCount < SAL_MAX_UINT16) { std::vector pUShorts(nCount); for (sal_Int32 i = 0; i < nCount; i++) pUShorts[i] = aSeq[i]; SetLRUFuncList(pUShorts.data(), nCount); } } SetAutoComplete(ScUnoHelpFunctions::GetBoolFromAny(aValues[SCINPUTOPT_AUTOINPUT])); SetDetectiveAuto(ScUnoHelpFunctions::GetBoolFromAny(aValues[SCINPUTOPT_DET_AUTO])); } void ScAppCfg::ReadRevisionCfg() { const Sequence aNames = GetRevisionPropertyNames(); const Sequence aValues = aRevisionItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; if (sal_Int32 nIntVal; aValues[SCREVISOPT_CHANGE] >>= nIntVal) SetTrackContentColor(Color(ColorTransparency, nIntVal)); if (sal_Int32 nIntVal; aValues[SCREVISOPT_INSERTION] >>= nIntVal) SetTrackInsertColor(Color(ColorTransparency, nIntVal)); if (sal_Int32 nIntVal; aValues[SCREVISOPT_DELETION] >>= nIntVal) SetTrackDeleteColor(Color(ColorTransparency, nIntVal)); if (sal_Int32 nIntVal; aValues[SCREVISOPT_MOVEDENTRY] >>= nIntVal) SetTrackMoveColor(Color(ColorTransparency, nIntVal)); } void ScAppCfg::ReadContentCfg() { const Sequence aNames = GetContentPropertyNames(); const Sequence aValues = aContentItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; if (sal_Int32 nIntVal; aValues[SCCONTENTOPT_LINK] >>= nIntVal) SetLinkMode(static_cast(nIntVal)); } void ScAppCfg::ReadSortListCfg() { const Sequence aNames = GetSortListPropertyNames(); const Sequence aValues = aSortListItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; if (Sequence aSeq; aValues[SCSORTLISTOPT_LIST] >>= aSeq) { ScUserList aList; // if setting is "default", keep default values from ScUserList ctor //TODO: mark "default" in a safe way const bool bDefault = (aSeq.getLength() == 1 && aSeq[0] == "NULL"); if (!bDefault) { for (const OUString& rStr : std::as_const(aSeq)) { ScUserListData* pNew = new ScUserListData(rStr); aList.push_back(pNew); } } ScGlobal::SetUserList(&aList); } } void ScAppCfg::ReadMiscCfg() { const Sequence aNames = GetMiscPropertyNames(); const Sequence aValues = aMiscItem.GetProperties(aNames); OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed"); if (aValues.getLength() != aNames.getLength()) return; if (sal_Int32 nIntVal; aValues[SCMISCOPT_DEFOBJWIDTH] >>= nIntVal) SetDefaultObjectSizeWidth(nIntVal); if (sal_Int32 nIntVal; aValues[SCMISCOPT_DEFOBJHEIGHT] >>= nIntVal) SetDefaultObjectSizeHeight(nIntVal); SetShowSharedDocumentWarning( ScUnoHelpFunctions::GetBoolFromAny(aValues[SCMISCOPT_SHOWSHAREDDOCWARN])); } void ScAppCfg::ReadCompatCfg() { const Sequence aNames = GetCompatPropertyNames(); const Sequence aValues = aCompatItem.GetProperties(aNames); if (aValues.getLength() != aNames.getLength()) return; sal_Int32 nIntVal = 0; // 0 = 'Default' aValues[SCCOMPATOPT_KEY_BINDING] >>= nIntVal; SetKeyBindingType(static_cast(nIntVal)); } IMPL_LINK_NOARG(ScAppCfg, LayoutCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetLayoutPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCLAYOUTOPT_MEASURE: pValues[nProp] <<= static_cast(GetAppMetric()); break; case SCLAYOUTOPT_STATUSBAR: pValues[nProp] <<= lcl_ConvertStatusBarFuncSetToSingle( GetStatusFunc() ); break; case SCLAYOUTOPT_ZOOMVAL: pValues[nProp] <<= static_cast(GetZoom()); break; case SCLAYOUTOPT_ZOOMTYPE: pValues[nProp] <<= static_cast(GetZoomType()); break; case SCLAYOUTOPT_SYNCZOOM: pValues[nProp] <<= GetSynchronizeZoom(); break; case SCLAYOUTOPT_STATUSBARMULTI: pValues[nProp] <<= GetStatusFunc(); break; } } aLayoutItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, LayoutNotifyHdl, ScLinkConfigItem&, void) { ReadLayoutCfg(); } IMPL_LINK_NOARG(ScAppCfg, InputCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetInputPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCINPUTOPT_LASTFUNCS: lcl_GetLastFunctions( pValues[nProp], *this ); break; case SCINPUTOPT_AUTOINPUT: pValues[nProp] <<= GetAutoComplete(); break; case SCINPUTOPT_DET_AUTO: pValues[nProp] <<= GetDetectiveAuto(); break; } } aInputItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, InputNotifyHdl, ScLinkConfigItem&, void) { ReadInputCfg(); } IMPL_LINK_NOARG(ScAppCfg, RevisionCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetRevisionPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCREVISOPT_CHANGE: pValues[nProp] <<= GetTrackContentColor(); break; case SCREVISOPT_INSERTION: pValues[nProp] <<= GetTrackInsertColor(); break; case SCREVISOPT_DELETION: pValues[nProp] <<= GetTrackDeleteColor(); break; case SCREVISOPT_MOVEDENTRY: pValues[nProp] <<= GetTrackMoveColor(); break; } } aRevisionItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, RevisionNotifyHdl, ScLinkConfigItem&, void) { ReadRevisionCfg(); } IMPL_LINK_NOARG(ScAppCfg, ContentCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetContentPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCCONTENTOPT_LINK: pValues[nProp] <<= static_cast(GetLinkMode()); break; } } aContentItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, ContentNotifyHdl, ScLinkConfigItem&, void) { ReadContentCfg(); } IMPL_LINK_NOARG(ScAppCfg, SortListCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetSortListPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCSORTLISTOPT_LIST: lcl_GetSortList( pValues[nProp] ); break; } } aSortListItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, SortListNotifyHdl, ScLinkConfigItem&, void) { ReadSortListCfg(); } IMPL_LINK_NOARG(ScAppCfg, MiscCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetMiscPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for(int nProp = 0; nProp < aNames.getLength(); nProp++) { switch(nProp) { case SCMISCOPT_DEFOBJWIDTH: pValues[nProp] <<= GetDefaultObjectSizeWidth(); break; case SCMISCOPT_DEFOBJHEIGHT: pValues[nProp] <<= GetDefaultObjectSizeHeight(); break; case SCMISCOPT_SHOWSHAREDDOCWARN: pValues[nProp] <<= GetShowSharedDocumentWarning(); break; } } aMiscItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, MiscNotifyHdl, ScLinkConfigItem&, void) { ReadMiscCfg(); } IMPL_LINK_NOARG(ScAppCfg, CompatCommitHdl, ScLinkConfigItem&, void) { Sequence aNames = GetCompatPropertyNames(); Sequence aValues(aNames.getLength()); Any* pValues = aValues.getArray(); for (int nProp = 0; nProp < aNames.getLength(); ++nProp) { switch(nProp) { case SCCOMPATOPT_KEY_BINDING: pValues[nProp] <<= static_cast(GetKeyBindingType()); break; } } aCompatItem.PutProperties(aNames, aValues); } IMPL_LINK_NOARG(ScAppCfg, CompatNotifyHdl, ScLinkConfigItem&, void) { ReadCompatCfg(); } void ScAppCfg::SetOptions( const ScAppOptions& rNew ) { *static_cast(this) = rNew; aLayoutItem.SetModified(); aInputItem.SetModified(); aRevisionItem.SetModified(); aContentItem.SetModified(); aSortListItem.SetModified(); aMiscItem.SetModified(); aCompatItem.SetModified(); aLayoutItem.Commit(); aInputItem.Commit(); aRevisionItem.Commit(); aContentItem.Commit(); aSortListItem.Commit(); aMiscItem.Commit(); aCompatItem.Commit(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */