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