You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
419 lines
12 KiB
419 lines
12 KiB
/***************************************************************************
|
|
copyright : (C) 2003-2006 by Robby Stephenson
|
|
email : robby@periapsis.org
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of version 2 of the GNU General Public License as *
|
|
* published by the Free Software Foundation; *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "filehandler.h"
|
|
#include "tellico_kernel.h"
|
|
#include "image.h"
|
|
#include "tellico_strings.h"
|
|
#include "tellico_utils.h"
|
|
#include "tellico_debug.h"
|
|
#include "core/netaccess.h"
|
|
|
|
#include <kurl.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kio/netaccess.h>
|
|
#include <ktempfile.h>
|
|
#include <ksavefile.h>
|
|
#include <kapplication.h>
|
|
#include <kfileitem.h>
|
|
#include <kio/chmodjob.h>
|
|
#include <kfilterdev.h>
|
|
|
|
#include <tqdom.h>
|
|
#include <tqfile.h>
|
|
|
|
using Tellico::FileHandler;
|
|
|
|
class FileHandler::ItemDeleter : public TQObject {
|
|
public:
|
|
ItemDeleter(KIO::Job* job, KFileItem* item) : TQObject(), m_job(job), m_item(item) {
|
|
FileHandler::s_deleterList.append(this);
|
|
connect(job, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(deleteLater()));
|
|
}
|
|
~ItemDeleter() {
|
|
FileHandler::s_deleterList.removeRef(this);
|
|
if(m_job) m_job->kill();
|
|
delete m_item; m_item = 0;
|
|
}
|
|
private:
|
|
TQGuardedPtr<KIO::Job> m_job;
|
|
KFileItem* m_item;
|
|
};
|
|
|
|
TQPtrList<FileHandler::ItemDeleter> FileHandler::s_deleterList;
|
|
|
|
FileHandler::FileRef::FileRef(const KURL& url_, bool quiet_, bool allowCompressed_) : m_device(0), m_isValid(false) {
|
|
if(url_.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
if(!Tellico::NetAccess::download(url_, m_filename, Kernel::self()->widget())) {
|
|
myDebug() << "FileRef::FileRef() - can't download " << url_ << endl;
|
|
TQString s = KIO::NetAccess::lastErrorString();
|
|
if(!s.isEmpty()) {
|
|
myDebug() << s << endl;
|
|
}
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorLoad).arg(url_.fileName()));
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
TQFile* file = new TQFile(m_filename);
|
|
if(file->exists()) {
|
|
m_isValid = true;
|
|
m_device = file;
|
|
} else {
|
|
delete file;
|
|
}
|
|
*/
|
|
if(allowCompressed_) {
|
|
m_device = KFilterDev::deviceForFile(m_filename);
|
|
} else {
|
|
m_device = TQT_TQIODEVICE(new TQFile(m_filename));
|
|
}
|
|
m_isValid = true;
|
|
}
|
|
|
|
FileHandler::FileRef::~FileRef() {
|
|
if(!m_filename.isEmpty()) {
|
|
Tellico::NetAccess::removeTempFile(m_filename);
|
|
}
|
|
if(m_device) {
|
|
m_device->close();
|
|
}
|
|
delete m_device;
|
|
m_device = 0;
|
|
m_isValid = false;
|
|
}
|
|
|
|
bool FileHandler::FileRef::open(bool quiet_) {
|
|
if(!isValid()) {
|
|
return false;
|
|
}
|
|
if(!m_device || !m_device->open(IO_ReadOnly)) {
|
|
if(!quiet_) {
|
|
KURL u;
|
|
u.setPath(fileName());
|
|
Kernel::self()->sorry(i18n(errorLoad).arg(u.fileName()));
|
|
}
|
|
delete m_device;
|
|
m_device = 0;
|
|
m_isValid = false;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
FileHandler::FileRef* FileHandler::fileRef(const KURL& url_, bool quiet_) {
|
|
return new FileRef(url_, quiet_);
|
|
}
|
|
|
|
TQString FileHandler::readTextFile(const KURL& url_, bool quiet_/*=false*/, bool useUTF8_ /*false*/, bool compress_/*=false*/) {
|
|
FileRef f(url_, quiet_, compress_);
|
|
if(!f.isValid()) {
|
|
return TQString();
|
|
}
|
|
|
|
if(f.open(quiet_)) {
|
|
TQTextStream stream(f.file());
|
|
if(useUTF8_) {
|
|
stream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
}
|
|
return stream.read();
|
|
}
|
|
return TQString();
|
|
}
|
|
|
|
TQDomDocument FileHandler::readXMLFile(const KURL& url_, bool processNamespace_, bool quiet_) {
|
|
FileRef f(url_, quiet_);
|
|
if(!f.isValid()) {
|
|
return TQDomDocument();
|
|
}
|
|
|
|
TQDomDocument doc;
|
|
TQString errorMsg;
|
|
int errorLine, errorColumn;
|
|
if(!f.open(quiet_)) {
|
|
return TQDomDocument();
|
|
}
|
|
if(!doc.setContent(f.file(), processNamespace_, &errorMsg, &errorLine, &errorColumn)) {
|
|
if(!quiet_) {
|
|
TQString details = i18n("There is an XML parsing error in line %1, column %2.").arg(errorLine).arg(errorColumn);
|
|
details += TQString::fromLatin1("\n");
|
|
details += i18n("The error message from TQt is:");
|
|
details += TQString::fromLatin1("\n\t") + errorMsg;
|
|
GUI::CursorSaver cs(TQt::arrowCursor);
|
|
KMessageBox::detailedSorry(Kernel::self()->widget(), i18n(errorLoad).arg(url_.fileName()), details);
|
|
}
|
|
return TQDomDocument();
|
|
}
|
|
return doc;
|
|
}
|
|
|
|
TQByteArray FileHandler::readDataFile(const KURL& url_, bool quiet_) {
|
|
FileRef f(url_, quiet_);
|
|
if(!f.isValid()) {
|
|
return TQByteArray();
|
|
}
|
|
|
|
f.open(quiet_);
|
|
return f.file()->readAll();
|
|
}
|
|
|
|
Tellico::Data::Image* FileHandler::readImageFile(const KURL& url_, bool quiet_, const KURL& referrer_) {
|
|
if(url_.isLocalFile()) {
|
|
return readImageFile(url_, quiet_);
|
|
}
|
|
|
|
KTempFile tmpFile;
|
|
KURL tmpURL;
|
|
tmpURL.setPath(tmpFile.name());
|
|
tmpFile.setAutoDelete(true);
|
|
|
|
KIO::Job* job = KIO::file_copy(url_, tmpURL, -1, true /* overwrite */);
|
|
job->addMetaData(TQString::fromLatin1("referrer"), referrer_.url());
|
|
|
|
if(!KIO::NetAccess::synchronousRun(job, Kernel::self()->widget())) {
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorLoad).arg(url_.fileName()));
|
|
}
|
|
return 0;
|
|
}
|
|
return readImageFile(tmpURL, quiet_);
|
|
}
|
|
|
|
Tellico::Data::Image* FileHandler::readImageFile(const KURL& url_, bool quiet_) {
|
|
FileRef f(url_, quiet_);
|
|
if(!f.isValid()) {
|
|
return 0;
|
|
}
|
|
|
|
Data::Image* img = new Data::Image(f.fileName());
|
|
if(img->isNull() && !quiet_) {
|
|
TQString str = i18n("Tellico is unable to load the image - %1.").arg(url_.fileName());
|
|
Kernel::self()->sorry(str);
|
|
}
|
|
return img;
|
|
}
|
|
|
|
bool FileHandler::queryExists(const KURL& url_) {
|
|
if(url_.isEmpty() || !KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
|
|
return true;
|
|
}
|
|
|
|
// we always overwrite the current URL without asking
|
|
if(url_ != Kernel::self()->URL()) {
|
|
GUI::CursorSaver cs(TQt::arrowCursor);
|
|
TQString str = i18n("A file named \"%1\" already exists. "
|
|
"Are you sure you want to overwrite it?").arg(url_.fileName());
|
|
int want_continue = KMessageBox::warningContinueCancel(Kernel::self()->widget(), str,
|
|
i18n("Overwrite File?"),
|
|
i18n("Overwrite"));
|
|
|
|
if(want_continue == KMessageBox::Cancel) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
KURL backup(url_);
|
|
backup.setPath(backup.path() + TQString::fromLatin1("~"));
|
|
|
|
bool success = true;
|
|
if(url_.isLocalFile()) {
|
|
// KSaveFile messes up users and groups
|
|
// the user is always reset to the current user
|
|
KFileItemList list;
|
|
int perm = -1;
|
|
TQString grp;
|
|
if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
|
|
KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url_, true);
|
|
perm = item.permissions();
|
|
grp = item.group();
|
|
|
|
KFileItem* backupItem = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, backup, true);
|
|
list.append(backupItem);
|
|
}
|
|
|
|
success = KSaveFile::backupFile(url_.path());
|
|
if(!list.isEmpty()) {
|
|
// have to leave the user alone
|
|
KIO::Job* job = KIO::chmod(list, perm, 0, TQString(), grp, true, false);
|
|
new ItemDeleter(job, list.first());
|
|
}
|
|
} else {
|
|
KIO::NetAccess::del(backup, Kernel::self()->widget()); // might fail if backup doesn't exist, that's ok
|
|
success = KIO::NetAccess::file_copy(url_, backup, -1 /* permissions */, true /* overwrite */,
|
|
false /* resume */, Kernel::self()->widget());
|
|
}
|
|
if(!success) {
|
|
Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName() + '~'));
|
|
}
|
|
return success;
|
|
}
|
|
|
|
bool FileHandler::writeTextURL(const KURL& url_, const TQString& text_, bool encodeUTF8_, bool force_, bool quiet_) {
|
|
if((!force_ && !queryExists(url_)) || text_.isNull()) {
|
|
if(text_.isNull()) {
|
|
myDebug() << "FileHandler::writeTextURL() - null string for " << url_ << endl;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if(url_.isLocalFile()) {
|
|
// KSaveFile messes up users and groups
|
|
// the user is always reset to the current user
|
|
KFileItemList list;
|
|
int perm = -1;
|
|
TQString grp;
|
|
if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
|
|
KFileItem* item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, url_, true);
|
|
list.append(item);
|
|
perm = item->permissions();
|
|
grp = item->group();
|
|
}
|
|
|
|
KSaveFile f(url_.path());
|
|
if(f.status() != 0) {
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
|
|
}
|
|
return false;
|
|
}
|
|
bool success = FileHandler::writeTextFile(f, text_, encodeUTF8_);
|
|
if(!list.isEmpty()) {
|
|
// have to leave the user alone
|
|
KIO::Job* job = KIO::chmod(list, perm, 0, TQString(), grp, true, false);
|
|
new ItemDeleter(job, list.first());
|
|
}
|
|
return success;
|
|
}
|
|
|
|
// save to remote file
|
|
KTempFile tempfile;
|
|
KSaveFile f(tempfile.name());
|
|
if(f.status() != 0) {
|
|
tempfile.unlink();
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool success = FileHandler::writeTextFile(f, text_, encodeUTF8_);
|
|
if(success) {
|
|
bool uploaded = KIO::NetAccess::upload(tempfile.name(), url_, Kernel::self()->widget());
|
|
if(!uploaded) {
|
|
tempfile.unlink();
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorUpload).arg(url_.fileName()));
|
|
}
|
|
success = false;
|
|
}
|
|
}
|
|
tempfile.unlink();
|
|
|
|
return success;
|
|
}
|
|
|
|
bool FileHandler::writeTextFile(KSaveFile& f_, const TQString& text_, bool encodeUTF8_) {
|
|
TQTextStream* t = f_.textStream();
|
|
if(encodeUTF8_) {
|
|
t->setEncoding(TQTextStream::UnicodeUTF8);
|
|
} else {
|
|
t->setEncoding(TQTextStream::Locale);
|
|
}
|
|
// kdDebug() << "-----------------------------" << endl
|
|
// << text_ << endl
|
|
// << "-----------------------------" << endl;
|
|
(*t) << text_;
|
|
bool success = f_.close();
|
|
#ifndef NDEBUG
|
|
if(!success) {
|
|
myDebug() << "FileHandler::writeTextFile() - status = " << f_.status();
|
|
}
|
|
#endif
|
|
return success;
|
|
}
|
|
|
|
bool FileHandler::writeDataURL(const KURL& url_, const TQByteArray& data_, bool force_, bool quiet_) {
|
|
if(!force_ && !queryExists(url_)) {
|
|
return false;
|
|
}
|
|
|
|
if(url_.isLocalFile()) {
|
|
// KSaveFile messes up users and groups
|
|
// the user is always reset to the current user
|
|
KFileItemList list;
|
|
int perm = -1;
|
|
TQString grp;
|
|
if(KIO::NetAccess::exists(url_, false, Kernel::self()->widget())) {
|
|
KFileItem* item = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, url_, true);
|
|
list.append(item);
|
|
perm = item->permissions();
|
|
grp = item->group();
|
|
}
|
|
|
|
KSaveFile f(url_.path());
|
|
if(f.status() != 0) {
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
|
|
}
|
|
return false;
|
|
}
|
|
bool success = FileHandler::writeDataFile(f, data_);
|
|
if(!list.isEmpty()) {
|
|
// have to leave the user alone
|
|
KIO::Job* job = KIO::chmod(list, perm, 0, TQString(), grp, true, false);
|
|
new ItemDeleter(job, list.first());
|
|
}
|
|
return success;
|
|
}
|
|
|
|
// save to remote file
|
|
KTempFile tempfile;
|
|
KSaveFile f(tempfile.name());
|
|
if(f.status() != 0) {
|
|
if(!quiet_) {
|
|
Kernel::self()->sorry(i18n(errorWrite).arg(url_.fileName()));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool success = FileHandler::writeDataFile(f, data_);
|
|
if(success) {
|
|
success = KIO::NetAccess::upload(tempfile.name(), url_, Kernel::self()->widget());
|
|
if(!success && !quiet_) {
|
|
Kernel::self()->sorry(i18n(errorUpload).arg(url_.fileName()));
|
|
}
|
|
}
|
|
tempfile.unlink();
|
|
|
|
return success;
|
|
}
|
|
|
|
bool FileHandler::writeDataFile(KSaveFile& f_, const TQByteArray& data_) {
|
|
// myDebug() << "FileHandler::writeDataFile()" << endl;
|
|
TQDataStream* s = f_.dataStream();
|
|
s->writeRawBytes(data_.data(), data_.size());
|
|
return f_.close();
|
|
}
|
|
|
|
void FileHandler::clean() {
|
|
s_deleterList.setAutoDelete(true);
|
|
s_deleterList.clear();
|
|
s_deleterList.setAutoDelete(false);
|
|
}
|