• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Plasma

bundle.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2007 Zack Rusin <zack@kde.org>
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021  */
00022 
00023 #include "bundle.h"
00024 
00025 #include <QBuffer>
00026 #include <QDebug>
00027 #include <QDir>
00028 #include <QFile>
00029 #include <QXmlStreamReader>
00030 
00031 #include <KIO/CopyJob>
00032 #include <KIO/Job>
00033 
00034 #include <Plasma/PackageMetadata>
00035 #include <Plasma/Package>
00036 
00037 void recursive_print(const KArchiveDirectory *dir, const QString &path)
00038 {
00039     const QStringList l = dir->entries();
00040     QStringList::const_iterator it = l.constBegin();
00041     for (; it != l.end(); ++it)
00042     {
00043         const KArchiveEntry* entry = dir->entry((*it));
00044         printf("mode=%07o %s %s size: %lld pos: %lld %s%s isdir=%d%s",
00045                entry->permissions(),
00046                entry->user().toLatin1().constData(),
00047                entry->group().toLatin1().constData(),
00048                entry->isDirectory() ? 0 : ((KArchiveFile*)entry)->size(),
00049                entry->isDirectory() ? 0 : ((KArchiveFile*)entry)->position(),
00050                path.toLatin1().constData(),
00051                (*it).toLatin1().constData(), entry->isDirectory(),
00052                entry->symLinkTarget().isEmpty() ? "" :
00053                QString(" symlink: %1").arg(
00054                    entry->symLinkTarget()).toLatin1().constData());
00055 
00056         //if (!entry->isDirectory()) printf("%d",
00057         //     ((KArchiveFile*)entry)->size());
00058         printf("\n");
00059         if (entry->isDirectory())
00060             recursive_print((KArchiveDirectory *)entry, path+(*it)+'/');
00061     }
00062 }
00063 
00064 
00065 static const KArchiveDirectory *recursiveFind(const KArchiveDirectory *dir)
00066 {
00067     const QStringList l = dir->entries();
00068     QStringList::const_iterator it;
00069     for (it = l.constBegin(); it != l.constEnd(); ++it) {
00070         const KArchiveEntry* entry = dir->entry((*it));
00071         if (entry->isDirectory()) {
00072             QString name = *it;
00073             if (name.startsWith(QLatin1String("__MACOSX"))) {
00074                 //skip this
00075                 continue;
00076             } else if (name.endsWith(QLatin1String(".wdgt"))) {
00077                 //got our bad boy
00078                 return static_cast<const KArchiveDirectory*>(entry);
00079             } else {
00080                 const KArchiveDirectory *fd =
00081                     recursiveFind(static_cast<const KArchiveDirectory*>(entry));
00082                 if (fd)
00083                     return fd;
00084             }
00085         }
00086     }
00087     return 0;
00088 }
00089 
00090 Bundle::Bundle(const QString &path)
00091     : PackageStructure(0, "MacDashboard"),
00092       m_isValid(false),
00093       m_width(0), m_height(0)
00094 {
00095     setContentsPrefix(QString());
00096     QFile f(path);
00097     f.open(QIODevice::ReadOnly);
00098     m_data = f.readAll();
00099     f.close();
00100     initTempDir();
00101     open();
00102 }
00103 
00104 Bundle::Bundle(const QByteArray &data)
00105     : PackageStructure(0, "MacDashboard"),
00106       m_isValid(false),
00107       m_width(0),
00108       m_height(0)
00109 {
00110     setContentsPrefix(QString());
00111     m_data = data;
00112     initTempDir();
00113     open();
00114 }
00115 
00116 Bundle::Bundle(QObject *parent, QVariantList args)
00117     : PackageStructure(parent, "MacDashboard"),
00118       m_isValid(false),
00119       m_tempDir(0),
00120       m_width(0),
00121       m_height(0)
00122 {
00123     Q_UNUSED(args)
00124     setContentsPrefix(QString());
00125 }
00126 
00127 Bundle::~Bundle()
00128 {
00129     close();
00130     qWarning("done");
00131 }
00132 
00133 void Bundle::setData(const QByteArray &data)
00134 {
00135     m_data = data;
00136     close();
00137     open();
00138 }
00139 
00140 QByteArray Bundle::data() const
00141 {
00142     return m_data;
00143 }
00144 
00145 bool Bundle::open()
00146 {
00147     if (!m_tempDir) {
00148         initTempDir();
00149     }
00150 
00151     if (m_data.isEmpty()) {
00152         return false;
00153     }
00154 
00155     QBuffer buffer(&m_data);
00156     KZip zip(&buffer);
00157     if (!zip.open(QIODevice::ReadOnly)) {
00158         qWarning("Couldn't open the bundle!");
00159         return false;
00160     }
00161 
00162     const KArchiveDirectory *dir = zip.directory();
00163 
00164     const KArchiveDirectory *foundDir = recursiveFind(dir);
00165     if (!foundDir) {
00166         qWarning("not a bundle");
00167         m_isValid = false;
00168         zip.close();
00169         return 0;
00170     }
00171 
00172     m_isValid = extractArchive(foundDir, QLatin1String(""));
00173     qDebug()<<"Dir = "<<foundDir->name() << m_isValid;
00174 
00175     if (m_isValid) {
00176         setPath(m_tempDir->name());
00177     }
00178 
00179     zip.close();
00180 
00181     return m_isValid;
00182 }
00183 
00184 bool Bundle::close()
00185 {
00186     bool ret = m_tempDir;
00187     delete m_tempDir;
00188     m_tempDir = 0;
00189     return ret;
00190 }
00191 
00192 bool Bundle::extractArchive(const KArchiveDirectory *dir, const QString &path)
00193 {
00194     const QStringList l = dir->entries();
00195 
00196     QStringList::const_iterator it;
00197     for (it = l.constBegin(); it != l.constEnd(); ++it) {
00198         const KArchiveEntry* entry = dir->entry((*it));
00199         QString fullPath = QString("%1/%2").arg(path).arg(*it);
00200         if (entry->isDirectory()) {
00201             QString outDir = QString("%1%2").arg(m_tempDir->name()).arg(path);
00202             QDir qdir(outDir);
00203             qdir.mkdir(*it);
00204             extractArchive(static_cast<const KArchiveDirectory*>(entry), fullPath);
00205         } else if (entry->isFile()) {
00206             QString outName = QString("%1%2").arg(m_tempDir->name()).arg(fullPath.remove(0, 1));
00207             //qDebug()<<"-------- "<<outName;
00208             QFile f(outName);
00209             if (!f.open(QIODevice::WriteOnly)) {
00210                 qWarning("Couldn't create %s", qPrintable(outName));
00211                 continue;
00212             }
00213             const KArchiveFile *archiveFile = static_cast<const KArchiveFile*>(entry);
00214             f.write(archiveFile->data());
00215             f.close();
00216         } else {
00217             qWarning("Unidentified entry at %s", qPrintable(fullPath));
00218         }
00219     }
00220     return true;
00221 }
00222 
00223 void Bundle::pathChanged()
00224 {
00225     //qDebug() << "path changed";
00226     m_isValid = extractInfo();
00227 }
00228 
00229 bool Bundle::extractInfo()
00230 {
00231     QString plistLocation = QString("%1Info.plist").arg(path());
00232     QString configXml = QString("%1config.xml").arg(path());
00233     if (QFile::exists(plistLocation)) {
00234         //qDebug() << "doing plist";
00235         return parsePlist(plistLocation);
00236     } else if (QFile::exists(configXml)) {
00237         return parseConfigXml(configXml);
00238     }
00239 
00240     return false;
00241 }
00242 
00243 bool Bundle::parsePlist(const QString &loc)
00244 {
00245     QFile f(loc);
00246     if (!f.open(QIODevice::ReadOnly)) {
00247         qWarning("Couldn't open info file: '%s'", qPrintable(loc));
00248         return false;
00249     }
00250 
00251     QMap<QString, QString> infoMap;
00252     QString str = f.readAll();
00253     QXmlStreamReader reader(str);
00254     while (!reader.atEnd()) {
00255         reader.readNext();
00256         // do processing
00257         if (reader.isStartElement()) {
00258             //qDebug() << reader.name().toString();
00259             if (reader.name() == "key") {
00260                 QString key, value;
00261                 reader.readNext();
00262                 if (reader.isCharacters()) {
00263                     QString str = reader.text().toString();
00264                     str = str.trimmed();
00265                     if (!str.isEmpty())
00266                         key = str;
00267                 }
00268                 if (key.isEmpty())
00269                     continue;
00270                 while (!reader.isStartElement())
00271                     reader.readNext();
00272                 if (reader.name() != "string" &&
00273                     reader.name() != "integer") {
00274                     qDebug()<<"Unrecognized val "<<reader.name().toString()
00275                             <<" for key "<<key;
00276                     continue;
00277                 }
00278                 reader.readNext();
00279                 if (reader.isCharacters()) {
00280                     QString str = reader.text().toString();
00281                     str = str.trimmed();
00282                     if (!str.isEmpty())
00283                         value = str;
00284                 }
00285                 //qDebug()<<"key = "<<key<<", value = "<<value;
00286                 infoMap.insert(key, value);
00287             }
00288         }
00289     }
00290 
00291     QMap<QString, QString>::const_iterator itr;
00292     for (itr = infoMap.constBegin(); itr != infoMap.constEnd(); ++itr) {
00293         kDebug() << itr.key() << itr.value();
00294         if (itr.key() == QLatin1String("CFBundleIdentifier")) {
00295             m_bundleId = itr.value();
00296         } else if (itr.key() == QLatin1String("CFBundleName")) {
00297             m_description = itr.value();
00298         } else if (itr.key() == QLatin1String("CFBundleDisplayName")) {
00299             m_name = itr.value();
00300         } else if (itr.key() == QLatin1String("CFBundleVersion")) {
00301             m_version = itr.value();
00302         } else if (itr.key() == QLatin1String("CloseBoxInsetX")) {
00303 
00304         } else if (itr.key() == QLatin1String("CloseBoxInsetY")) {
00305 
00306         } else if (itr.key() == QLatin1String("Height")) {
00307             m_height = itr.value().toInt();
00308         } else if (itr.key() == QLatin1String("Width")) {
00309             m_width = itr.value().toInt();
00310         } else if (itr.key() == QLatin1String("MainHTML")) {
00311             m_htmlLocation = QString("%1%2").arg(path()).arg(itr.value());
00312             addFileDefinition("mainscript", itr.value(), i18n("Main Webpage"));
00313         } else {
00314             qDebug()<<"Unrecognized key = "<<itr.key();
00315         }
00316     }
00317     m_iconLocation = QString("%1Icon.png").arg(path());
00318     kDebug() << path();
00319     addDirectoryDefinition("root", "/", i18n("Root HTML directory"));
00320 
00321     //qDebug()<<"name = "<<m_name;
00322     //qDebug()<<"id   = "<<m_bundleId;
00323     //qDebug()<<"html = "<<m_htmlLocation;
00324     //qDebug()<<"icon = "<<m_iconLocation;
00325 
00326     return !m_bundleId.isEmpty();
00327 }
00328 
00329 bool Bundle::installPackage(const QString &archivePath, const QString &packageRoot)
00330 {
00331     //kDebug() << "??????????????" << archivePath << packageRoot;
00332     QFile f(archivePath);
00333     f.open(QIODevice::ReadOnly);
00334     m_data = f.readAll();
00335     f.close();
00336     open();
00337 
00338     if (m_isValid) {
00339         m_tempDir->setAutoRemove(false);
00340         QString pluginName = "dashboard_" + m_bundleId;
00341         //kDebug() << "valid, so going to move it in to" << pluginName;
00342         KIO::CopyJob* job = KIO::move(m_tempDir->name(), packageRoot + pluginName, KIO::HideProgressInfo);
00343         m_isValid = job->exec();
00344 
00345         if (m_isValid) {
00346             //kDebug() << "still so good ... registering";
00347             Plasma::PackageMetadata data;
00348             data.setName(m_name);
00349             data.setDescription(m_description);
00350             data.setPluginName(pluginName);
00351             data.setImplementationApi("dashboard");
00352             Plasma::Package::registerPackage(data, m_iconLocation);
00353         }
00354     }
00355 
00356     if (!m_isValid) {
00357         // make sure we clean up after ourselves afterwards on failure
00358         m_tempDir->setAutoRemove(true);
00359     }
00360 
00361     return m_isValid;
00362 }
00363 
00364 bool Bundle::parseConfigXml(const QString &loc)
00365 {
00366     QFile f(loc);
00367     if (!f.open(QIODevice::ReadOnly)) {
00368         qWarning("Couldn't open info file: '%s'", qPrintable(loc));
00369         return false;
00370     }
00371 
00372     qWarning("FIXME: Widgets 1.0 not implemented");
00373 
00374     return false;
00375 }
00376 
00377 void Bundle::initTempDir()
00378 {
00379     m_tempDir = new KTempDir();
00380     //make it explicit
00381     m_tempDir->setAutoRemove(true);
00382 }
00383 
00384 QString Bundle::bundleId() const
00385 {
00386     return m_bundleId;
00387 }
00388 
00389 QString Bundle::name() const
00390 {
00391     return m_name;
00392 }
00393 
00394 QString Bundle::version() const
00395 {
00396     return m_version;
00397 }
00398 
00399 QString Bundle::description() const
00400 {
00401     return m_description;
00402 }
00403 
00404 int Bundle::width() const
00405 {
00406     return m_width;
00407 }
00408 
00409 int Bundle::height() const
00410 {
00411     return m_height;
00412 }
00413 
00414 QString Bundle::htmlLocation() const
00415 {
00416     return m_htmlLocation;
00417 }
00418 
00419 QString Bundle::iconLocation() const
00420 {
00421     return m_iconLocation;
00422 }
00423 
00424 bool Bundle::isValid() const
00425 {
00426     return m_isValid;
00427 }
00428 
00429 

Plasma

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal