summaryrefslogtreecommitdiffstats
path: root/src/translators/bibtexmlimporter.cpp
blob: bf33c02ad8b86f75d299cbe0394d92ffb4a0071d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/***************************************************************************
    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 <kapplication.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, TQT_SIGNAL(signalCancelled(ProgressItem*)), TQT_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"