• Skip to content
  • Skip to link menu
KDE 4.1 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.h>
00035 #include <plasma/package.h>
00036 
00037 void recursive_print(const KArchiveDirectory *dir, const QString &path)
00038 {
00039     QStringList l = dir->entries();
00040     QStringList::Iterator it = l.begin();
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     QStringList l = dir->entries();
00068     QStringList::Iterator it;
00069     for (it = l.begin(); it != l.end(); ++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(0, "MacDashboard"),
00118       m_isValid(false),
00119       m_tempDir(0),
00120       m_width(0),
00121       m_height(0)
00122 {
00123     setContentsPrefix(QString());
00124 }
00125 
00126 Bundle::~Bundle()
00127 {
00128     close();
00129     qWarning("done");
00130 }
00131 
00132 void Bundle::setData(const QByteArray &data)
00133 {
00134     m_data = data;
00135     close();
00136     open();
00137 }
00138 
00139 QByteArray Bundle::data() const
00140 {
00141     return m_data;
00142 }
00143 
00144 bool Bundle::open()
00145 {
00146     if (m_data.isEmpty())
00147         return false;
00148 
00149     if (!m_tempDir)
00150         initTempDir();
00151 
00152     QBuffer buffer(&m_data);
00153     KZip zip(&buffer);
00154     if (!zip.open(QIODevice::ReadOnly)) {
00155         qWarning("Couldn't open the bundle!");
00156         return false;
00157     }
00158 
00159     const KArchiveDirectory *dir = zip.directory();
00160 
00161     const KArchiveDirectory *foundDir = recursiveFind(dir);
00162     if (!foundDir) {
00163         qWarning("not a bundle");
00164         m_isValid = false;
00165         zip.close();
00166         return 0;
00167     }
00168 
00169     m_isValid = extractArchive(foundDir, QLatin1String(""));
00170     qDebug()<<"Dir = "<<foundDir->name() << m_isValid;
00171 
00172     if (m_isValid) {
00173         setPath(m_tempDir->name());
00174     }
00175 
00176     zip.close();
00177 
00178     return m_isValid;
00179 }
00180 
00181 bool Bundle::close()
00182 {
00183     bool ret = m_tempDir;
00184     delete m_tempDir;
00185     m_tempDir = 0;
00186     return ret;
00187 }
00188 
00189 bool Bundle::extractArchive(const KArchiveDirectory *dir, const QString &path)
00190 {
00191     QStringList l = dir->entries();
00192 
00193     QStringList::Iterator it;
00194     for (it = l.begin(); it != l.end(); ++it) {
00195         const KArchiveEntry* entry = dir->entry((*it));
00196         QString fullPath = QString("%1/%2").arg(path).arg(*it);
00197         if (entry->isDirectory()) {
00198             QString outDir = QString("%1%2").arg(m_tempDir->name()).arg(path);
00199             QDir qdir(outDir);
00200             qdir.mkdir(*it);
00201             extractArchive(static_cast<const KArchiveDirectory*>(entry), fullPath);
00202         } else if (entry->isFile()) {
00203             QString outName = QString("%1%2").arg(m_tempDir->name()).arg(fullPath.remove(0, 1));
00204             //qDebug()<<"-------- "<<outName;
00205             QFile f(outName);
00206             if (!f.open(QIODevice::WriteOnly)) {
00207                 qWarning("Couldn't create %s", qPrintable(outName));
00208                 continue;
00209             }
00210             const KArchiveFile *archiveFile = static_cast<const KArchiveFile*>(entry);
00211             f.write(archiveFile->data());
00212             f.close();
00213         } else {
00214             qWarning("Unidentified entry at %s", qPrintable(fullPath));
00215         }
00216     }
00217     return true;
00218 }
00219 
00220 void Bundle::pathChanged()
00221 {
00222     //qDebug() << "path changed";
00223     m_isValid = extractInfo();
00224 }
00225 
00226 bool Bundle::extractInfo()
00227 {
00228     QString plistLocation = QString("%1Info.plist").arg(path());
00229     QString configXml = QString("%1config.xml").arg(path());
00230     if (QFile::exists(plistLocation)) {
00231         //qDebug() << "doing plist";
00232         return parsePlist(plistLocation);
00233     } else if (QFile::exists(configXml)) {
00234         return parseConfigXml(configXml);
00235     }
00236 
00237     return false;
00238 }
00239 
00240 bool Bundle::parsePlist(const QString &loc)
00241 {
00242     QFile f(loc);
00243     if (!f.open(QIODevice::ReadOnly)) {
00244         qWarning("Couldn't open info file: '%s'", qPrintable(loc));
00245         return false;
00246     }
00247 
00248     QMap<QString, QString> infoMap;
00249     QString str = f.readAll();
00250     QXmlStreamReader reader(str);
00251     while (!reader.atEnd()) {
00252         reader.readNext();
00253         // do processing
00254         if (reader.isStartElement()) {
00255             //qDebug() << reader.name().toString();
00256             if (reader.name() == "key") {
00257                 QString key, value;
00258                 reader.readNext();
00259                 if (reader.isCharacters()) {
00260                     QString str = reader.text().toString();
00261                     str = str.trimmed();
00262                     if (!str.isEmpty())
00263                         key = str;
00264                 }
00265                 if (key.isEmpty())
00266                     continue;
00267                 while (!reader.isStartElement())
00268                     reader.readNext();
00269                 if (reader.name() != "string" &&
00270                     reader.name() != "integer") {
00271                     qDebug()<<"Unrecognized val "<<reader.name().toString()
00272                             <<" for key "<<key;
00273                     continue;
00274                 }
00275                 reader.readNext();
00276                 if (reader.isCharacters()) {
00277                     QString str = reader.text().toString();
00278                     str = str.trimmed();
00279                     if (!str.isEmpty())
00280                         value = str;
00281                 }
00282                 //qDebug()<<"key = "<<key<<", value = "<<value;
00283                 infoMap.insert(key, value);
00284             }
00285         }
00286     }
00287 
00288     QMap<QString, QString>::const_iterator itr;
00289     for (itr = infoMap.constBegin(); itr != infoMap.constEnd(); ++itr) {
00290         kDebug() << itr.key() << itr.value();
00291         if (itr.key() == QLatin1String("CFBundleIdentifier")) {
00292             m_bundleId = itr.value();
00293         } else if (itr.key() == QLatin1String("CFBundleName")) {
00294             m_description = itr.value();
00295         } else if (itr.key() == QLatin1String("CFBundleDisplayName")) {
00296             m_name = itr.value();
00297         } else if (itr.key() == QLatin1String("CFBundleVersion")) {
00298             m_version = itr.value();
00299         } else if (itr.key() == QLatin1String("CloseBoxInsetX")) {
00300 
00301         } else if (itr.key() == QLatin1String("CloseBoxInsetY")) {
00302 
00303         } else if (itr.key() == QLatin1String("Height")) {
00304             m_height = itr.value().toInt();
00305         } else if (itr.key() == QLatin1String("Width")) {
00306             m_width = itr.value().toInt();
00307         } else if (itr.key() == QLatin1String("MainHTML")) {
00308             m_htmlLocation = QString("%1%2").arg(path()).arg(itr.value());
00309             addFileDefinition("webpage", itr.value(), i18n("Main Webpage"));
00310         } else {
00311             qDebug()<<"Unrecognized key = "<<itr.key();
00312         }
00313     }
00314     m_iconLocation = QString("%1Icon.png").arg(path());
00315 
00316     //qDebug()<<"name = "<<m_name;
00317     //qDebug()<<"id   = "<<m_bundleId;
00318     //qDebug()<<"html = "<<m_htmlLocation;
00319     //qDebug()<<"icon = "<<m_iconLocation;
00320 
00321     return !m_bundleId.isEmpty();
00322 }
00323 
00324 bool Bundle::installPackage(const QString &archivePath, const QString &packageRoot)
00325 {
00326     //kDebug() << "??????????????" << archivePath << packageRoot;
00327     QFile f(archivePath);
00328     f.open(QIODevice::ReadOnly);
00329     m_data = f.readAll();
00330     f.close();
00331     open();
00332 
00333     if (m_isValid) {
00334         m_tempDir->setAutoRemove(false);
00335         QString pluginName = "dashboard_" + m_bundleId;
00336         //kDebug() << "valid, so going to move it in to" << pluginName;
00337         KIO::CopyJob* job = KIO::move(m_tempDir->name(), packageRoot + pluginName, KIO::HideProgressInfo);
00338         m_isValid = job->exec();
00339 
00340         if (m_isValid) {
00341             //kDebug() << "still so good ... registering";
00342             Plasma::PackageMetadata data;
00343             data.setName(m_name);
00344             data.setDescription(m_description);
00345             data.setPluginName(pluginName);
00346             data.setImplementationApi("dashboard");
00347             Plasma::Package::registerPackage(data, m_iconLocation);
00348         }
00349     }
00350 
00351     if (!m_isValid) {
00352         // make sure we clean up after ourselves afterwards on failure
00353         m_tempDir->setAutoRemove(true);
00354     }
00355 
00356     return m_isValid;
00357 }
00358 
00359 bool Bundle::parseConfigXml(const QString &loc)
00360 {
00361     QFile f(loc);
00362     if (!f.open(QIODevice::ReadOnly)) {
00363         qWarning("Couldn't open info file: '%s'", qPrintable(loc));
00364         return false;
00365     }
00366 
00367     qWarning("FIXME: Widgets 1.0 not implemented");
00368 
00369     return false;
00370 }
00371 
00372 void Bundle::initTempDir()
00373 {
00374     m_tempDir = new KTempDir();
00375     //make it explicit
00376     m_tempDir->setAutoRemove(true);
00377 }
00378 
00379 QString Bundle::bundleId() const
00380 {
00381     return m_bundleId;
00382 }
00383 
00384 QString Bundle::name() const
00385 {
00386     return m_name;
00387 }
00388 
00389 QString Bundle::version() const
00390 {
00391     return m_version;
00392 }
00393 
00394 QString Bundle::description() const
00395 {
00396     return m_description;
00397 }
00398 
00399 int Bundle::width() const
00400 {
00401     return m_width;
00402 }
00403 
00404 int Bundle::height() const
00405 {
00406     return m_height;
00407 }
00408 
00409 QString Bundle::htmlLocation() const
00410 {
00411     return m_htmlLocation;
00412 }
00413 
00414 QString Bundle::iconLocation() const
00415 {
00416     return m_iconLocation;
00417 }
00418 
00419 bool Bundle::isValid() const
00420 {
00421     return m_isValid;
00422 }
00423 
00424 

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
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
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