BibliographyGenerator.cpp 8.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* This file is part of the KDE project
 * Copyright (C) 2011 Smit Patel <smitpatel24@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "BibliographyGenerator.h"
21 22
#include "KoInlineCite.h"

23
#include <klocalizedstring.h>
24
#include <KoOdfBibliographyConfiguration.h>
25
#include <KoInlineTextObjectManager.h>
26 27 28 29 30 31
#include <KoParagraphStyle.h>
#include <KoTextDocument.h>
#include <KoStyleManager.h>

#include <QTextFrame>

Smit Patel's avatar
Smit Patel committed
32 33
static QList<SortKeyPair> sortKeys;

34
BibliographyGenerator::BibliographyGenerator(QTextDocument *bibDocument, const QTextBlock &block, KoBibliographyInfo *bibInfo)
35 36
    : QObject(bibDocument)
    , m_bibDocument(bibDocument)
37
    , m_bibInfo(bibInfo)
38
    , m_block(block)
39
{
40
    Q_ASSERT(bibDocument);
41 42 43 44
    Q_ASSERT(bibInfo);

    m_bibInfo->setGenerator(this);

45
    bibDocument->setUndoRedoEnabled(false);
46
    generate();
47 48 49 50
}

BibliographyGenerator::~BibliographyGenerator()
{
51
    delete m_bibInfo;
52 53
}

Smit Patel's avatar
Smit Patel committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
static bool compare_on(int keyIndex, KoInlineCite *c1, KoInlineCite *c2)
{
    if ( keyIndex == sortKeys.size() ) return false;
    else if (sortKeys[keyIndex].second == Qt::AscendingOrder) {
        if (c1->dataField( sortKeys[keyIndex].first ) < c2->dataField( sortKeys[keyIndex].first )) return true;
        else if (c1->dataField( sortKeys[keyIndex].first ) > c2->dataField( sortKeys[keyIndex].first )) return false;
    } else if (sortKeys[keyIndex].second == Qt::DescendingOrder) {
        if (c1->dataField( sortKeys[keyIndex].first ) < c2->dataField( sortKeys[keyIndex].first )) return false;
        else if (c1->dataField( sortKeys[keyIndex].first ) > c2->dataField( sortKeys[keyIndex].first )) return true;
    } else return compare_on( keyIndex + 1, c1, c2 );

    return false;
}

static bool lessThan(KoInlineCite *c1, KoInlineCite *c2)
{
    return compare_on(0, c1, c2);
}

static QList<KoInlineCite *> sort(QList<KoInlineCite *> cites, QList<SortKeyPair> keys)
{
    sortKeys = keys;
    sortKeys << QPair<QString, Qt::SortOrder>("identifier", Qt::AscendingOrder);
77
    std::sort(cites.begin(), cites.end(), lessThan);
Smit Patel's avatar
Smit Patel committed
78
    return cites;
79 80 81 82 83 84 85
}

