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

superkaramba

  • superkaramba
  • src
themefile.cpp
1/****************************************************************************
2* themefile.cpp - Theme file handling
3*
4* Copyright (C) 2003 Hans Karlsson <karlsson.h@home.se>
5* Copyright (C) 2003-2004 Adam Geitgey <adam@rootnode.org>
6* Copyright (c) 2004 Petri Damstén <damu@iki.fi>
7*
8* This file is part of SuperKaramba.
9*
10* SuperKaramba is free software; you can redistribute it and/or modify
11* it under the terms of the GNU General Public License as published by
12* the Free Software Foundation; either version 2 of the License, or
13* (at your option) any later version.
14*
15* SuperKaramba is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18* GNU General Public License for more details.
19*
20* You should have received a copy of the GNU General Public License
21* along with SuperKaramba; if not, write to the Free Software
22* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23****************************************************************************/
24#include "themefile.h"
25#include "lineparser.h"
26#include "themelocale.h"
27#include <kdebug.h>
28#include <kurl.h>
29#include <kzip.h>
30#include <tdeapplication.h>
31#include <tdemessagebox.h>
32#include <kstandarddirs.h>
33#include <tdelocale.h>
34#include <tdeio/netaccess.h>
35#include <tqtextstream.h>
36#include <tqfileinfo.h>
37#include <tqdom.h>
38#include <tqdir.h>
39
40class ZipFile
41{
42 public:
43 ZipFile() :
44 m_zip(0), m_file(0)
45 {
46 }
47 void setFile(const TQString& filename)
48 {
49 m_filename = filename;
50 if(filename.isEmpty())
51 return;
52
53 const KArchiveEntry* entry;
54
55 entry = m_dir->entry(filename);
56 if(entry == 0 || !entry->isFile())
57 {
58 m_file = 0;
59 return;
60 }
61 m_file = static_cast<const KArchiveFile*>(entry);
62 }
63 void setZip(const TQString& zipfile)
64 {
65 closeZip();
66
67 m_zip = new KZip(zipfile);
68
69 if(!m_zip->open(IO_ReadOnly))
70 {
71 tqDebug("Unable to open '%s' for reading.", zipfile.ascii());
72 return;
73 }
74 m_dir = m_zip->directory();
75 if(m_dir == 0)
76 {
77 tqDebug("Error reading directory contents of file %s", zipfile.ascii());
78 return;
79 }
80 }
81
82 virtual ~ZipFile()
83 {
84 closeZip();
85 }
86
87 void closeZip()
88 {
89 if(m_zip)
90 {
91 m_zip->close();
92 delete m_zip;
93 }
94 }
95
96 TQByteArray data()
97 {
98 if(m_file)
99 return m_file->data();
100 else
101 {
102 if(!m_filename.isEmpty())
103 tqDebug("Error reading file %s from zip", m_filename.ascii());
104 return TQByteArray();
105 }
106 }
107
108 bool exists()
109 {
110 return (m_file != 0);
111 }
112
113 private:
114 KZip* m_zip;
115 const KArchiveFile* m_file;
116 TQString m_filename;
117 const KArchiveDirectory* m_dir;
118};
119
120ThemeFile::ThemeFile(const KURL& url)
121 : m_stream(0), m_locale(0), m_zip(0)
122{
123 if(url.isValid())
124 set(url);
125}
126
127ThemeFile::~ThemeFile()
128{
129 delete m_stream;
130 delete m_locale;
131 delete m_zip;
132}
133
134bool ThemeFile::open()
135{
136 bool result = false;
137
138 close();
139
140 if(m_zipTheme)
141 {
142 m_zip->setFile(m_theme);
143 m_ba = m_zip->data();
144 if(m_ba.size() > 0)
145 {
146 m_stream = new TQTextStream(m_ba, IO_ReadOnly);
147 result = true;
148 }
149 }
150 else
151 {
152 m_fl.setName(m_file);
153
154 if(m_fl.open(IO_ReadOnly|IO_Translate))
155 {
156 m_stream = new TQTextStream(&m_fl); // use a text stream
157 result = true;
158 }
159 }
160 return result;
161}
162
163bool ThemeFile::nextLine(LineParser& parser)
164{
165 parser.set("");
166
167 if(m_stream)
168 {
169 TQString result = m_stream->readLine();
170
171 if(result.isNull())
172 return false;
173 parser.set(result);
174 return true;
175 }
176 return false;
177}
178
179bool ThemeFile::close()
180{
181 if(m_stream)
182 {
183 delete m_stream;
184 m_stream = 0;
185 m_fl.close();
186 m_ba.resize(0);
187 return true;
188 }
189 return false;
190}
191
192bool ThemeFile::isValid() const
193{
194 return (exists() && !m_name.isEmpty() && !m_theme.isEmpty());
195}
196
197bool ThemeFile::exists() const
198{
199 TQFileInfo file(m_file);
200 return file.exists();
201}
202
203TQPixmap ThemeFile::icon() const
204{
205 return TQPixmap(readThemeFile(m_icon));
206}
207
208bool ThemeFile::set(const KURL &url)
209{
210 if(!url.isLocalFile() && !url.protocol().isEmpty())
211 {
212 if(KMessageBox::warningContinueCancel(kapp->activeWindow(),
213 i18n("You are about to install and run %1 SuperKaramba theme. Since "
214 "themes can contain executable code you should only install themes "
215 "from sources that you trust. Continue?"), i18n("Executable Code Warning"), i18n("Install")
216 .arg(url.prettyURL()))
217 == KMessageBox::Cancel)
218 {
219 return false;
220 }
221
222 TQDir themeDir(locateLocal("appdata", "themes/", true));
223 TQFileInfo localFile = themeDir.filePath(url.fileName());
224
225 if(localFile.exists())
226 {
227 if(KMessageBox::warningContinueCancel(kapp->activeWindow(),
228 i18n("%1 already exists. Do you want to overwrite it?")
229 .arg(localFile.filePath()),i18n("File Exists"),i18n("Overwrite"))
230 == KMessageBox::Cancel)
231 {
232 return false;
233 }
234 }
235 if(!TDEIO::NetAccess::file_copy(url, localFile.filePath(), -1, true,
236 false, kapp->mainWidget()))
237 {
238 return false;
239 }
240 m_file = localFile.filePath();
241 }
242 else
243 {
244 if(url.directory().isEmpty() || url.directory() == "/")
245 m_file = canonicalFile(TQDir::current().filePath(url.fileName()));
246 else
247 m_file = canonicalFile(url.path());
248 if(!exists())
249 return false;
250 }
251
252 TQFileInfo fi(m_file);
253
254 m_name = fi.baseName( TRUE );
255 m_theme = m_name + ".theme";
256 m_python = m_name;
257 m_id = m_name;
258
259 if(isZipFile(m_file))
260 {
261 m_path = m_file;
262 m_zipTheme = true;
263 m_zip = new ZipFile();
264 m_zip->setZip(m_file);
265 }
266 else
267 {
268 m_path = fi.dirPath(true) + "/";
269 m_zipTheme = false;
270 }
271 parseXml();
272
273 TQFileInfo fimo(m_python);
274 if(m_python.isEmpty())
275 fimo.setFile(m_theme);
276 else
277 fimo.setFile(m_python);
278 m_mo = fimo.baseName( TRUE );
279
280 m_locale = new ThemeLocale(this);
281 return isValid();
282}
283
284void ThemeFile::parseXml()
285{
286 if(!fileExists("maindata.xml"))
287 return;
288 TQByteArray ba = readThemeFile("maindata.xml");
289 TQDomDocument doc("superkaramba_theme");
290 doc.setContent(ba);
291 TQDomElement element = doc.documentElement();
292
293 TQDomNode n = element.firstChild();
294 while(!n.isNull())
295 {
296 TQDomElement e = n.toElement();
297 if(!e.isNull())
298 {
299 if(e.tagName() == "name")
300 m_name = e.text();
301 else if(e.tagName() == "themefile")
302 m_theme = e.text();
303 else if(e.tagName() == "python_module")
304 {
305 m_python = e.text();
306 if(m_python.right(3).lower() == ".py")
307 m_python.remove(m_python.length() - 3, 3);
308 }
309 else if(e.tagName() == "description")
310 m_description = e.text();
311 else if(e.tagName() == "author")
312 m_author = e.text();
313 else if(e.tagName() == "author_email")
314 m_authorEmail = e.text();
315 else if(e.tagName() == "homepage")
316 m_homepage = e.text();
317 else if(e.tagName() == "icon")
318 m_icon = e.text();
319 else if(e.tagName() == "version")
320 m_version = e.text();
321 else if(e.tagName() == "license")
322 m_license = e.text();
323 }
324 n = n.nextSibling();
325 }
326}
327
328bool ThemeFile::canUninstall() const
329{
330 TQFileInfo fi(file());
331 if(fi.permission(TQFileInfo::WriteUser) ||
332 fi.permission(TQFileInfo::WriteGroup) ||
333 fi.permission(TQFileInfo::WriteOther))
334 return true;
335 return false;
336}
337
338bool ThemeFile::isThemeFile(const TQString& filename) const
339{
340 TQFileInfo fileInfo(filename);
341
342 return fileInfo.isRelative();
343}
344
345bool ThemeFile::fileExists(const TQString& filename) const
346{
347 if(isThemeFile(filename))
348 {
349 if(isZipTheme())
350 {
351 m_zip->setFile(filename);
352 return m_zip->exists();
353 }
354 else
355 return TQFileInfo(path() + "/" + filename).exists();
356 }
357 else
358 return TQFileInfo(filename).exists();
359}
360
361TQByteArray ThemeFile::readThemeFile(const TQString& filename) const
362{
363 //TQTime time;
364 //time.start();
365 TQByteArray ba;
366
367 if(isZipTheme())
368 {
369 m_zip->setFile(filename);
370 ba = m_zip->data();
371 }
372 else
373 {
374 TQFile file(path() + "/" + filename);
375
376 if(file.open(IO_ReadOnly))
377 {
378 ba = file.readAll();
379 file.close();
380 }
381 }
382 //kdDebug() << "Read theme file: " << filename << ", " << time.elapsed()
383 // << "ms" << endl;
384 return ba;
385}
386
387bool ThemeFile::isZipFile(const TQString& filename)
388{
389 TQFile file(filename);
390
391 if(file.open(IO_ReadOnly))
392 {
393 unsigned char buf[5];
394
395 if(file.readBlock((char*)buf, 4) == 4)
396 {
397 if(buf[0] == 'P' && buf[1] == 'K' && buf[2] == 3 && buf[3] == 4)
398 return true;
399 }
400 }
401 return false;
402}
403
404bool ThemeFile::pythonModuleExists() const
405{
406 return (!m_python.isEmpty() && fileExists(m_python + ".py"));
407}
408
409TQString ThemeFile::canonicalFile(const TQString& file)
410{
411 // Get absolute path with NO symlinks
412 TQFileInfo fi(file);
413 return TQDir(fi.dir().canonicalPath()).filePath(fi.fileName());
414}
LineParser
Definition: lineparser.h:34

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.9.4
This website is maintained by Timothy Pearson.