• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • superkaramba
 

superkaramba

themefile.cpp

00001 /****************************************************************************
00002 *  themefile.cpp - Theme file handling
00003 *
00004 *  Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
00005 *  Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
00006 *  Copyright (c) 2004 Petri Damstén <damu@iki.fi>
00007 *
00008 *  This file is part of SuperKaramba.
00009 *
00010 *  SuperKaramba is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  SuperKaramba is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with SuperKaramba; if not, write to the Free Software
00022 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 ****************************************************************************/
00024 #include "themefile.h"
00025 #include "lineparser.h"
00026 #include "themelocale.h"
00027 #include <kdebug.h>
00028 #include <kurl.h>
00029 #include <kzip.h>
00030 #include <tdeapplication.h>
00031 #include <tdemessagebox.h>
00032 #include <kstandarddirs.h>
00033 #include <tdelocale.h>
00034 #include <tdeio/netaccess.h>
00035 #include <tqtextstream.h>
00036 #include <tqfileinfo.h>
00037 #include <tqdom.h>
00038 #include <tqdir.h>
00039 
00040 class ZipFile
00041 {
00042   public:
00043     ZipFile() :
00044       m_zip(0), m_file(0)
00045     {
00046     }
00047     void setFile(const TQString& filename)
00048     {
00049       m_filename = filename;
00050       if(filename.isEmpty())
00051         return;
00052 
00053       const KArchiveEntry* entry;
00054 
00055       entry = m_dir->entry(filename);
00056       if(entry == 0 || !entry->isFile())
00057       {
00058         m_file = 0;
00059         return;
00060       }
00061       m_file = static_cast<const KArchiveFile*>(entry);
00062     }
00063     void setZip(const TQString& zipfile)
00064     {
00065       closeZip();
00066 
00067       m_zip = new KZip(zipfile);
00068 
00069       if(!m_zip->open(IO_ReadOnly))
00070       {
00071         tqDebug("Unable to open '%s' for reading.", zipfile.ascii());
00072         return;
00073       }
00074       m_dir = m_zip->directory();
00075       if(m_dir == 0)
00076       {
00077         tqDebug("Error reading directory contents of file %s", zipfile.ascii());
00078         return;
00079       }
00080     }
00081 
00082     virtual ~ZipFile()
00083     {
00084       closeZip();
00085     }
00086 
00087     void closeZip()
00088     {
00089       if(m_zip)
00090       {
00091         m_zip->close();
00092         delete  m_zip;
00093       }
00094     }
00095 
00096     TQByteArray data()
00097     {
00098       if(m_file)
00099         return m_file->data();
00100       else
00101       {
00102         if(!m_filename.isEmpty())
00103           tqDebug("Error reading file %s from zip", m_filename.ascii());
00104         return TQByteArray();
00105       }
00106     }
00107 
00108     bool exists()
00109     {
00110       return (m_file != 0);
00111     }
00112 
00113   private:
00114     KZip* m_zip;
00115     const KArchiveFile* m_file;
00116     TQString m_filename;
00117     const KArchiveDirectory* m_dir;
00118 };
00119 
00120 ThemeFile::ThemeFile(const KURL& url)
00121   : m_stream(0), m_locale(0), m_zip(0)
00122 {
00123   if(url.isValid())
00124     set(url);
00125 }
00126 
00127 ThemeFile::~ThemeFile()
00128 {
00129   delete m_stream;
00130   delete m_locale;
00131   delete m_zip;
00132 }
00133 
00134 bool ThemeFile::open()
00135 {
00136   bool result = false;
00137 
00138   close();
00139 
00140   if(m_zipTheme)
00141   {
00142     m_zip->setFile(m_theme);
00143     m_ba = m_zip->data();
00144     if(m_ba.size() > 0)
00145     {
00146       m_stream = new TQTextStream(m_ba, IO_ReadOnly);
00147       result = true;
00148     }
00149   }
00150   else
00151   {
00152     m_fl.setName(m_file);
00153 
00154     if(m_fl.open(IO_ReadOnly|IO_Translate))
00155     {
00156       m_stream = new TQTextStream(&m_fl);        // use a text stream
00157       result = true;
00158     }
00159   }
00160   return result;
00161 }
00162 
00163 bool ThemeFile::nextLine(LineParser& parser)
00164 {
00165   parser.set("");
00166 
00167   if(m_stream)
00168   {
00169     TQString result = m_stream->readLine();
00170 
00171     if(result.isNull())
00172       return false;
00173     parser.set(result);
00174     return true;
00175   }
00176   return false;
00177 }
00178 
00179 bool ThemeFile::close()
00180 {
00181   if(m_stream)
00182   {
00183     delete m_stream;
00184     m_stream = 0;
00185     m_fl.close();
00186     m_ba.resize(0);
00187     return true;
00188   }
00189   return false;
00190 }
00191 
00192 bool ThemeFile::isValid() const
00193 {
00194   return (exists() && !m_name.isEmpty() && !m_theme.isEmpty());
00195 }
00196 
00197 bool ThemeFile::exists() const
00198 {
00199   TQFileInfo file(m_file);
00200   return file.exists();
00201 }
00202 
00203 TQPixmap ThemeFile::icon() const
00204 {
00205   return TQPixmap(readThemeFile(m_icon));
00206 }
00207 
00208 bool ThemeFile::set(const KURL &url)
00209 {
00210   if(!url.isLocalFile() && !url.protocol().isEmpty())
00211   {
00212     if(KMessageBox::warningContinueCancel(TQT_TQWIDGET(kapp->activeWindow()),
00213        i18n("You are about to install and run %1 SuperKaramba theme. Since "
00214             "themes can contain executable code you should only install themes "
00215             "from sources that you trust. Continue?"), i18n("Executable Code Warning"), i18n("Install")
00216            .arg(url.prettyURL()))
00217        == KMessageBox::Cancel)
00218     {
00219       return false;
00220     }
00221 
00222     TQDir themeDir(locateLocal("appdata", "themes/", true));
00223     TQFileInfo localFile = themeDir.filePath(url.fileName());
00224 
00225     if(localFile.exists())
00226     {
00227       if(KMessageBox::warningContinueCancel(TQT_TQWIDGET(kapp->activeWindow()),
00228          i18n("%1 already exists. Do you want to overwrite it?")
00229              .arg(localFile.filePath()),i18n("File Exists"),i18n("Overwrite"))
00230          == KMessageBox::Cancel)
00231       {
00232         return false;
00233       }
00234     }
00235     if(!TDEIO::NetAccess::file_copy(url, localFile.filePath(), -1, true,
00236       false, kapp->mainWidget()))
00237     {
00238       return false;
00239     }
00240     m_file = localFile.filePath();
00241   }
00242   else
00243   {
00244     if(url.directory().isEmpty() || url.directory() == "/")
00245       m_file = canonicalFile(TQDir::current().filePath(url.fileName()));
00246     else
00247       m_file = canonicalFile(url.path());
00248     if(!exists())
00249       return false;
00250   }
00251 
00252   TQFileInfo fi(m_file);
00253 
00254   m_name = fi.baseName( TRUE );
00255   m_theme = m_name + ".theme";
00256   m_python = m_name;
00257   m_id = m_name;
00258 
00259   if(isZipFile(m_file))
00260   {
00261     m_path = m_file;
00262     m_zipTheme = true;
00263     m_zip = new ZipFile();
00264     m_zip->setZip(m_file);
00265   }
00266   else
00267   {
00268     m_path = fi.dirPath(true) + "/";
00269     m_zipTheme = false;
00270   }
00271   parseXml();
00272 
00273   TQFileInfo fimo(m_python);
00274   if(m_python.isEmpty())
00275     fimo.setFile(m_theme);
00276   else
00277     fimo.setFile(m_python);
00278   m_mo = fimo.baseName( TRUE );
00279 
00280   m_locale = new ThemeLocale(this);
00281   return isValid();
00282 }
00283 
00284 void ThemeFile::parseXml()
00285 {
00286   if(!fileExists("maindata.xml"))
00287     return;
00288   TQByteArray ba = readThemeFile("maindata.xml");
00289   TQDomDocument doc("superkaramba_theme");
00290   doc.setContent(ba);
00291   TQDomElement element = doc.documentElement();
00292 
00293   TQDomNode n = element.firstChild();
00294   while(!n.isNull())
00295   {
00296     TQDomElement e = n.toElement();
00297     if(!e.isNull())
00298     {
00299       if(e.tagName() == "name")
00300         m_name = e.text();
00301       else if(e.tagName() == "themefile")
00302         m_theme = e.text();
00303       else if(e.tagName() == "python_module")
00304       {
00305         m_python = e.text();
00306         if(m_python.right(3).lower() == ".py")
00307           m_python.remove(m_python.length() - 3, 3);
00308       }
00309       else if(e.tagName() == "description")
00310         m_description = e.text();
00311       else if(e.tagName() == "author")
00312         m_author = e.text();
00313       else if(e.tagName() == "author_email")
00314         m_authorEmail = e.text();
00315       else if(e.tagName() == "homepage")
00316         m_homepage = e.text();
00317       else if(e.tagName() == "icon")
00318         m_icon = e.text();
00319       else if(e.tagName() == "version")
00320         m_version = e.text();
00321       else if(e.tagName() == "license")
00322         m_license = e.text();
00323     }
00324     n = n.nextSibling();
00325   }
00326 }
00327 
00328 bool ThemeFile::canUninstall() const
00329 {
00330   TQFileInfo fi(file());
00331   if(fi.permission(TQFileInfo::WriteUser) ||
00332      fi.permission(TQFileInfo::WriteGroup) ||
00333      fi.permission(TQFileInfo::WriteOther))
00334     return true;
00335   return false;
00336 }
00337 
00338 bool ThemeFile::isThemeFile(const TQString& filename) const
00339 {
00340   TQFileInfo fileInfo(filename);
00341 
00342   return fileInfo.isRelative();
00343 }
00344 
00345 bool ThemeFile::fileExists(const TQString& filename) const
00346 {
00347   if(isThemeFile(filename))
00348   {
00349     if(isZipTheme())
00350     {
00351       m_zip->setFile(filename);
00352       return m_zip->exists();
00353     }
00354     else
00355       return TQFileInfo(path() + "/" + filename).exists();
00356   }
00357   else
00358     return TQFileInfo(filename).exists();
00359 }
00360 
00361 TQByteArray ThemeFile::readThemeFile(const TQString& filename) const
00362 {
00363   //TQTime time;
00364   //time.start();
00365   TQByteArray ba;
00366 
00367   if(isZipTheme())
00368   {
00369     m_zip->setFile(filename);
00370     ba = m_zip->data();
00371   }
00372   else
00373   {
00374     TQFile file(path() + "/" + filename);
00375 
00376     if(file.open(IO_ReadOnly))
00377     {
00378       ba = file.readAll();
00379       file.close();
00380     }
00381   }
00382   //kdDebug() << "Read theme file: " << filename << ", " << time.elapsed()
00383   //    << "ms" << endl;
00384   return ba;
00385 }
00386 
00387 bool ThemeFile::isZipFile(const TQString& filename)
00388 {
00389   TQFile file(filename);
00390 
00391   if(file.open(IO_ReadOnly))
00392   {
00393     unsigned char buf[5];
00394 
00395     if(file.readBlock((char*)buf, 4) == 4)
00396     {
00397       if(buf[0] == 'P' && buf[1] == 'K' && buf[2] == 3 && buf[3] == 4)
00398         return true;
00399     }
00400   }
00401   return false;
00402 }
00403 
00404 bool ThemeFile::pythonModuleExists() const
00405 {
00406   return (!m_python.isEmpty() && fileExists(m_python + ".py"));
00407 }
00408 
00409 TQString ThemeFile::canonicalFile(const TQString& file)
00410 {
00411   // Get absolute path with NO symlinks
00412   TQFileInfo fi(file);
00413   return TQDir(fi.dir().canonicalPath()).filePath(fi.fileName());
00414 }

superkaramba

Skip menu "superkaramba"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members

superkaramba

Skip menu "superkaramba"
  • kcalc
  •   knumber
  • superkaramba
Generated for superkaramba by doxygen 1.6.3
This website is maintained by Timothy Pearson.