|
|
|
/***************************************************************************
|
|
|
|
copyright : (C) 2005-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 "filelistingimporter.h"
|
|
|
|
#include "../collections/filecatalog.h"
|
|
|
|
#include "../entry.h"
|
|
|
|
#include "../field.h"
|
|
|
|
#include "../latin1literal.h"
|
|
|
|
#include "../imagefactory.h"
|
|
|
|
#include "../tellico_utils.h"
|
|
|
|
#include "../tellico_kernel.h"
|
|
|
|
#include "../progressmanager.h"
|
|
|
|
#include "../core/netaccess.h"
|
|
|
|
#include "../tellico_debug.h"
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <kmountpoint.h>
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <tdeio/netaccess.h>
|
|
|
|
|
|
|
|
#include <tqcheckbox.h>
|
|
|
|
#include <tqvgroupbox.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
static const int FILE_PREVIEW_SIZE = 128;
|
|
|
|
// volume name starts at 16*2048+40 bytes into the header
|
|
|
|
static const int VOLUME_NAME_POS = 32808;
|
|
|
|
static const int VOLUME_NAME_SIZE = 32;
|
|
|
|
}
|
|
|
|
|
|
|
|
using Tellico::Import::FileListingImporter;
|
|
|
|
|
|
|
|
FileListingImporter::FileListingImporter(const KURL& url_) : Importer(url_), m_coll(0), m_widget(0),
|
|
|
|
m_job(0), m_cancelled(false) {
|
|
|
|
m_files.setAutoDelete(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool FileListingImporter::canImport(int type) const {
|
|
|
|
return type == Data::Collection::File;
|
|
|
|
}
|
|
|
|
|
|
|
|
Tellico::Data::CollPtr FileListingImporter::collection() {
|
|
|
|
if(m_coll) {
|
|
|
|
return m_coll;
|
|
|
|
}
|
|
|
|
|
|
|
|
ProgressItem& item = ProgressManager::self()->newProgressItem(this, i18n("Scanning files..."), true);
|
|
|
|
item.setTotalSteps(100);
|
|
|
|
connect(&item, TQT_SIGNAL(signalCancelled(ProgressItem*)), TQT_SLOT(slotCancel()));
|
|
|
|
ProgressItem::Done done(this);
|
|
|
|
|
|
|
|
// going to assume only one volume will ever be imported
|
|
|
|
TQString volume = volumeName();
|
|
|
|
|
|
|
|
m_job = m_recursive->isChecked()
|
|
|
|
? TDEIO::listRecursive(url(), true, false)
|
|
|
|
: TDEIO::listDir(url(), true, false);
|
|
|
|
connect(m_job, TQT_SIGNAL(entries(TDEIO::Job*, const TDEIO::UDSEntryList&)),
|
|
|
|
TQT_SLOT(slotEntries(TDEIO::Job*, const TDEIO::UDSEntryList&)));
|
|
|
|
|
|
|
|
if(!TDEIO::NetAccess::synchronousRun(m_job, Kernel::self()->widget()) || m_cancelled) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool usePreview = m_filePreview->isChecked();
|
|
|
|
|
|
|
|
const TQString title = TQString::fromLatin1("title");
|
|
|
|
const TQString url = TQString::fromLatin1("url");
|
|
|
|
const TQString desc = TQString::fromLatin1("description");
|
|
|
|
const TQString vol = TQString::fromLatin1("volume");
|
|
|
|
const TQString folder = TQString::fromLatin1("folder");
|
|
|
|
const TQString type = TQString::fromLatin1("mimetype");
|
|
|
|
const TQString size = TQString::fromLatin1("size");
|
|
|
|
const TQString perm = TQString::fromLatin1("permissions");
|
|
|
|
const TQString owner = TQString::fromLatin1("owner");
|
|
|
|
const TQString group = TQString::fromLatin1("group");
|
|
|
|
const TQString created = TQString::fromLatin1("created");
|
|
|
|
const TQString modified = TQString::fromLatin1("modified");
|
|
|
|
const TQString metainfo = TQString::fromLatin1("metainfo");
|
|
|
|
const TQString icon = TQString::fromLatin1("icon");
|
|
|
|
|
|
|
|
m_coll = new Data::FileCatalog(true);
|
|
|
|
TQString tmp;
|
|
|
|
const uint stepSize = TQMAX(1, m_files.count()/100);
|
|
|
|
const bool showProgress = options() & ImportProgress;
|
|
|
|
|
|
|
|
item.setTotalSteps(m_files.count());
|
|
|
|
uint j = 0;
|
|
|
|
for(KFileItemListIterator it(m_files); !m_cancelled && it.current(); ++it, ++j) {
|
|
|
|
Data::EntryPtr entry = new Data::Entry(m_coll);
|
|
|
|
|
|
|
|
const KURL u = it.current()->url();
|
|
|
|
entry->setField(title, u.fileName());
|
|
|
|
entry->setField(url, u.url());
|
|
|
|
entry->setField(desc, it.current()->mimeComment());
|
|
|
|
entry->setField(vol, volume);
|
|
|
|
tmp = KURL::relativePath(this->url().path(), u.directory());
|
|
|
|
// remove "./" from the string
|
|
|
|
entry->setField(folder, tmp.right(tmp.length()-2));
|
|
|
|
entry->setField(type, it.current()->mimetype());
|
|
|
|
entry->setField(size, TDEIO::convertSize(it.current()->size()));
|
|
|
|
entry->setField(perm, it.current()->permissionsString());
|
|
|
|
entry->setField(owner, it.current()->user());
|
|
|
|
entry->setField(group, it.current()->group());
|
|
|
|
|
|
|
|
time_t t = it.current()->time(TDEIO::UDS_CREATION_TIME);
|
|
|
|
if(t > 0) {
|
|
|
|
TQDateTime dt;
|
|
|
|
dt.setTime_t(t);
|
|
|
|
entry->setField(created, dt.toString(Qt::ISODate));
|
|
|
|
}
|
|
|
|
t = it.current()->time(TDEIO::UDS_MODIFICATION_TIME);
|
|
|
|
if(t > 0) {
|
|
|
|
TQDateTime dt;
|
|
|
|
dt.setTime_t(t);
|
|
|
|
entry->setField(modified, dt.toString(Qt::ISODate));
|
|
|
|
}
|
|
|
|
const KFileMetaInfo& meta = it.current()->metaInfo();
|
|
|
|
if(meta.isValid() && !meta.isEmpty()) {
|
|
|
|
const TQStringList keys = meta.supportedKeys();
|
|
|
|
TQStringList strings;
|
|
|
|
for(TQStringList::ConstIterator it2 = keys.begin(); it2 != keys.end(); ++it2) {
|
|
|
|
KFileMetaInfoItem item = meta.item(*it2);
|
|
|
|
if(item.isValid()) {
|
|
|
|
TQString s = item.string();
|
|
|
|
if(!s.isEmpty()) {
|
|
|
|
strings << item.key() + "::" + s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
entry->setField(metainfo, strings.join(TQString::fromLatin1("; ")));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_cancelled && usePreview) {
|
|
|
|
m_pixmap = NetAccess::filePreview(it.current(), FILE_PREVIEW_SIZE);
|
|
|
|
if(m_pixmap.isNull()) {
|
|
|
|
m_pixmap = it.current()->pixmap(0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
m_pixmap = it.current()->pixmap(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_pixmap.isNull()) {
|
|
|
|
// is png best option?
|
|
|
|
TQString id = ImageFactory::addImage(m_pixmap, TQString::fromLatin1("PNG"));
|
|
|
|
if(!id.isEmpty()) {
|
|
|
|
entry->setField(icon, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_coll->addEntries(entry);
|
|
|
|
|
|
|
|
if(showProgress && j%stepSize == 0) {
|
|
|
|
ProgressManager::self()->setProgress(this, j);
|
|
|
|
kapp->processEvents();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(m_cancelled) {
|
|
|
|
m_coll = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_coll;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQWidget* FileListingImporter::widget(TQWidget* parent_, const char* name_) {
|
|
|
|
if(m_widget) {
|
|
|
|
return m_widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_widget = new TQWidget(parent_, name_);
|
|
|
|
TQVBoxLayout* l = new TQVBoxLayout(m_widget);
|
|
|
|
|
|
|
|
TQVGroupBox* box = new TQVGroupBox(i18n("File Listing Options"), m_widget);
|
|
|
|
|
|
|
|
m_recursive = new TQCheckBox(i18n("Recursive folder search"), box);
|
|
|
|
TQWhatsThis::add(m_recursive, i18n("If checked, folders are recursively searched for all files."));
|
|
|
|
// by default, make it checked
|
|
|
|
m_recursive->setChecked(true);
|
|
|
|
|
|
|
|
m_filePreview = new TQCheckBox(i18n("Generate file previews"), box);
|
|
|
|
TQWhatsThis::add(m_filePreview, i18n("If checked, previews of the file contents are generated, which can slow down "
|
|
|
|
"the folder listing."));
|
|
|
|
// by default, make it no previews
|
|
|
|
m_filePreview->setChecked(false);
|
|
|
|
|
|
|
|
l->addWidget(box);
|
|
|
|
l->addStretch(1);
|
|
|
|
return m_widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileListingImporter::slotEntries(TDEIO::Job* job_, const TDEIO::UDSEntryList& list_) {
|
|
|
|
if(m_cancelled) {
|
|
|
|
job_->kill();
|
|
|
|
m_job = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(TDEIO::UDSEntryList::ConstIterator it = list_.begin(); it != list_.end(); ++it) {
|
|
|
|
KFileItem* item = new KFileItem(*it, url(), false, true);
|
|
|
|
if(item->isFile()) {
|
|
|
|
m_files.append(item);
|
|
|
|
} else {
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString FileListingImporter::volumeName() const {
|
|
|
|
// this functions turns /media/cdrom into /dev/hdc, then reads 32 bytes after the 16 x 2048 header
|
|
|
|
TQString volume;
|
|
|
|
const KMountPoint::List mountPoints = KMountPoint::currentMountPoints(KMountPoint::NeedRealDeviceName);
|
|
|
|
for(KMountPoint::List::ConstIterator it = mountPoints.begin(), end = mountPoints.end(); it != end; ++it) {
|
|
|
|
// path() could be /media/cdrom
|
|
|
|
// which could be the mount point of the device
|
|
|
|
// I know it works for iso9660 (cdrom) and udf (dvd)
|
|
|
|
if(url().path() == (*it)->mountPoint()
|
|
|
|
&& ((*it)->mountType() == Latin1Literal("iso9660")
|
|
|
|
|| (*it)->mountType() == Latin1Literal("udf"))) {
|
|
|
|
volume = (*it)->mountPoint();
|
|
|
|
if(!(*it)->realDeviceName().isEmpty()) {
|
|
|
|
TQString devName = (*it)->realDeviceName();
|
|
|
|
if(devName.endsWith(TQChar('/'))) {
|
|
|
|
devName.truncate(devName.length()-1);
|
|
|
|
}
|
|
|
|
// TQFile can't do a sequential seek, and I don't want to do a 32808x loop on getch()
|
|
|
|
FILE* dev = 0;
|
|
|
|
if((dev = fopen(devName.latin1(), "rb")) != 0) {
|
|
|
|
// returns 0 on success
|
|
|
|
if(fseek(dev, VOLUME_NAME_POS, SEEK_SET) == 0) {
|
|
|
|
char buf[VOLUME_NAME_SIZE];
|
|
|
|
int ret = fread(buf, 1, VOLUME_NAME_SIZE, dev);
|
|
|
|
if(ret == VOLUME_NAME_SIZE) {
|
|
|
|
volume = TQString::fromLatin1(buf, VOLUME_NAME_SIZE).stripWhiteSpace();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
myDebug() << "FileListingImporter::volumeName() - can't seek " << devName << endl;
|
|
|
|
}
|
|
|
|
fclose(dev);
|
|
|
|
} else {
|
|
|
|
myDebug() << "FileListingImporter::volumeName() - can't read " << devName << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return volume;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileListingImporter::slotCancel() {
|
|
|
|
m_cancelled = true;
|
|
|
|
if(m_job) {
|
|
|
|
m_job->kill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "filelistingimporter.moc"
|