void BibliographyGenerator::generate()
{
    if (!m_bibInfo)
        return;

86 87
    QTextCursor cursor = m_bibDocument->rootFrame()->lastCursorPosition();
    cursor.setPosition(m_bibDocument->rootFrame()->firstPosition(), QTextCursor::KeepAnchor);
88 89
    cursor.beginEditBlock();

90 91
    KoTextDocument koDocument(m_block.document());
    KoStyleManager *styleManager = koDocument.styleManager();
92 93 94 95

    if (!m_bibInfo->m_indexTitleTemplate.text.isNull()) {
        KoParagraphStyle *titleStyle = styleManager->paragraphStyle(m_bibInfo->m_indexTitleTemplate.styleId);
        if (!titleStyle) {
Smit Patel's avatar
Smit Patel committed
96 97
            titleStyle = styleManager->defaultBibliographyTitleStyle();
            m_bibInfo->m_indexTitleTemplate.styleName = titleStyle->name();
98 99 100 101 102
        }

        QTextBlock titleTextBlock = cursor.block();
        titleStyle->applyStyle(titleTextBlock);

103 104
        cursor.insertText(m_bibInfo->m_indexTitleTemplate.text);
        cursor.insertBlock();
105 106
    }

107
    QTextCharFormat savedCharFormat = cursor.charFormat();
Smit Patel's avatar
Smit Patel committed
108 109

    QList<KoInlineCite*> citeList;
110 111 112
    if (styleManager->bibliographyConfiguration()->sortByPosition()) {
        citeList = koDocument.inlineTextObjectManager()->
            citationsSortedByPosition(false, m_block.document()->firstBlock());
Smit Patel's avatar
Smit Patel committed
113
    } else {
114 115 116
        citeList = sort(koDocument.inlineTextObjectManager()->
                        citationsSortedByPosition(false, m_block.document()->firstBlock()),
                        koDocument.styleManager()->bibliographyConfiguration()->sortKeys());
Smit Patel's avatar
Smit Patel committed
117
    }
118

119 120 121 122
    foreach (KoInlineCite *cite, citeList)
    {
        KoParagraphStyle *bibTemplateStyle = 0;
        BibliographyEntryTemplate bibEntryTemplate;
123
        if (m_bibInfo->m_entryTemplate.contains(cite->bibliographyType())) {
124 125

            bibEntryTemplate = m_bibInfo->m_entryTemplate[cite->bibliographyType()];
126 127 128

            bibTemplateStyle = styleManager->paragraphStyle(bibEntryTemplate.styleId);
            if (bibTemplateStyle == 0) {
Smit Patel's avatar
Smit Patel committed
129 130
                bibTemplateStyle = styleManager->defaultBibliographyEntryStyle(bibEntryTemplate.bibliographyType);
                bibEntryTemplate.styleName = bibTemplateStyle->name();
131
            }
132 133 134
        } else {
            continue;
        }
135

136
        cursor.insertBlock(QTextBlockFormat(),QTextCharFormat());
137 138

        QTextBlock bibEntryTextBlock = cursor.block();
139 140
        bibTemplateStyle->applyStyle(bibEntryTextBlock);
        bool spanEnabled = false;           //true if data field is not empty
Smit Patel's avatar
Smit Patel committed
141

142 143 144 145
        foreach (IndexEntry * entry, bibEntryTemplate.indexEntries) {
            switch(entry->name) {
                case IndexEntry::BIBLIOGRAPHY: {
                    IndexEntryBibliography *indexEntry = static_cast<IndexEntryBibliography *>(entry);
Smit Patel's avatar
Smit Patel committed
146 147
                    cursor.insertText(QString(((spanEnabled)?" ":"")).append(cite->dataField(indexEntry->dataField)));
                    spanEnabled = !cite->dataField(indexEntry->dataField).isEmpty();
148 149 150 151 152
                    break;
                }
                case IndexEntry::SPAN: {
                    if(spanEnabled) {
                        IndexEntrySpan *span = static_cast<IndexEntrySpan*>(entry);
153 154
                        cursor.insertText(span->text);
                    }
155 156 157 158
                    break;
                }
                case IndexEntry::TAB_STOP: {
                    IndexEntryTabStop *tabEntry = static_cast<IndexEntryTabStop*>(entry);
159

160
                    cursor.insertText("\t");
161

162 163 164 165 166 167
                    QTextBlockFormat blockFormat = cursor.blockFormat();
                    QList<QVariant> tabList;
                    if (tabEntry->m_position == "MAX") {
                        tabEntry->tab.position = m_maxTabPosition;
                    } else {
                        tabEntry->tab.position = tabEntry->m_position.toDouble();
168
                    }
169 170 171 172
                    tabList.append(QVariant::fromValue<KoText::Tab>(tabEntry->tab));
                    blockFormat.setProperty(KoParagraphStyle::TabPositions, QVariant::fromValue<QList<QVariant> >(tabList));
                    cursor.setBlockFormat(blockFormat);
                    break;
173
                }
174 175 176 177 178
                default:{
                    break;
                }
            }
        }// foreach
179
    }
180
    cursor.setCharFormat(savedCharFormat);   // restore the cursor char format
181 182
}

Smit Patel's avatar
Smit Patel committed
183 184 185
QMap<QString, BibliographyEntryTemplate> BibliographyGenerator::defaultBibliographyEntryTemplates()
{
    QMap<QString, BibliographyEntryTemplate> entryTemplates;
186
    foreach (const QString &bibType, KoOdfBibliographyConfiguration::bibTypes) {
Smit Patel's avatar
Smit Patel committed
187
        BibliographyEntryTemplate bibEntryTemplate;
188

Smit Patel's avatar
Smit Patel committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        //Now creating default IndexEntries for all BibliographyEntryTemplates
        IndexEntryBibliography *identifier = new IndexEntryBibliography(QString());
        IndexEntryBibliography *author = new IndexEntryBibliography(QString());
        IndexEntryBibliography *title = new IndexEntryBibliography(QString());
        IndexEntryBibliography *year = new IndexEntryBibliography(QString());
        IndexEntrySpan *firstSpan = new IndexEntrySpan(QString());
        IndexEntrySpan *otherSpan = new IndexEntrySpan(QString());

        identifier->dataField = "identifier";
        author->dataField = "author";
        title->dataField = "title";
        year->dataField = "year";
        firstSpan->text = ":";
        otherSpan->text = ",";

        bibEntryTemplate.bibliographyType = bibType;
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(identifier));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(firstSpan));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(author));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(otherSpan));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(title));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(otherSpan));
        bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(year));

        entryTemplates[bibType] = bibEntryTemplate;
    }
    return entryTemplates;
}