File: main.cpp

package info (click to toggle)
photoqt 5.2%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,736 kB
  • sloc: cpp: 32,751; python: 2,635; xml: 268; javascript: 42; makefile: 15
file content (315 lines) | stat: -rw-r--r-- 11,378 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/**************************************************************************
 **                                                                      **
 ** Copyright (C) 2011-2026 Lukas Spies                                  **
 ** Contact: https://photoqt.org                                         **
 **                                                                      **
 ** This file is part of PhotoQt.                                        **
 **                                                                      **
 ** PhotoQt is free software: you can redistribute it and/or modify      **
 ** it under the terms of the GNU General Public License as published by **
 ** the Free Software Foundation, either version 2 of the License, or    **
 ** (at your option) any later version.                                  **
 **                                                                      **
 ** PhotoQt is distributed in the hope that it will be useful,           **
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of       **
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        **
 ** GNU General Public License for more details.                         **
 **                                                                      **
 ** You should have received a copy of the GNU General Public License    **
 ** along with PhotoQt. If not, see <http://www.gnu.org/licenses/>.      **
 **                                                                      **
 **************************************************************************/

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QFileInfo>
#include <QSettings>
#include <QScreen>
#include <clocale>
#include <QSqlError>
#include <QSqlQuery>

#ifdef PQMEXIV2
#ifdef PQMEXIV2_ENABLE_BMFF
#define EXV_ENABLE_BMFF
#endif
#endif

// This needs to come early (in particular before the FreImage header)
#ifdef Q_OS_WIN
#include <windows.h>
#endif

#include <pqc_configfiles.h>
#include <pqc_singleinstance.h>
#include <pqc_validate.h>
#include <pqc_notify_cpp.h>
#include <pqc_messagehandler.h>
#include <pqc_imageformats.h>
#include <pqc_providericon.h>
#include <pqc_providertheme.h>
#include <pqc_providerthumb.h>
#include <pqc_providertooltipthumb.h>
#include <pqc_providerfolderthumb.h>
#include <pqc_providerdragthumb.h>
#include <pqc_providerfull.h>
#include <pqc_providersvg.h>
#include <pqc_providersvgcolor.h>
#include <pqc_providermipmap.h>
#include <pqc_extensionshandler.h>
#include <pqc_extensionsettings.h>
#include <pqc_look.h>
#include <pqc_startuphandler.h>
#include <pqc_settingscpp.h>

#if defined(PQMIMAGEMAGICK) || defined(PQMGRAPHICSMAGICK)
#include <Magick++.h>
#endif

#ifdef PQMDEVIL
#include <IL/il.h>
#endif

#ifdef PQMLIBVIPS
#include <vips/vips8>
#endif

#ifdef PQMEXIV2
#include <exiv2/exiv2.hpp>
#endif

#ifdef Q_OS_WIN
#include <QQuickWindow>
#include <QSGRendererInterface>
#endif

#ifdef PQMFLATPAKBUILD
#include <gio/gio.h>
#endif

#ifdef PQMEXTENSIONS
#include <QtCrypto>
#endif

