File indexing completed on 2024-04-28 16:32:02

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 "translators/translators.h" // needed for file type enum
0029 
0030 #include <KAboutData>
0031 #include <KLocalizedString>
0032 #include <KCrash>
0033 #include <KSharedConfig>
0034 #include <Kdelibs4ConfigMigrator>
0035 #include <Kdelibs4Migration>
0036 
0037 #include <QApplication>
0038 #include <QCommandLineParser>
0039 #include <QCommandLineOption>
0040 #include <QDir>
0041 #include <QFile>
0042 #include <QStack>
0043 
0044 int main(int argc, char* argv[]) {
0045   QApplication app(argc, argv);
0046   QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
0047   KLocalizedString::setApplicationDomain("tellico");
0048   app.setApplicationVersion(QStringLiteral(TELLICO_VERSION));
0049 
0050   Q_INIT_RESOURCE(icons);
0051 
0052   // Migrate KDE4 configuration and data files
0053   Kdelibs4ConfigMigrator migrator(QStringLiteral("tellico"));
0054   migrator.setConfigFiles(QStringList() << QStringLiteral("tellicorc"));
0055   migrator.setUiFiles(QStringList() << QStringLiteral("tellicoui.rc"));
0056 
0057   if(migrator.migrate()) {
0058     // migrate old data
0059     typedef QPair<QString, QString> StringPair;
0060     QList<StringPair> filesToCopy;
0061     QList<QString> dirsToCreate;
0062 
0063     Kdelibs4Migration dataMigrator;
0064     const QString sourceBasePath = dataMigrator.saveLocation("data", QStringLiteral("tellico"));
0065     const QString targetBasePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/');
0066     QString sourceFilePath, targetFilePath;
0067 
0068     // first copy tellico-common.xsl if exists
0069     QString fileName = QStringLiteral("tellico-common.xsl");
0070     sourceFilePath = sourceBasePath + QLatin1Char('/') + fileName;
0071     targetFilePath = targetBasePath + QLatin1Char('/') + fileName;
0072     if(QFile::exists(sourceFilePath) && !QFile::exists(targetFilePath)) {
0073       filesToCopy << qMakePair(sourceFilePath, targetFilePath);
0074     }
0075 
0076     // then migrate data directories
0077     QStack<QString> dirsToCheck;
0078     dirsToCheck.push(QStringLiteral("report-templates"));
0079     dirsToCheck.push(QStringLiteral("entry-templates"));
0080     dirsToCheck.push(QStringLiteral("data-sources"));
0081     // this will copy all the images shared between collections
0082     dirsToCheck.push(QStringLiteral("data"));
0083     while(!dirsToCheck.isEmpty()) {
0084       QString dataDir = dirsToCheck.pop();
0085       QDir sourceDir(sourceBasePath + dataDir);
0086       if(sourceDir.exists()) {
0087         if(!QDir().exists(targetBasePath + dataDir)) {
0088           dirsToCreate << (targetBasePath + dataDir);
0089         }
0090         // grab the internal directories, so we can be recursive
0091         QStringList moreDirs = sourceDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
0092         foreach(const QString& moreDir, moreDirs) {
0093           dirsToCheck.push(dataDir + QLatin1Char('/') + moreDir);
0094         }
0095         QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
0096         foreach(const QString& fileName, fileNames) {
0097           sourceFilePath = sourceBasePath + dataDir + QLatin1Char('/') + fileName;
0098           targetFilePath = targetBasePath + dataDir + QLatin1Char('/') + fileName;
0099           if(!QFile::exists(targetFilePath)) {
0100             filesToCopy << qMakePair(sourceFilePath, targetFilePath);
0101           }
0102         }
0103       }
0104     }
0105 
0106     foreach(const QString& dir, dirsToCreate) {
0107       QDir().mkpath(dir);
0108     }
0109     foreach(const StringPair& pair, filesToCopy) {
0110       QFile::copy(pair.first, pair.second);
0111     }
0112 
0113     // update the configuration cache
0114     KSharedConfig::openConfig()->reparseConfiguration();
0115   }
0116 
0117   KCrash::initialize();
0118 
0119   // component name = "tellico" is same as bugs.kde.org product name
0120   KAboutData aboutData(QStringLiteral("tellico"), QStringLiteral("Tellico"),
0121                        QStringLiteral(TELLICO_VERSION), i18n("Tellico - collection management software, free and simple"),
0122                        KAboutLicense::GPL_V2,
0123                        i18n("(c) 2001-2023, Robby Stephenson"),
0124                        QString(),
0125                        QStringLiteral("https://tellico-project.org"));
0126   aboutData.addAuthor(QStringLiteral("Robby Stephenson"), QString(), QStringLiteral("robby@periapsis.org"));
0127   aboutData.addAuthor(QStringLiteral("Mathias Monnerville"), i18n("Data source scripts"));
0128   aboutData.addAuthor(QStringLiteral("Regis Boudin"), QString(), QStringLiteral("regis@boudin.name"));
0129   aboutData.addAuthor(QStringLiteral("Petri Damstén"), QString(), QStringLiteral("damu@iki.fi"));
0130   aboutData.addAuthor(QStringLiteral("Sebastian Held"), QString());
0131 
0132   aboutData.addCredit(QStringLiteral("Virginie Quesnay"), i18n("Icons"));
0133   aboutData.addCredit(QStringLiteral("Amarok"), i18n("Code examples and general inspiration"),
0134                       QString(), QStringLiteral("https://amarok.kde.org"));
0135   aboutData.addCredit(QStringLiteral("Greg Ward"), i18n("Author of btparse library"));
0136   aboutData.addCredit(QStringLiteral("Robert Gamble"), i18n("Author of libcsv library"));
0137   aboutData.addCredit(QStringLiteral("Valentin Lavrinenko"), i18n("Author of rtf2html library"));
0138 
0139   aboutData.addLicense(KAboutLicense::GPL_V3);
0140   aboutData.setOrganizationDomain("kde.org");
0141   aboutData.setDesktopFileName(QStringLiteral("org.kde.tellico.desktop"));
0142 
0143   QCommandLineParser parser;
0144   parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("nofile"), i18n("Do not reopen the last open file")));
0145   parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("bibtex"), i18n("Import <filename> as a bibtex file")));
0146   parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("mods"), i18n("Import <filename> as a MODS file")));
0147   parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("ris"), i18n("Import <filename> as a RIS file")));
0148   parser.addPositionalArgument(QStringLiteral("[filename]"), i18n("File to open"));
0149 
0150   aboutData.setupCommandLine(&parser);
0151 
0152   parser.process(app);
0153   aboutData.processCommandLine(&parser);
0154   KAboutData::setApplicationData(aboutData);
0155 
0156   if(app.isSessionRestored()) {
0157     RESTORE(Tellico::MainWindow);
0158   } else {
0159     Tellico::MainWindow* tellico = new Tellico::MainWindow();
0160     tellico->show();
0161     tellico->slotShowTipOfDay(false);
0162     // slotInit gets called out of a QTimer signal
0163     // but it wasn't always completing in-time
0164     // so call it manually to ensure it has finished
0165     tellico->slotInit();
0166 
0167     QStringList args = parser.positionalArguments();
0168     if(args.count() > 0) {
0169       Tellico::Import::Format format = Tellico::Import::TellicoXML;
0170       if(parser.isSet(QStringLiteral("bibtex"))) {
0171         format = Tellico::Import::Bibtex;
0172       } else if(parser.isSet(QStringLiteral("mods"))) {
0173         format = Tellico::Import::MODS;
0174       } else if(parser.isSet(QStringLiteral("ris"))) {
0175         format = Tellico::Import::RIS;
0176       };
0177       if(format == Tellico::Import::TellicoXML) {
0178         tellico->slotFileOpen(QUrl::fromUserInput(args.at(0), QDir::currentPath()));
0179       } else {
0180         tellico->importFile(format, QUrl::fromUserInput(args.at(0)), Tellico::Import::Replace);
0181         for(int i = 1; i < args.count(); ++i) {
0182           tellico->importFile(format, QUrl::fromUserInput(args.at(i)), Tellico::Import::Append);
0183         }
0184       }
0185     } else {
0186       // bit of a hack, I just want the --nofile option
0187       // if --nofile is NOT passed, then the file option is set
0188       // is it's set, then go ahead and check for opening previous file
0189       tellico->initFileOpen(parser.isSet(QStringLiteral("nofile")));
0190     }
0191   }
0192 
0193   return app.exec();
0194 }