File indexing completed on 2024-05-12 08:17:14

0001 /*
0002 Gwenview: an image viewer
0003 Copyright 2007-2012 Aurélien Gâteau <agateau@kde.org>
0004 
0005 This program is free software; you can redistribute it and/or
0006 modify it under the terms of the GNU General Public License
0007 as published by the Free Software Foundation; either version 2
0008 of the License, or (at your option) any later version.
0009 
0010 This program is distributed in the hope that it will be useful,
0011 but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 GNU General Public License for more details.
0014 
0015 You should have received a copy of the GNU General Public License
0016 along with this program; if not, write to the Free Software
0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018 
0019 */
0020 #include <config-gwenview.h>
0021 
0022 // Qt
0023 #include <QApplication>
0024 #include <QCommandLineParser>
0025 #include <QPointer>
0026 #include <QScopedPointer>
0027 #include <QStringList>
0028 #include <QTemporaryDir>
0029 #include <QUrl>
0030 
0031 // KF
0032 #include <KAboutData>
0033 #include <KActionCollection>
0034 #include <KIO/CopyJob>
0035 #include <KLocalizedString>
0036 
0037 // Local
0038 #include "mainwindow.h"
0039 #include <lib/about.h>
0040 #include <lib/gwenviewconfig.h>
0041 
0042 #ifdef HAVE_FITS
0043 // This hack is needed to include the fitsplugin moc file in main.cpp
0044 // Otherwise the linker complains about: undefined reference to `qt_static_plugin_FitsPlugin()'
0045 // This symbol is defined in the moc file, but it is not a visible symbol after libgwenview is linked.
0046 // If Q_IMPORT_PLUGIN(FitsPlugin) is moved to the library, gwenview crashes on the first call to FitsPlugin()
0047 // when the vtable is looked up in the plugin registration.
0048 #include <../lib/imageformats/moc_fitsplugin.cpp>
0049 #endif
0050 
0051 // To shut up libtiff
0052 #ifdef HAVE_TIFF
0053 #include <QLoggingCategory>
0054 #include <tiffio.h>
0055 
0056 namespace
0057 {
0058 Q_DECLARE_LOGGING_CATEGORY(LibTiffLog)
0059 Q_LOGGING_CATEGORY(LibTiffLog, "gwenview.libtiff", QtWarningMsg)
0060 
0061 static void handleTiffWarning(const char *mod, const char *fmt, va_list ap)
0062 {
0063     qCDebug(LibTiffLog) << "Warning:" << mod << QString::vasprintf(fmt, ap);
0064 }
0065 
0066 static void handleTiffError(const char *mod, const char *fmt, va_list ap)
0067 {
0068     // Since we're doing thumbnails, we don't really care about warnings by default either
0069     qCWarning(LibTiffLog) << "Error" << mod << QString::vasprintf(fmt, ap);
0070 }
0071 
0072 } // namespace
0073 #endif
0074 
0075 // To enable AVIF/HEIF/JPEG-XL metadata support in Exiv2
0076 #include <exiv2/exiv2.hpp>
0077 
0078 #ifdef KIMAGEANNOTATOR_CAN_LOAD_TRANSLATIONS
0079 #include <kImageAnnotator/KImageAnnotator.h>
0080 #endif
0081 
0082 class StartHelper
0083 {
0084 public:
0085     StartHelper(const QStringList &args, bool fullscreen, bool slideshow)
0086         : mFullScreen(false)
0087         , mSlideShow(false)
0088     {
0089         if (!args.isEmpty()) {
0090             parseArgs(args, fullscreen, slideshow);
0091         }
0092     }
0093 
0094     void parseArgs(const QStringList &args, bool fullscreen, bool slideshow)
0095     {
0096         if (args.count() > 1) {
0097             // Create a temp dir containing links to url args
0098             mMultipleUrlsDir.reset(new QTemporaryDir);
0099             mUrl = QUrl::fromLocalFile(mMultipleUrlsDir->path());
0100             QList<QUrl> list;
0101             QStringList tmpArgs = args;
0102             tmpArgs.removeDuplicates();
0103             QStringList fileNames;
0104             for (const QString &url : qAsConst(tmpArgs)) {
0105                 QUrl fileUrl = QUrl::fromUserInput(url, QDir::currentPath(), QUrl::AssumeLocalFile);
0106                 if (!fileNames.contains(fileUrl.fileName())) {
0107                     fileNames << fileUrl.fileName();
0108                     list << fileUrl;
0109                 }
0110             }
0111 
0112             KIO::CopyJob *job = KIO::link(list, mUrl);
0113             job->exec();
0114         } else {
0115             QString tmpArg = args.first();
0116             mUrl = QUrl::fromUserInput(tmpArg, QDir::currentPath(), QUrl::AssumeLocalFile);
0117         }
0118 
0119         if (mUrl.isValid() && (fullscreen || slideshow)) {
0120             mFullScreen = true;
0121             if (slideshow) {
0122                 mSlideShow = true;
0123             }
0124         }
0125     }
0126 
0127     void createMainWindow()
0128     {
0129         mMainWindow = new Gwenview::MainWindow();
0130         if (mUrl.isValid()) {
0131             mMainWindow->setInitialUrl(mUrl);
0132         } else {
0133             mMainWindow->showStartMainPage();
0134         }
0135 
0136         mMainWindow->show();
0137         if (mFullScreen) {
0138             mMainWindow->actionCollection()->action(QStringLiteral("fullscreen"))->trigger();
0139         }
0140 
0141         if (mSlideShow) {
0142             mMainWindow->startSlideShow();
0143         }
0144     }
0145 
0146 private:
0147     QUrl mUrl;
0148     bool mFullScreen;
0149     bool mSlideShow;
0150     QScopedPointer<QTemporaryDir> mMultipleUrlsDir;
0151     QPointer<Gwenview::MainWindow> mMainWindow;
0152 };
0153 
0154 int main(int argc, char *argv[])
0155 {
0156     // enable AVIF/HEIF/JPEG-XL metadata support
0157 #ifdef EXV_ENABLE_BMFF
0158     Exiv2::enableBMFF(true);
0159 #endif
0160 
0161 #ifdef HAVE_TIFF
0162     TIFFSetWarningHandler(handleTiffWarning);
0163     TIFFSetErrorHandler(handleTiffError);
0164 #endif
0165 
0166     /**
0167      * enable high dpi support
0168      */
0169     QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
0170 
0171     QApplication app(argc, argv);
0172     KLocalizedString::setApplicationDomain("gwenview");
0173     QScopedPointer<KAboutData> aboutData(Gwenview::createAboutData(QStringLiteral("gwenview"), /* component name */
0174                                                                    i18n("Gwenview") /* display name */
0175                                                                    ));
0176     aboutData->setShortDescription(i18n("An Image Viewer"));
0177 
0178     aboutData->setOrganizationDomain(QByteArray("kde.org"));
0179     KAboutData::setApplicationData(*aboutData);
0180     QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("gwenview"), app.windowIcon()));
0181 
0182     QCommandLineParser parser;
0183     aboutData.data()->setupCommandLine(&parser);
0184     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("fullscreen"), i18n("Start in fullscreen mode")));
0185     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("s") << QStringLiteral("slideshow"), i18n("Start in slideshow mode")));
0186     parser.addPositionalArgument("url", i18n("A starting file or folders"));
0187     parser.process(app);
0188     aboutData.data()->processCommandLine(&parser);
0189 
0190     // startHelper must live for the whole life of the application
0191     StartHelper startHelper(parser.positionalArguments(),
0192                             parser.isSet(QStringLiteral("f")) ? true : Gwenview::GwenviewConfig::fullScreenModeActive(),
0193                             parser.isSet(QStringLiteral("s")));
0194     if (app.isSessionRestored()) {
0195         kRestoreMainWindows<Gwenview::MainWindow>();
0196     } else {
0197         startHelper.createMainWindow();
0198     }
0199 
0200     // Workaround for QTBUG-38613
0201     // Another solution would be to port BalooSemanticInfoBackend::refreshAllTags
0202     // to be async rather than using exec().
0203     qApp->sendPostedEvents(nullptr, QEvent::DeferredDelete);
0204 
0205 #ifdef KIMAGEANNOTATOR_CAN_LOAD_TRANSLATIONS
0206     kImageAnnotator::loadTranslations();
0207 #endif
0208 
0209     return app.exec();
0210 }
0211 
0212 #ifdef HAVE_FITS
0213 Q_IMPORT_PLUGIN(FitsPlugin)
0214 #endif