1 | /*************************************************************************** |
2 | * Copyright (C) 2007 by Kevin Krammer <kevin.krammer@gmx.at> * |
3 | * * |
4 | * This program is free software; you can redistribute it and/or modify * |
5 | * it under the terms of the GNU Library General Public License as * |
6 | * published by the Free Software Foundation; either version 2 of the * |
7 | * License, or (at your option) any later version. * |
8 | * * |
9 | * This program is distributed in the hope that it will be useful, * |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
12 | * GNU General Public License for more details. * |
13 | * * |
14 | * You should have received a copy of the GNU Library General Public * |
15 | * License along with this program; if not, write to the * |
16 | * Free Software Foundation, Inc., * |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
18 | ***************************************************************************/ |
19 | |
20 | #ifndef XDGBASEDIRS_H |
21 | #define XDGBASEDIRS_H |
22 | |
23 | // Qt includes |
24 | #include <QtCore/QFlags> |
25 | #include <QtCore/QStringList> |
26 | |
27 | #include "akonadiprotocolinternals_export.h" |
28 | |
29 | // forward declarations |
30 | class QString; |
31 | |
32 | namespace Akonadi { |
33 | |
34 | class XdgBaseDirsPrivate; |
35 | |
36 | /** |
37 | @brief Resource type based handling of standard directories |
38 | |
39 | Developers of several Free Software desktop projects have created |
40 | a specification for handling so-called "base directories", i.e. |
41 | lists of system wide directories and directories within each user's |
42 | home directory for installing and later finding certain files. |
43 | |
44 | This class handles the respective behaviour, i.e. environment variables |
45 | and their defaults, for the following type of resources: |
46 | - "config" |
47 | - "data" |
48 | |
49 | Example: getting the Akonadi server config file "akonadiserverrc", assuming |
50 | that Akonadi stores its config in an additional subdirectoy called "akonadi" |
51 | @code |
52 | QString relativeFileName = QLatin1String( "akonadi/akonadiserverrc" ); |
53 | |
54 | // look for the file "akonadiserverrc" with additional subdirectory "akonadi" |
55 | // in any directory associated with resource type "config" |
56 | QString configFile = XdgBaseDirs::findResourceFile( "config", relativeFileName ); |
57 | |
58 | if ( configFile.isEmpty() ) { |
59 | // No config file yet, get the suitable user specific directory for storing |
60 | // a new one |
61 | configFile = XdgBaseDirs::saveDir( "config", QLatin1String( "akonadi" ) ); |
62 | configFile += QLatin1String( "akonadiserverrc" ); |
63 | } |
64 | |
65 | QSettings serverConfig( configFile ); |
66 | @endcode |
67 | |
68 | @author Kevin Krammer, <kevin.krammer@gmx.at> |
69 | |
70 | @see http://www.freedesktop.org/wiki/Specifications/basedir-spec |
71 | */ |
72 | class AKONADIPROTOCOLINTERNALS_EXPORT XdgBaseDirs |
73 | { |
74 | public: |
75 | /** |
76 | @brief Creates the instance |
77 | */ |
78 | XdgBaseDirs(); |
79 | |
80 | /** |
81 | @brief Destroys the instance |
82 | */ |
83 | ~XdgBaseDirs(); |
84 | |
85 | /** |
86 | @brief Returns the user specific directory for the given resource type |
87 | |
88 | Unless the user's environment has a specific path set as an override |
89 | this will be the default as defined in the freedesktop.org base-dir-spec |
90 | |
91 | @note Caches the value of the first call |
92 | |
93 | @param resource a named resource type, e.g. "config" |
94 | |
95 | @return a directory path |
96 | |
97 | @see systemPathList() |
98 | @see saveDir() |
99 | */ |
100 | static QString homePath(const char *resource); |
101 | |
102 | /** |
103 | @brief Returns the list of system wide directories for a given resource type |
104 | |
105 | The returned list can contain one or more directory paths. If there are more |
106 | than one, the list is sorted by falling priority, i.e. if an entry is valid |
107 | for the respective use case (e.g. contains a file the application looks for) |
108 | the list should not be processed further. |
109 | |
110 | @note The user's resource path should, to be compliant with the spec, |
111 | always be treated as having higher priority than any path in the |
112 | list of system wide paths |
113 | |
114 | @note Caches the value of the first call |
115 | |
116 | @param resource a named resource type, e.g. "config" |
117 | |
118 | @return a priority sorted list of directory paths |
119 | |
120 | @see homePath() |
121 | */ |
122 | static QStringList systemPathList(const char *resource); |
123 | |
124 | /** |
125 | @brief Searches the resource specific directories for a given file |
126 | |
127 | Convenience method for finding a given file (with optional relative path) |
128 | in any of the configured base directories for a given resource type. |
129 | |
130 | Will check the user local directory first and then process the system |
131 | wide path list according to the inherent priority. |
132 | |
133 | @param resource a named resource type, e.g. "config" |
134 | @param relPath relative path of a file to look for, |
135 | e.g."akonadi/akonadiserverrc" |
136 | |
137 | @returns the file path of the first match, or @c QString() if no such |
138 | relative path exists in any of the base directories or if |
139 | a match is not a file |
140 | |
141 | @see findResourceDir() |
142 | @see saveDir |
143 | */ |
144 | static QString findResourceFile(const char *resource, const QString &relPath); |
145 | |
146 | /** |
147 | @brief Searches the executable specific directories for a given file |
148 | |
149 | Convenience method for finding a given executable (with optional relative path) |
150 | in any of the configured directories for a this special type. |
151 | |
152 | @note This is not based on the XDG base dir spec, since it does not cover |
153 | executable |
154 | |
155 | @param relPath relative path of a file to look for, |
156 | e.g."akonadiserver" |
157 | @param searchPath additional paths to search for the executable, |
158 | only used if the file was not found in PATH and the install prefix |
159 | |
160 | @returns the file path of the first match, or @c QString() if no such |
161 | relative path exists in any of the base directories |
162 | |
163 | @see findResourceFile() |
164 | */ |
165 | static QString findExecutableFile(const QString &relPath, const QStringList &searchPath = QStringList()); |
166 | |
167 | /** |
168 | @brief Searches the plugin specific directories for a given file |
169 | |
170 | Convenience method for finding a given plugin (with optional relative path) |
171 | in any of the configured directories for a this special type. |
172 | |
173 | @note This is not based on the XDG base dir spec, since it does not cover |
174 | plugins |
175 | |
176 | @param relPath relative path of a file to look for, |
177 | e.g."akonadi_knut_resource" |
178 | @param searchPath additional paths to search for the plugin, |
179 | only used if the file was not found in QT_PLUGIN_PATH and the install prefix |
180 | |
181 | @returns the file path of the first match, or @c QString() if no such |
182 | relative path exists in any of the base directories |
183 | |
184 | @see findResourceFile() |
185 | */ |
186 | static QString findPluginFile(const QString &relPath, const QStringList &searchPath = QStringList()); |
187 | |
188 | /** |
189 | @brief Returns plugin specific directories |
190 | |
191 | Convenience method for listing directories that can be scanned for available |
192 | plugins. |
193 | |
194 | @note This is not based on the XDG base dir spec, since it does not cover |
195 | plugins. |
196 | |
197 | @return directories where application should look for plugins |
198 | */ |
199 | static QStringList findPluginDirs(); |
200 | |
201 | /** |
202 | @brief Searches the resource specific directories for a given subdirectory |
203 | |
204 | Convenience method for finding a given relative subdirectory in any of |
205 | the configured base directories for a given resource type. |
206 | |
207 | Will check the user local directory first and then process the system |
208 | wide path list according to the inherent priority. |
209 | |
210 | Use findAllResourceDirs() if looking for all directories with the given |
211 | subdirectory. |
212 | |
213 | @param resource a named resource type, e.g. "config" |
214 | @param relPath relative path of a subdirectory to look for, |
215 | e.g."akonadi/agents" |
216 | |
217 | @returns the directory path of the first match, or @c QString() if no such |
218 | relative path exists in any of the base directories or if |
219 | a match is not a directory |
220 | |
221 | @see findResourceFile() |
222 | @see saveDir() |
223 | */ |
224 | static QString findResourceDir(const char *resource, const QString &relPath); |
225 | |
226 | /** |
227 | @brief Searches the resource specific directories for a given subdirectory |
228 | |
229 | Convenience method for getting a list of directoreis with a given relative |
230 | subdirectory in any of the configured base directories for a given |
231 | resource type. |
232 | |
233 | Will check the user local directory first and then process the system |
234 | wide path list according to the inherent priority. |
235 | |
236 | Similar to findResourceDir() but does not just find the first best match |
237 | but all matching resource directories. The resuling list will be sorted |
238 | according to the same proprity criteria. |
239 | |
240 | @param resource a named resource type, e.g. "config" |
241 | @param relPath relative path of a subdirectory to look for, |
242 | e.g."akonadi/agents" |
243 | |
244 | @returns a list of directory paths, or @c QString() if no such |
245 | relative path exists in any of the base directories or if |
246 | non of the matches is a directory |
247 | |
248 | @see findResourceDir() |
249 | */ |
250 | static QStringList findAllResourceDirs(const char *resource, const QString &relPath); |
251 | |
252 | /** |
253 | @brief Finds or creates the "save to" directory for a given resource |
254 | |
255 | Convenience method for creating subdirectores relative to a given |
256 | resource type's user directory, i.e. homePath() + relPath |
257 | |
258 | If the target directory does not exists, it an all necessary parent |
259 | directories will be created, unless denied by the filesystem. |
260 | |
261 | @param resource a named resource type, e.g. "config" |
262 | @param relPath relative path of a directory to be used for file writing |
263 | |
264 | @return the directory path of the "save to" directory or @c QString() |
265 | if the directory or one of its parents could not be created |
266 | |
267 | @see findResourceDir() |
268 | */ |
269 | static QString saveDir(const char *resource, const QString &relPath); |
270 | |
271 | /** |
272 | * @brief Open mode flags for resource files |
273 | * |
274 | * FileAccessMode is a typedef for QFlags<FileAccessFlag>. It stores |
275 | * a OR combination of FileAccessFlag values |
276 | */ |
277 | enum FileAccessFlag { |
278 | ReadOnly = 0x1, |
279 | WriteOnly = 0x2, |
280 | ReadWrite = ReadOnly | WriteOnly |
281 | }; |
282 | |
283 | typedef QFlags<FileAccessFlag> FileAccessMode; |
284 | |
285 | /** |
286 | * @brief Returns the path of the Akonadi server config file |
287 | * |
288 | * Convenience method for getting the server config file "akonadiserverrc" |
289 | * since this is an often needed procedure in several parts of the code. |
290 | * |
291 | * @param openMode how the application wants to use the config file |
292 | * |
293 | * @return the path of the server config file, suitable for \p openMode |
294 | */ |
295 | static QString akonadiServerConfigFile(FileAccessMode openMode = ReadOnly); |
296 | |
297 | /** |
298 | * @brief Returns the path of the Akonadi data connection config file |
299 | * |
300 | * Convenience method for getting the server config file "akonadiconnectionrc" |
301 | * since this is an often needed procedure in several parts of the code. |
302 | * |
303 | * @param openMode how the application wants to use the config file |
304 | * |
305 | * @return the path of the data connection config file, suitable for \p openMode |
306 | */ |
307 | static QString akonadiConnectionConfigFile(FileAccessMode openMode = ReadOnly); |
308 | |
309 | private: |
310 | XdgBaseDirsPrivate *const d; |
311 | |
312 | private: |
313 | static QString akonadiConfigFile(const QString &file, FileAccessMode openMode); |
314 | |
315 | private: |
316 | XdgBaseDirs(const XdgBaseDirs &); |
317 | XdgBaseDirs &operator=(const XdgBaseDirs &); |
318 | }; |
319 | |
320 | } |
321 | |
322 | #endif |
323 | |