diff options
author | Sumit Chauhan <sumitcn25@gmail.com> | 2019-05-22 01:19:21 +0530 |
---|---|---|
committer | Szymon Kłos <szymon.klos@collabora.com> | 2019-06-10 19:18:22 +0200 |
commit | c473c5b462f33df439b4b62b394c5d7811a05c7c (patch) | |
tree | a5a59b3dbf3fede8a2015c1765ef39f91f804c3c | |
parent | d85499381177bbd050ed85f66f4386d5f41db237 (diff) |
Using registrymodifications.xcu for storing customized uiitem data
This patch store and render the GtkToolButton/GtkMenuButton of
notebookbar*.ui show/hide property in registrymodifications.xcu.
The patch also gives a solution to copy the notebookbar*.ui
file in user directory from share directory provided file is absent
in user directory.The patch also uses libxml2 library and write i.e
change the property of uiitem(GtkToolButton/GtkMenuButton) in
notebookbar*.ui files present in user directory.
Change-Id: I518f37fc858250a04fafd2a4475e3ed03185f6ff
Reviewed-on: https://gerrit.libreoffice.org/72698
Tested-by: Jenkins
Reviewed-by: Szymon Kłos <szymon.klos@collabora.com>
-rw-r--r-- | cui/Library_cui.mk | 2 | ||||
-rw-r--r-- | cui/source/customize/CustomNotebookbarGenerator.cxx | 299 | ||||
-rw-r--r-- | cui/source/inc/CustomNotebookbarGenerator.hxx | 43 | ||||
-rw-r--r-- | include/sal/log-areas.dox | 1 | ||||
-rw-r--r-- | officecfg/registry/data/org/openoffice/Office/UI/ToolbarMode.xcu | 70 | ||||
-rw-r--r-- | officecfg/registry/schema/org/openoffice/Office/UI/ToolbarMode.xcs | 11 |
6 files changed, 426 insertions, 0 deletions
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk index 2d46420c4b1a..4cf00159dcad 100644 --- a/cui/Library_cui.mk +++ b/cui/Library_cui.mk @@ -70,6 +70,7 @@ $(eval $(call gb_Library_use_externals,cui,\ curl) \ icuuc \ icu_headers \ + libxml2 \ orcus-parser \ orcus \ )) @@ -96,6 +97,7 @@ $(eval $(call gb_Library_add_exception_objects,cui,\ cui/source/customize/SvxConfigPageHelper \ cui/source/customize/SvxMenuConfigPage \ cui/source/customize/SvxToolbarConfigPage \ + cui/source/customize/CustomNotebookbarGenerator \ cui/source/dialogs/about \ cui/source/dialogs/colorpicker \ cui/source/dialogs/cuicharmap \ diff --git a/cui/source/customize/CustomNotebookbarGenerator.cxx b/cui/source/customize/CustomNotebookbarGenerator.cxx new file mode 100644 index 000000000000..925f43dd0add --- /dev/null +++ b/cui/source/customize/CustomNotebookbarGenerator.cxx @@ -0,0 +1,299 @@ +/* -*- 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 <rtl/bootstrap.hxx> +#include <CustomNotebookbarGenerator.hxx> +#include <osl/file.hxx> +#include <vcl/dialog.hxx> +#include <sfx2/viewfrm.hxx> +#include <officecfg/Office/UI/ToolbarMode.hxx> +#include <com/sun/star/frame/ModuleManager.hpp> +#include <unotools/confignode.hxx> +#include <libxml/xmlmemory.h> +#include <libxml/parser.h> + +#define aUIItemIDLength 255 +#define aUIPropertiesCount 3 + +using namespace css; + +CustomNotebookbarGenerator::CustomNotebookbarGenerator() {} + +static OUString lcl_activeAppName(vcl::EnumContext::Application eApp) +{ + switch (eApp) + { + case vcl::EnumContext::Application::Writer: + return OUString("ActiveWriter"); + break; + case vcl::EnumContext::Application::Calc: + return OUString("ActiveCalc"); + break; + case vcl::EnumContext::Application::Impress: + return OUString("ActiveImpress"); + break; + case vcl::EnumContext::Application::Draw: + return OUString("ActiveDraw"); + break; + default: + return OUString(); + break; + } +} + +static OUString lcl_getAppName(vcl::EnumContext::Application eApp) +{ + switch (eApp) + { + case vcl::EnumContext::Application::Writer: + return OUString("Writer"); + break; + case vcl::EnumContext::Application::Calc: + return OUString("Calc"); + break; + case vcl::EnumContext::Application::Impress: + return OUString("Impress"); + break; + case vcl::EnumContext::Application::Draw: + return OUString("Draw"); + break; + default: + return OUString(); + break; + } +} + +static OUString getAppNameRegistryPath() +{ + vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any; + const Reference<frame::XFrame>& xFrame + = SfxViewFrame::Current()->GetFrame().GetFrameInterface(); + const Reference<frame::XModuleManager> xModuleManager + = frame::ModuleManager::create(::comphelper::getProcessComponentContext()); + eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame)); + + OUString sAppName(lcl_getAppName(eApp)); + OUStringBuffer sPath("org.openoffice.Office.UI.ToolbarMode/Applications/"); + sPath.append(sAppName); + return sPath.makeStringAndClear(); +} + +static OUString customizedUIPathBuffer() +{ + OUString sDirPath("$BRAND_BASE_DIR/user/config/soffice.cfg/"); + rtl::Bootstrap::expandMacros(sDirPath); + return sDirPath; +} + +OUString CustomNotebookbarGenerator::getCustomizedUIPath() +{ + OUStringBuffer aCustomizedUIPathBuffer; + aCustomizedUIPathBuffer.append(customizedUIPathBuffer()); + OUString sAppName, sNotebookbarUIFileName; + CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName); + OUString sUIFilePath + = "modules/s" + sAppName.toAsciiLowerCase() + "/ui/" + sNotebookbarUIFileName; + aCustomizedUIPathBuffer.append(sUIFilePath); + OUString sCustomizedUIPath = aCustomizedUIPathBuffer.makeStringAndClear(); + return sCustomizedUIPath; +} + +static OUString getOriginalUIPath() +{ + OUStringBuffer aOriginalUIPathBuffer = VclBuilderContainer::getUIRootDir(); + OUString sAppName, sNotebookbarUIFileName; + CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName); + OUString sUIFilePath + = "modules/s" + sAppName.toAsciiLowerCase() + "/ui/" + sNotebookbarUIFileName; + aOriginalUIPathBuffer.append(sUIFilePath); + OUString sOriginalUIPath = aOriginalUIPathBuffer.makeStringAndClear(); + return sOriginalUIPath; +} + +static OUString getUIDirPath() +{ + OUString sAppName, sNotebookbarUIFileName; + CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName); + OUString sUIDirPath + = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"; + return sUIDirPath; +} + +char* CustomNotebookbarGenerator::convertToCharPointer(const OUString& sString) +{ + char* cString = nullptr; + cString = new char[sString.getLength() + 1]; + for (int nIdx = 0; nIdx < sString.getLength(); nIdx++) + *(cString + nIdx) = char(sString[nIdx]); + *(cString + sString.getLength()) = '\0'; + return cString; +} + +static void changeNodeValue(xmlNode* pNodePtr, char* pProperty, 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, char* pUIItemID, char* pProperty, + 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(char* pDocName, char* pUIItemID, char* pProperty, + char* pValue) +{ + xmlDocPtr pDocPtr; + xmlNodePtr pNodePtr; + + pDocPtr = xmlParseFile(pDocName); + pNodePtr = xmlDocGetRootElement(pDocPtr); + searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue); + return pDocPtr; +} + +void CustomNotebookbarGenerator::modifyCustomizedUIFile(Sequence<OUString> sUIItemProperties) +{ + OUString sCustomizedUIPath = getCustomizedUIPath(); + char* cCustomizedUIPath = convertToCharPointer(sCustomizedUIPath); + for (auto const& aValue : sUIItemProperties) + { + char** pProperties = new char*[aUIPropertiesCount]; + for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++) + { + int nIdx = int(aIndex); + sal_Int32 rPos = aIndex; + pProperties[nIdx] = new char[aUIItemIDLength]; + pProperties[nIdx] = convertToCharPointer(aValue.getToken(rPos, ',', rPos)); + } + xmlDocPtr doc; + doc = notebookbarXMLParser(cCustomizedUIPath, pProperties[0], pProperties[1], + pProperties[2]); + + for (int nIdx = 0; nIdx < aUIPropertiesCount; nIdx++) + { + delete[] pProperties[nIdx]; + } + delete[] pProperties; + + if (doc != nullptr) + { + xmlSaveFormatFile(cCustomizedUIPath, doc, 1); + xmlFreeDoc(doc); + } + } + delete[] cCustomizedUIPath; +} + +void CustomNotebookbarGenerator::getFileNameAndAppName(OUString& sAppName, + OUString& sNotebookbarUIFileName) +{ + utl::OConfigurationTreeRoot aRoot(::comphelper::getProcessComponentContext(), + "org.openoffice.Office.UI.ToolbarMode/", false); + const Reference<frame::XFrame>& xFrame + = SfxViewFrame::Current()->GetFrame().GetFrameInterface(); + const Reference<frame::XModuleManager> xModuleManager + = frame::ModuleManager::create(::comphelper::getProcessComponentContext()); + + vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any; + 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) +{ + OUStringBuffer aPath = getAppNameRegistryPath(); + const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), + aPath.makeStringAndClear(), 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) +{ + OUStringBuffer aPath = getAppNameRegistryPath(); + const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), + aPath.makeStringAndClear(), true); + const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes"); + const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType)); + + css::uno::Any aUIItemProperties(makeAny(sUIItemProperties)); + aModeNode.setNodeValue("UIItemProperties", aUIItemProperties); + aAppNode.commit(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
\ No newline at end of file diff --git a/cui/source/inc/CustomNotebookbarGenerator.hxx b/cui/source/inc/CustomNotebookbarGenerator.hxx new file mode 100644 index 000000000000..89276a1b9088 --- /dev/null +++ b/cui/source/inc/CustomNotebookbarGenerator.hxx @@ -0,0 +1,43 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_CUI_SOURCE_INC_CUSTOMNOTEBOOKBARGENERATOR_HXX +#define INCLUDED_CUI_SOURCE_INC_CUSTOMNOTEBOOKBARGENERATOR_HXX + +#include "cfg.hxx" + +using namespace css::uno; + +class CustomNotebookbarGenerator +{ +public: + CustomNotebookbarGenerator(); + static OUString getCustomizedUIPath(); + static char* convertToCharPointer(const OUString& sString); + static Sequence<OUString> getCustomizedUIItem(OUString sNotebookbarConfigType); + static void getFileNameAndAppName(OUString& sAppName, OUString& sNotebookbarUIFileName); + static void modifyCustomizedUIFile(Sequence<OUString> sUIItemProperties); + static void createCustomizedUIFile(); + static void setCustomizedUIItem(Sequence<OUString> sUIItemProperties, + OUString sNotebookbarConfigType); +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
\ No newline at end of file diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 6af454e1387d..ac391bb3eb81 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -124,6 +124,7 @@ certain functionality. @section cui @li @c cui.customize +@li @c cui.customnotebookbar @li @c cui.dialogs @li @c cui.factory @li @c cui.options diff --git a/officecfg/registry/data/org/openoffice/Office/UI/ToolbarMode.xcu b/officecfg/registry/data/org/openoffice/Office/UI/ToolbarMode.xcu index 28b38336294c..98f3cafc33ae 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/ToolbarMode.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/ToolbarMode.xcu @@ -178,6 +178,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -206,6 +211,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -234,6 +244,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -265,6 +280,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -410,6 +430,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -438,6 +463,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -466,6 +496,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -494,6 +529,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -614,6 +654,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -642,6 +687,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -670,6 +720,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -734,6 +789,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -793,6 +853,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> @@ -824,6 +889,11 @@ <value> </value> </prop> + <prop oor:name="UIItemProperties"> + <value oor:separator=";"> + UIItemID , propertyName , propertyValue; + </value> + </prop> <prop oor:name="Sidebar"> <value>Arrow</value> </prop> diff --git a/officecfg/registry/schema/org/openoffice/Office/UI/ToolbarMode.xcs b/officecfg/registry/schema/org/openoffice/Office/UI/ToolbarMode.xcs index f97ec55e2dc8..b8c69f354398 100644 --- a/officecfg/registry/schema/org/openoffice/Office/UI/ToolbarMode.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/UI/ToolbarMode.xcs @@ -64,6 +64,17 @@ <desc>List of visible toolbars activated by user.</desc> </info> </prop> + <prop oor:name="UIItemProperties" oor:type="oor:string-list" oor:nillable="false"> + <info> + <desc> + List of context descriptors. Each context descriptor is a string that contains three comma + separated values (note that values are case sensitive): + 1. UIItemID - contains the ID of uiitem(GtkToolButton/GtkMenuItem) of notebookbar + 2. propertyName - contains the value of attibute(name) of property node. + 3. propertyValue - cotains the value of property node. + </desc> + </info> + </prop> <prop oor:name="Sidebar" oor:type="xs:string" oor:nillable="false"> <info> <desc> |