LibreOffice Module cui (master)  1
CustomNotebookbarGenerator.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
21 #include <rtl/bootstrap.hxx>
22 #include <config_folders.h>
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 
33 #define aUIPropertiesCount 3
34 
35 using namespace css;
36 
38 
40 {
41  switch (eApp)
42  {
44  return "ActiveWriter";
45  break;
47  return "ActiveCalc";
48  break;
50  return "ActiveImpress";
51  break;
53  return "ActiveDraw";
54  break;
55  default:
56  return OUString();
57  break;
58  }
59 }
60 
62 {
63  switch (eApp)
64  {
66  return "Writer";
67  break;
69  return "Calc";
70  break;
72  return "Impress";
73  break;
75  return "Draw";
76  break;
77  default:
78  return OUString();
79  break;
80  }
81 }
82 
83 static OUString getAppNameRegistryPath()
84 {
86  const Reference<frame::XFrame>& xFrame
88  const Reference<frame::XModuleManager> xModuleManager
89  = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
90  eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
91 
92  OUString sAppName(lcl_getAppName(eApp));
93  return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName;
94 }
95 
96 static OUString customizedUIPathBuffer()
97 {
98  OUString sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
99  "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
100  rtl::Bootstrap::expandMacros(sDirPath);
101  return sDirPath;
102 }
103 
105 {
106  OUString sAppName, sNotebookbarUIFileName;
107  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
108  return customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
109  + sNotebookbarUIFileName;
110 }
111 
113 {
114  OUString sAppName, sNotebookbarUIFileName;
115  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
116  return AllSettings::GetUIRootDir() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
117  + sNotebookbarUIFileName;
118 }
119 
120 static OUString getUIDirPath()
121 {
122  OUString sAppName, sNotebookbarUIFileName;
123  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
124  OUString sUIDirPath
125  = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/";
126  return sUIDirPath;
127 }
128 
129 OString CustomNotebookbarGenerator::getSystemPath(OUString const& sURL)
130 {
131  if (sURL.isEmpty())
132  return OString();
133  OUString sSystemPathSettings;
134  if (osl_getSystemPathFromFileURL(sURL.pData, &sSystemPathSettings.pData) != osl_File_E_None)
135  {
136  SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL);
137  return OString();
138  }
139  OString osSystemPathSettings
140  = OUStringToOString(sSystemPathSettings, osl_getThreadTextEncoding());
141  return osSystemPathSettings;
142 }
143 
144 static void changeNodeValue(xmlNode* pNodePtr, const char* pProperty, const char* pValue)
145 {
146  pNodePtr = pNodePtr->xmlChildrenNode;
147  while (pNodePtr)
148  {
149  if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
150  {
151  xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
152  if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pProperty))))
153  xmlNodeSetContent(pNodePtr, reinterpret_cast<const xmlChar*>(pValue));
154  xmlFree(UriValue);
155  break;
156  }
157  pNodePtr = pNodePtr->next;
158  }
159 }
160 
161 static void searchNodeAndAttribute(xmlNode* pNodePtr, const char* pUIItemID, const char* pProperty,
162  const char* pValue)
163 {
164  pNodePtr = pNodePtr->xmlChildrenNode;
165  while (pNodePtr)
166  {
167  if (pNodePtr->type == XML_ELEMENT_NODE)
168  {
169  if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("object"))))
170  {
171  xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
172  if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pUIItemID))))
173  changeNodeValue(pNodePtr, pProperty, pValue);
174  xmlFree(UriValue);
175  }
176  searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
177  }
178  pNodePtr = pNodePtr->next;
179  }
180 }
181 
182 static xmlDocPtr notebookbarXMLParser(const OString& rDocName, const OString& rUIItemID,
183  const OString& rProperty, const OString& rValue)
184 {
185  xmlDocPtr pDocPtr = xmlParseFile(rDocName.getStr());
186  xmlNodePtr pNodePtr = xmlDocGetRootElement(pDocPtr);
187  searchNodeAndAttribute(pNodePtr, rUIItemID.getStr(), rProperty.getStr(), rValue.getStr());
188  return pDocPtr;
189 }
190 
192 {
193  OString sCustomizedUIPath = getSystemPath(getCustomizedUIPath());
194  for (auto const& aValue : sUIItemProperties)
195  {
196  std::vector<OString> aProperties(aUIPropertiesCount);
197  for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++)
198  {
199  sal_Int32 nPos = aIndex;
200  OUString sToken = aValue.getToken(nPos, ',', nPos);
201  aProperties[aIndex] = OUStringToOString(sToken, RTL_TEXTENCODING_UTF8);
202  }
203  xmlDocPtr doc = notebookbarXMLParser(sCustomizedUIPath, aProperties[0], aProperties[1],
204  aProperties[2]);
205 
206  if (doc != nullptr)
207  {
208  xmlSaveFormatFile(sCustomizedUIPath.getStr(), doc, 1);
209  xmlFreeDoc(doc);
210  }
211  }
212 }
213 
215  OUString& sNotebookbarUIFileName)
216 {
218  if (!pFrame)
219  return;
220 
221  const auto xContext = comphelper::getProcessComponentContext();
222  utl::OConfigurationTreeRoot aRoot(xContext, "org.openoffice.Office.UI.ToolbarMode/", false);
223  const Reference<frame::XFrame>& xFrame = pFrame->GetFrame().GetFrameInterface();
224  const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create(xContext);
225 
227  = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
228  OUString sActiveAppName(lcl_activeAppName(eApp));
229  sAppName = lcl_getAppName(eApp);
230  const Any aValue = aRoot.getNodeValue(sActiveAppName);
231  aValue >>= sNotebookbarUIFileName;
232 }
233 
235 {
236  OUString sUserUIDir = getUIDirPath();
237  OUString sOriginalUIPath = getOriginalUIPath();
238  OUString sCustomizedUIPath = getCustomizedUIPath();
239 
240  sal_uInt32 nflag = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
241  osl::Directory aDirectory(sUserUIDir);
242  if (aDirectory.open() != osl::FileBase::E_None)
243  osl::Directory::create(sUserUIDir, nflag);
244  else
245  SAL_WARN("cui.customnotebookbar",
246  "Cannot create the directory or directory was present :" << sUserUIDir);
247 
248  osl::File aFile(sCustomizedUIPath);
249  if (aFile.open(nflag) != osl::FileBase::E_None)
250  osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
251  else
252  SAL_WARN("cui.customnotebookbar",
253  "Cannot copy the file or file was present :" << sCustomizedUIPath);
254 }
255 
257 {
258  OUString aPath = getAppNameRegistryPath();
260  false);
261 
262  const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
263  const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
264  const Any aValue = aModeNode.getNodeValue("UIItemProperties");
265  Sequence<OUString> aValues;
266  aValue >>= aValues;
267  return aValues;
268 }
269 
271  OUString sNotebookbarConfigType)
272 {
273  OUString aPath = getAppNameRegistryPath();
275  true);
276  const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
277  const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
278 
279  css::uno::Any aUIItemProperties(makeAny(sUIItemProperties));
280  aModeNode.setNodeValue("UIItemProperties", aUIItemProperties);
281  aAppNode.commit();
282 }
283 
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define aUIPropertiesCount
static void getFileNameAndAppName(OUString &sAppName, OUString &sNotebookbarUIFileName)
OConfigurationNode openNode(const OUString &_rPath) const
static OUString getUIDirPath()
static void modifyCustomizedUIFile(const Sequence< OUString > &sUIItemProperties)
Reference< XFrame > xFrame
static xmlDocPtr notebookbarXMLParser(const OString &rDocName, const OString &rUIItemID, const OString &rProperty, const OString &rValue)
static OUString customizedUIPathBuffer()
PropertiesInfo aProperties
SfxFrame & GetFrame() const
static void searchNodeAndAttribute(xmlNode *pNodePtr, const char *pUIItemID, const char *pProperty, const char *pValue)
static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
static OUString GetUIRootDir()
#define SAL_CONFIGFILE(name)
static OString getSystemPath(OUString const &sURL)
static OUString lcl_activeAppName(vcl::EnumContext::Application eApp)
static Application GetApplicationEnum(const OUString &rsApplicationName)
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
static Sequence< OUString > getCustomizedUIItem(OUString sNotebookbarConfigType)
OString OUStringToOString(const OUString &str, ConnectionSettings const *settings)
static OUString getAppNameRegistryPath()
static SfxViewFrame * Current()
std::deque< AttacherIndex_Impl > aIndex
css::uno::Any getNodeValue(const OUString &_rPath) const
Reference< XComponentContext > getProcessComponentContext()
static void changeNodeValue(xmlNode *pNodePtr, const char *pProperty, const char *pValue)
#define SAL_WARN(area, stream)
static void setCustomizedUIItem(Sequence< OUString > sUIItemProperties, OUString sNotebookbarConfigType)
sal_uInt16 nPos
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)