• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
package.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 * Copyright 2007 by Aaron Seigo <aseigo@kde.org> *
3 * Copyright 2007 by Riccardo Iaconelli <riccardo@kde.org> *
4 * *
5 * This library is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU Library General Public *
7 * License as published by the Free Software Foundation; either *
8 * version 2 of the License, or (at your option) any later version. *
9 * *
10 * This library is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 * Library General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU Library General Public License *
16 * along with this library; see the file COPYING.LIB. If not, write to *
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
18 * Boston, MA 02110-1301, USA. *
19 *******************************************************************************/
20 
21 #include "package.h"
22 #include "config-plasma.h"
23 
24 #include <QDir>
25 #include <QFile>
26 #include <QRegExp>
27 #include <QtNetwork/QHostInfo>
28 
29 #ifdef QCA2_FOUND
30 #include <QtCrypto>
31 #endif
32 
33 #include <karchive.h>
34 #include <kcomponentdata.h>
35 #include <kdesktopfile.h>
36 #include <kmimetype.h>
37 #include <kplugininfo.h>
38 #include <kstandarddirs.h>
39 #include <ktar.h>
40 #include <ktempdir.h>
41 #include <ktemporaryfile.h>
42 #include <kzip.h>
43 #include <kdebug.h>
44 
45 #include "authorizationmanager.h"
46 #include "packagemetadata.h"
47 #include "private/authorizationmanager_p.h"
48 #include "private/package_p.h"
49 #include "private/plasmoidservice_p.h"
50 #include "private/service_p.h"
51 
52 namespace Plasma
53 {
54 
55 bool copyFolder(QString sourcePath, QString targetPath)
56 {
57  QDir source(sourcePath);
58  if(!source.exists())
59  return false;
60 
61  QDir target(targetPath);
62  if(!target.exists()) {
63  QString targetName = target.dirName();
64  target.cdUp();
65  target.mkdir(targetName);
66  target = QDir(targetPath);
67  }
68 
69  foreach (const QString &fileName, source.entryList(QDir::Files)) {
70  QString sourceFilePath = sourcePath + QDir::separator() + fileName;
71  QString targetFilePath = targetPath + QDir::separator() + fileName;
72 
73  if (!QFile::copy(sourceFilePath, targetFilePath)) {
74  return false;
75  }
76  }
77 
78  foreach (const QString &subFolderName, source.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) {
79  QString sourceSubFolderPath = sourcePath + QDir::separator() + subFolderName;
80  QString targetSubFolderPath = targetPath + QDir::separator() + subFolderName;
81 
82  if (!copyFolder(sourceSubFolderPath, targetSubFolderPath)) {
83  return false;
84  }
85  }
86 
87  return true;
88 }
89 
90 bool removeFolder(QString folderPath)
91 {
92  QDir folder(folderPath);
93  if(!folder.exists())
94  return false;
95 
96  foreach (const QString &fileName, folder.entryList(QDir::Files)) {
97  if (!QFile::remove(folderPath + QDir::separator() + fileName)) {
98  return false;
99  }
100  }
101 
102  foreach (const QString &subFolderName, folder.entryList(QDir::AllDirs | QDir::NoDotAndDotDot)) {
103  if (!removeFolder(folderPath + QDir::separator() + subFolderName)) {
104  return false;
105  }
106  }
107 
108  QString folderName = folder.dirName();
109  folder.cdUp();
110  return folder.rmdir(folderName);
111 }
112 
113 Package::Package()
114  : d(new PackagePrivate(PackageStructure::Ptr(0), QString()))
115 {
116 }
117 
118 Package::Package(const QString &packageRoot, const QString &package,
119  PackageStructure::Ptr structure)
120  : d(new PackagePrivate(structure, packageRoot, package))
121 {
122 }
123 
124 Package::Package(const QString &packagePath, PackageStructure::Ptr structure)
125  : d(new PackagePrivate(structure, packagePath))
126 {
127 }
128 
129 Package::Package(const Package &other)
130  : d(new PackagePrivate(*other.d))
131 {
132 }
133 
134 Package::~Package()
135 {
136  delete d;
137 }
138 
139 Package &Package::operator=(const Package &rhs)
140 {
141  if (&rhs != this) {
142  *d = *rhs.d;
143  }
144 
145  return *this;
146 }
147 
148 bool Package::isValid() const
149 {
150  return d->isValid();
151 }
152 
153 bool PackagePrivate::isValid()
154 {
155  if (!valid || !structure) {
156  return false;
157  }
158 
159  //search for the file in all prefixes and in all possible paths for each prefix
160  //even if it's a big nested loop, usually there is one prefix and one location
161  //so shouldn't cause too much disk access
162  QStringList prefixes = structure->contentsPrefixPaths();
163  if (prefixes.isEmpty()) {
164  prefixes << QString();
165  }
166 
167  foreach (const char *dir, structure->requiredDirectories()) {
168  bool failed = true;
169  foreach (const QString &path, structure->searchPath(dir)) {
170  foreach (const QString &prefix, prefixes) {
171  if (QFile::exists(structure->path() + prefix + path)) {
172  failed = false;
173  break;
174  }
175  }
176  if (!failed) {
177  break;
178  }
179  }
180 
181  if (failed) {
182  kWarning() << "Could not find required directory" << dir;
183  valid = false;
184  return false;
185  }
186  }
187 
188  foreach (const char *file, structure->requiredFiles()) {
189  bool failed = true;
190  foreach (const QString &path, structure->searchPath(file)) {
191  foreach (const QString &prefix, prefixes) {
192  if (QFile::exists(structure->path() + prefix + path)) {
193  failed = false;
194  break;
195  }
196  }
197  if (!failed) {
198  break;
199  }
200  }
201 
202  if (failed) {
203  kWarning() << "Could not find required file" << file;
204  valid = false;
205  return false;
206  }
207  }
208 
209  valid = true;
210  return true;
211 }
212 
213 QString Package::filePath(const char *fileType, const QString &filename) const
214 {
215  if (!d->valid) {
216  //kDebug() << "package is not valid";
217  return QString();
218  }
219 
220  QStringList paths;
221 
222  if (qstrlen(fileType) != 0) {
223  paths = d->structure->searchPath(fileType);
224 
225  if (paths.isEmpty()) {
226  //kDebug() << "no matching path came of it, while looking for" << fileType << filename;
227  return QString();
228  }
229  } else {
230  //when filetype is empty paths is always empty, so try with an empty string
231  paths << QString();
232  }
233 
234  //Nested loop, but in the medium case resolves to just one iteration
235  QStringList prefixes = d->structure->contentsPrefixPaths();
236  if (prefixes.isEmpty()) {
237  prefixes << QString();
238  }
239 
240  //kDebug() << "prefixes:" << prefixes.count() << prefixes;
241  foreach (const QString &contentsPrefix, prefixes) {
242  const QString prefix(d->structure->path() + contentsPrefix);
243 
244  foreach (const QString &path, paths) {
245  QString file = prefix + path;
246 
247  if (!filename.isEmpty()) {
248  file.append("/").append(filename);
249  }
250 
251  //kDebug() << "testing" << file << QFile::exists("/bin/ls") << QFile::exists(file);
252  if (QFile::exists(file)) {
253  if (d->structure->allowExternalPaths()) {
254  //kDebug() << "found" << file;
255  return file;
256  }
257 
258  // ensure that we don't return files outside of our base path
259  // due to symlink or ../ games
260  QDir dir(file);
261  QString canonicalized = dir.canonicalPath() + QDir::separator();
262 
263  //kDebug() << "testing that" << canonicalized << "is in" << d->structure->path();
264  if (canonicalized.startsWith(d->structure->path())) {
265  //kDebug() << "found" << file;
266  return file;
267  }
268  }
269  }
270  }
271 
272  //kDebug() << fileType << filename << "does not exist in" << prefixes << "at root" << d->structure->path();
273  return QString();
274 }
275 
276 QString Package::filePath(const char *fileType) const
277 {
278  return filePath(fileType, QString());
279 }
280 
281 QStringList Package::entryList(const char *fileType) const
282 {
283  if (!d->valid) {
284  return QStringList();
285  }
286 
287  return d->structure->entryList(fileType);
288 }
289 
290 PackageMetadata Package::metadata() const
291 {
292  if (d->structure) {
293  return d->structure->metadata();
294  }
295 
296  return PackageMetadata();
297 }
298 
299 void Package::setPath(const QString &path)
300 {
301  d->setPathFromStructure(path);
302 }
303 
304 const QString Package::path() const
305 {
306  return d->structure ? d->structure->path() : QString();
307 }
308 
309 const PackageStructure::Ptr Package::structure() const
310 {
311  return d->structure;
312 }
313 
314 #ifdef QCA2_FOUND
315 void PackagePrivate::updateHash(const QString &basePath, const QString &subPath, const QDir &dir, QCA::Hash &hash)
316 {
317  // hash is calculated as a function of:
318  // * files ordered alphabetically by name, with each file's:
319  // * path relative to the content root
320  // * file data
321  // * directories ordered alphabetically by name, with each dir's:
322  // * path relative to the content root
323  // * file listing (recursing)
324  // symlinks (in both the file and dir case) are handled by adding
325  // the name of the symlink itself and the abs path of what it points to
326 
327  const QDir::SortFlags sorting = QDir::Name | QDir::IgnoreCase;
328  const QDir::Filters filters = QDir::Hidden | QDir::System | QDir::NoDotAndDotDot;
329  foreach (const QString &file, dir.entryList(QDir::Files | filters, sorting)) {
330  if (!subPath.isEmpty()) {
331  hash.update(subPath.toUtf8());
332  }
333 
334  hash.update(file.toUtf8());
335 
336  QFileInfo info(dir.path() + '/' + file);
337  if (info.isSymLink()) {
338  hash.update(info.symLinkTarget().toUtf8());
339  } else {
340  QFile f(info.filePath());
341  if (f.open(QIODevice::ReadOnly)) {
342  while (!f.atEnd()) {
343  hash.update(f.read(1024));
344  }
345  } else {
346  kWarning() << "could not add" << f.fileName() << "to the hash; file could not be opened for reading. "
347  << "permissions fail?" << info.permissions() << info.isFile();
348  }
349  }
350  }
351 
352  foreach (const QString &subDirPath, dir.entryList(QDir::Dirs | filters, sorting)) {
353  const QString relativePath = subPath + subDirPath + '/';
354  hash.update(relativePath.toUtf8());
355 
356  QDir subDir(dir.path());
357  subDir.cd(subDirPath);
358 
359  if (subDir.path() != subDir.canonicalPath()) {
360  hash.update(subDir.canonicalPath().toUtf8());
361  } else {
362  updateHash(basePath, relativePath, subDir, hash);
363  }
364  }
365 }
366 #endif
367 
368 QString Package::contentsHash() const
369 {
370 #ifdef QCA2_FOUND
371  if (!d->valid) {
372  kWarning() << "can not create hash due to Package being invalid";
373  return QString();
374  }
375 
376  //FIXME: the initializer should go somewhere global to be shared between all plasma uses?
377  QCA::Initializer init;
378  if (!QCA::isSupported("sha1")) {
379  kWarning() << "can not create hash for" << path() << "due to no SHA1 support in QCA2";
380  return QString();
381  }
382 
383  QCA::Hash hash("sha1");
384  QString metadataPath = d->structure->path() + "metadata.desktop";
385  if (QFile::exists(metadataPath)) {
386  QFile f(metadataPath);
387  if (f.open(QIODevice::ReadOnly)) {
388  while (!f.atEnd()) {
389  hash.update(f.read(1024));
390  }
391  } else {
392  kWarning() << "could not add" << f.fileName() << "to the hash; file could not be opened for reading.";
393  }
394  } else {
395  kWarning() << "no metadata at" << metadataPath;
396  }
397 
398  QStringList prefixes = d->structure->contentsPrefixPaths();
399  if (prefixes.isEmpty()) {
400  prefixes << QString();
401  }
402 
403  foreach (QString prefix, prefixes) {
404  const QString basePath = d->structure->path() + prefix;
405  QDir dir(basePath);
406 
407  if (!dir.exists()) {
408  return QString();
409  }
410 
411  d->updateHash(basePath, QString(), dir, hash);
412  }
413  return QCA::arrayToHex(hash.final().toByteArray());
414 #else
415  // no QCA2!
416  kWarning() << "can not create hash for" << path() << "due to no cryptographic support (QCA2)";
417  return QString();
418 #endif
419 }
420 
421 //TODO: provide a version of this that allows one to ask for certain types of packages, etc?
422 // should we be using KService here instead/as well?
423 QStringList Package::listInstalled(const QString &packageRoot) // static
424 {
425  QDir dir(packageRoot);
426 
427  if (!dir.exists()) {
428  return QStringList();
429  }
430 
431  QStringList packages;
432 
433  foreach (const QString &sdir, dir.entryList(QDir::AllDirs | QDir::Readable)) {
434  QString metadata = packageRoot + '/' + sdir + "/metadata.desktop";
435  if (QFile::exists(metadata)) {
436  PackageMetadata m(metadata);
437  packages << m.pluginName();
438  }
439  }
440 
441  return packages;
442 }
443 
444 QStringList Package::listInstalledPaths(const QString &packageRoot) // static
445 {
446  QDir dir(packageRoot);
447 
448  if (!dir.exists()) {
449  return QStringList();
450  }
451 
452  QStringList packages;
453 
454  foreach (const QString &sdir, dir.entryList(QDir::AllDirs | QDir::Readable)) {
455  QString metadata = packageRoot + '/' + sdir + "/metadata.desktop";
456  if (QFile::exists(metadata)) {
457  packages << sdir;
458  }
459  }
460 
461  return packages;
462 }
463 
464 bool Package::installPackage(const QString &package,
465  const QString &packageRoot,
466  const QString &servicePrefix) // static
467 {
468  //TODO: report *what* failed if something does fail
469  QDir root(packageRoot);
470 
471  if (!root.exists()) {
472  KStandardDirs::makeDir(packageRoot);
473  if (!root.exists()) {
474  kWarning() << "Could not create package root directory:" << packageRoot;
475  return false;
476  }
477  }
478 
479  QFileInfo fileInfo(package);
480  if (!fileInfo.exists()) {
481  kWarning() << "No such file:" << package;
482  return false;
483  }
484 
485  QString path;
486  KTempDir tempdir;
487  bool archivedPackage = false;
488 
489  if (fileInfo.isDir()) {
490  // we have a directory, so let's just install what is in there
491  path = package;
492 
493  // make sure we end in a slash!
494  if (path[path.size() - 1] != '/') {
495  path.append('/');
496  }
497  } else {
498  KArchive *archive = 0;
499  KMimeType::Ptr mimetype = KMimeType::findByPath(package);
500 
501  if (mimetype->is("application/zip")) {
502  archive = new KZip(package);
503  } else if (mimetype->is("application/x-compressed-tar") ||
504  mimetype->is("application/x-tar")|| mimetype->is("application/x-bzip-compressed-tar") ||
505  mimetype->is("application/x-xz-compressed-tar") || mimetype->is("application/x-lzma-compressed-tar")) {
506  archive = new KTar(package);
507  } else {
508  kWarning() << "Could not open package file, unsupported archive format:" << package << mimetype->name();
509  return false;
510  }
511 
512  if (!archive->open(QIODevice::ReadOnly)) {
513  kWarning() << "Could not open package file:" << package;
514  delete archive;
515  return false;
516  }
517 
518  archivedPackage = true;
519  path = tempdir.name();
520 
521  const KArchiveDirectory *source = archive->directory();
522  source->copyTo(path);
523 
524  QStringList entries = source->entries();
525  if (entries.count() == 1) {
526  const KArchiveEntry *entry = source->entry(entries[0]);
527  if (entry->isDirectory()) {
528  path.append(entry->name()).append("/");
529  }
530  }
531  delete archive;
532  }
533 
534  QString metadataPath = path + "metadata.desktop";
535  if (!QFile::exists(metadataPath)) {
536  kWarning() << "No metadata file in package" << package << metadataPath;
537  return false;
538  }
539 
540  PackageMetadata meta(metadataPath);
541  QString targetName = meta.pluginName();
542 
543  if (targetName.isEmpty()) {
544  kWarning() << "Package plugin name not specified";
545  return false;
546  }
547 
548  // Ensure that package names are safe so package uninstall can't inject
549  // bad characters into the paths used for removal.
550  QRegExp validatePluginName("^[\\w-\\.]+$"); // Only allow letters, numbers, underscore and period.
551  if (!validatePluginName.exactMatch(targetName)) {
552  kWarning() << "Package plugin name " << targetName << "contains invalid characters";
553  return false;
554  }
555 
556  targetName = packageRoot + '/' + targetName;
557  if (QFile::exists(targetName)) {
558  kWarning() << targetName << "already exists";
559  return false;
560  }
561 
562  if (archivedPackage) {
563  // it's in a temp dir, so just move it over.
564  const bool ok = copyFolder(path, targetName);
565  removeFolder(path);
566  if (!ok) {
567  kWarning() << "Could not move package to destination:" << targetName;
568  return false;
569  }
570  } else {
571  kDebug() << "************************** 12";
572  // it's a directory containing the stuff, so copy the contents rather
573  // than move them
574  const bool ok = copyFolder(path, targetName);
575  kDebug() << "************************** 13";
576  if (!ok) {
577  kWarning() << "Could not copy package to destination:" << targetName;
578  return false;
579  }
580  }
581 
582  if (archivedPackage) {
583  // no need to remove the temp dir (which has been successfully moved if it's an archive)
584  tempdir.setAutoRemove(false);
585  }
586 
587  if (!servicePrefix.isEmpty()) {
588  // and now we register it as a service =)
589  kDebug() << "************************** 1";
590  QString metaPath = targetName + "/metadata.desktop";
591  kDebug() << "************************** 2";
592  KDesktopFile df(metaPath);
593  KConfigGroup cg = df.desktopGroup();
594  kDebug() << "************************** 3";
595 
596  // Q: should not installing it as a service disqualify it?
597  // Q: i don't think so since KServiceTypeTrader may not be
598  // used by the installing app in any case, and the
599  // package is properly installed - aseigo
600 
601  //TODO: reduce code duplication with registerPackage below
602 
603  QString serviceName = servicePrefix + meta.pluginName();
604 
605  QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop");
606  kDebug() << "************************** 4";
607  const bool ok = QFile::copy(metaPath, service);
608  kDebug() << "************************** 5";
609  if (ok) {
610  // the icon in the installed file needs to point to the icon in the
611  // installation dir!
612  QString iconPath = targetName + '/' + cg.readEntry("Icon");
613  QFile icon(iconPath);
614  if (icon.exists()) {
615  KDesktopFile df(service);
616  KConfigGroup cg = df.desktopGroup();
617  cg.writeEntry("Icon", iconPath);
618  }
619  } else {
620  kWarning() << "Could not register package as service (this is not necessarily fatal):" << serviceName;
621  }
622  kDebug() << "************************** 7";
623  }
624 
625  return true;
626 }
627 
628 bool Package::uninstallPackage(const QString &pluginName,
629  const QString &packageRoot,
630  const QString &servicePrefix) // static
631 {
632  // We need to remove the package directory and its metadata file.
633  QString targetName = pluginName;
634  targetName = packageRoot + '/' + targetName;
635 
636  if (!QFile::exists(targetName)) {
637  kWarning() << targetName << "does not exist";
638  return false;
639  }
640 
641  QString serviceName = servicePrefix + pluginName;
642 
643  QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop");
644  kDebug() << "Removing service file " << service;
645  bool ok = QFile::remove(service);
646 
647  if (!ok) {
648  kWarning() << "Unable to remove " << service;
649  }
650 
651  ok = removeFolder(targetName);
652  const QString errorString("unknown");
653  if (!ok) {
654  kWarning() << "Could not delete package from:" << targetName << " : " << errorString;
655  return false;
656  }
657 
658  return true;
659 }
660 
661 bool Package::registerPackage(const PackageMetadata &data, const QString &iconPath)
662 {
663  QString serviceName("plasma-applet-" + data.pluginName());
664  QString service = KStandardDirs::locateLocal("services", serviceName + ".desktop");
665 
666  if (data.pluginName().isEmpty()) {
667  return false;
668  }
669 
670  data.write(service);
671 
672  KDesktopFile config(service);
673  KConfigGroup cg = config.desktopGroup();
674  const QString type = data.type().isEmpty() ? "Service" : data.type();
675  cg.writeEntry("Type", type);
676  const QString serviceTypes = data.serviceType().isNull() ? "Plasma/Applet,Plasma/Containment" : data.serviceType();
677  cg.writeEntry("X-KDE-ServiceTypes", serviceTypes);
678  cg.writeEntry("X-KDE-PluginInfo-EnabledByDefault", true);
679 
680  QFile icon(iconPath);
681  if (icon.exists()) {
682  //FIXME: the '/' search will break on non-UNIX. do we care?
683  QString installedIcon("plasma_applet_" + data.pluginName() +
684  iconPath.right(iconPath.length() - iconPath.lastIndexOf("/")));
685  cg.writeEntry("Icon", installedIcon);
686  installedIcon = KStandardDirs::locateLocal("icon", installedIcon);
687  QFile::copy(iconPath, installedIcon);
688  }
689 
690  return true;
691 }
692 
693 bool Package::createPackage(const PackageMetadata &metadata,
694  const QString &source,
695  const QString &destination,
696  const QString &icon) // static
697 {
698  Q_UNUSED(icon)
699  if (!metadata.isValid()) {
700  kWarning() << "Metadata file is not complete";
701  return false;
702  }
703 
704  // write metadata in a temporary file
705  KTemporaryFile metadataFile;
706  if (!metadataFile.open()) {
707  return false;
708  }
709  metadata.write(metadataFile.fileName());
710 
711  // put everything into a zip archive
712  KZip creation(destination);
713  creation.setCompression(KZip::NoCompression);
714  if (!creation.open(QIODevice::WriteOnly)) {
715  return false;
716  }
717 
718  creation.addLocalFile(metadataFile.fileName(), "metadata.desktop");
719  creation.addLocalDirectory(source, "contents");
720  creation.close();
721  return true;
722 }
723 
724 PackagePrivate::PackagePrivate(const PackageStructure::Ptr st, const QString &p)
725  : structure(st),
726  service(0)
727 {
728  setPathFromStructure(p);
729 }
730 
731 PackagePrivate::PackagePrivate(const PackageStructure::Ptr st, const QString &packageRoot, const QString &path)
732  : structure(st),
733  service(0)
734 {
735  setPathFromStructure(packageRoot.isEmpty() ? path : packageRoot % "/" % path);
736 }
737 
738 PackagePrivate::PackagePrivate(const PackagePrivate &other)
739  : structure(other.structure),
740  service(other.service),
741  valid(other.valid)
742 {
743 }
744 
745 PackagePrivate::~PackagePrivate()
746 {
747 }
748 
749 PackagePrivate &PackagePrivate::operator=(const PackagePrivate &rhs)
750 {
751  structure = rhs.structure;
752  service = rhs.service;
753  valid = rhs.valid;
754  return *this;
755 }
756 
757 void PackagePrivate::setPathFromStructure(const QString &path)
758 {
759  if (!structure) {
760  valid = false;
761  return;
762  }
763 
764  QStringList paths;
765  if (path.isEmpty()) {
766  paths << structure->defaultPackageRoot();
767  } else if (QDir::isRelativePath(path)) {
768  QString p = structure->defaultPackageRoot() % "/" % path % "/";
769 
770  if (QDir::isRelativePath(p)) {
771  paths = KGlobal::dirs()->findDirs("data", p);
772  } else {
773  paths << p;
774  }
775  } else {
776  paths << path;
777  }
778 
779  foreach (const QString &p, paths) {
780  structure->setPath(p);
781  // reset valid, otherwise isValid() short-circuits
782  valid = true;
783  if (isValid()) {
784  return;
785  }
786  }
787 
788  valid = false;
789  structure->setPath(QString());
790 }
791 
792 void PackagePrivate::publish(AnnouncementMethods methods)
793 {
794  if (!structure) {
795  return;
796  }
797 
798  if (!service) {
799  service = new PlasmoidService(structure->path());
800  }
801 
802  QString resourceName =
803  i18nc("%1 is the name of a plasmoid, %2 the name of the machine that plasmoid is published on",
804  "%1 on %2", structure->metadata().name(), QHostInfo::localHostName());
805  kDebug() << "publishing package under name " << resourceName;
806  service->d->publish(methods, resourceName, structure->metadata());
807 }
808 
809 void PackagePrivate::unpublish()
810 {
811  if (service) {
812  service->d->unpublish();
813  }
814 }
815 
816 bool PackagePrivate::isPublished() const
817 {
818  if (service) {
819  return service->d->isPublished();
820  } else {
821  return false;
822  }
823 }
824 
825 } // Namespace
packagemetadata.h
Plasma::PackageMetadata::serviceType
QString serviceType() const
Definition: packagemetadata.cpp:169
authorizationmanager.h
Plasma::PackageMetadata::pluginName
QString pluginName() const
Definition: packagemetadata.cpp:254
Plasma::Package::listInstalled
static QStringList listInstalled(const QString &packageRoot)
Returns a list of all installed packages by name.
Definition: package.cpp:423
Plasma::Package::listInstalledPaths
static QStringList listInstalledPaths(const QString &packageRoot)
Returns a list of all paths of installed packages in the given root.
Definition: package.cpp:444
Plasma::PackageMetadata::write
void write(const QString &filename) const
Writes out the metadata to filename, which should be a .desktop file.
Definition: packagemetadata.cpp:87
Plasma::Package::structure
const PackageStructure::Ptr structure() const
Definition: package.cpp:309
Plasma::PackageMetadata::isValid
bool isValid() const
Definition: packagemetadata.cpp:79
Plasma::Package::registerPackage
static bool registerPackage(const PackageMetadata &data, const QString &iconPath)
Registers a package described by the given desktop file.
Definition: package.cpp:661
Plasma::Package::uninstallPackage
static bool uninstallPackage(const QString &package, const QString &packageRoot, const QString &servicePrefix)
Uninstalls a package.
Definition: package.cpp:628
Plasma::Package::installPackage
static bool installPackage(const QString &package, const QString &packageRoot, const QString &servicePrefix)
Installs a package.
Definition: package.cpp:464
Plasma::Package::path
const QString path() const
Definition: package.cpp:304
Plasma::copyFolder
bool copyFolder(QString sourcePath, QString targetPath)
Definition: package.cpp:55
Plasma::PackageMetadata::type
QString type() const
Definition: packagemetadata.cpp:239
Plasma::Package::operator=
Package & operator=(const Package &rhs)
Assignment operator.
Definition: package.cpp:139
Plasma::PackageStructure::Ptr
KSharedPtr< PackageStructure > Ptr
Definition: packagestructure.h:77
Plasma::Package::isValid
bool isValid() const
Definition: package.cpp:148
Plasma::Package
object representing an installed Plasmagik package
Definition: package.h:42
Plasma::removeFolder
bool removeFolder(QString folderPath)
Definition: package.cpp:90
Plasma::Package::entryList
QStringList entryList(const char *fileType) const
Get the list of files of a given type.
Definition: package.cpp:281
Plasma::Package::metadata
PackageMetadata metadata() const
Definition: package.cpp:290
Plasma::Package::~Package
~Package()
Definition: package.cpp:134
Plasma::Package::contentsHash
QString contentsHash() const
Definition: package.cpp:368
Plasma::type
static QScriptValue type(QScriptContext *ctx, QScriptEngine *eng)
Definition: easingcurve.cpp:63
package.h
Plasma::Package::Package
Package()
Default constructor that creates an invalid Package.
Definition: package.cpp:113
Plasma::PackageMetadata
Provides metadata for a Package.
Definition: packagemetadata.h:39
Plasma::Package::setPath
void setPath(const QString &path)
Sets the path to the root of this package.
Definition: package.cpp:299
Plasma::PackageStructure
A description of the expected file structure of a given package type.
Definition: packagestructure.h:72
Plasma::Package::filePath
QString filePath(const char *fileType, const QString &filename) const
Get the path to a given file.
Definition: package.cpp:213
Plasma::Package::createPackage
static bool createPackage(const PackageMetadata &metadata, const QString &source, const QString &destination, const QString &icon=QString())
Creates a package based on the metadata from the files contained in the source directory.
Definition: package.cpp:693
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:33 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal