CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxDataLocations.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 #include "cxDataLocations.h"
12 
13 #include <iostream>
14 #include <QApplication>
15 #include <QDir>
16 #include "cxConfig.h"
17 #include "cxSettings.h"
18 #include "cxFileHelpers.h"
19 #include "cxTypeConversions.h"
20 #include "cxReporter.h"
21 #include "cxProfile.h"
22 
23 namespace cx
24 {
25 
26 //---------------------------------------------------------
27 bool DataLocations::mTestMode = false;
28 bool DataLocations::mRunFromBuildFolder = false;
29 bool DataLocations::mBuildFolderChecked = false;
30 QString DataLocations::mWebsiteUrl = "";
31 //---------------------------------------------------------
32 
34 {
35  mTestMode = true;
38 }
39 
41 {
42  return mTestMode;
43 }
44 
46 {
47  QString settingsPath = cx::DataLocations::getRootConfigPath() + "/settings";
48  QString dataRootConfigFile = settingsPath + "/data_root_location.txt";
49  if (QFileInfo(dataRootConfigFile).exists())
50  {
51  return readTestDataPathFromFile(dataRootConfigFile);
52  }
53  else
54  {
55  return CX_DATA_ROOT;
56  }
57 }
58 
60 {
61  QString settingsPath = cx::DataLocations::getRootConfigPath() + "/settings";
62  QString dataRootConfigFile = settingsPath + "/large_data_root_location.txt";
63  if (QFileInfo(dataRootConfigFile).exists())
64  {
65  return readTestDataPathFromFile(dataRootConfigFile);
66  }
67  else
68  {
69  return CX_LARGE_DATA_ROOT;
70  }
71 }
72 
73 QString DataLocations::getExistingTestData(QString pathRelativeToTestDataRoot, QString filename)
74 {
75  QString path;
76 
77  path = QString("%1/%2/%3").arg(getTestDataPath()).arg(pathRelativeToTestDataRoot).arg(filename);
78  if (QFileInfo(path).exists())
79  return path;
80 
81  path = QString("%1/%2/%3").arg(getLargeTestDataPath()).arg(pathRelativeToTestDataRoot).arg(filename);
82  if (QFileInfo(path).exists())
83  return path;
84 
85  return "";
86 }
87 
88 QString DataLocations::readTestDataPathFromFile(QString filename)
89 {
90  QFile file(filename);
91  file.open(QFile::ReadOnly);
92  QString cxDataRoot(file.readAll());
93  return cxDataRoot;
94 }
95 
97 {
98  QString homepath = QDir::homePath() + "/" + CX_SYSTEM_BASE_NAME + "_settings";
99 
100  if (mTestMode)
101  homepath = homepath + "/temp";
102 
103  return homepath;
104 }
105 
107 {
108  QString pathToDelete = DataLocations::getPersistentWritablePath();
109  QDir dir(pathToDelete);
110  CX_LOG_INFO() << "Going to delete:" << dir.absolutePath();
111  dir.removeRecursively();
112 }
113 
114 
116 {
117  // This method is becoming problematic (2015-11-30/CA):
118  // the APPLE case returns path to folder enclosing the bundle
119  // while the LINUX/WIN case returns path to bin folder.
120  // This is not symmetric - it should be. Try to migrate away from this
121  // method, using applicationDirPath instead, and remove it.
122  //
123 #ifdef __APPLE__
124  QString path(qApp->applicationDirPath()+"/../../..");
125  QString bundle = QDir(qApp->applicationDirPath()+"/../..").canonicalPath();
126  if (QFileInfo(bundle).isBundle())
127  return QDir(path).canonicalPath();
128  else
129  return qApp->applicationDirPath();
130 #else
131  QString path(qApp->applicationDirPath());
132  return path;
133 #endif
134 }
135 
137 {
138  QStringList retval;
139 
140  if(!isRunFromBuildFolder())
141  {
142  QString appPath(qApp->applicationDirPath());
143 
144  QString installLocation = appPath;
145 #ifndef CX_WINDOWS
146  installLocation = appPath + "/plugins";
147 #endif
148  if (QFile(installLocation).exists())
149  retval << installLocation;
150 
151  QString fallbackInstallLocation = appPath;
152  if (QFile(fallbackInstallLocation).exists())
153  retval << fallbackInstallLocation; }
154  else
155  {
156  QString bundlePath = DataLocations::getBundlePath();
157 
158  QString buildLocation = bundlePath;
159 #ifndef CX_WINDOWS
160  buildLocation = bundlePath + "/plugins";
161 #endif
162  if (QFile(buildLocation).exists())
163  retval << buildLocation;
164  }
165 
166  return retval;
167 }
168 
170 {
171  QStringList paths = getRootConfigPaths();
172  if (paths.empty())
173  return "";
174  // Those who ask for a single (legacy) config path need
175  // the default CX path, not the override.
176  return paths.back();
177 }
178 
180 {
181  if(!isRunFromBuildFolder())
182  {
183  // look for installed location
184  QString path = QString("%1/%2").arg(qApp->applicationDirPath()).arg(CX_CONFIG_ROOT_RELATIVE_INSTALLED);
185  if (QDir(path).exists())
186  return QStringList() << QDir(path).canonicalPath();
187  else
188  {
189  std::cout << "DataLocations::getRootConfigPaths(): Cannot find config root path: " << path << std::endl;
190  return QStringList();
191  }
192  }
193 
194  // add folders with the most important first: If the same file exists in both locations,
195  // the first should be prefered.
196  QStringList retval;
197  if (QDir(CX_OPTIONAL_CONFIG_ROOT).exists()) // look for override folder in source code
198  retval << QDir(CX_OPTIONAL_CONFIG_ROOT).canonicalPath();
199  if (QDir(CX_CONFIG_ROOT).exists()) // look for default folder in source code
200  retval << QDir(CX_CONFIG_ROOT).canonicalPath();
201 
202  return retval;
203 }
204 
206 {
207  if(!isRunFromBuildFolder())
208  {
209  QString path = QString("%1/%2").arg(qApp->applicationDirPath()).arg(CX_DOC_ROOT_RELATIVE_INSTALLED);
210  // QString path = getBundlePath() + "/" + CX_DOC_ROOT_RELATIVE_INSTALLED; // look for installed location
211  if (QDir(path).exists())
212  return QDir(path).canonicalPath();
213  else
214  {
215  CX_LOG_ERROR() << QString("Cannot find doc path: ") << path;
216  return "";
217  }
218  }
219 
220  if (QDir(CX_DOC_ROOT).exists()) // look for folder in source code
221  return QDir(CX_DOC_ROOT).canonicalPath();
222  else
223  {
224  CX_LOG_ERROR() << QString("Cannot find doc path: ") << CX_DOC_ROOT;
225  return "";
226  }
227 }
228 
229 QStringList DataLocations::appendStringToAllElements(QStringList root, QString suffix)
230 {
231  QStringList retval;
232  for (int i=0; i<root.size(); ++i)
233  retval << root[i] + suffix;
234  return retval;
235 }
236 
237 namespace
238 {
239 QString changeExtension(QString name, QString ext)
240 {
241  QStringList splitName = name.split(".");
242  splitName[splitName.size()-1] = ext;
243  return splitName.join(".");
244 }
245 } //namespace
246 
248 {
249  QString path(getPersistentWritablePath()+"/cache");
250  return path;
251 }
252 
253 QString DataLocations::findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath)
254 {
255  return findConfigPath("", pathRelativeToConfigRoot, alternativeAbsolutePath);
256 }
257 
258 QString DataLocations::findConfigPath(QString fileName, QString pathRelativeToConfigRoot, QString alternativeAbsolutePath)
259 {
260  QFileInfo filePath(findConfigFilePath(fileName, pathRelativeToConfigRoot, alternativeAbsolutePath));
261  return filePath.absolutePath() + "/";
262 }
263 
264 QString DataLocations::findConfigFilePath(QString fileName, QString pathRelativeToConfigRoot, QString alternativeAbsolutePath)
265 {
266  QStringList paths;
267  foreach (QString root, getRootConfigPaths())
268  {
269  QString path = root + "/" + pathRelativeToConfigRoot + "/" + fileName;
270  paths << path;
271  if (QFileInfo(path).exists())
272  return path;
273  }
274 
275  QString path = QString(alternativeAbsolutePath + "/" + fileName);
276  paths << path;
277  if (QFileInfo(path).exists())
278  return path;
279 
280  reportWarning("DataLocations::findConfigFile. Error: Can't find " + fileName + " in any of\n" + paths.join(" \n"));
281  return "";
282 }
283 
284 QString DataLocations::checkExecutableExist(QString path, QString filename)
285 {
286  QStringList retval;
287  path = QDir::cleanPath(path);
288  if (QDir(path).exists(filename))
289  return QDir(DataLocations::getBundlePath()).absoluteFilePath(path + "/" + filename);
290  return "";
291 }
292 
294 {
295  QString result;
296  //#ifdef __APPLE__
297  // // run from installed folder on mac
298  // result = DataLocations::checkExecutableExist(qApp->applicationDirPath(), filename);
299  // if (!result.isEmpty())
300  // return result;
301  //#endif
302  // run from installed or build bin folder
303  result = DataLocations::checkExecutableExist(qApp->applicationDirPath(), filename);
304  if (!result.isEmpty())
305  return result;
306 
307  return result;
308 }
309 
310 void DataLocations::setWebsiteURL(QString websiteUrl)
311 {
312  mWebsiteUrl = websiteUrl;
313 }
314 
316 {
317  return mWebsiteUrl;
318 }
319 
321 {
322  return QString("http://custusx.org/uploads");
323 }
324 
326 {
327  QString version(CustusX_VERSION_STRING);
328  if (version.contains("dev"))
329  version = "nightly";
330  QString url = QString("%1/user_doc/%2")
332  .arg(version);
333  return url;
334 }
335 
337 {
338  if(!mBuildFolderChecked)
339  {
340  QString bundlePath = DataLocations::getBundlePath();
341 
342  //Check if cxConfig.h file exists relative to the run application
343  QString pathToConfigFile = bundlePath + "/../source/resource/core/settings/cxConfig.h";
344  if (QFile(pathToConfigFile).exists())
345  {
346  std::cout << "Using paths from build folder" << std::endl;
347  mRunFromBuildFolder = true;
348  }
349  else
350  mRunFromBuildFolder = false;
351  mBuildFolderChecked = true;
352  }
353 
354  return mRunFromBuildFolder;
355 }
356 
357 } // namespace cx
static QString getExistingTestData(QString pathRelativeToTestDataRoot, QString filename="")
Return full path to test data, both normal and large repositories are searched.
bool removeNonemptyDirRecursively(const QString &dirName)
#define CX_LOG_INFO
Definition: cxLogger.h:96
static QString findConfigPath(QString fileName, QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
static bool isRunFromBuildFolder()
static QString getWebsiteUserDocumentationURL()
static QString getLargeTestDataPath()
return path to test data folder containing large data sets
static QStringList getRootConfigPaths()
static void setWebsiteURL(QString websiteUrl)
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
static QString getCachePath()
return path to a folder that is used during execution, will be cleared at start and stop...
#define CX_LOG_ERROR
Definition: cxLogger.h:99
static QString getWebsiteURL()
static QString findConfigFilePath(QString fileName, QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
static QString getTestDataPath()
return path to test data folder
static QString getPersistentWritablePath()
Path to location usable for persistent and temporary storage of config. Do not use directly...
static bool isTestMode()
static QStringList getDefaultPluginsPath()
return the folder where plugins should be located, by default.
static QString getRootConfigPath()
return path to root config folder. May be replaced with getExistingConfigPath()
QString changeExtension(QString name, QString ext)
static QString findExecutableInStandardLocations(QString filename)
look for an exe in the same folder as the executable or bundle.
static QStringList appendStringToAllElements(QStringList root, QString suffix)
static void setTestMode()
set a testing mode that changes location of settings files to a temp folder.
static void deletePersistentWritablePath()
Deletes the folder called *_settings.
static QString getDocPath()
return path to folder containing documentation files
static QString getBundlePath()
return the folder where the bundle or executable are located.
static QString getUploadsUrl()
Namespace for all CustusX production code.