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 <rtl/ustrbuf.hxx>
23 #include <config_folders.h>
24 #include <CustomNotebookbarGenerator.hxx>
25 #include <osl/file.hxx>
26 #include <osl/thread.h>
27 #include <vcl/builder.hxx>
28 #include <vcl/EnumContext.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <com/sun/star/frame/ModuleManager.hpp>
31 #include <unotools/confignode.hxx>
32 #include <libxml/parser.h>
34 #define aUIPropertiesCount 3
38 CustomNotebookbarGenerator::CustomNotebookbarGenerator() {}
40 static OUString
lcl_activeAppName(vcl::EnumContext::Application eApp
)
44 case vcl::EnumContext::Application::Writer
:
45 return "ActiveWriter";
47 case vcl::EnumContext::Application::Calc
:
50 case vcl::EnumContext::Application::Impress
:
51 return "ActiveImpress";
53 case vcl::EnumContext::Application::Draw
:
62 static OUString
lcl_getAppName(vcl::EnumContext::Application eApp
)
66 case vcl::EnumContext::Application::Writer
:
69 case vcl::EnumContext::Application::Calc
:
72 case vcl::EnumContext::Application::Impress
:
75 case vcl::EnumContext::Application::Draw
:
84 static OUString
getAppNameRegistryPath()
86 vcl::EnumContext::Application eApp
= vcl::EnumContext::Application::Any
;
87 const Reference
<frame::XFrame
>& xFrame
88 = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
89 const Reference
<frame::XModuleManager
> xModuleManager
90 = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
91 eApp
= vcl::EnumContext::GetApplicationEnum(xModuleManager
->identify(xFrame
));
93 OUString
sAppName(lcl_getAppName(eApp
));
94 return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName
;
97 static OUString
customizedUIPathBuffer()
99 OUString
sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
100 "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
101 rtl::Bootstrap::expandMacros(sDirPath
);
105 OUString
CustomNotebookbarGenerator::getCustomizedUIPath()
107 OUString sAppName
, sNotebookbarUIFileName
;
108 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
109 return customizedUIPathBuffer() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/"
110 + sNotebookbarUIFileName
;
113 OUString
CustomNotebookbarGenerator::getOriginalUIPath()
115 OUString sAppName
, sNotebookbarUIFileName
;
116 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
117 return VclBuilderContainer::getUIRootDir() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/"
118 + sNotebookbarUIFileName
;
121 static OUString
getUIDirPath()
123 OUString sAppName
, sNotebookbarUIFileName
;
124 CustomNotebookbarGenerator::getFileNameAndAppName(sAppName
, sNotebookbarUIFileName
);
126 = customizedUIPathBuffer() + "modules/s" + sAppName
.toAsciiLowerCase() + "/ui/";
130 OString
CustomNotebookbarGenerator::getSystemPath(OUString
const& sURL
)
134 OUString sSystemPathSettings
;
135 if (osl_getSystemPathFromFileURL(sURL
.pData
, &sSystemPathSettings
.pData
) != osl_File_E_None
)
137 SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL
);
140 OString osSystemPathSettings
141 = OUStringToOString(sSystemPathSettings
, osl_getThreadTextEncoding());
142 return osSystemPathSettings
;
145 static void changeNodeValue(xmlNode
* pNodePtr
, const char* pProperty
, const char* pValue
)
147 pNodePtr
= pNodePtr
->xmlChildrenNode
;
150 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("property"))))
152 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("name"));
153 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pProperty
))))
154 xmlNodeSetContent(pNodePtr
, reinterpret_cast<const xmlChar
*>(pValue
));
158 pNodePtr
= pNodePtr
->next
;
162 static void searchNodeAndAttribute(xmlNode
* pNodePtr
, const char* pUIItemID
, const char* pProperty
,
165 pNodePtr
= pNodePtr
->xmlChildrenNode
;
168 if (pNodePtr
->type
== XML_ELEMENT_NODE
)
170 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("object"))))
172 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("id"));
173 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pUIItemID
))))
174 changeNodeValue(pNodePtr
, pProperty
, pValue
);
177 searchNodeAndAttribute(pNodePtr
, pUIItemID
, pProperty
, pValue
);
179 pNodePtr
= pNodePtr
->next
;
183 static xmlDocPtr
notebookbarXMLParser(const OString
& rDocName
, const OString
& rUIItemID
,
184 const OString
& rProperty
, const OString
& rValue
)
186 xmlDocPtr pDocPtr
= xmlParseFile(rDocName
.getStr());
187 xmlNodePtr pNodePtr
= xmlDocGetRootElement(pDocPtr
);
188 searchNodeAndAttribute(pNodePtr
, rUIItemID
.getStr(), rProperty
.getStr(), rValue
.getStr());
192 void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence
<OUString
>& sUIItemProperties
)
194 OString sCustomizedUIPath
= getSystemPath(getCustomizedUIPath());
195 for (auto const& aValue
: sUIItemProperties
)
197 std::vector
<OString
> aProperties(aUIPropertiesCount
);
198 for (sal_Int32 aIndex
= 0; aIndex
< aUIPropertiesCount
; aIndex
++)
200 sal_Int32 nPos
= aIndex
;
201 OUString sToken
= aValue
.getToken(nPos
, ',', nPos
);
202 aProperties
[aIndex
] = OUStringToOString(sToken
, RTL_TEXTENCODING_UTF8
);
204 xmlDocPtr doc
= notebookbarXMLParser(sCustomizedUIPath
, aProperties
[0], aProperties
[1],
209 xmlSaveFormatFile(sCustomizedUIPath
.getStr(), doc
, 1);
215 void CustomNotebookbarGenerator::getFileNameAndAppName(OUString
& sAppName
,
216 OUString
& sNotebookbarUIFileName
)
218 SfxViewFrame
* pFrame
= SfxViewFrame::Current();
222 const auto xContext
= comphelper::getProcessComponentContext();
223 utl::OConfigurationTreeRoot
aRoot(xContext
, "org.openoffice.Office.UI.ToolbarMode/", false);
224 const Reference
<frame::XFrame
>& xFrame
= pFrame
->GetFrame().GetFrameInterface();
225 const Reference
<frame::XModuleManager
> xModuleManager
= frame::ModuleManager::create(xContext
);
227 vcl::EnumContext::Application eApp
228 = vcl::EnumContext::GetApplicationEnum(xModuleManager
->identify(xFrame
));
229 OUString
sActiveAppName(lcl_activeAppName(eApp
));
230 sAppName
= lcl_getAppName(eApp
);
231 const Any aValue
= aRoot
.getNodeValue(sActiveAppName
);
232 aValue
>>= sNotebookbarUIFileName
;
235 void CustomNotebookbarGenerator::createCustomizedUIFile()
237 OUString sUserUIDir
= getUIDirPath();
238 OUString sOriginalUIPath
= getOriginalUIPath();
239 OUString sCustomizedUIPath
= getCustomizedUIPath();
241 sal_uInt32 nflag
= osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
;
242 osl::Directory
aDirectory(sUserUIDir
);
243 if (aDirectory
.open() != osl::FileBase::E_None
)
244 osl::Directory::create(sUserUIDir
, nflag
);
246 SAL_WARN("cui.customnotebookbar",
247 "Cannot create the directory or directory was present :" << sUserUIDir
);
249 osl::File
aFile(sCustomizedUIPath
);
250 if (aFile
.open(nflag
) != osl::FileBase::E_None
)
251 osl::File::copy(sOriginalUIPath
, sCustomizedUIPath
);
253 SAL_WARN("cui.customnotebookbar",
254 "Cannot copy the file or file was present :" << sCustomizedUIPath
);
257 Sequence
<OUString
> CustomNotebookbarGenerator::getCustomizedUIItem(OUString sNotebookbarConfigType
)
259 OUString aPath
= getAppNameRegistryPath();
260 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
263 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode("Modes");
264 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(sNotebookbarConfigType
));
265 const Any aValue
= aModeNode
.getNodeValue("UIItemProperties");
266 Sequence
<OUString
> aValues
;
271 void CustomNotebookbarGenerator::setCustomizedUIItem(Sequence
<OUString
> sUIItemProperties
,
272 OUString sNotebookbarConfigType
)
274 OUString aPath
= getAppNameRegistryPath();
275 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
277 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode("Modes");
278 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(sNotebookbarConfigType
));
280 css::uno::Any
aUIItemProperties(makeAny(sUIItemProperties
));
281 aModeNode
.setNodeValue("UIItemProperties", aUIItemProperties
);
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */