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.
tellico/src/translators/bibtexmlimporter.cpp

164 lines
5.9 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 "bibtexmlimporter.h"
#include "tellico_xml.h"
#include "bibtexhandler.h"
#include "../collections/bibtexcollection.h"
#include "../field.h"
#include "../entry.h"
#include "../latin1literal.h"
#include "../tellico_strings.h"
#include "../progressmanager.h"
#include "../tellico_debug.h"
#include <tdeapplication.h>
using Tellico::Import::BibtexmlImporter;
bool BibtexmlImporter::canImport(int type) const {
return type == Data::Collection::Bibtex;
}
Tellico::Data::CollPtr BibtexmlImporter::collection() {
if(!m_coll) {
loadDomDocument();
}
return m_coll;
}
void BibtexmlImporter::loadDomDocument() {
TQDomElement root = domDocument().documentElement();
if(root.isNull() || root.localName() != Latin1Literal("file")) {
setStatusMessage(i18n(errorLoad).arg(url().fileName()));
return;
}
const TQString& ns = XML::nsBibtexml;
m_coll = new Data::BibtexCollection(true);
TQDomNodeList entryelems = root.elementsByTagNameNS(ns, TQString::fromLatin1("entry"));
// kdDebug() << "BibtexmlImporter::loadDomDocument - found " << entryelems.count() << " entries" << endl;
const uint count = entryelems.count();
const uint stepSize = TQMAX(s_stepSize, count/100);
const bool showProgress = options() & ImportProgress;
ProgressItem& item = ProgressManager::self()->newProgressItem(this, progressLabel(), true);
item.setTotalSteps(count);
connect(&item, TQ_SIGNAL(signalCancelled(ProgressItem*)), TQ_SLOT(slotCancel()));
ProgressItem::Done done(this);
for(uint j = 0; !m_cancelled && j < entryelems.count(); ++j) {
readEntry(entryelems.item(j));
if(showProgress && j%stepSize == 0) {
ProgressManager::self()->setProgress(this, j);
kapp->processEvents();
}
} // end entry loop
}
void BibtexmlImporter::readEntry(const TQDomNode& entryNode_) {
TQDomNode node = const_cast<TQDomNode&>(entryNode_);
Data::EntryPtr entry = new Data::Entry(m_coll);
/* The Bibtexml format looks like
<entry id="...">
<book>
<authorlist>
<author>...</author>
</authorlist>
<publisher>...</publisher> */
TQString type = node.firstChild().toElement().tagName();
entry->setField(TQString::fromLatin1("entry-type"), type);
TQString id = node.toElement().attribute(TQString::fromLatin1("id"));
entry->setField(TQString::fromLatin1("bibtex-key"), id);
TQString name, value;
// field values are first child of first child of entry node
for(TQDomNode n = node.firstChild().firstChild(); !n.isNull(); n = n.nextSibling()) {
// n could be something like authorlist, with multiple authors, or just
// a plain element with a single text child...
// second case first
if(n.firstChild().isText()) {
name = n.toElement().tagName();
value = n.toElement().text();
} else {
// is either titlelist, authorlist, editorlist, or keywords
TQString parName = n.toElement().tagName();
if(parName == Latin1Literal("titlelist")) {
for(TQDomNode n2 = node.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
name = n2.toElement().tagName();
value = n2.toElement().text();
if(!name.isEmpty() && !value.isEmpty()) {
BibtexHandler::setFieldValue(entry, name, value.simplifyWhiteSpace());
}
}
name.truncate(0);
value.truncate(0);
} else {
name = n.firstChild().toElement().tagName();
if(name == Latin1Literal("keyword")) {
name = TQString::fromLatin1("keywords");
}
value.truncate(0);
for(TQDomNode n2 = n.firstChild(); !n2.isNull(); n2 = n2.nextSibling()) {
// n2 could have first, middle, lastname elements...
if(name == Latin1Literal("person")) {
TQStringList names;
names << TQString::fromLatin1("initials") << TQString::fromLatin1("first")
<< TQString::fromLatin1("middle") << TQString::fromLatin1("prelast")
<< TQString::fromLatin1("last") << TQString::fromLatin1("lineage");
for(TQStringList::ConstIterator it = names.begin(); it != names.end(); ++it) {
TQDomNodeList list = n2.toElement().elementsByTagName(*it);
if(list.count() > 1) {
value += list.item(0).toElement().text();
}
if(*it != names.last()) {
value += TQString::fromLatin1(" ");
}
}
}
for(TQDomNode n3 = n2.firstChild(); !n3.isNull(); n3 = n3.nextSibling()) {
if(n3.isElement()) {
value += n3.toElement().text();
} else if(n3.isText()) {
value += n3.toText().data();
}
if(n3 != n2.lastChild()) {
value += TQString::fromLatin1(" ");
}
}
if(n2 != n.lastChild()) {
value += TQString::fromLatin1("; ");
}
}
}
}
if(!name.isEmpty() && !value.isEmpty()) {
BibtexHandler::setFieldValue(entry, name, value.simplifyWhiteSpace());
}
}
m_coll->addEntries(entry);
}
void BibtexmlImporter::slotCancel() {
m_cancelled = true;
}
#include "bibtexmlimporter.moc"