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 <vcl/builder.hxx>
27 #include <vcl/EnumContext.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <com/sun/star/frame/ModuleManager.hpp>
30 #include <unotools/confignode.hxx>
31 #include <libxml/parser.h>
33 #define aUIItemIDLength 255
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 char* CustomNotebookbarGenerator::convertToCharPointer(const OUString
& sString
)
132 char* cString
= new char[sString
.getLength() + 1];
133 for (int nIdx
= 0; nIdx
< sString
.getLength(); nIdx
++)
134 *(cString
+ nIdx
) = char(sString
[nIdx
]);
135 *(cString
+ sString
.getLength()) = '\0';
139 static void changeNodeValue(xmlNode
* pNodePtr
, char* pProperty
, char* pValue
)
141 pNodePtr
= pNodePtr
->xmlChildrenNode
;
144 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("property"))))
146 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("name"));
147 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pProperty
))))
148 xmlNodeSetContent(pNodePtr
, reinterpret_cast<const xmlChar
*>(pValue
));
152 pNodePtr
= pNodePtr
->next
;
156 static void searchNodeAndAttribute(xmlNode
* pNodePtr
, char* pUIItemID
, char* pProperty
,
159 pNodePtr
= pNodePtr
->xmlChildrenNode
;
162 if (pNodePtr
->type
== XML_ELEMENT_NODE
)
164 if (!(xmlStrcmp(pNodePtr
->name
, reinterpret_cast<const xmlChar
*>("object"))))
166 xmlChar
* UriValue
= xmlGetProp(pNodePtr
, reinterpret_cast<const xmlChar
*>("id"));
167 if (!(xmlStrcmp(UriValue
, reinterpret_cast<const xmlChar
*>(pUIItemID
))))
168 changeNodeValue(pNodePtr
, pProperty
, pValue
);
171 searchNodeAndAttribute(pNodePtr
, pUIItemID
, pProperty
, pValue
);
173 pNodePtr
= pNodePtr
->next
;
177 static xmlDocPtr
notebookbarXMLParser(const char* pDocName
, char* pUIItemID
, char* pProperty
,
183 pDocPtr
= xmlParseFile(pDocName
);
184 pNodePtr
= xmlDocGetRootElement(pDocPtr
);
185 searchNodeAndAttribute(pNodePtr
, pUIItemID
, pProperty
, pValue
);
189 void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence
<OUString
>& sUIItemProperties
)
191 OUString sCustomizedUIPath
= getCustomizedUIPath();
192 char* cCustomizedUIPath
= convertToCharPointer(sCustomizedUIPath
);
193 for (auto const& aValue
: sUIItemProperties
)
195 char** pProperties
= new char*[aUIPropertiesCount
];
196 for (sal_Int32 aIndex
= 0; aIndex
< aUIPropertiesCount
; aIndex
++)
198 int nIdx
= int(aIndex
);
199 sal_Int32 rPos
= aIndex
;
200 pProperties
[nIdx
] = new char[aUIItemIDLength
];
201 pProperties
[nIdx
] = convertToCharPointer(aValue
.getToken(rPos
, ',', rPos
));
204 doc
= notebookbarXMLParser(cCustomizedUIPath
, pProperties
[0], pProperties
[1],
207 for (int nIdx
= 0; nIdx
< aUIPropertiesCount
; nIdx
++)
209 delete[] pProperties
[nIdx
];
211 delete[] pProperties
;
215 xmlSaveFormatFile(cCustomizedUIPath
, doc
, 1);
219 delete[] cCustomizedUIPath
;
222 void CustomNotebookbarGenerator::getFileNameAndAppName(OUString
& sAppName
,
223 OUString
& sNotebookbarUIFileName
)
225 const auto xContext
= comphelper::getProcessComponentContext();
226 utl::OConfigurationTreeRoot
aRoot(xContext
, "org.openoffice.Office.UI.ToolbarMode/", false);
227 const Reference
<frame::XFrame
>& xFrame
228 = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
229 const Reference
<frame::XModuleManager
> xModuleManager
= frame::ModuleManager::create(xContext
);
231 vcl::EnumContext::Application eApp
232 = vcl::EnumContext::GetApplicationEnum(xModuleManager
->identify(xFrame
));
233 OUString
sActiveAppName(lcl_activeAppName(eApp
));
234 sAppName
= lcl_getAppName(eApp
);
235 const Any aValue
= aRoot
.getNodeValue(sActiveAppName
);
236 aValue
>>= sNotebookbarUIFileName
;
239 void CustomNotebookbarGenerator::createCustomizedUIFile()
241 OUString sUserUIDir
= getUIDirPath();
242 OUString sOriginalUIPath
= getOriginalUIPath();
243 OUString sCustomizedUIPath
= getCustomizedUIPath();
245 sal_uInt32 nflag
= osl_File_OpenFlag_Read
| osl_File_OpenFlag_Write
;
246 osl::Directory
aDirectory(sUserUIDir
);
247 if (aDirectory
.open() != osl::FileBase::E_None
)
248 osl::Directory::create(sUserUIDir
, nflag
);
250 SAL_WARN("cui.customnotebookbar",
251 "Cannot create the directory or directory was present :" << sUserUIDir
);
253 osl::File
aFile(sCustomizedUIPath
);
254 if (aFile
.open(nflag
) != osl::FileBase::E_None
)
255 osl::File::copy(sOriginalUIPath
, sCustomizedUIPath
);
257 SAL_WARN("cui.customnotebookbar",
258 "Cannot copy the file or file was present :" << sCustomizedUIPath
);
261 Sequence
<OUString
> CustomNotebookbarGenerator::getCustomizedUIItem(OUString sNotebookbarConfigType
)
263 OUString aPath
= getAppNameRegistryPath();
264 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
267 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode("Modes");
268 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(sNotebookbarConfigType
));
269 const Any aValue
= aModeNode
.getNodeValue("UIItemProperties");
270 Sequence
<OUString
> aValues
;
275 void CustomNotebookbarGenerator::setCustomizedUIItem(Sequence
<OUString
> sUIItemProperties
,
276 OUString sNotebookbarConfigType
)
278 OUString aPath
= getAppNameRegistryPath();
279 const utl::OConfigurationTreeRoot
aAppNode(::comphelper::getProcessComponentContext(), aPath
,
281 const utl::OConfigurationNode aModesNode
= aAppNode
.openNode("Modes");
282 const utl::OConfigurationNode
aModeNode(aModesNode
.openNode(sNotebookbarConfigType
));
284 css::uno::Any
aUIItemProperties(makeAny(sUIItemProperties
));
285 aModeNode
.setNodeValue("UIItemProperties", aUIItemProperties
);
289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */