1 | /****************************************************************************** |
2 | * Copyright 2007 by Aaron Seigo <aseigo@kde.org> * |
3 | * * |
4 | * This library is free software; you can redistribute it and/or * |
5 | * modify it under the terms of the GNU Library General Public * |
6 | * License as published by the Free Software Foundation; either * |
7 | * version 2 of the License, or (at your option) any later version. * |
8 | * * |
9 | * This library 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 GNU * |
12 | * Library General Public License for more details. * |
13 | * * |
14 | * You should have received a copy of the GNU Library General Public License * |
15 | * along with this library; see the file COPYING.LIB. If not, write to * |
16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * |
17 | * Boston, MA 02110-1301, USA. * |
18 | *******************************************************************************/ |
19 | |
20 | #ifndef PLASMA_PACKAGESTRUCTURE_H |
21 | #define PLASMA_PACKAGESTRUCTURE_H |
22 | |
23 | #include <QtCore/QStringList> |
24 | #include <QtCore/QSharedData> |
25 | |
26 | #include <kgenericfactory.h> |
27 | #include <klocale.h> |
28 | #include <ksharedptr.h> |
29 | |
30 | #include <plasma/version.h> |
31 | #include "packagemetadata.h" |
32 | |
33 | class KConfigBase; |
34 | |
35 | namespace Plasma |
36 | { |
37 | |
38 | class PackageStructurePrivate; |
39 | |
40 | /** |
41 | * @class PackageStructure plasma/packagestructure.h <Plasma/PackageStructure> |
42 | * |
43 | * @short A description of the expected file structure of a given package type |
44 | * |
45 | * PackageStructure defines what is in a package. This information is used |
46 | * to create packages and provides a way to programatically refer to contents. |
47 | * |
48 | * An example usage of this class might be: |
49 | * |
50 | @code |
51 | PackageStructure structure; |
52 | |
53 | structure.addDirectoryDefinition("images", "pics/", i18n("Images")); |
54 | QStringList mimetypes; |
55 | mimetypes << "image/svg" << "image/png" << "image/jpeg"; |
56 | structure.setMimetypes("images", mimetypes); |
57 | |
58 | structure.addDirectoryDefinition("scripts", "code/", i18n("Executable Scripts")); |
59 | mimetypes.clear(); |
60 | mimetypes << "text/\*"; |
61 | structure.setMimetypes("scripts", mimetypes); |
62 | |
63 | structure.addFileDefinition("mainscript", "code/main.js", i18n("Main Script File")); |
64 | structure.setRequired("mainscript", true); |
65 | @endcode |
66 | * One may also choose to create a subclass of PackageStructure and include the setup |
67 | * in the constructor. |
68 | * |
69 | * Either way, PackageStructure creates a sort of "contract" between the packager and |
70 | * the application which is also self-documenting. |
71 | **/ |
72 | class PLASMA_EXPORT PackageStructure : public QObject, public QSharedData |
73 | { |
74 | Q_OBJECT |
75 | |
76 | public: |
77 | typedef KSharedPtr<PackageStructure> Ptr; |
78 | |
79 | /** |
80 | * Default constructor for a package structure definition |
81 | * |
82 | * @param type the type of package. This is often application specific. |
83 | **/ |
84 | explicit PackageStructure(QObject *parent = 0, |
85 | const QString &type = i18nc("A non-functional package" , "Invalid" )); |
86 | |
87 | /** |
88 | * Destructor |
89 | **/ |
90 | virtual ~PackageStructure(); |
91 | |
92 | /** |
93 | * Assignment operator |
94 | **/ |
95 | PackageStructure &operator=(const PackageStructure &rhs); |
96 | |
97 | /** |
98 | * Loads a package format by name. |
99 | * |
100 | * @param format If not empty, attempts to locate the given format, either |
101 | * from built-ins or via plugins. |
102 | * @return a package that matches the format, if available. The caller |
103 | * is responsible for deleting the object. |
104 | */ |
105 | static PackageStructure::Ptr load(const QString &packageFormat); |
106 | |
107 | /** |
108 | * Type of package this structure describes |
109 | **/ |
110 | QString type() const; |
111 | |
112 | /** |
113 | * The directories defined for this package |
114 | **/ |
115 | QList<const char*> directories() const; |
116 | |
117 | /** |
118 | * The required directories defined for this package |
119 | **/ |
120 | QList<const char*> requiredDirectories() const; |
121 | |
122 | /** |
123 | * The individual files, by key, that are defined for this package |
124 | **/ |
125 | QList<const char*> files() const; |
126 | |
127 | /** |
128 | * The individual required files, by key, that are defined for this package |
129 | **/ |
130 | QList<const char*> requiredFiles() const; |
131 | |
132 | /** |
133 | * Adds a directory to the structure of the package. It is added as |
134 | * a not-required element with no associated mimetypes. |
135 | * |
136 | * Starting in 4.6, if an entry with the given key |
137 | * already exists, the path is added to it as a search alternative. |
138 | * |
139 | * @param key used as an internal label for this directory |
140 | * @param path the path within the package for this directory |
141 | * @param name the user visible (translated) name for the directory |
142 | **/ |
143 | void addDirectoryDefinition(const char *key, const QString &path, const QString &name); |
144 | |
145 | /** |
146 | * Adds a file to the structure of the package. It is added as |
147 | * a not-required element with no associated mimetypes. |
148 | * |
149 | * Starting in 4.6, if an entry with the given key |
150 | * already exists, the path is added to it as a search alternative. |
151 | * |
152 | * @param key used as an internal label for this file |
153 | * @param path the path within the package for this file |
154 | * @param name the user visible (translated) name for the file |
155 | **/ |
156 | void addFileDefinition(const char *key, const QString &path, const QString &name); |
157 | |
158 | /** |
159 | * Removes a definition from the structure of the package. |
160 | * @since 4.6 |
161 | * @param key the internal label of the file or directory to remove |
162 | */ |
163 | void removeDefinition(const char *key); |
164 | |
165 | /** |
166 | * @return path relative to the package root for the given entry |
167 | * @deprecatd use searchPaths instead |
168 | **/ |
169 | QString path(const char *key) const; |
170 | |
171 | /** |
172 | * @return a list of paths relative to the package root for the given entry. |
173 | * They are orted by importance: when searching for a file the paths |
174 | * will be searched in order |
175 | * @since 4.6 |
176 | **/ |
177 | QStringList searchPath(const char *key) const; |
178 | |
179 | /** |
180 | * Get the list of files of a given type. |
181 | * |
182 | * @param key the type of file to look for |
183 | * @return list of files by name |
184 | * @since 4.3 |
185 | */ |
186 | QStringList entryList(const char *key); |
187 | |
188 | /** |
189 | * @return user visible name for the given entry |
190 | **/ |
191 | QString name(const char *key) const; |
192 | |
193 | /** |
194 | * Sets whether or not a given part of the structure is required or not. |
195 | * The path must already have been added using addDirectoryDefinition |
196 | * or addFileDefinition. |
197 | * |
198 | * @param key the entry within the package |
199 | * @param required true if this entry is required, false if not |
200 | */ |
201 | void setRequired(const char *key, bool required); |
202 | |
203 | /** |
204 | * @return true if the item at path exists and is required |
205 | **/ |
206 | bool isRequired(const char *key) const; |
207 | |
208 | /** |
209 | * Defines the default mimetypes for any definitions that do not have |
210 | * associated mimetypes. Handy for packages with only one or predominantly |
211 | * one file type. |
212 | * |
213 | * @param mimetypes a list of mimetypes |
214 | **/ |
215 | void setDefaultMimetypes(QStringList mimetypes); |
216 | |
217 | /** |
218 | * Define mimetypes for a given part of the structure |
219 | * The path must already have been added using addDirectoryDefinition |
220 | * or addFileDefinition. |
221 | * |
222 | * @param key the entry within the package |
223 | * @param mimetypes a list of mimetypes |
224 | **/ |
225 | void setMimetypes(const char *key, QStringList mimetypes); |
226 | |
227 | /** |
228 | * @return the mimetypes associated with the path, if any |
229 | **/ |
230 | QStringList mimetypes(const char *key) const; |
231 | |
232 | /** |
233 | * Sets the path to the package. Useful for package formats |
234 | * which do not have well defined contents prior to installation. |
235 | */ |
236 | void setPath(const QString &path); |
237 | |
238 | /** |
239 | * @return the path to the package, or QString() if none |
240 | */ |
241 | QString path() const; |
242 | |
243 | /** |
244 | * Read a package structure from a config file. |
245 | */ |
246 | void read(const KConfigBase *config); |
247 | |
248 | /** |
249 | * Write this package structure to a config file. |
250 | */ |
251 | void write(KConfigBase *config) const; |
252 | |
253 | /** |
254 | * Installs a package matching this package structure. By default installs a |
255 | * native Plasma::Package. |
256 | * |
257 | * @param archivePath path to the package archive file |
258 | * @param packageRoot path to the directory where the package should be |
259 | * installed to |
260 | * @return true on successful installation, false otherwise |
261 | **/ |
262 | virtual bool installPackage(const QString &archivePath, const QString &packageRoot); |
263 | |
264 | /** |
265 | * Uninstalls a package matching this package structure. |
266 | * |
267 | * @param packageName the name of the package to remove |
268 | * @param packageRoot path to the directory where the package should be installed to |
269 | * @return true on successful removal of the package, false otherwise |
270 | */ |
271 | virtual bool uninstallPackage(const QString &packageName, const QString &packageRoot); |
272 | |
273 | /** |
274 | * When called, the package plugin should display a window to the user |
275 | * that they can use to browser, select and then install widgets supported by |
276 | * this package plugin with. |
277 | * |
278 | * The user interface may be an in-process dialog or an out-of-process application. |
279 | * |
280 | * When the process is complete, the newWidgetBrowserFinished() signal must be |
281 | * emitted. |
282 | * |
283 | * @param parent the parent widget to use for the widget |
284 | */ |
285 | virtual void createNewWidgetBrowser(QWidget *parent = 0); |
286 | |
287 | /** |
288 | * @return the prefix inserted between the base path and content entries |
289 | * @deprecated use contentsPrefixPaths() instead. |
290 | */ |
291 | KDE_DEPRECATED QString contentsPrefix() const; |
292 | |
293 | /** |
294 | * @return the prefix paths inserted between the base path and content entries, in order of priority. |
295 | * When searching for a file, all paths will be tried in order. |
296 | * @since 4.6 |
297 | */ |
298 | QStringList contentsPrefixPaths() const; |
299 | |
300 | /** |
301 | * @return preferred package root. This defaults to plasma/plasmoids/ |
302 | */ |
303 | QString defaultPackageRoot() const; |
304 | |
305 | /** |
306 | * @return service prefix used in desktop files. This defaults to plasma-applet- |
307 | */ |
308 | QString servicePrefix() const; |
309 | |
310 | /** |
311 | * Sets service prefix. |
312 | */ |
313 | void setServicePrefix(const QString &servicePrefix); |
314 | |
315 | /** |
316 | * @return the package metadata object. |
317 | */ |
318 | virtual PackageMetadata metadata(); |
319 | |
320 | /** |
321 | * @return true if paths/symlinks outside the package itself should be followed. |
322 | * By default this is set to false for security reasons. |
323 | */ |
324 | bool allowExternalPaths() const; |
325 | |
326 | Q_SIGNALS: |
327 | /** |
328 | * Emitted when the new widget browser process completes. |
329 | */ |
330 | void newWidgetBrowserFinished(); |
331 | |
332 | protected: |
333 | /** |
334 | * Sets whether or not external paths/symlinks can be followed by a package |
335 | * @param allow true if paths/symlinks outside of the package should be followed, |
336 | * false if they should be rejected. |
337 | */ |
338 | void setAllowExternalPaths(bool allow); |
339 | |
340 | /** |
341 | * Sets the prefix that all the contents in this package should |
342 | * appear under. This defaults to "contents/" and is added automatically |
343 | * between the base path and the entries as defined by the package |
344 | * structure |
345 | * |
346 | * @param prefix the directory prefix to use |
347 | * @deprecated use setContentsPrefixPaths() instead. |
348 | */ |
349 | KDE_DEPRECATED void setContentsPrefix(const QString &prefix); |
350 | |
351 | /** |
352 | * Sets the prefixes that all the contents in this package should |
353 | * appear under. This defaults to "contents/" and is added automatically |
354 | * between the base path and the entries as defined by the package |
355 | * structure. Multiple entries can be added. |
356 | * In this case each file request will be searched in all prefixes in order, |
357 | * and the first found will be returned. |
358 | * |
359 | * @param prefix paths the directory prefix to use |
360 | * @since 4.6 |
361 | */ |
362 | void setContentsPrefixPaths(const QStringList &prefixPaths); |
363 | |
364 | /** |
365 | * Sets preferred package root. |
366 | */ |
367 | void setDefaultPackageRoot(const QString &packageRoot); |
368 | |
369 | /** |
370 | * Called whenever the path changes so that subclasses may take |
371 | * package specific actions. |
372 | */ |
373 | virtual void pathChanged(); |
374 | |
375 | private: |
376 | PackageStructurePrivate * const d; |
377 | }; |
378 | |
379 | /** |
380 | * Register an applet when it is contained in a loadable module |
381 | */ |
382 | #define K_EXPORT_PLASMA_PACKAGESTRUCTURE(libname, classname) \ |
383 | K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \ |
384 | K_EXPORT_PLUGIN(factory("plasma_packagestructure_" #libname)) \ |
385 | K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION) |
386 | |
387 | } // Plasma namespace |
388 | #endif |
389 | |