File indexing completed on 2025-01-12 04:35:49
0001 /*************************************************************************** 0002 * SPDX-License-Identifier: GPL-2.0-or-later 0003 * * 0004 * SPDX-FileCopyrightText: 2004-2019 Thomas Fischer <fischer@unix-ag.uni-kl.de> 0005 * * 0006 * This program is free software; you can redistribute it and/or modify * 0007 * it under the terms of the GNU General Public License as published by * 0008 * the Free Software Foundation; either version 2 of the License, or * 0009 * (at your option) any later version. * 0010 * * 0011 * This program is distributed in the hope that it will be useful, * 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0014 * GNU General Public License for more details. * 0015 * * 0016 * You should have received a copy of the GNU General Public License * 0017 * along with this program; if not, see <https://www.gnu.org/licenses/>. * 0018 ***************************************************************************/ 0019 0020 #include "statistics.h" 0021 0022 #include <QFormLayout> 0023 #include <QLabel> 0024 #include <QFont> 0025 #include <QItemSelectionModel> 0026 0027 #include <KLocalizedString> 0028 0029 #include <File> 0030 #include <file/FileView> 0031 #include <Entry> 0032 #include <Macro> 0033 #include <Comment> 0034 #include "openfileinfo.h" 0035 0036 class Statistics::StatisticsPrivate 0037 { 0038 private: 0039 // UNUSED Statistics *p; 0040 QLabel *labelNumberOfElements, *labelNumberOfEntries, *labelNumberOfJournalArticles, *labelNumberOfConferencePublications, *labelNumberOfBooks, *labelNumberOfOtherEntries, *labelNumberOfComments, *labelNumberOfMacros; 0041 0042 public: 0043 FileView *fileView; 0044 const File *file; 0045 const QItemSelectionModel *selectionModel; 0046 0047 StatisticsPrivate(Statistics *parent) 0048 : /* UNUSED p(parent),*/ fileView(nullptr), file(nullptr), selectionModel(nullptr) { 0049 QFormLayout *layout = new QFormLayout(parent); 0050 0051 labelNumberOfElements = new QLabel(parent); 0052 setBold(labelNumberOfElements); 0053 layout->addRow(i18n("Number of Elements:"), labelNumberOfElements); 0054 0055 labelNumberOfEntries = new QLabel(parent); 0056 setBold(labelNumberOfEntries); 0057 layout->addRow(i18n("Number of Entries:"), labelNumberOfEntries); 0058 0059 labelNumberOfJournalArticles = new QLabel(parent); 0060 layout->addRow(i18n("Journal Articles:"), labelNumberOfJournalArticles); 0061 0062 labelNumberOfConferencePublications = new QLabel(parent); 0063 layout->addRow(i18n("Conference Publications:"), labelNumberOfConferencePublications); 0064 0065 labelNumberOfBooks = new QLabel(parent); 0066 layout->addRow(i18n("Books:"), labelNumberOfBooks); 0067 0068 labelNumberOfOtherEntries = new QLabel(parent); 0069 layout->addRow(i18n("Other Entries:"), labelNumberOfOtherEntries); 0070 0071 labelNumberOfComments = new QLabel(parent); 0072 setBold(labelNumberOfComments); 0073 layout->addRow(i18n("Number of Comments:"), labelNumberOfComments); 0074 0075 labelNumberOfMacros = new QLabel(parent); 0076 setBold(labelNumberOfMacros); 0077 layout->addRow(i18n("Number of Macros:"), labelNumberOfMacros); 0078 } 0079 0080 void setBold(QLabel *label) { 0081 QFont font = label->font(); 0082 font.setBold(true); 0083 label->setFont(font); 0084 } 0085 0086 void update() { 0087 file = fileView != nullptr && fileView->fileModel() != nullptr ? fileView->fileModel()->bibliographyFile() : nullptr; 0088 selectionModel = fileView != nullptr ? fileView->selectionModel() : nullptr; 0089 0090 if (file != nullptr) { 0091 int numElements, numEntries, numJournalArticles, numConferencePublications, numBooks, numComments, numMacros; 0092 countElementTypes(numElements, numEntries, numJournalArticles, numConferencePublications, numBooks, numComments, numMacros); 0093 0094 labelNumberOfElements->setText(QString::number(numElements)); 0095 labelNumberOfEntries->setText(QString::number(numEntries)); 0096 labelNumberOfJournalArticles->setText(QString::number(numJournalArticles)); 0097 labelNumberOfConferencePublications->setText(QString::number(numConferencePublications)); 0098 labelNumberOfBooks->setText(QString::number(numBooks)); 0099 labelNumberOfOtherEntries->setText(QString::number(numEntries - numJournalArticles - numConferencePublications - numBooks)); 0100 labelNumberOfComments->setText(QString::number(numComments)); 0101 labelNumberOfMacros->setText(QString::number(numMacros)); 0102 } else { 0103 labelNumberOfElements->setText(QChar(0x2013)); 0104 labelNumberOfEntries->setText(QChar(0x2013)); 0105 labelNumberOfJournalArticles->setText(QChar(0x2013)); 0106 labelNumberOfConferencePublications->setText(QChar(0x2013)); 0107 labelNumberOfBooks->setText(QChar(0x2013)); 0108 labelNumberOfOtherEntries->setText(QChar(0x2013)); 0109 labelNumberOfComments->setText(QChar(0x2013)); 0110 labelNumberOfMacros->setText(QChar(0x2013)); 0111 } 0112 } 0113 0114 void countElement(const QSharedPointer<const Element> &element, int &numEntries, int &numJournalArticles, int &numConferencePublications, int &numBooks, int &numComments, int &numMacros) { 0115 const QSharedPointer<const Entry> entry = element.dynamicCast<const Entry>(); 0116 if (!entry.isNull()) { 0117 if (entry->type().toLower() == Entry::etArticle) 0118 ++numJournalArticles; 0119 else if (entry->type().toLower() == Entry::etInProceedings) 0120 ++numConferencePublications; 0121 else if (entry->type().toLower() == Entry::etBook) 0122 ++numBooks; 0123 ++numEntries; 0124 } else if (!element.dynamicCast<const Macro>().isNull()) 0125 ++numMacros; 0126 else if (!element.dynamicCast<const Comment>().isNull()) 0127 ++numComments; 0128 } 0129 0130 void countElementTypes(int &numElements, int &numEntries, int &numJournalArticles, int &numConferencePublications, int &numBooks, int &numComments, int &numMacros) { 0131 numElements = numEntries = numJournalArticles = numConferencePublications = numBooks = numComments = numMacros = 0; 0132 Q_ASSERT_X(file != nullptr, "Statistics::StatisticsPrivate::countElementTypes(..)", "Function was called with file==NULL"); 0133 0134 if (selectionModel != nullptr && selectionModel->selectedRows().count() > 1) { 0135 /// Use selected items for statistics if selection contains at least two elements 0136 const auto selectedRows = selectionModel->selectedRows(); 0137 numElements = selectedRows.count(); 0138 for (const QModelIndex &index : selectedRows) { 0139 const int row = index.row(); 0140 if (row >= 0 && row < file->count()) 0141 countElement(file->at(row), numEntries, numJournalArticles, numConferencePublications, numBooks, numComments, numMacros); 0142 } 0143 } else { 0144 /// Default/fall-back: use whole file for statistics 0145 numElements = file->count(); 0146 for (const auto &element : const_cast<const File &>(*file)) 0147 countElement(element, numEntries, numJournalArticles, numConferencePublications, numBooks, numComments, numMacros); 0148 } 0149 } 0150 }; 0151 0152 Statistics::Statistics(QWidget *parent) 0153 : QWidget(parent), d(new StatisticsPrivate(this)) 0154 { 0155 d->update(); 0156 connect(&OpenFileInfoManager::instance(), &OpenFileInfoManager::currentChanged, this, &Statistics::update); 0157 } 0158 0159 Statistics::~Statistics() 0160 { 0161 delete d; 0162 } 0163 0164 void Statistics::setFileView(FileView *fileView) 0165 { 0166 if (d->fileView != nullptr) 0167 disconnect(d->fileView, &FileView::selectedElementsChanged, this, &Statistics::update); 0168 d->fileView = fileView; 0169 if (d->fileView != nullptr) 0170 connect(d->fileView, &FileView::selectedElementsChanged, this, &Statistics::update); 0171 d->update(); 0172 } 0173 0174 void Statistics::update() 0175 { 0176 d->update(); 0177 }