File indexing completed on 2024-05-19 05:05:46
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 "bibliographyservice.h" 0021 0022 #include <QCoreApplication> 0023 #include <QStandardPaths> 0024 #include <QProcess> 0025 0026 #include <KSharedConfig> 0027 #include <KConfigGroup> 0028 #include <KLocalizedString> 0029 #include <KMessageBox> 0030 0031 class BibliographyService::Private 0032 { 0033 private: 0034 /// Representing configuration file "mimeapps.list" 0035 /// see https://www.freedesktop.org/wiki/Specifications/mime-apps-spec/ 0036 KSharedConfig::Ptr configXDGMimeAppsList; 0037 /// Groups inside "mimeapps.list" 0038 KConfigGroup configGroupAddedKDEServiceAssociations, configGroupRemovedKDEServiceAssociations; 0039 KConfigGroup configGroupAddedAssociations, configGroupRemovedAssociations; 0040 0041 /// Names of .desktop files for KBibTeX (application and KPart) 0042 static const QString kbibtexApplicationDesktop; 0043 static const QString kbibtexPartDesktop; 0044 /// Names of .desktop files for Kate (application and KPart) 0045 static const QString kateApplicationDesktop; 0046 static const QString katePartDesktop; 0047 0048 public: 0049 QWidget *parentWidget; 0050 static const QStringList textBasedMimeTypes; 0051 0052 Private(QWidget *w, BibliographyService *parent) 0053 : configXDGMimeAppsList(KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation)), 0054 configGroupAddedKDEServiceAssociations(configXDGMimeAppsList, QStringLiteral("Added KDE Service Associations")), 0055 configGroupRemovedKDEServiceAssociations(configXDGMimeAppsList, QStringLiteral("Removed KDE Service Associations")), 0056 configGroupAddedAssociations(configXDGMimeAppsList, QStringLiteral("Added Associations")), 0057 configGroupRemovedAssociations(configXDGMimeAppsList, QStringLiteral("Removed Associations")), 0058 parentWidget(w) 0059 { 0060 Q_UNUSED(parent) 0061 } 0062 0063 bool setKBibTeXforMimeType(const QString &mimetype, const bool isPlainTextFormat) { 0064 /// Check that configuration file is writeable before continuing 0065 if (!configXDGMimeAppsList->isConfigWritable(true)) 0066 return false; 0067 0068 /// Configuration which application to use to open bibliography files 0069 QStringList addedAssociations = configGroupAddedAssociations.readXdgListEntry(mimetype, QStringList()); 0070 /// Remove KBibTeX from list (will be added later to list's head) 0071 addedAssociations.removeAll(kbibtexApplicationDesktop); 0072 if (isPlainTextFormat) { 0073 /// Remove Kate from list (will be added later to list's second position) 0074 addedAssociations.removeAll(kateApplicationDesktop); 0075 /// Add Kate to list's head (will turn up as second) 0076 addedAssociations.prepend(kateApplicationDesktop); 0077 } 0078 /// Add KBibTeX to list's head 0079 addedAssociations.prepend(kbibtexApplicationDesktop); 0080 /// Write out and sync changes 0081 configGroupAddedAssociations.writeXdgListEntry(mimetype, addedAssociations); 0082 configGroupAddedAssociations.sync(); 0083 0084 /// Configuration which part to use to open bibliography files 0085 QStringList addedKDEServiceAssociations = configGroupAddedKDEServiceAssociations.readXdgListEntry(mimetype, QStringList()); 0086 /// Remove KBibTeX from list (will be added later to list's head) 0087 addedKDEServiceAssociations.removeAll(kbibtexPartDesktop); 0088 if (isPlainTextFormat) { 0089 /// Remove Kate from list (will be added later to list's second position) 0090 addedKDEServiceAssociations.removeAll(katePartDesktop); 0091 /// Add Kate to list's head (will turn up as second) 0092 addedKDEServiceAssociations.prepend(katePartDesktop); 0093 } 0094 /// Add KBibTeX to list's head 0095 addedKDEServiceAssociations.prepend(kbibtexPartDesktop); 0096 /// Write out and sync changes 0097 configGroupAddedKDEServiceAssociations.writeXdgListEntry(mimetype, addedKDEServiceAssociations); 0098 configGroupAddedKDEServiceAssociations.sync(); 0099 0100 /// Configuration which application NOT to use to open bibliography files 0101 QStringList removedAssociations = configGroupRemovedAssociations.readXdgListEntry(mimetype, QStringList()); 0102 /// If list of applications not to use is not empty ... 0103 if (!removedAssociations.isEmpty()) { 0104 /// Remove KBibTeX from list 0105 removedAssociations.removeAll(kbibtexApplicationDesktop); 0106 if (isPlainTextFormat) 0107 /// Remove Kate from list 0108 removedAssociations.removeAll(kateApplicationDesktop); 0109 if (removedAssociations.isEmpty()) 0110 /// Empty lists can be removed from configuration file 0111 configGroupRemovedAssociations.deleteEntry(mimetype); 0112 else 0113 /// Write out updated list 0114 configGroupRemovedAssociations.writeXdgListEntry(mimetype, removedAssociations); 0115 /// Sync changes 0116 configGroupRemovedAssociations.sync(); 0117 } 0118 0119 /// Configuration which part NOT to use to open bibliography files 0120 QStringList removedKDEServiceAssociations = configGroupRemovedKDEServiceAssociations.readXdgListEntry(mimetype, QStringList()); 0121 /// If list of parts not to use is not empty ... 0122 if (!removedKDEServiceAssociations.isEmpty()) { 0123 /// Remove KBibTeX part from list 0124 removedKDEServiceAssociations.removeAll(kbibtexPartDesktop); 0125 if (isPlainTextFormat) 0126 /// Remove Kate part from list 0127 removedKDEServiceAssociations.removeAll(katePartDesktop); 0128 if (removedKDEServiceAssociations.isEmpty()) 0129 /// Empty lists can be removed from configuration file 0130 configGroupRemovedKDEServiceAssociations.deleteEntry(mimetype); 0131 else 0132 /// Write out updated list 0133 configGroupRemovedKDEServiceAssociations.writeXdgListEntry(mimetype, removedKDEServiceAssociations); 0134 /// Sync changes 0135 configGroupRemovedKDEServiceAssociations.sync(); 0136 } 0137 0138 return true; 0139 } 0140 0141 bool isKBibTeXdefaultForMimeType(const QString &mimetype) const { 0142 /// Fetch all four configuration groups 0143 const QStringList addedAssociations = configGroupAddedAssociations.readXdgListEntry(mimetype, QStringList()); 0144 const QStringList addedKDEServiceAssociations = configGroupAddedKDEServiceAssociations.readXdgListEntry(mimetype, QStringList()); 0145 const QStringList removedAssociations = configGroupRemovedAssociations.readXdgListEntry(mimetype, QStringList()); 0146 const QStringList removedKDEServiceAssociations = configGroupRemovedKDEServiceAssociations.readXdgListEntry(mimetype, QStringList()); 0147 /// KBibTeX is default editor for bibliography if ... 0148 /// - the list of applications associated to mime type is not empty 0149 /// - KBibTeX is head of this list 0150 /// - KBibTeX is not named in the list of applications not be used 0151 /// - the list of parts associated to mime type is not empty 0152 /// - KBibTeX part is head of this list 0153 /// - KBibTeX part is not named in the list of parts not be used 0154 return !addedAssociations.isEmpty() && addedAssociations.first() == kbibtexApplicationDesktop && !removedAssociations.contains(kbibtexApplicationDesktop) && !addedKDEServiceAssociations.isEmpty() && addedKDEServiceAssociations.first() == kbibtexPartDesktop && !removedKDEServiceAssociations.contains(kbibtexPartDesktop); 0155 } 0156 }; 0157 0158 const QString BibliographyService::Private::kbibtexApplicationDesktop = QStringLiteral("org.kde.kbibtex.desktop"); 0159 const QString BibliographyService::Private::kbibtexPartDesktop = QStringLiteral("kbibtexpart.desktop"); 0160 const QString BibliographyService::Private::kateApplicationDesktop = QStringLiteral("org.kde.kate.desktop"); 0161 const QString BibliographyService::Private::katePartDesktop = QStringLiteral("katepart.desktop"); 0162 const QStringList BibliographyService::Private::textBasedMimeTypes { 0163 QStringLiteral("text/x-bibtex"), ///< classical BibTeX bibliographies 0164 QStringLiteral("application/x-research-info-systems"), ///< Research Information Systems (RIS) bibliographies 0165 QStringLiteral("application/x-isi-export-format") ///< Information Sciences Institute (ISI) bibliographies 0166 }; 0167 0168 BibliographyService::BibliographyService(QWidget *parentWidget) 0169 : QObject(parentWidget), d(new BibliographyService::Private(parentWidget, this)) 0170 { 0171 /// nothing 0172 } 0173 0174 BibliographyService::~BibliographyService() 0175 { 0176 delete d; 0177 } 0178 0179 void BibliographyService::setKBibTeXasDefault() { 0180 /// Go through all supported mime types 0181 for (const QString &mimeType : BibliographyService::Private::textBasedMimeTypes) { 0182 d->setKBibTeXforMimeType(mimeType, true); 0183 } 0184 0185 /// kbuildsycoca5 has to be run to update the mime type associations 0186 QProcess *kbuildsycoca5Process = new QProcess(d->parentWidget); 0187 connect(kbuildsycoca5Process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), QCoreApplication::instance(), [this](const int exitCode, const QProcess::ExitStatus exitStatus) { 0188 if (exitCode != 0 || exitStatus != QProcess::NormalExit) 0189 KMessageBox::error(d->parentWidget, i18n("Failed to run 'kbuildsycoca5' to update mime type associations.\n\nThe system may not know how to use KBibTeX to open bibliography files."), i18n("Failed to run 'kbuildsycoca5'")); 0190 }); 0191 kbuildsycoca5Process->start(QStringLiteral("kbuildsycoca5"), QStringList()); 0192 } 0193 0194 bool BibliographyService::isKBibTeXdefault() const { 0195 /// Go through all supported mime types 0196 for (const QString &mimeType : BibliographyService::Private::textBasedMimeTypes) { 0197 /// Test if KBibTeX is default handler for mime type 0198 if (!d->isKBibTeXdefaultForMimeType(mimeType)) 0199 return false; ///< Failing any test means KBibTeX is not default application/part 0200 } 0201 return true; ///< All tests passed, KBibTeX is default application/part 0202 }