30 #include <KApplication> 
   31 #include <KMessageBox> 
   32 #include <KStandardDirs> 
   35 #include <kio/copyjob.h> 
   36 #include <KIO/NetAccess> 
   37 #include <kross/core/manager.h> 
   38 #include <kross/core/interpreter.h> 
   46             m_zip(0), m_file(0), m_tempDir(0)
 
   48     void setFile(
const QString& filename)
 
   50         m_filename = filename;
 
   51         if (filename.isEmpty())
 
   54         const KArchiveEntry* entry;
 
   56         entry = m_dir->entry(filename);
 
   57         if (entry == 0 || !entry->isFile()) {
 
   61         m_file = 
static_cast<const KArchiveFile*
>(entry);
 
   63     void setZip(
const QString& zipfile)
 
   67         m_zip = 
new KZip(zipfile);
 
   69         if (!m_zip->open(QIODevice::ReadOnly)) {
 
   70             qDebug(
"Unable to open '%s' for reading.", zipfile.toAscii().constData());
 
   73         m_dir = m_zip->directory();
 
   75             qDebug(
"Error reading directory contents of file %s", zipfile.toAscii().constData());
 
   97             return m_file->data();
 
   99             if (!m_filename.isEmpty())
 
  100                 qDebug(
"Error reading file %s from zip", m_filename.toAscii().constData());
 
  107         return (m_file != 0);
 
  110     QString extractArchive()
 
  112         QString tmpPath = KStandardDirs::locateLocal(
"tmp", 
"runningThemes/");
 
  114         m_tempDir = 
new KTempDir(tmpPath);
 
  115         m_tempDir->setAutoRemove(
true);
 
  117         m_dir->copyTo(m_tempDir->name());
 
  119         return m_tempDir->name();
 
  122     bool extractArchiveTo(
const QString& path)
 
  128     bool extractArchiveFileTo(
const QString& file, 
const QString& path)
 
  130         const KArchiveEntry* entry = m_dir ? m_dir->entry(file) : 0;
 
  131         const KArchiveFile* f = (entry && entry->isFile()) ? static_cast<const KArchiveFile*>(entry) : 0;
 
  140     const KArchiveFile* m_file;
 
  142     const KArchiveDirectory* m_dir;
 
  146 class ThemeFile::Private
 
  172         : zipTheme(false), stream(0), 
locale(0), zip(0)
 
  204         d->zip->setFile(d->theme);
 
  205         d->ba = d->zip->data();
 
  206         if (d->ba.size() > 0) {
 
  207             d->stream = 
new QTextStream(d->ba, QIODevice::ReadOnly);
 
  211         d->fl.setFileName(d->file);
 
  213         if (d->fl.open(QIODevice::ReadOnly | QIODevice::Text)) {
 
  214             d->stream = 
new QTextStream(&d->fl);        
 
  226         QString result = d->stream->readLine();
 
  227         while ( result.endsWith(
"\\") ) {
 
  229             result += d->stream->readLine();
 
  254     return (
exists() && !d->name.isEmpty() && !d->theme.isEmpty());
 
  259     QFileInfo 
file(d->file);
 
  260     return file.exists();
 
  277     if (!url.isLocalFile() && !url.protocol().isEmpty()) {
 
  278         if (KMessageBox::warningContinueCancel(qApp->activeWindow(),
 
  279                                                i18n(
"You are about to install and run %1 SuperKaramba theme. Since " 
  280                                                     "themes can contain executable code you should only install themes " 
  281                                                     "from sources that you trust. Continue?",
 
  283                                                i18n(
"Executable Code Warning"),
 
  284                                                KGuiItem(i18n(
"Install")))
 
  286                 == KMessageBox::Cancel) {
 
  290         QDir themeDir(KStandardDirs::locateLocal(
"appdata", 
"themes/", 
true));
 
  291         QFileInfo localFile = themeDir.filePath(url.fileName());
 
  293         if (localFile.exists()) {
 
  294             if (KMessageBox::warningContinueCancel(qApp->activeWindow(),
 
  295                                                    i18n(
"%1 already exists. Do you want to overwrite it?", localFile.filePath()),
 
  297                                                    KGuiItem(i18n(
"Overwrite"))
 
  299                     == KMessageBox::Cancel) {
 
  304         KIO::Job *job = KIO::file_copy(url, localFile.filePath(), -1, KIO::Overwrite);
 
  306         if (!KIO::NetAccess::synchronousRun(job, qApp->activeWindow())) {
 
  310         d->file = localFile.filePath();
 
  312         if (url.directory().isEmpty() || url.directory() == 
"/")
 
  313             d->file = 
canonicalFile(QDir::current().filePath(url.fileName()));
 
  322     QFileInfo fi(d->file);
 
  324     d->name = fi.completeBaseName();
 
  325     d->theme = d->name + 
".theme";
 
  328     bool fileExtensionFound = 
false;
 
  329     const QStringList availInterp = Kross::Manager::self().interpreters();
 
  330     foreach (
const QString &interpreter, availInterp) {
 
  331         QString fileExtension = Kross::Manager::self().interpreterInfo(interpreter)->wildcard();
 
  332         fileExtension.remove(0, 1);
 
  334         if (
fileExists(fi.path() + 
'/' + d->script + fileExtension)) {
 
  335             d->script += fileExtension;
 
  336             fileExtensionFound = 
true;
 
  340     if (!fileExtensionFound) {
 
  349         d->zip = 
new ZipFile();
 
  350         d->zip->setZip(d->file);
 
  352         d->path = fi.absoluteDir().absolutePath() + 
'/';
 
  357     QFileInfo fimo(d->script);
 
  358     if (d->script.isEmpty())
 
  359         fimo.setFile(d->theme);
 
  361         fimo.setFile(d->script);
 
  362     d->mo = fimo.completeBaseName();
 
  373 void ThemeFile::parseXml()
 
  378     QDomDocument doc(
"superkaramba_theme");
 
  380     QDomElement element = doc.documentElement();
 
  382     QDomNode n = element.firstChild();
 
  383     while (!n.isNull()) {
 
  384         QDomElement e = n.toElement();
 
  386             if (e.tagName() == 
"name") {
 
  388             } 
else if (e.tagName() == 
"themefile") {
 
  390             } 
else if (e.tagName() == 
"python_module") {
 
  391                 d->script = e.text();
 
  392             } 
else if (e.tagName() == 
"script_module") {
 
  393                 d->script = e.text();
 
  394             } 
else if (e.tagName() == 
"description") {
 
  395                 d->description = e.text();
 
  396             } 
else if (e.tagName() == 
"author") {
 
  397                 d->author = e.text();
 
  398             } 
else if (e.tagName() == 
"author_email") {
 
  399                 d->authorEmail = e.text();
 
  400             } 
else if (e.tagName() == 
"homepage") {
 
  401                  d->homepage = e.text();
 
  402             } 
else if (e.tagName() == 
"icon") {
 
  404             } 
else if (e.tagName() == 
"version") {
 
  405                 d->version = e.text();
 
  406             } 
else if (e.tagName() == 
"license") {
 
  407                 d->license = e.text();
 
  416     QFileInfo fi(
file());
 
  417     if (fi.permission(QFile::WriteUser) ||
 
  418             fi.permission(QFile::WriteGroup) ||
 
  419             fi.permission(QFile::WriteOther))
 
  426     QFileInfo fileInfo(filename);
 
  428     return fileInfo.isRelative();
 
  435             d->zip->setFile(filename);
 
  436             return d->zip->exists();
 
  438             return QFileInfo(
path() + 
'/' + filename).exists();
 
  440         return QFileInfo(filename).exists();
 
  450         d->zip->setFile(filename);
 
  453         QFile 
file(
path() + 
'/' + filename);
 
  455         if (file.open(QIODevice::ReadOnly)) {
 
  467     QFile 
file(filename);
 
  469     if (file.open(QIODevice::ReadOnly)) {
 
  470         unsigned char buf[5];
 
  472         if (file.read((
char*)buf, 4) == 4) {
 
  473             if (buf[0] == 
'P' && buf[1] == 
'K' && buf[2] == 3 && buf[3] == 4)
 
  482     if (d->script.isEmpty()) {
 
  497     return QDir(fi.dir().canonicalPath()).filePath(fi.fileName());
 
  503         return d->zip->extractArchive();
 
  511     return isZipTheme() ? d->zip->extractArchiveTo(path) : 
false;
 
  516     return isZipTheme() ? d->zip->extractArchiveFileTo(file, path) : 
false;
 
  526     KIO::CopyJob* job = KIO::copy(url, path, KIO::HideProgressInfo | KIO::Overwrite);
 
  527     bool ok = KIO::NetAccess::synchronousRun( job, 0 );
 
  578     return d->description;
 
  588     return d->authorEmail;
 
void set(const QString &line)
 
const ThemeLocale * locale() const 
 
const QString & file() const 
 
const QString & authorEmail() const 
 
static QString canonicalFile(const QString &file)
 
const QString & scriptModule() const 
 
bool copyArchiveTo(const QString &path)
 
bool isThemeFile(const QString &filename) const 
 
const QString & id() const 
 
const QString & name() const 
 
bool scriptModuleExists() const 
 
bool extractArchiveFileTo(const QString &file, const QString &path)
 
bool nextLine(LineParser &parser)
 
const QString & description() const 
 
const QString & homepage() const 
 
bool set(const KUrl &url)
 
const QString & version() const 
 
bool extractArchiveTo(const QString &path)
 
ThemeFile(const KUrl &url=KUrl())
 
const QString & path() const 
 
bool canUninstall() const 
 
const QString & mo() const 
 
const QString & author() const 
 
static bool isZipFile(const QString &filename)
 
QByteArray readThemeFile(const QString &filename) const 
 
QString extractArchive() const 
 
const QString & license() const 
 
bool fileExists(const QString &filename) const