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