File indexing completed on 2024-05-05 04:19:17

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, bool spotlightmode)
0086         : mFullScreen(false)
0087         , mSlideShow(false)
0088         , mSpotlightMode(false)
0089     {
0090         if (!args.isEmpty()) {
0091             parseArgs(args, fullscreen, slideshow, spotlightmode);
0092         }
0093     }
0094 
0095     void parseArgs(const QStringList &args, bool fullscreen, bool slideshow, bool spotlightmode)
0096     {
0097         if (args.count() > 1) {
0098             // Create a temp dir containing links to url args
0099             mMultipleUrlsDir.reset(new QTemporaryDir);
0100             mUrl = QUrl::fromLocalFile(mMultipleUrlsDir->path());
0101             QList<QUrl> list;
0102             QStringList tmpArgs = args;
0103             tmpArgs.removeDuplicates();
0104             QStringList fileNames;
0105             for (const QString &url : qAsConst(tmpArgs)) {
0106                 QUrl fileUrl = QUrl::fromUserInput(url, QDir::currentPath(), QUrl::AssumeLocalFile);
0107                 if (!fileNames.contains(fileUrl.fileName())) {
0108                     fileNames << fileUrl.fileName();
0109                     list << fileUrl;
0110                 }
0111             }
0112 
0113             KIO::CopyJob *job = KIO::link(list, mUrl);
0114             job->exec();
0115         } else {
0116             QString tmpArg = args.first();
0117             mUrl = QUrl::fromUserInput(tmpArg, QDir::currentPath(), QUrl::AssumeLocalFile);
0118         }
0119 
0120         if (mUrl.isValid() && (fullscreen || slideshow)) {
0121             mFullScreen = true;
0122             if (slideshow) {
0123                 mSlideShow = true;
0124             }
0125         }
0126         if (mUrl.isValid() && spotlightmode) {
0127             mSpotlightMode = true;
0128         }
0129     }
0130 
0131     void createMainWindow()
0132     {
0133         mMainWindow = new Gwenview::MainWindow();
0134         if (mUrl.isValid()) {
0135             mMainWindow->setInitialUrl(mUrl);
0136         } else {
0137             mMainWindow->showStartMainPage();
0138         }
0139 
0140         mMainWindow->show();
0141         if (mFullScreen) {
0142             mMainWindow->actionCollection()->action(QStringLiteral("fullscreen"))->trigger();
0143         } else if (mSpotlightMode) {
0144             mMainWindow->actionCollection()->action(QStringLiteral("view_toggle_spotlightmode"))->trigger();
0145         }
0146 
0147         if (mSlideShow) {
0148             mMainWindow->startSlideShow();
0149         }
0150     }
0151 
0152 private:
0153     QUrl mUrl;
0154     bool mFullScreen;
0155     bool mSlideShow;
0156     bool mSpotlightMode;
0157     QScopedPointer<QTemporaryDir> mMultipleUrlsDir;
0158     QPointer<Gwenview::MainWindow> mMainWindow;
0159 };
0160 
0161 int main(int argc, char *argv[])
0162 {
0163     // enable AVIF/HEIF/JPEG-XL metadata support
0164 #ifdef EXV_ENABLE_BMFF
0165     Exiv2::enableBMFF(true);
0166 #endif
0167 
0168 #ifdef HAVE_TIFF
0169     TIFFSetWarningHandler(handleTiffWarning);
0170     TIFFSetErrorHandler(handleTiffError);
0171 #endif
0172 
0173     /**
0174      * enable high dpi support
0175      */
0176     QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
0177 
0178     QApplication app(argc, argv);
0179     KLocalizedString::setApplicationDomain("gwenview");
0180     QScopedPointer<KAboutData> aboutData(Gwenview::createAboutData(QStringLiteral("gwenview"), /* component name */
0181                                                                    i18n("Gwenview") /* display name */
0182                                                                    ));
0183     aboutData->setShortDescription(i18n("An Image Viewer"));
0184 
0185     aboutData->setOrganizationDomain(QByteArray("kde.org"));
0186     KAboutData::setApplicationData(*aboutData);
0187     QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("gwenview"), app.windowIcon()));
0188 
0189     QCommandLineParser parser;
0190     aboutData.data()->setupCommandLine(&parser);
0191     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("fullscreen"), i18n("Start in fullscreen mode")));
0192     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("s") << QStringLiteral("slideshow"), i18n("Start in slideshow mode")));
0193     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("m") << QStringLiteral("spotlight"), i18n("Start in spotlight mode")));
0194     parser.addPositionalArgument("url", i18n("A starting file or folders"));
0195     parser.process(app);
0196     aboutData.data()->processCommandLine(&parser);
0197 
0198     // startHelper must live for the whole life of the application
0199     StartHelper startHelper(parser.positionalArguments(),
0200                             parser.isSet(QStringLiteral("f")) ? true : Gwenview::GwenviewConfig::fullScreenModeActive(),
0201                             parser.isSet(QStringLiteral("s")),
0202                             parser.isSet(QStringLiteral("m")) ? true : Gwenview::GwenviewConfig::spotlightMode());
0203     if (app.isSessionRestored()) {
0204         kRestoreMainWindows<Gwenview::MainWindow>();
0205     } else {
0206         startHelper.createMainWindow();
0207     }
0208 
0209     // Workaround for QTBUG-38613
0210     // Another solution would be to port BalooSemanticInfoBackend::refreshAllTags
0211     // to be async rather than using exec().
0212     qApp->sendPostedEvents(nullptr, QEvent::DeferredDelete);
0213 
0214 #ifdef KIMAGEANNOTATOR_CAN_LOAD_TRANSLATIONS
0215     kImageAnnotator::loadTranslations();
0216 #endif
0217 
0218     return app.exec();
0219 }
0220 
0221 #ifdef HAVE_FITS
0222 Q_IMPORT_PLUGIN(FitsPlugin)
0223 #endif