Warning, file /office/calligra/libs/text/BibliographyGenerator.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2011 Smit Patel <smitpatel24@gmail.com>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Library General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2 of the License, or (at your option) any later version.
0008  *
0009  * This library is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012  * Library General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU Library General Public License
0015  * along with this library; see the file COPYING.LIB.  If not, write to
0016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "BibliographyGenerator.h"
0021 #include "KoInlineCite.h"
0022 
0023 #include <klocalizedstring.h>
0024 #include <KoOdfBibliographyConfiguration.h>
0025 #include <KoInlineTextObjectManager.h>
0026 #include <KoParagraphStyle.h>
0027 #include <KoTextDocument.h>
0028 #include <KoStyleManager.h>
0029 
0030 #include <QTextFrame>
0031 
0032 #include <algorithm>
0033 
0034 static QVector<SortKeyPair> sortKeys;
0035 
0036 BibliographyGenerator::BibliographyGenerator(QTextDocument *bibDocument, const QTextBlock &block, KoBibliographyInfo *bibInfo)
0037     : QObject(bibDocument)
0038     , m_bibDocument(bibDocument)
0039     , m_bibInfo(bibInfo)
0040     , m_block(block)
0041 {
0042     Q_ASSERT(bibDocument);
0043     Q_ASSERT(bibInfo);
0044 
0045     m_bibInfo->setGenerator(this);
0046 
0047     bibDocument->setUndoRedoEnabled(false);
0048     generate();
0049 }
0050 
0051 BibliographyGenerator::~BibliographyGenerator()
0052 {
0053     delete m_bibInfo;
0054 }
0055 
0056 static bool compare_on(int keyIndex, KoInlineCite *c1, KoInlineCite *c2)
0057 {
0058     if ( keyIndex == sortKeys.size() ) return false;
0059     else if (sortKeys[keyIndex].second == Qt::AscendingOrder) {
0060         if (c1->dataField( sortKeys[keyIndex].first ) < c2->dataField( sortKeys[keyIndex].first )) return true;
0061         else if (c1->dataField( sortKeys[keyIndex].first ) > c2->dataField( sortKeys[keyIndex].first )) return false;
0062     } else if (sortKeys[keyIndex].second == Qt::DescendingOrder) {
0063         if (c1->dataField( sortKeys[keyIndex].first ) < c2->dataField( sortKeys[keyIndex].first )) return false;
0064         else if (c1->dataField( sortKeys[keyIndex].first ) > c2->dataField( sortKeys[keyIndex].first )) return true;
0065     } else return compare_on( keyIndex + 1, c1, c2 );
0066 
0067     return false;
0068 }
0069 
0070 static bool lessThan(KoInlineCite *c1, KoInlineCite *c2)
0071 {
0072     return compare_on(0, c1, c2);
0073 }
0074 
0075 static QList<KoInlineCite *> sort(QList<KoInlineCite *> cites, const QVector<SortKeyPair> &keys)
0076 {
0077     sortKeys = keys;
0078     sortKeys << QPair<QString, Qt::SortOrder>("identifier", Qt::AscendingOrder);
0079     std::sort(cites.begin(), cites.end(), lessThan);
0080     return cites;
0081 }
0082 
0083 void BibliographyGenerator::generate()
0084 {
0085     if (!m_bibInfo)
0086         return;
0087 
0088     QTextCursor cursor = m_bibDocument->rootFrame()->lastCursorPosition();
0089     cursor.setPosition(m_bibDocument->rootFrame()->firstPosition(), QTextCursor::KeepAnchor);
0090     cursor.beginEditBlock();
0091 
0092     KoStyleManager *styleManager = KoTextDocument(m_block.document()).styleManager();
0093 
0094     if (!m_bibInfo->m_indexTitleTemplate.text.isNull()) {
0095         KoParagraphStyle *titleStyle = styleManager->paragraphStyle(m_bibInfo->m_indexTitleTemplate.styleId);
0096         if (!titleStyle) {
0097             titleStyle = styleManager->defaultBibliographyTitleStyle();
0098             m_bibInfo->m_indexTitleTemplate.styleName = titleStyle->name();
0099         }
0100 
0101         QTextBlock titleTextBlock = cursor.block();
0102         titleStyle->applyStyle(titleTextBlock);
0103 
0104         cursor.insertText(m_bibInfo->m_indexTitleTemplate.text);
0105         cursor.insertBlock();
0106     }
0107 
0108     QTextCharFormat savedCharFormat = cursor.charFormat();
0109 
0110     QList<KoInlineCite*> citeList;
0111     if ( KoTextDocument(m_block.document()).styleManager()->bibliographyConfiguration()->sortByPosition() ) {
0112         citeList = KoTextDocument(m_block.document())
0113                 .inlineTextObjectManager()->citationsSortedByPosition(false, m_block.document()->firstBlock());
0114     } else {
0115         KoTextDocument *doc = new KoTextDocument(m_block.document());
0116         citeList = sort(doc->inlineTextObjectManager()->citationsSortedByPosition(false, m_block.document()->firstBlock()),
0117                         KoTextDocument(m_block.document()).styleManager()->bibliographyConfiguration()->sortKeys());
0118     }
0119 
0120     foreach (KoInlineCite *cite, citeList)
0121     {
0122         KoParagraphStyle *bibTemplateStyle = 0;
0123         BibliographyEntryTemplate bibEntryTemplate;
0124         if (m_bibInfo->m_entryTemplate.contains(cite->bibliographyType())) {
0125 
0126             bibEntryTemplate = m_bibInfo->m_entryTemplate[cite->bibliographyType()];
0127 
0128             bibTemplateStyle = styleManager->paragraphStyle(bibEntryTemplate.styleId);
0129             if (bibTemplateStyle == 0) {
0130                 bibTemplateStyle = styleManager->defaultBibliographyEntryStyle(bibEntryTemplate.bibliographyType);
0131                 bibEntryTemplate.styleName = bibTemplateStyle->name();
0132             }
0133         } else {
0134             continue;
0135         }
0136 
0137         cursor.insertBlock(QTextBlockFormat(),QTextCharFormat());
0138 
0139         QTextBlock bibEntryTextBlock = cursor.block();
0140         bibTemplateStyle->applyStyle(bibEntryTextBlock);
0141         bool spanEnabled = false;           //true if data field is not empty
0142 
0143         foreach (IndexEntry * entry, bibEntryTemplate.indexEntries) {
0144             switch(entry->name) {
0145                 case IndexEntry::BIBLIOGRAPHY: {
0146                     IndexEntryBibliography *indexEntry = static_cast<IndexEntryBibliography *>(entry);
0147                     cursor.insertText(QString(((spanEnabled)?" ":"")).append(cite->dataField(indexEntry->dataField)));
0148                     spanEnabled = !cite->dataField(indexEntry->dataField).isEmpty();
0149                     break;
0150                 }
0151                 case IndexEntry::SPAN: {
0152                     if(spanEnabled) {
0153                         IndexEntrySpan *span = static_cast<IndexEntrySpan*>(entry);
0154                         cursor.insertText(span->text);
0155                     }
0156                     break;
0157                 }
0158                 case IndexEntry::TAB_STOP: {
0159                     IndexEntryTabStop *tabEntry = static_cast<IndexEntryTabStop*>(entry);
0160 
0161                     cursor.insertText("\t");
0162 
0163                     QTextBlockFormat blockFormat = cursor.blockFormat();
0164                     QList<QVariant> tabList;
0165                     if (tabEntry->m_position == "MAX") {
0166                         tabEntry->tab.position = m_maxTabPosition;
0167                     } else {
0168                         tabEntry->tab.position = tabEntry->m_position.toDouble();
0169                     }
0170                     tabList.append(QVariant::fromValue<KoText::Tab>(tabEntry->tab));
0171                     blockFormat.setProperty(KoParagraphStyle::TabPositions, QVariant::fromValue<QList<QVariant> >(tabList));
0172                     cursor.setBlockFormat(blockFormat);
0173                     break;
0174                 }
0175                 default:{
0176                     break;
0177                 }
0178             }
0179         }// foreach
0180     }
0181     cursor.setCharFormat(savedCharFormat);   // restore the cursor char format
0182 }
0183 
0184 QMap<QString, BibliographyEntryTemplate> BibliographyGenerator::defaultBibliographyEntryTemplates()
0185 {
0186     QMap<QString, BibliographyEntryTemplate> entryTemplates;
0187     foreach (const QString &bibType, KoOdfBibliographyConfiguration::bibTypes) {
0188         BibliographyEntryTemplate bibEntryTemplate;
0189 
0190         //Now creating default IndexEntries for all BibliographyEntryTemplates
0191         IndexEntryBibliography *identifier = new IndexEntryBibliography(QString());
0192         IndexEntryBibliography *author = new IndexEntryBibliography(QString());
0193         IndexEntryBibliography *title = new IndexEntryBibliography(QString());
0194         IndexEntryBibliography *year = new IndexEntryBibliography(QString());
0195         IndexEntrySpan *firstSpan = new IndexEntrySpan(QString());
0196         IndexEntrySpan *otherSpan = new IndexEntrySpan(QString());
0197 
0198         identifier->dataField = "identifier";
0199         author->dataField = "author";
0200         title->dataField = "title";
0201         year->dataField = "year";
0202         firstSpan->text = ":";
0203         otherSpan->text = ",";
0204 
0205         bibEntryTemplate.bibliographyType = bibType;
0206         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(identifier));
0207         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(firstSpan));
0208         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(author));
0209         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(otherSpan));
0210         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(title));
0211         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(otherSpan));
0212         bibEntryTemplate.indexEntries.append(static_cast<IndexEntry *>(year));
0213 
0214         entryTemplates[bibType] = bibEntryTemplate;
0215     }
0216     return entryTemplates;
0217 }