summaryrefslogtreecommitdiffstats
path: root/cui/source/customize/CustomNotebookbarGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'cui/source/customize/CustomNotebookbarGenerator.cxx')
-rw-r--r--cui/source/customize/CustomNotebookbarGenerator.cxx282
1 files changed, 282 insertions, 0 deletions
diff --git a/cui/source/customize/CustomNotebookbarGenerator.cxx b/cui/source/customize/CustomNotebookbarGenerator.cxx
new file mode 100644
index 0000000000..ba5d881822
--- /dev/null
+++ b/cui/source/customize/CustomNotebookbarGenerator.cxx
@@ -0,0 +1,282 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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 <comphelper/processfactory.hxx>
+#include <rtl/bootstrap.hxx>
+#include <config_folders.h>
+#include <CustomNotebookbarGenerator.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <vcl/EnumContext.hxx>
+#include <vcl/settings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <unotools/confignode.hxx>
+#include <libxml/parser.h>
+#include <o3tl/string_view.hxx>
+
+#define aUIPropertiesCount 3
+
+using namespace css;
+
+CustomNotebookbarGenerator::CustomNotebookbarGenerator() {}
+
+static OUString lcl_activeAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "ActiveWriter";
+ case vcl::EnumContext::Application::Calc:
+ return "ActiveCalc";
+ case vcl::EnumContext::Application::Impress:
+ return "ActiveImpress";
+ case vcl::EnumContext::Application::Draw:
+ return "ActiveDraw";
+ default:
+ return OUString();
+ }
+}
+
+static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "Writer";
+ case vcl::EnumContext::Application::Calc:
+ return "Calc";
+ case vcl::EnumContext::Application::Impress:
+ return "Impress";
+ case vcl::EnumContext::Application::Draw:
+ return "Draw";
+ default:
+ return OUString();
+ }
+}
+
+static OUString getAppNameRegistryPath()
+{
+ vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any;
+
+ if (SfxViewFrame* pViewFrame = SfxViewFrame::Current())
+ {
+ const Reference<frame::XFrame>& xFrame = pViewFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager
+ = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
+ eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ }
+
+ OUString sAppName(lcl_getAppName(eApp));
+ return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName;
+}
+
+static OUString customizedUIPathBuffer()
+{
+ OUString sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
+ "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
+ rtl::Bootstrap::expandMacros(sDirPath);
+ return sDirPath;
+}
+
+OUString CustomNotebookbarGenerator::getCustomizedUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+OUString CustomNotebookbarGenerator::getOriginalUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return AllSettings::GetUIRootDir() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+static OUString getUIDirPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ OUString sUIDirPath
+ = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/";
+ return sUIDirPath;
+}
+
+OString CustomNotebookbarGenerator::getSystemPath(OUString const& sURL)
+{
+ if (sURL.isEmpty())
+ return OString();
+ OUString sSystemPathSettings;
+ if (osl_getSystemPathFromFileURL(sURL.pData, &sSystemPathSettings.pData) != osl_File_E_None)
+ {
+ SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL);
+ return OString();
+ }
+ OString osSystemPathSettings
+ = OUStringToOString(sSystemPathSettings, osl_getThreadTextEncoding());
+ return osSystemPathSettings;
+}
+
+static void changeNodeValue(xmlNode* pNodePtr, const char* pProperty, const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pProperty))))
+ xmlNodeSetContent(pNodePtr, reinterpret_cast<const xmlChar*>(pValue));
+ xmlFree(UriValue);
+ break;
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static void searchNodeAndAttribute(xmlNode* pNodePtr, const char* pUIItemID, const char* pProperty,
+ const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (pNodePtr->type == XML_ELEMENT_NODE)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("object"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pUIItemID))))
+ changeNodeValue(pNodePtr, pProperty, pValue);
+ xmlFree(UriValue);
+ }
+ searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static xmlDocPtr notebookbarXMLParser(const OString& rDocName, const OString& rUIItemID,
+ const OString& rProperty, const OString& rValue)
+{
+ xmlDocPtr pDocPtr = xmlParseFile(rDocName.getStr());
+ xmlNodePtr pNodePtr = xmlDocGetRootElement(pDocPtr);
+ searchNodeAndAttribute(pNodePtr, rUIItemID.getStr(), rProperty.getStr(), rValue.getStr());
+ return pDocPtr;
+}
+
+void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence<OUString>& sUIItemProperties)
+{
+ const OUString sUIPath = getCustomizedUIPath();
+ if (osl::File(sUIPath).open(osl_File_OpenFlag_Read) != osl::FileBase::E_None)
+ createCustomizedUIFile();
+
+ const OString sCustomizedUIPath = getSystemPath(sUIPath);
+ for (auto const& aValue : sUIItemProperties)
+ {
+ std::vector<OString> aProperties(aUIPropertiesCount);
+ for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++)
+ {
+ sal_Int32 nPos = aIndex;
+ std::u16string_view sToken = o3tl::getToken(aValue, nPos, ',', nPos);
+ aProperties[aIndex] = OUStringToOString(sToken, RTL_TEXTENCODING_UTF8);
+ }
+ xmlDocPtr doc = notebookbarXMLParser(sCustomizedUIPath, aProperties[0], aProperties[1],
+ aProperties[2]);
+
+ if (doc != nullptr)
+ {
+ xmlSaveFormatFile(sCustomizedUIPath.getStr(), doc, 1);
+ xmlFreeDoc(doc);
+ }
+ }
+}
+
+void CustomNotebookbarGenerator::getFileNameAndAppName(OUString& sAppName,
+ OUString& sNotebookbarUIFileName)
+{
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if (!pFrame)
+ return;
+
+ const auto xContext = comphelper::getProcessComponentContext();
+ utl::OConfigurationTreeRoot aRoot(xContext, "org.openoffice.Office.UI.ToolbarMode/", false);
+ const Reference<frame::XFrame>& xFrame = pFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create(xContext);
+
+ vcl::EnumContext::Application eApp
+ = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ OUString sActiveAppName(lcl_activeAppName(eApp));
+ sAppName = lcl_getAppName(eApp);
+ const Any aValue = aRoot.getNodeValue(sActiveAppName);
+ aValue >>= sNotebookbarUIFileName;
+}
+
+void CustomNotebookbarGenerator::createCustomizedUIFile()
+{
+ OUString sUserUIDir = getUIDirPath();
+ OUString sOriginalUIPath = getOriginalUIPath();
+ OUString sCustomizedUIPath = getCustomizedUIPath();
+
+ sal_uInt32 nflag = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
+ osl::Directory aDirectory(sUserUIDir);
+ if (aDirectory.open() != osl::FileBase::E_None)
+ osl::Directory::create(sUserUIDir, nflag);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot create the directory or directory was present :" << sUserUIDir);
+
+ osl::File aFile(sCustomizedUIPath);
+ if (aFile.open(nflag) != osl::FileBase::E_None)
+ osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot copy the file or file was present :" << sCustomizedUIPath);
+}
+
+Sequence<OUString> CustomNotebookbarGenerator::getCustomizedUIItem(OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ false);
+
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+ const Any aValue = aModeNode.getNodeValue("UIItemProperties");
+ Sequence<OUString> aValues;
+ aValue >>= aValues;
+ return aValues;
+}
+
+void CustomNotebookbarGenerator::setCustomizedUIItem(Sequence<OUString> sUIItemProperties,
+ OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ true);
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+
+ css::uno::Any aUIItemProperties(sUIItemProperties);
+ aModeNode.setNodeValue("UIItemProperties", aUIItemProperties);
+ aAppNode.commit();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */