• 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 <tdestandarddirs.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 
40 class 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 
120 ThemeFile::ThemeFile(const KURL& url)
121  : m_stream(0), m_locale(0), m_zip(0)
122 {
123  if(url.isValid())
124  set(url);
125 }
126 
127 ThemeFile::~ThemeFile()
128 {
129  delete m_stream;
130  delete m_locale;
131  delete m_zip;
132 }
133 
134 bool 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 
163 bool 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 
179 bool 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 
192 bool ThemeFile::isValid() const
193 {
194  return (exists() && !m_name.isEmpty() && !m_theme.isEmpty());
195 }
196 
197 bool ThemeFile::exists() const
198 {
199  TQFileInfo file(m_file);
200  return file.exists();
201 }
202 
203 TQPixmap ThemeFile::icon() const
204 {
205  return TQPixmap(readThemeFile(m_icon));
206 }
207 
208 bool ThemeFile::set(const KURL &url)
209 {
210  if(!url.isLocalFile() && !url.protocol().isEmpty())
211  {
212  if(KMessageBox::warningContinueCancel(tdeApp->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(tdeApp->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, tdeApp->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 
284 void 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 
328 bool 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 
338 bool ThemeFile::isThemeFile(const TQString& filename) const
339 {
340  TQFileInfo fileInfo(filename);
341 
342  return fileInfo.isRelative();
343 }
344 
345 bool 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 
361 TQByteArray 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 
387 bool 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 
404 bool ThemeFile::pythonModuleExists() const
405 {
406  return (!m_python.isEmpty() && fileExists(m_python + ".py"));
407 }
408 
409 TQString 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:33

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