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 <rtl/ustrbuf.hxx>
23 #include <config_folders.h>
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>
32 
33 #define aUIItemIDLength 255
34 #define aUIPropertiesCount 3
35 
36 using namespace css;
37 
39 
41 {
42  switch (eApp)
43  {
45  return "ActiveWriter";
46  break;
48  return "ActiveCalc";
49  break;
51  return "ActiveImpress";
52  break;
54  return "ActiveDraw";
55  break;
56  default:
57  return OUString();
58  break;
59  }
60 }
61 
63 {
64  switch (eApp)
65  {
67  return "Writer";
68  break;
70  return "Calc";
71  break;
73  return "Impress";
74  break;
76  return "Draw";
77  break;
78  default:
79  return OUString();
80  break;
81  }
82 }
83 
84 static OUString getAppNameRegistryPath()
85 {
87  const Reference<frame::XFrame>& xFrame
89  const Reference<frame::XModuleManager> xModuleManager
90  = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
91  eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
92 
93  OUString sAppName(lcl_getAppName(eApp));
94  OUStringBuffer sPath("org.openoffice.Office.UI.ToolbarMode/Applications/");
95  sPath.append(sAppName);
96  return sPath.makeStringAndClear();
97 }
98 
99 static OUString customizedUIPathBuffer()
100 {
101  OUString sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
102  "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
103  rtl::Bootstrap::expandMacros(sDirPath);
104  return sDirPath;
105 }
106 
108 {
109  OUString sAppName, sNotebookbarUIFileName;
110  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
111  return customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
112  + sNotebookbarUIFileName;
113 }
114 
116 {
117  OUString sAppName, sNotebookbarUIFileName;
118  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
119  return VclBuilderContainer::getUIRootDir() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
120  + sNotebookbarUIFileName;
121 }
122 
123 static OUString getUIDirPath()
124 {
125  OUString sAppName, sNotebookbarUIFileName;
126  CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
127  OUString sUIDirPath
128  = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/";
129  return sUIDirPath;
130 }
131 
133 {
134  char* cString = new char[sString.getLength() + 1];
135  for (int nIdx = 0; nIdx < sString.getLength(); nIdx++)
136  *(cString + nIdx) = char(sString[nIdx]);
137  *(cString + sString.getLength()) = '\0';
138  return cString;
139 }
140 
141 static void changeNodeValue(xmlNode* pNodePtr, char* pProperty, char* pValue)
142 {
143  pNodePtr = pNodePtr->xmlChildrenNode;
144  while (pNodePtr)
145  {
146  if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
147  {
148  xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
149  if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pProperty))))
150  xmlNodeSetContent(pNodePtr, reinterpret_cast<const xmlChar*>(pValue));
151  xmlFree(UriValue);
152  break;
153  }
154  pNodePtr = pNodePtr->next;
155  }
156 }
157 
158 static void searchNodeAndAttribute(xmlNode* pNodePtr, char* pUIItemID, char* pProperty,
159  char* pValue)
160 {
161  pNodePtr = pNodePtr->xmlChildrenNode;
162  while (pNodePtr)
163  {
164  if (pNodePtr->type == XML_ELEMENT_NODE)
165  {
166  if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("object"))))
167  {
168  xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
169  if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pUIItemID))))
170  changeNodeValue(pNodePtr, pProperty, pValue);
171  xmlFree(UriValue);
172  }
173  searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
174  }
175  pNodePtr = pNodePtr->next;
176  }
177 }
178 
179 static xmlDocPtr notebookbarXMLParser(char* pDocName, char* pUIItemID, char* pProperty,
180  char* pValue)
181 {
182  xmlDocPtr pDocPtr;
183  xmlNodePtr pNodePtr;
184 
185  pDocPtr = xmlParseFile(pDocName);
186  pNodePtr = xmlDocGetRootElement(pDocPtr);
187  searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
188  return pDocPtr;
189 }
190 
192 {
193  OUString sCustomizedUIPath = getCustomizedUIPath();
194  char* cCustomizedUIPath = convertToCharPointer(sCustomizedUIPath);
195  for (auto const& aValue : sUIItemProperties)
196  {
197  char** pProperties = new char*[aUIPropertiesCount];
198  for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++)
199  {
200  int nIdx = int(aIndex);
201  sal_Int32 rPos = aIndex;
202  pProperties[nIdx] = new char[aUIItemIDLength];
203  pProperties[nIdx] = convertToCharPointer(aValue.getToken(rPos, ',', rPos));
204  }
205  xmlDocPtr doc;
206  doc = notebookbarXMLParser(cCustomizedUIPath, pProperties[0], pProperties[1],
207  pProperties[2]);
208 
209  for (int nIdx = 0; nIdx < aUIPropertiesCount; nIdx++)
210  {
211  delete[] pProperties[nIdx];
212  }
213  delete[] pProperties;
214 
215  if (doc != nullptr)
216  {
217  xmlSaveFormatFile(cCustomizedUIPath, doc, 1);
218  xmlFreeDoc(doc);
219  }
220  }
221  delete[] cCustomizedUIPath;
222 }
223 
225  OUString& sNotebookbarUIFileName)
226 {
227  const auto xContext = comphelper::getProcessComponentContext();
228  utl::OConfigurationTreeRoot aRoot(xContext, "org.openoffice.Office.UI.ToolbarMode/", false);
229  const Reference<frame::XFrame>& xFrame
231  const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create(xContext);
232 
234  = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
235  OUString sActiveAppName(lcl_activeAppName(eApp));
236  sAppName = lcl_getAppName(eApp);
237  const Any aValue = aRoot.getNodeValue(sActiveAppName);
238  aValue >>= sNotebookbarUIFileName;
239 }
240 
242 {
243  OUString sUserUIDir = getUIDirPath();
244  OUString sOriginalUIPath = getOriginalUIPath();
245  OUString sCustomizedUIPath = getCustomizedUIPath();
246 
247  sal_uInt32 nflag = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
248  osl::Directory aDirectory(sUserUIDir);
249  if (aDirectory.open() != osl::FileBase::E_None)
250  osl::Directory::create(sUserUIDir, nflag);
251  else
252  SAL_WARN("cui.customnotebookbar",
253  "Cannot create the directory or directory was present :" << sUserUIDir);
254 
255  osl::File aFile(sCustomizedUIPath);
256  if (aFile.open(nflag) != osl::FileBase::E_None)
257  osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
258  else
259  SAL_WARN("cui.customnotebookbar",
260  "Cannot copy the file or file was present :" << sCustomizedUIPath);
261 }
262 
264 {
265  OUStringBuffer aPath = getAppNameRegistryPath();
267  aPath.makeStringAndClear(), false);
268 
269  const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
270  const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
271  const Any aValue = aModeNode.getNodeValue("UIItemProperties");
272  Sequence<OUString> aValues;
273  aValue >>= aValues;
274  return aValues;
275 }
276 
278  OUString sNotebookbarConfigType)
279 {
280  OUStringBuffer aPath = getAppNameRegistryPath();
282  aPath.makeStringAndClear(), true);
283  const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
284  const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
285 
286  css::uno::Any aUIItemProperties(makeAny(sUIItemProperties));
287  aModeNode.setNodeValue("UIItemProperties", aUIItemProperties);
288  aAppNode.commit();
289 }
290 
291 /* 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 changeNodeValue(xmlNode *pNodePtr, char *pProperty, char *pValue)
static void modifyCustomizedUIFile(const Sequence< OUString > &sUIItemProperties)
Reference< XFrame > xFrame
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
static void searchNodeAndAttribute(xmlNode *pNodePtr, char *pUIItemID, char *pProperty, char *pValue)
static OUString customizedUIPathBuffer()
SfxFrame & GetFrame() const
static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
#define aUIItemIDLength
#define SAL_CONFIGFILE(name)
static OUString lcl_activeAppName(vcl::EnumContext::Application eApp)
static Application GetApplicationEnum(const OUString &rsApplicationName)
static OUString getUIRootDir()
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
static Sequence< OUString > getCustomizedUIItem(OUString sNotebookbarConfigType)
static xmlDocPtr notebookbarXMLParser(char *pDocName, char *pUIItemID, char *pProperty, char *pValue)
static OUString getAppNameRegistryPath()
static SfxViewFrame * Current()
static char * convertToCharPointer(const OUString &sString)
css::uno::Any getNodeValue(const OUString &_rPath) const
Reference< XComponentContext > getProcessComponentContext()
#define SAL_WARN(area, stream)
static void setCustomizedUIItem(Sequence< OUString > sUIItemProperties, OUString sNotebookbarConfigType)
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)