1 /*
2 * %kadu copyright begin%
3 * Copyright 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
4 * %kadu copyright end%
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <QtCore/QCoreApplication>
21 #include <QtCore/QDir>
22 #include <QtCore/QFile>
23 #include <QtCore/QFileInfo>
24
25 #ifdef Q_OS_WIN
26 #include <shlobj.h>
27 #include <windows.h>
28 #endif
29
30 #include "kadu-config.h"
31
32 #include "paths-provider.h"
33
homePath()34 QString PathsProvider::homePath()
35 {
36 #ifdef Q_OS_WIN
37 wchar_t homepath[MAX_PATH];
38
39 // There is unfortunately no way to get this path using Qt4 API.
40 if (SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, homepath)))
41 return QDir(QString::fromWCharArray(homepath)).canonicalPath();
42 #endif
43
44 return QDir::homePath();
45 }
46
webKitPath(const QString & path)47 QString PathsProvider::webKitPath(const QString &path)
48 {
49 if (path.isEmpty())
50 return path;
51 if (path.startsWith(QStringLiteral("file:///")))
52 return path;
53 if (path.startsWith('/'))
54 return "file://" + path;
55 return "file:///" + path;
56 }
57
PathsProvider(const QString & customProfileDir,QObject * parent)58 PathsProvider::PathsProvider(const QString &customProfileDir, QObject *parent) :
59 QObject{parent}
60 {
61 initBasicPaths();
62 initProfilePath(customProfileDir);
63 }
64
~PathsProvider()65 PathsProvider::~PathsProvider()
66 {
67 }
68
initBasicPaths()69 void PathsProvider::initBasicPaths()
70 {
71 #if defined(Q_OS_UNIX)
72 DesktopFilePath = QCoreApplication::applicationDirPath() + QStringLiteral("/" KADU_DESKTOP_FILE_PATH_RELATIVE_TO_BIN);
73 DesktopFilePath = QFileInfo(DesktopFilePath).canonicalFilePath();
74 #endif
75
76 DataPath = QCoreApplication::applicationDirPath() + QStringLiteral("/" KADU_DATADIR_RELATIVE_TO_BIN);
77 QString canonicalPath = QDir(DataPath).canonicalPath();
78 if (!canonicalPath.isEmpty())
79 DataPath = canonicalPath + '/';
80
81 PluginsLibPath = QCoreApplication::applicationDirPath() + QStringLiteral("/" KADU_PLUGINS_LIBDIR_RELATIVE_TO_BIN);
82 canonicalPath = QDir(PluginsLibPath).canonicalPath();
83 if (!canonicalPath.isEmpty())
84 PluginsLibPath = canonicalPath + '/';
85 }
86
initProfilePath(const QString & customProfileDir)87 void PathsProvider::initProfilePath(const QString &customProfileDir)
88 {
89 #if defined(Q_OS_WIN)
90 const QString defaultConfigDirRelativeToHome = QStringLiteral("Kadu");
91 const QString &oldMidConfigDir = defaultConfigDirRelativeToHome;
92 #else
93 const QString defaultConfigDirRelativeToHome = QStringLiteral(".kadu");
94 const QString oldMidConfigDir = QStringLiteral("kadu");
95 #endif
96
97 if (customProfileDir.isEmpty())
98 {
99 if (QFileInfo(dataPath() + QStringLiteral("portable")).exists())
100 ProfilePath = dataPath() + QStringLiteral("config");
101 else
102 ProfilePath = homePath() + '/' + defaultConfigDirRelativeToHome;
103 }
104 else
105 {
106 if (customProfileDir.startsWith(QStringLiteral("./"))
107 #ifdef Q_OS_WIN
108 || customProfileDir.startsWith(QStringLiteral(".\\"))
109 #endif
110 )
111 ProfilePath = QDir::currentPath() + '/' + customProfileDir;
112 else if (QDir(customProfileDir).isAbsolute())
113 ProfilePath = customProfileDir;
114 else if (QFileInfo(dataPath() + QStringLiteral("portable")).exists())
115 ProfilePath = dataPath() + customProfileDir;
116 else
117 ProfilePath = homePath() + '/' + customProfileDir;
118
119 // compatibility with 0.6.5 and older versions
120 if (QDir(ProfilePath + '/' + oldMidConfigDir).exists())
121 ProfilePath += '/' + oldMidConfigDir;
122 }
123
124 // Do not cache QDir objects here unless you know what you are doing and
125 // you have tested your changes thoroughly under Windows. Using official
126 // Qt 4.8.1 MSVC 2010 build QDir thinks the dir does not exist if initially
127 // it did not exist, even though we successfully call QDir::mkpath(). Hence
128 // QDir::canonicalPath() returs empty string.
129 if (!QDir(ProfilePath).exists())
130 {
131 QDir().mkpath(ProfilePath);
132 // This equals to 0700 on Unix-like.
133 QFile(ProfilePath).setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | QFile::ReadUser | QFile::WriteUser | QFile::ExeUser);
134 }
135
136 QString canonicalPath = QDir(ProfilePath).canonicalPath();
137 if (!canonicalPath.isEmpty())
138 ProfilePath = canonicalPath;
139 if (!ProfilePath.isEmpty() && !ProfilePath.endsWith(QStringLiteral("/")))
140 ProfilePath += '/';
141 }
142