int main(int argc, char **argv) {

    QFileInfo info_exe(argv[0]);

#ifdef Q_OS_WIN

#ifdef PQMEXIV2
    // Exiv2 0.28.x and above needs this locale in order to support proper unicode (e.g., CJK characters) in file names/paths
    setlocale(LC_ALL, ".UTF8");
#endif

    qputenv("PATH", QString("%1;%2").arg(qgetenv("PATH"),info_exe.absolutePath().replace("/", "\\")).toLocal8Bit());
    qputenv("MAGICK_CODER_MODULE_PATH", QString("%1").arg(info_exe.absolutePath().replace("/", "\\") + "\\imagemagick\\coders").toLocal8Bit());
    qputenv("MAGICK_FILTER_MODULE_PATH", QString("%1").arg(info_exe.absolutePath().replace("/", "\\") + "\\imagemagick\\filters").toLocal8Bit());

    // This allows for semi-transparent windows
    // By default Qt6 uses Direct3D which does not seem to support this
    QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
#endif

#ifdef PQMPORTABLETWEAKS
    // create directory and set hidden attribute
#ifdef Q_OS_WIN
    QString configLocation = argc > 1 ? QDir::fromNativeSeparators(argv[1]) : QCoreApplication::applicationDirPath();
    QFileInfo info(configLocation);
    if(info.isRelative())
        configLocation = info.absoluteFilePath();
    QString oldportablefolder = QString("%1/photoqt-data").arg(configLocation);
    QString portablefolder = QString("%1/PhotoQtData").arg(configLocation);
    QDir olddir(oldportablefolder);
    QDir newdir(portablefolder);
    if(olddir.exists() && !newdir.exists()) {
        SetFileAttributesA(olddir.absolutePath().toLocal8Bit(), FILE_ATTRIBUTE_NORMAL);
        // move old dir to new dir and remove hidden flag
        if(!olddir.rename(oldportablefolder, portablefolder))
            qWarning() << "Error renaming photoqt-data to PhotoQtData";
    } else {
        // make sure new dir exists
        newdir.mkdir(portablefolder);
    }
#else
    QString portablefolder = QString("%1/PhotoQtData").arg(argc > 1 ? argv[1] : QCoreApplication::applicationDirPath());
    QDir dir;
    dir.mkdir(portablefolder);
#endif
    qputenv("PHOTOQT_PORTABLE_DATA_LOCATION", portablefolder.toLocal8Bit());
#endif

    // avoids warning for customizing native styles (observed in particular on Windows)
    qputenv("QT_QUICK_CONTROLS_IGNORE_CUSTOMIZATION_WARNINGS", "1");

    // Set app information
    QApplication::setApplicationName("PhotoQt");
    QApplication::setOrganizationName("");
    QApplication::setOrganizationDomain("photoqt.org");
    QApplication::setApplicationVersion(PQMVERSION);
    QApplication::setQuitOnLastWindowClosed(true);

    // Set the desktop filename. On Wayland this is necessary to set the icon in the window title and panel
    QApplication::setDesktopFileName("org.photoqt.PhotoQt");

    // custom message handler for qDebug/qLog/qInfo/etc.
    qInstallMessageHandler(pqcMessageHandler);

    /******************************************/

#ifdef PQMEXTENSIONS
    QCA::Initializer init;
#endif

    /******************************************/

    // only a single instance
    PQCSingleInstance app(argc, argv);

    /******************************************/
    // we take care of any startup checks and potential migrations

    PQCStartupHandler startupHandler(app.getForceShowWizard(), app.getForceSkipWizard());

    /******************************************/

#ifdef PQMVIDEOMPV
    // Qt sets the locale in the QApplication constructor, but libmpv
    // requires the LC_NUMERIC category to be set to "C", so change it back.
    std::setlocale(LC_NUMERIC, "C");
#endif

#ifdef PQMEXIV2
#if EXIV2_TEST_VERSION(0, 28, 0)
    // In this case Exiv2::enableBMFF() defaults to true
    // and the call to it is deprecated
#else
    #ifdef PQMEXIV2_ENABLE_BMFF
        Exiv2::enableBMFF(true);
    #endif
#endif
#endif

#ifdef PQMFLATPAKBUILD
#if !GLIB_CHECK_VERSION(2,35,0)
    g_type_init();
#endif
#endif

    // handle export/import commands
    if(app.exportAndQuit != "") {
        startupHandler.exportData(app.exportAndQuit);
        return 0;
    } else if(app.importAndQuit != "") {
        startupHandler.importData(app.importAndQuit);
        return 0;
    } else if(app.checkConfig) {
        startupHandler.setupDatabases();
        PQCValidate validate;
        validate.validate();
        return 0;
    } else if(app.resetConfig) {
        startupHandler.resetToDefaults();
        return 0;
    } else if(app.showInfo) {
        startupHandler.showInfo();
        return 0;
    } else if(app.installExtensionFileName != "") {
        PQCExtensionsHandler::get().installExtension(app.installExtensionFileName);
    }

    // setting up databases needs to happen here for the Release build
    startupHandler.setupDatabases();
    startupHandler.performChecksAndUpdates();

    /***************************************/
    // figure out modern vs integrated without use of PQCSettings

    if(app.forceModernInterface || app.forceIntegratedInterface) {
        bool useModernInterface = !app.forceIntegratedInterface;
        QSqlDatabase dbtmp = QSqlDatabase::database("settings");
        QSqlQuery query(dbtmp);
        query.prepare("INSERT OR REPLACE INTO `general` (`name`,`value`,`datatype`) VALUES ('InterfaceVariant', :val, 'string')");
        query.bindValue(":val", (useModernInterface ? "modern" : "integrated"));
        if(!query.exec())
            qWarning() << "Unable to update value generalInterfaceVariant:" << query.lastError().text();
        query.clear();
        dbtmp.close();
        PQCSettingsCPP::get().forceInterfaceVariant((useModernInterface ? "modern" : "integrated"));
    }

    /***************************************/

    // Get screenshots for fake transparency
    bool success = true;
    for(int i = 0; i < QApplication::screens().count(); ++i) {
        QScreen *screen = QApplication::screens().at(i);
        QRect r = screen->geometry();
        QPixmap pix = screen->grabWindow(0,r.x(),r.y(),r.width(),r.height());
        if(!pix.save(QDir::tempPath() + QString("/photoqt_screenshot_%1.jpg").arg(i))) {
            qDebug() << "Error taking screenshot for screen #" << i;
            success = false;
            break;
        }
    }
    PQCNotifyCPP::get().setHaveScreenshots(success);

    /***************************************/

// only one of them will be defined at a time
#if defined(PQMGRAPHICSMAGICK) || defined(PQMIMAGEMAGICK)
    // Initialise Magick as early as possible
    // this needs to happen BEFORE startup check as this might call into Magick
    Magick::InitializeMagick(*argv);
#endif

#ifdef PQMDEVIL
    ilInit();
#endif

#ifdef PQMLIBVIPS
    VIPS_INIT(argv[0]);
#endif

    /***************************************/

    QQmlApplicationEngine engine;

    QObject::connect(&engine, &QQmlApplicationEngine::objectCreationFailed, &app, []() { QApplication::exit(-1); }, Qt::QueuedConnection);

    engine.addImageProvider("icon", new PQCProviderIcon);
    engine.addImageProvider("theme", new PQCProviderTheme);
    engine.addImageProvider("thumb", new PQCAsyncImageProviderThumb);
    engine.addImageProvider("tooltipthumb", new PQCAsyncImageProviderTooltipThumb);
    engine.addImageProvider("folderthumb", new PQCAsyncImageProviderFolderThumb);
    engine.addImageProvider("dragthumb", new PQCAsyncImageProviderDragThumb);
    engine.addImageProvider("full", new PQCProviderFull);
    engine.addImageProvider("svg", new PQCProviderSVG);
    engine.addImageProvider("svgcolor", new PQCProviderSVGColor);
    engine.addImageProvider("mipmap", new PQCAsyncImageProviderMipMap);

    // These only need to be imported where needed
    qmlRegisterSingletonInstance("PQCExtensionsHandler", 1, 0, "PQCExtensionsHandler", &PQCExtensionsHandler::get());

    // the extension settings item
    qmlRegisterType<ExtensionSettings>("ExtensionSettings", 1, 0, "ExtensionSettings");

#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
    engine.loadFromModule("PhotoQt", "PQMainWindow");
#else
    // In Qt 6.4 this path is not automatically added as import path meaning without this PhotoQt wont find any of its modules
    // We also cannot use loadFromModule() as that does not exist yet.
    engine.addImportPath(":/");
    engine.load("qrc:/PhotoQt/qml/PQMainWindow.qml");
#endif

    int currentExitCode = app.exec();

#ifdef PQMLIBVIPS
    vips_shutdown();
#endif

    return currentExitCode;

}