1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/processfactory.hxx>
21 #include <rtl/bootstrap.hxx>
22 #include <config_folders.h>
23 #include <CustomNotebookbarGenerator.hxx>
24 #include <osl/file.hxx>
25 #include <osl/thread.h>
26 #include <vcl/EnumContext.hxx>
27 #include <vcl/settings.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <com/sun/star/frame/ModuleManager.hpp>
30 #include <unotools/confignode.hxx>
31 #include <libxml/parser.h>
32 #include <o3tl/string_view.hxx>
34 #define aUIPropertiesCount 3
38 CustomNotebookbarGenerator::CustomNotebookbarGenerator() {}
40 static OUString
lcl_activeAppName(vcl::EnumContext::Application eApp
)
44 case vcl::EnumContext::Application::Writer
:
45 return u
"ActiveWriter"_ustr
;
46 case vcl::EnumContext::Application::Calc
:
47 return u
"ActiveCalc"_ustr
;
48 case vcl::EnumContext::Application::Impress
:
49 return u
"ActiveImpress"_ustr
;
50 case vcl::EnumContext::Application::Draw
:
51 return u
"ActiveDraw"_ustr
;
57 static OUString
lcl_getAppName(vcl::EnumContext::Application eApp
)
61 case vcl::EnumContext::Application::Writer
:
62 return u
"Writer"_ustr
;
63 case vcl::EnumContext::Application::Calc
:
65 case vcl::EnumContext::Application::Impress
:
66 return u
"Impress"_ustr
;
67 case vcl::EnumContext::Application::Draw
:
74 static OUString
getAppNameRegistryPath()
76 vcl::EnumContext::Application eApp
= vcl::EnumContext::Application::Any
;
78 if (SfxViewFrame
* pViewFrame
= SfxViewFrame::Current())
80 const Reference
<frame::XFrame
>& xFrame
= pViewFrame
->GetFrame().GetFrameInterface();
81 const Reference
<frame::XModuleManager
> xModuleManager
82 = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
83 eApp
= vcl::EnumContext::GetApplicationEnum(xModuleManager
->identify(xFrame
));
86 OUString
sAppName(lcl_getAppName(eApp
));
87 return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName
;
90 static OUString
customizedUIPathBuffer()
92 OUString
sDirPath(u
"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
93 "bootstrap") ":UserInstallation}/user/config/soffice.cfg/"_ustr
);
94 rtl::Bootstrap::expandMacros(sDirPath
);
98 OUString
CustomNotebookbarGenerator::getCustomizedUIPath()
100 OUString sAppName
, sNotebookbarUIFileName
;
101 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
102 return customizedUIPathBuffer() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/"
103 + sNotebookbarUIFileName
;
106 OUString
CustomNotebookbarGenerator::getOriginalUIPath()
108 OUString sAppName
, sNotebookbarUIFileName
;
109 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
110 return AllSettings::GetUIRootDir() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/"
111 + sNotebookbarUIFileName
;
114 static OUString
getUIDirPath()
116 OUString sAppName
, sNotebookbarUIFileName
;
117 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
119 = customizedUIPathBuffer() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/";
123 OString
CustomNotebookbarGenerator::getSystemPath(OUString
const& sURL
)
127 OUString sSystemPathSettings
;
128 if (osl_getSystemPathFromFileURL(sURL
.pData
, &sSystemPathSettings
.pData
) != osl_File_E_None
)
130 SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL
);
133 OString osSystemPathSettings
134 = OUStringToOString(sSystemPathSettings
, osl_getThreadTextEncoding());
135 return osSystemPathSettings
;
138 static void changeNodeValue(xmlNode
* pNodePtr
, const char* pProperty
, const char* pValue
)
140 pNodePtr
= pNodePtr
->xmlChildrenNode
;
143 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("property"))))
145 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("name"));
146 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pProperty
))))
147 xmlNodeSetContent(pNodePtr
, reinterpret_cast<const xmlChar
*>(pValue
));
151 pNodePtr
= pNodePtr
->next
;
155 static void searchNodeAndAttribute(xmlNode
* pNodePtr
, const char* pUIItemID
, const char* pProperty
,
158 pNodePtr
= pNodePtr
->xmlChildrenNode
;
161 if (pNodePtr
->type
== XML_ELEMENT_NODE
)
163 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("object"))))
165 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("id"));
166 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pUIItemID
))))
167 changeNodeValue(pNodePtr
, pProperty
, pValue
);
170 searchNodeAndAttribute(pNodePtr
, pUIItemID
, pProperty
, pValue
);
172 pNodePtr
= pNodePtr
->next
;
176 static xmlDocPtr
notebookbarXMLParser(const OString
& rDocName
, const OString
& rUIItemID
,
177 const OString
& rProperty
, const OString
& rValue
)
179 xmlDocPtr pDocPtr
= xmlParseFile(rDocName
.getStr());
180 xmlNodePtr pNodePtr
= xmlDocGetRootElement(pDocPtr
);
181 searchNodeAndAttribute(pNodePtr
, rUIItemID
.getStr(), rProperty
.getStr(), rValue
.getStr());
185 void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence
<OUString
>& sUIItemProperties
)
187 const OUString sUIPath
= getCustomizedUIPath();
188 if (osl::File(sUIPath
).open(osl_File_OpenFlag_Read
) != osl::FileBase::E_None
)
189 createCustomizedUIFile();
191 const OString sCustomizedUIPath
= getSystemPath(sUIPath
);
192 for (auto const& aValue
: sUIItemProperties
)
194 std::vector
<OString
> aProperties(aUIPropertiesCount
);
195 for (sal_Int32 aIndex
= 0; aIndex
< aUIPropertiesCount
; aIndex
++)
197 sal_Int32 nPos
= aIndex
;
198 std::u16string_view sToken
= o3tl::getToken(aValue
, nPos
, ',', nPos
);
199 aProperties
[aIndex
] = OUStringToOString(sToken
, RTL_TEXTENCODING_UTF8
);
201 xmlDocPtr doc
= notebookbarXMLParser(sCustomizedUIPath
, aProperties
[0], aProperties
[1],
206 xmlSaveFormatFile(sCustomizedUIPath
.getStr(), doc
, 1);
212 void CustomNotebookbarGenerator::getFileNameAndAppName(OUString
& sAppName
,
213 OUString
& sNotebookbarUIFileName
)
215 SfxViewFrame
* pFrame
= SfxViewFrame::Current();
219 const auto& xContext
= comphelper::getProcessComponentContext();
220 utl::OConfigurationTreeRoot
aRoot(xContext
, u
"org.openoffice.Office.UI.ToolbarMode/"_ustr
,
222 const Reference
<frame::XFrame
>& xFrame
= pFrame
->GetFrame().GetFrameInterface();
223 const Reference
<frame::XModuleManager
> xModuleManager
= frame::ModuleManager::create(xContext
);
225 vcl::EnumContext::Application eApp
226 = vcl::EnumContext::GetApplicationEnum(xModuleManager
->identify(xFrame
));
227 OUString
sActiveAppName(lcl_activeAppName(eApp
));
228 sAppName
= lcl_getAppName(eApp
);
229 const Any aValue
= aRoot
.getNodeValue(sActiveAppName
);
230 aValue
>>= sNotebookbarUIFileName
;
233 void CustomNotebookbarGenerator::createCustomizedUIFile()
235 OUString sUserUIDir
= getUIDirPath();
236 OUString sOriginalUIPath
= getOriginalUIPath();
237 OUString sCustomizedUIPath
= getCustomizedUIPath();
239 sal_uInt32 nflag
= osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
;
240 osl::Directory
aDirectory(sUserUIDir
);
241 if (aDirectory
.open() != osl::FileBase::E_None
)
242 osl::Directory::create(sUserUIDir
, nflag
);
244 SAL_WARN("cui.customnotebookbar",
245 "Cannot create the directory or directory was present :" << sUserUIDir
);
247 osl::File
aFile(sCustomizedUIPath
);
248 if (aFile
.open(nflag
) != osl::FileBase::E_None
)
249 osl::File::copy(sOriginalUIPath
, sCustomizedUIPath
);
251 SAL_WARN("cui.customnotebookbar",
252 "Cannot copy the file or file was present :" << sCustomizedUIPath
);
256 CustomNotebookbarGenerator::getCustomizedUIItem(const OUString
& sNotebookbarConfigType
)
258 OUString aPath
= getAppNameRegistryPath();
259 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
262 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode(u
"Modes"_ustr
);
263 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(sNotebookbarConfigType
));
264 const Any aValue
= aModeNode
.getNodeValue(u
"UIItemProperties"_ustr
);
265 Sequence
<OUString
> aValues
;
270 void CustomNotebookbarGenerator::setCustomizedUIItem(const Sequence
<OUString
>& rUIItemProperties
,
271 const OUString
& rNotebookbarConfigType
)
273 OUString aPath
= getAppNameRegistryPath();
274 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
276 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode(u
"Modes"_ustr
);
277 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(rNotebookbarConfigType
));
279 css::uno::Any
aUIItemProperties(rUIItemProperties
);
280 aModeNode
.setNodeValue(u
"UIItemProperties"_ustr
, aUIItemProperties
);
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */