1 /*
2 Gwenview: an image viewer
3 Copyright 2007-2012 Aurélien Gâteau <agateau@kde.org>
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 */
20 #include <config-gwenview.h>
21
22 // Qt
23 #include <QApplication>
24 #include <QCommandLineParser>
25 #include <QPointer>
26 #include <QScopedPointer>
27 #include <QStringList>
28 #include <QTemporaryDir>
29 #include <QUrl>
30
31 // KF
32 #include <KAboutData>
33 #include <KActionCollection>
34 #include <KIO/CopyJob>
35 #include <KLocalizedString>
36
37 // Local
38 #include "mainwindow.h"
39 #include <lib/about.h>
40 #include <lib/gwenviewconfig.h>
41
42 #ifdef HAVE_FITS
43 // This hack is needed to include the fitsplugin moc file in main.cpp
44 // Otherwise the linker complains about: undefined reference to `qt_static_plugin_FitsPlugin()'
45 // This symbol is defined in the moc file, but it is not a visible symbol after libgwenview is linked.
46 // If Q_IMPORT_PLUGIN(FitsPlugin) is moved to the library, gwenview crashes on the first call to FitsPlugin()
47 // when the vtable is looked up in the plugin registration.
48 #include <../lib/imageformats/moc_fitsplugin.cpp>
49 #endif
50
51 // To shut up libtiff
52 #ifdef HAVE_TIFF
53 #include <QLoggingCategory>
54 #include <tiffio.h>
55
56 namespace
57 {
58 Q_DECLARE_LOGGING_CATEGORY(LibTiffLog)
59 Q_LOGGING_CATEGORY(LibTiffLog, "gwenview.libtiff", QtWarningMsg)
60
handleTiffWarning(const char * mod,const char * fmt,va_list ap)61 static void handleTiffWarning(const char *mod, const char *fmt, va_list ap)
62 {
63 qCDebug(LibTiffLog) << "Warning:" << mod << QString::vasprintf(fmt, ap);
64 }
65
handleTiffError(const char * mod,const char * fmt,va_list ap)66 static void handleTiffError(const char *mod, const char *fmt, va_list ap)
67 {
68 // Since we're doing thumbnails, we don't really care about warnings by default either
69 qCWarning(LibTiffLog) << "Error" << mod << QString::vasprintf(fmt, ap);
70 }
71
72 } // namespace
73 #endif
74
75 class StartHelper
76 {
77 public:
StartHelper(const QStringList & args,bool fullscreen,bool slideshow)78 StartHelper(const QStringList &args, bool fullscreen, bool slideshow)
79 : mFullScreen(false)
80 , mSlideShow(false)
81 {
82 if (!args.isEmpty()) {
83 parseArgs(args, fullscreen, slideshow);
84 }
85 }
86
parseArgs(const QStringList & args,bool fullscreen,bool slideshow)87 void parseArgs(const QStringList &args, bool fullscreen, bool slideshow)
88 {
89 if (args.count() > 1) {
90 // Create a temp dir containing links to url args
91 mMultipleUrlsDir.reset(new QTemporaryDir);
92 mUrl = QUrl::fromLocalFile(mMultipleUrlsDir->path());
93 QList<QUrl> list;
94 QStringList tmpArgs = args;
95 tmpArgs.removeDuplicates();
96 QStringList fileNames;
97 for (const QString &url : qAsConst(tmpArgs)) {
98 QUrl fileUrl = QUrl::fromUserInput(url, QDir::currentPath(), QUrl::AssumeLocalFile);
99 if (!fileNames.contains(fileUrl.fileName())) {
100 fileNames << fileUrl.fileName();
101 list << fileUrl;
102 }
103 }
104
105 KIO::CopyJob *job = KIO::link(list, mUrl);
106 job->exec();
107 } else {
108 QString tmpArg = args.first();
109 mUrl = QUrl::fromUserInput(tmpArg, QDir::currentPath(), QUrl::AssumeLocalFile);
110 }
111
112 if (mUrl.isValid() && (fullscreen || slideshow)) {
113 mFullScreen = true;
114 if (slideshow) {
115 mSlideShow = true;
116 }
117 }
118 }
119
createMainWindow()120 void createMainWindow()
121 {
122 mMainWindow = new Gwenview::MainWindow();
123 if (mUrl.isValid()) {
124 mMainWindow->setInitialUrl(mUrl);
125 } else {
126 mMainWindow->showStartMainPage();
127 }
128
129 mMainWindow->show();
130 if (mFullScreen) {
131 mMainWindow->actionCollection()->action(QStringLiteral("fullscreen"))->trigger();
132 } else {
133 mMainWindow->show();
134 }
135
136 if (mSlideShow) {
137 mMainWindow->startSlideShow();
138 }
139 }
140
141 private:
142 QUrl mUrl;
143 bool mFullScreen;
144 bool mSlideShow;
145 QScopedPointer<QTemporaryDir> mMultipleUrlsDir;
146 QPointer<Gwenview::MainWindow> mMainWindow;
147 };
148
main(int argc,char * argv[])149 int main(int argc, char *argv[])
150 {
151 #ifdef HAVE_TIFF
152 TIFFSetWarningHandler(handleTiffWarning);
153 TIFFSetErrorHandler(handleTiffError);
154 #endif
155
156 /**
157 * enable high dpi support
158 */
159 QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
160 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
161 QCoreApplication::setAttribute(Qt::AA_CompressHighFrequencyEvents, true);
162
163 QApplication app(argc, argv);
164 KLocalizedString::setApplicationDomain("gwenview");
165 QScopedPointer<KAboutData> aboutData(Gwenview::createAboutData(QStringLiteral("gwenview"), /* component name */
166 i18n("Gwenview") /* display name */
167 ));
168 aboutData->setShortDescription(i18n("An Image Viewer"));
169
170 aboutData->setOrganizationDomain(QByteArray("kde.org"));
171 KAboutData::setApplicationData(*aboutData);
172 QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("gwenview"), app.windowIcon()));
173
174 QCommandLineParser parser;
175 aboutData.data()->setupCommandLine(&parser);
176 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("fullscreen"), i18n("Start in fullscreen mode")));
177 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("s") << QStringLiteral("slideshow"), i18n("Start in slideshow mode")));
178 parser.addPositionalArgument("url", i18n("A starting file or folders"));
179 parser.process(app);
180 aboutData.data()->processCommandLine(&parser);
181
182 // startHelper must live for the whole life of the application
183 StartHelper startHelper(parser.positionalArguments(),
184 parser.isSet(QStringLiteral("f")) ? true : Gwenview::GwenviewConfig::fullScreenModeActive(),
185 parser.isSet(QStringLiteral("s")));
186 if (app.isSessionRestored()) {
187 kRestoreMainWindows<Gwenview::MainWindow>();
188 } else {
189 startHelper.createMainWindow();
190 }
191
192 // Workaround for QTBUG-38613
193 // Another solution would be to port BalooSemanticInfoBackend::refreshAllTags
194 // to be async rather than using exec().
195 qApp->sendPostedEvents(nullptr, QEvent::DeferredDelete);
196
197 return app.exec();
198 }
199
200 #ifdef HAVE_FITS
201 Q_IMPORT_PLUGIN(FitsPlugin)
202 #endif
203