File indexing completed on 2024-04-28 05:08:24
0001 /*************************************************************************** 0002 Copyright (C) 2001-2018 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include <config.h> 0026 0027 #include "mainwindow.h" 0028 #include "core/logger.h" 0029 #include "translators/translators.h" // needed for file type enum 0030 #include "tellico_debug.h" 0031 0032 #include <KAboutData> 0033 #include <KLocalizedString> 0034 #include <KCrash> 0035 #include <KSharedConfig> 0036 #include <Kdelibs4ConfigMigrator> 0037 #include <Kdelibs4Migration> 0038 0039 #include <QApplication> 0040 #include <QCommandLineParser> 0041 #include <QCommandLineOption> 0042 #include <QDir> 0043 #include <QFile> 0044 #include <QStack> 0045 #include <QDebug> 0046 0047 int main(int argc, char* argv[]) { 0048 QApplication app(argc, argv); 0049 QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 0050 KLocalizedString::setApplicationDomain("tellico"); 0051 app.setApplicationVersion(QStringLiteral(TELLICO_VERSION)); 0052 0053 Q_INIT_RESOURCE(icons); 0054 0055 // Migrate KDE4 configuration and data files 0056 Kdelibs4ConfigMigrator migrator(QStringLiteral("tellico")); 0057 migrator.setConfigFiles(QStringList() << QStringLiteral("tellicorc")); 0058 migrator.setUiFiles(QStringList() << QStringLiteral("tellicoui.rc")); 0059 0060 if(migrator.migrate()) { 0061 // migrate old data 0062 typedef QPair<QString, QString> StringPair; 0063 QList<StringPair> filesToCopy; 0064 QList<QString> dirsToCreate; 0065 0066 Kdelibs4Migration dataMigrator; 0067 const QString sourceBasePath = dataMigrator.saveLocation("data", QStringLiteral("tellico")); 0068 const QString targetBasePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/'); 0069 QString sourceFilePath, targetFilePath; 0070 0071 // first copy tellico-common.xsl if exists 0072 QString fileName = QStringLiteral("tellico-common.xsl"); 0073 sourceFilePath = sourceBasePath + QLatin1Char('/') + fileName; 0074 targetFilePath = targetBasePath + QLatin1Char('/') + fileName; 0075 if(QFile::exists(sourceFilePath) && !QFile::exists(targetFilePath)) { 0076 filesToCopy << qMakePair(sourceFilePath, targetFilePath); 0077 } 0078 0079 // then migrate data directories 0080 QStack<QString> dirsToCheck; 0081 dirsToCheck.push(QStringLiteral("report-templates")); 0082 dirsToCheck.push(QStringLiteral("entry-templates")); 0083 dirsToCheck.push(QStringLiteral("data-sources")); 0084 // this will copy all the images shared between collections 0085 dirsToCheck.push(QStringLiteral("data")); 0086 while(!dirsToCheck.isEmpty()) { 0087 QString dataDir = dirsToCheck.pop(); 0088 QDir sourceDir(sourceBasePath + dataDir); 0089 if(sourceDir.exists()) { 0090 if(!QDir().exists(targetBasePath + dataDir)) { 0091 dirsToCreate << (targetBasePath + dataDir); 0092 } 0093 // grab the internal directories, so we can be recursive 0094 QStringList moreDirs = sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); 0095 foreach(const QString& moreDir, moreDirs) { 0096 dirsToCheck.push(dataDir + QLatin1Char('/') + moreDir); 0097 } 0098 QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); 0099 foreach(const QString& fileName, fileNames) { 0100 sourceFilePath = sourceBasePath + dataDir + QLatin1Char('/') + fileName; 0101 targetFilePath = targetBasePath + dataDir + QLatin1Char('/') + fileName; 0102 if(!QFile::exists(targetFilePath)) { 0103 filesToCopy << qMakePair(sourceFilePath, targetFilePath); 0104 } 0105 } 0106 } 0107 } 0108 0109 foreach(const QString& dir, dirsToCreate) { 0110 QDir().mkpath(dir); 0111 } 0112 foreach(const StringPair& pair, filesToCopy) { 0113 QFile::copy(pair.first, pair.second); 0114 } 0115 0116 // update the configuration cache 0117 KSharedConfig::openConfig()->reparseConfiguration(); 0118 } 0119 0120 KCrash::initialize(); 0121 0122 // component name = "tellico" is same as bugs.kde.org product name 0123 KAboutData aboutData(QStringLiteral("tellico"), QStringLiteral("Tellico"), 0124 QStringLiteral(TELLICO_VERSION), i18n("Tellico - collection management software, free and simple"), 0125 KAboutLicense::GPL_V2, 0126 i18n("(c) 2001-2023, Robby Stephenson"), 0127 QString(), 0128 QStringLiteral("https://tellico-project.org")); 0129 aboutData.addAuthor(QStringLiteral("Robby Stephenson"), QString(), QStringLiteral("robby@periapsis.org")); 0130 aboutData.addAuthor(QStringLiteral("Mathias Monnerville"), i18n("Data source scripts")); 0131 aboutData.addAuthor(QStringLiteral("Regis Boudin"), QString(), QStringLiteral("regis@boudin.name")); 0132 aboutData.addAuthor(QStringLiteral("Petri Damstén"), QString(), QStringLiteral("damu@iki.fi")); 0133 aboutData.addAuthor(QStringLiteral("Sebastian Held"), QString()); 0134 0135 aboutData.addCredit(QStringLiteral("Virginie Quesnay"), i18n("Icons")); 0136 aboutData.addCredit(QStringLiteral("Amarok"), i18n("Code examples and general inspiration"), 0137 QString(), QStringLiteral("https://amarok.kde.org")); 0138 aboutData.addCredit(QStringLiteral("Greg Ward"), i18n("Author of btparse library")); 0139 aboutData.addCredit(QStringLiteral("Robert Gamble"), i18n("Author of libcsv library")); 0140 aboutData.addCredit(QStringLiteral("Valentin Lavrinenko"), i18n("Author of rtf2html library")); 0141 0142 aboutData.addLicense(KAboutLicense::GPL_V3); 0143 aboutData.setOrganizationDomain("kde.org"); 0144 aboutData.setDesktopFileName(QStringLiteral("org.kde.tellico.desktop")); 0145 0146 QCommandLineParser parser; 0147 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("nofile"), i18n("Do not reopen the last open file"))); 0148 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("bibtex"), i18n("Import <filename> as a bibtex file"))); 0149 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("mods"), i18n("Import <filename> as a MODS file"))); 0150 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("ris"), i18n("Import <filename> as a RIS file"))); 0151 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("pdf"), i18n("Import <filename> as a PDF file"))); 0152 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("log"), i18n("Log diagnostic output"))); 0153 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("logfile"), i18n("Write log output to <filename>"), QStringLiteral("logfile"))); 0154 parser.addPositionalArgument(QStringLiteral("[filename]"), i18n("File to open")); 0155 0156 aboutData.setupCommandLine(&parser); 0157 0158 parser.process(app); 0159 aboutData.processCommandLine(&parser); 0160 KAboutData::setApplicationData(aboutData); 0161 0162 #ifndef NDEBUG 0163 QLoggingCategory::setFilterRules(QStringLiteral("tellico.debug = true")); 0164 #endif 0165 // initialize logger 0166 Tellico::Logger::self(); 0167 QString logFile = qEnvironmentVariable("TELLICO_LOGFILE"); 0168 if(parser.isSet(QStringLiteral("logfile"))) { 0169 logFile = parser.value(QStringLiteral("logfile")); 0170 } 0171 if(logFile.isEmpty() && parser.isSet(QStringLiteral("log"))) { 0172 // use default log file location 0173 logFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/tellico_log.txt"); 0174 } 0175 if(!logFile.isEmpty()) { 0176 Tellico::Logger::self()->setLogFile(logFile); 0177 myLog() << "Starting Tellico" << QStringLiteral(TELLICO_VERSION) << "at" << QDateTime::currentDateTime().toString(Qt::ISODate); 0178 myLog() << "Opening log file" << logFile; 0179 } 0180 0181 if(app.isSessionRestored()) { 0182 myLog() << "Restoring previous session"; 0183 RESTORE(Tellico::MainWindow); 0184 } else { 0185 Tellico::MainWindow* tellico = new Tellico::MainWindow(); 0186 tellico->show(); 0187 // slotInit gets called out of a QTimer signal 0188 // but it wasn't always completing in-time 0189 // so call it manually to ensure it has finished 0190 tellico->slotInit(); 0191 0192 QStringList args = parser.positionalArguments(); 0193 if(args.count() > 0) { 0194 QLatin1String formatStr; 0195 Tellico::Import::Format format = Tellico::Import::TellicoXML; 0196 if(parser.isSet(QStringLiteral("bibtex"))) { 0197 format = Tellico::Import::Bibtex; 0198 formatStr = QLatin1String("bibtex"); 0199 } else if(parser.isSet(QStringLiteral("mods"))) { 0200 format = Tellico::Import::MODS; 0201 formatStr = QLatin1String("mods"); 0202 } else if(parser.isSet(QStringLiteral("ris"))) { 0203 format = Tellico::Import::RIS; 0204 formatStr = QLatin1String("ris"); 0205 } else if(parser.isSet(QStringLiteral("pdf"))) { 0206 format = Tellico::Import::PDF; 0207 formatStr = QLatin1String("pdf"); 0208 }; 0209 const QUrl fileToLoad = QUrl::fromUserInput(args.at(0), QDir::currentPath()); 0210 if(format == Tellico::Import::TellicoXML) { 0211 myLog() << "Opening" << fileToLoad.toDisplayString(QUrl::PreferLocalFile); 0212 tellico->slotFileOpen(fileToLoad); 0213 } else { 0214 myLog() << "Importing" << formatStr << "-" << fileToLoad.toDisplayString(QUrl::PreferLocalFile); 0215 tellico->importFile(format, fileToLoad, Tellico::Import::Replace); 0216 for(int i = 1; i < args.count(); ++i) { 0217 myLog() << "Appending" << fileToLoad.toDisplayString(QUrl::PreferLocalFile); 0218 tellico->importFile(format, fileToLoad, Tellico::Import::Append); 0219 } 0220 } 0221 } else { 0222 // bit of a hack, I just want the --nofile option 0223 // if --nofile is NOT passed, then the file option is set 0224 // is it's set, then go ahead and check for opening previous file 0225 tellico->initFileOpen(parser.isSet(QStringLiteral("nofile"))); 0226 } 0227 } 0228 0229 return app.exec(); 0230 }