Krita Source Code Documentation
Loading...
Searching...
No Matches
KisApplication Class Reference

Base class for the Krita app. More...

#include <KisApplication.h>

+ Inheritance diagram for KisApplication:

Classes

class  Private
 
class  ResetStarting
 

Public Slots

void executeRemoteArguments (QByteArray message, KisMainWindow *mainWindow)
 
void fileOpenRequested (const QString &url)
 
void remoteArguments (const QString &message)
 
void setSplashScreenLoadingText (const QString &)
 
- Public Slots inherited from QtSingleApplication
void activateWindow ()
 
bool sendMessage (const QString &message, int timeout=5000)
 

Public Member Functions

void addResourceTypes ()
 
void askResetConfig ()
 
bool event (QEvent *event) override
 
KisExtendedModifiersMapperPluginInterfaceextendedModifiersPluginInterface ()
 
void hideSplashScreen ()
 
void initializeGlobals (const KisApplicationArguments &args)
 
bool isStoreApplication ()
 
 KisApplication (const QString &key, int &argc, char **argv)
 
void loadPlugins ()
 
bool notify (QObject *receiver, QEvent *event) override
 Overridden to handle exceptions from event handlers.
 
void processPostponedSynchronizationEvents ()
 
bool registerResources ()
 
void setSplashScreen (QWidget *splash)
 
virtual bool start (const KisApplicationArguments &args)
 
 ~KisApplication () override
 
- Public Member Functions inherited from QtSingleApplication
QWidget * activationWindow () const
 
QString id () const
 
void initialize (bool dummy=true)
 
bool isRunning ()
 
 QtSingleApplication (const QString &id, int &argc, char **argv)
 
 QtSingleApplication (int &argc, char **argv, bool GUIenabled=true)
 
 QtSingleApplication (int &argc, char **argv, Type type)
 
void setActivationWindow (QWidget *aw, bool activateOnMessage=true)
 

Static Public Member Functions

static void verifyMetatypeRegistration ()
 

Private Slots

void slotSetLongPress (bool enabled)
 

Private Member Functions

void checkAutosaveFiles ()
 
bool createNewDocFromTemplate (const QString &fileName, KisMainWindow *m_mainWindow)
 
void resetConfig ()
 

Private Attributes

QScopedPointer< Privated
 

Friends

class ResetStarting
 

Additional Inherited Members

- Signals inherited from QtSingleApplication
void messageReceived (const QString &message)
 

Detailed Description

Base class for the Krita app.

This class handles arguments given on the command line and shows a generic about dialog for the Krita app.

In addition it adds the standard directories where Krita can find its images etc.

If the last mainwindow becomes closed, KisApplication automatically calls QApplication::quit.

Definition at line 38 of file KisApplication.h.

Constructor & Destructor Documentation

◆ KisApplication()

KisApplication::KisApplication ( const QString & key,
int & argc,
char ** argv )
explicit

Creates an application object, adds some standard directories and initializes kimgio.

Load platform plugin for modifiers fetching

Definition at line 226 of file KisApplication.cpp.

227 : QtSingleApplication(key, argc, argv)
228 , d(new Private)
229{
230#ifdef Q_OS_ANDROID
231 // The hardware renderer backend on Android doesn't support proper stacking,
232 // causing windows with QtQuick widgets to always stack behind everything
233 // else, including our own dialog decorations.
234 qputenv("QT_QUICK_BACKEND", "software");
235#endif
236#ifdef Q_OS_MACOS
238#endif
239
240 QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath());
241
242#ifndef Q_OS_MACOS
243 setWindowIcon(KisIconUtils::loadIcon("krita-branding"));
244#endif
245
246 // if style is set from config, try to load that
247 KisConfig cfg(true);
248 QString widgetStyleFromConfig = cfg.widgetStyle();
249 QString defaultStyle = style()->objectName().toLower();
250 if (!widgetStyleFromConfig.isEmpty()) {
251 qApp->setStyle(widgetStyleFromConfig);
252#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
253 } else if (defaultStyle == "macintosh" || defaultStyle == "windowsvista") {
254 // default to Fusion instead of styles that use native theming
255 qApp->setStyle("fusion");
256 }
257#else
258 } else if (style()->objectName().toLower() == "macos" || defaultStyle == "windowsvista") {
259 // default to Fusion instead of styles that use native theming
260 qApp->setStyle("fusion");
261 }
262#endif
263
267 {
268 d->extendedModifiersPluginInterface.reset(KisPlatformPluginInterfaceFactory::instance()->createExtendedModifiersMapper());
269 }
270
271 // store the style name
272 qApp->setProperty(currentUnderlyingStyleNameProperty, style()->objectName());
274
275
276#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
277
282 struct PlatformWindowCreationFilter : QObject
283 {
284 using QObject::QObject;
285
286 bool eventFilter(QObject *watched, QEvent *event) override {
287 if (event->type() == QEvent::PlatformSurface) {
288 QWidget *widget = qobject_cast<QWidget*>(watched);
289 if (!widget) return false;
290
295 if (watched->property("krita_skip_srgb_surface_manager_assignment").toBool()) {
296 return false;
297 }
298
299 QPlatformSurfaceEvent *surfaceEvent = static_cast<QPlatformSurfaceEvent*>(event);
300 if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
301 QWindow *nativeWindow = widget->windowHandle();
302 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(widget->windowHandle(), false);
303
304 if (!nativeWindow->findChild<KisSRGBSurfaceColorSpaceManager*>()) {
306 }
307 }
308 }
309
310 return false;
311 }
312 };
313
314 this->installEventFilter(new PlatformWindowCreationFilter(this));
315#endif /* KRITA_USE_SURFACE_COLOR_MANAGEMENT_API */
316}
QScopedPointer< Private > d
void processPostponedSynchronizationEvents()
static KisPlatformPluginInterfaceFactory * instance()
static KisSRGBSurfaceColorSpaceManager * tryCreateForCurrentPlatform(QWidget *widget)
static void registerSynchronizedEventBarrier(std::function< void()> callback)
QtSingleApplication(int &argc, char **argv, bool GUIenabled=true)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
constexpr const char * currentUnderlyingStyleNameProperty
Definition kis_global.h:116
static QVariantHash defaultStyle
QIcon loadIcon(const QString &name)
void setMouseCoalescingEnabled(bool enabled)
Definition osx.mm:17

References defaultStyle, KisIconUtils::loadIcon(), setMouseCoalescingEnabled(), and KisConfig::widgetStyle().

◆ ~KisApplication()

KisApplication::~KisApplication ( )
override

Destructor.

Definition at line 873 of file KisApplication.cpp.

874{
875 if (!isRunning()) {
878 }
879}
static void performHouseKeepingOnExit()
perform optimize and vacuum when necessary
static void deleteTemporaryResources()
Delete all storages that are Unknown or Memory and all resources that are marked temporary or belong ...

References KisResourceCacheDb::deleteTemporaryResources(), QtSingleApplication::isRunning(), and KisResourceCacheDb::performHouseKeepingOnExit().

Member Function Documentation

◆ addResourceTypes()

void KisApplication::addResourceTypes ( )

Definition at line 352 of file KisApplication.cpp.

353{
354 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::addResourceTypes"));
355
356 // All Krita's resource types
357 KoResourcePaths::addAssetType("markers", "data", "/styles/");
358 KoResourcePaths::addAssetType("kis_pics", "data", "/pics/");
359 KoResourcePaths::addAssetType("kis_images", "data", "/images/");
360 KoResourcePaths::addAssetType("metadata_schema", "data", "/metadata/schemas/");
361 KoResourcePaths::addAssetType("gmic_definitions", "data", "/gmic/");
362 KoResourcePaths::addAssetType("kis_shortcuts", "data", "/shortcuts/");
363 KoResourcePaths::addAssetType("kis_actions", "data", "/actions");
364 KoResourcePaths::addAssetType("kis_actions", "data", "/pykrita");
365 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc");
366 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/");
367 KoResourcePaths::addAssetType("tags", "data", "/tags/");
368 KoResourcePaths::addAssetType("templates", "data", "/templates");
369 KoResourcePaths::addAssetType("pythonscripts", "data", "/pykrita");
370 KoResourcePaths::addAssetType("preset_icons", "data", "/preset_icons");
371#if defined HAVE_SEEXPR
372 KoResourcePaths::addAssetType(ResourceType::SeExprScripts, "data", "/seexpr_scripts/", true);
373#endif
374
375 // Make directories for all resources we can save, and tags
376 KoResourcePaths::saveLocation("data", "/asl/", true);
377 KoResourcePaths::saveLocation("data", "/css_styles/", true);
378 KoResourcePaths::saveLocation("data", "/input/", true);
379 KoResourcePaths::saveLocation("data", "/pykrita/", true);
380 KoResourcePaths::saveLocation("data", "/color-schemes/", true);
381 KoResourcePaths::saveLocation("data", "/preset_icons/", true);
382 KoResourcePaths::saveLocation("data", "/preset_icons/tool_icons/", true);
383 KoResourcePaths::saveLocation("data", "/preset_icons/emblem_icons/", true);
384}
static void addAssetType(const QString &type, const char *basetype, const QString &relativeName, bool priority=true)
static QString saveLocation(const QString &type, const QString &suffix=QString(), bool create=true)
const QString SeExprScripts

References KoResourcePaths::addAssetType(), KoResourcePaths::saveLocation(), and ResourceType::SeExprScripts.

◆ askResetConfig()

void KisApplication::askResetConfig ( )

Checks if user is holding ctrl+alt+shift keys and asks if the settings file should be cleared.

Typically called during startup before reading the config.

Definition at line 1331 of file KisApplication.cpp.

1332{
1333 bool ok = QMessageBox::question(qApp->activeWindow(),
1334 i18nc("@title:window", "Krita"),
1335 i18n("Do you want to clear the settings file?"),
1336 QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes;
1337 if (ok) {
1338 resetConfig();
1339 }
1340}

References resetConfig().

◆ checkAutosaveFiles()

void KisApplication::checkAutosaveFiles ( )
private
Returns
the number of autosavefiles opened

Definition at line 1163 of file KisApplication.cpp.

1164{
1165 if (d->batchRun) return;
1166
1168
1169 // Check for autosave files from a previous run. There can be several, and
1170 // we want to offer a restore for every one. Including a nice thumbnail!
1171
1172 // Hidden autosave files
1173 QStringList filters = QStringList() << QString(".krita-*-*-autosave.kra");
1174
1175 // all autosave files for our application
1176 QStringList autosaveFiles = dir.entryList(filters, QDir::Files | QDir::Hidden);
1177
1178 // Visible autosave files
1179 filters = QStringList() << QString("krita-*-*-autosave.kra");
1180 autosaveFiles += dir.entryList(filters, QDir::Files);
1181
1182 // Allow the user to make their selection
1183 if (autosaveFiles.size() > 0) {
1184 if (d->splashScreen) {
1185 // hide the splashscreen to see the dialog
1187 }
1188 d->autosaveDialog = new KisAutoSaveRecoveryDialog(autosaveFiles, activeWindow());
1189 QDialog::DialogCode result = (QDialog::DialogCode) d->autosaveDialog->exec();
1190
1191 if (result == QDialog::Accepted) {
1192 QStringList filesToRecover = d->autosaveDialog->recoverableFiles();
1193 Q_FOREACH (const QString &autosaveFile, autosaveFiles) {
1194 if (!filesToRecover.contains(autosaveFile)) {
1195 KisUsageLogger::log(QString("Removing autosave file %1").arg(dir.absolutePath() + "/" + autosaveFile));
1196 QFile::remove(dir.absolutePath() + "/" + autosaveFile);
1197 }
1198 }
1199 autosaveFiles = filesToRecover;
1200 } else {
1201 autosaveFiles.clear();
1202 }
1203
1204 if (autosaveFiles.size() > 0) {
1205 QList<QString> autosavePaths;
1206 Q_FOREACH (const QString &autoSaveFile, autosaveFiles) {
1207 const QString path = dir.absolutePath() + QLatin1Char('/') + autoSaveFile;
1208 autosavePaths << path;
1209 }
1210 if (d->mainWindow) {
1211 Q_FOREACH (const QString &path, autosavePaths) {
1212 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1213 d->mainWindow->openDocument(path, flags | KisMainWindow::RecoveryFile);
1214 }
1215 }
1216 }
1217 // cleanup
1218 delete d->autosaveDialog;
1219 d->autosaveDialog = nullptr;
1220 }
1221}
QList< QString > QStringList
static void log(const QString &message)
Logs with date/time.

References KisAutoSaveRecoveryDialog::autoSaveLocation(), KisMainWindow::BatchMode, d, hideSplashScreen(), KisUsageLogger::log(), KisMainWindow::None, and KisMainWindow::RecoveryFile.

◆ createNewDocFromTemplate()

bool KisApplication::createNewDocFromTemplate ( const QString & fileName,
KisMainWindow * m_mainWindow )
private

Definition at line 1223 of file KisApplication.cpp.

1224{
1225 QString templatePath;
1226
1227 if (QFile::exists(fileName)) {
1228 templatePath = fileName;
1229 dbgUI << "using full path...";
1230 }
1231 else {
1232 QString desktopName(fileName);
1233 const QString templatesResourcePath = QStringLiteral("templates/");
1234
1235 QStringList paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + "*/" + desktopName);
1236 if (paths.isEmpty()) {
1237 paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + desktopName);
1238 }
1239
1240 if (paths.isEmpty()) {
1241 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1242 i18n("No template found for: %1", desktopName));
1243 } else if (paths.count() > 1) {
1244 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1245 i18n("Too many templates found for: %1", desktopName));
1246 } else {
1247 templatePath = paths.at(0);
1248 }
1249 }
1250
1251 if (!templatePath.isEmpty()) {
1252 KDesktopFile templateInfo(templatePath);
1253
1254 KisMainWindow::OpenFlags batchFlags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1255 if (mainWindow->openDocument(templatePath, KisMainWindow::Import | batchFlags)) {
1256 dbgUI << "Template loaded...";
1257 return true;
1258 }
1259 else {
1260 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1261 i18n("Template %1 failed to load.", fileName));
1262 }
1263 }
1264
1265 return false;
1266}
static QStringList findAllAssets(const QString &type, const QString &filter=QString(), SearchOptions options=NoSearchOptions)
#define dbgUI
Definition kis_debug.h:55

References KisMainWindow::BatchMode, d, dbgUI, KoResourcePaths::findAllAssets(), KisMainWindow::Import, KisMainWindow::None, and KisMainWindow::openDocument().

◆ event()

bool KisApplication::event ( QEvent * event)
override

Definition at line 387 of file KisApplication.cpp.

388{
389
390 #ifdef Q_OS_MACOS
391 if (event->type() == QEvent::FileOpen) {
392 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
393 fileOpenRequested(openEvent->file());
394 return true;
395 }
396 #endif
397 return QApplication::event(event);
398}
bool event(QEvent *event) override
void fileOpenRequested(const QString &url)

References event(), and fileOpenRequested().

◆ executeRemoteArguments

void KisApplication::executeRemoteArguments ( QByteArray message,
KisMainWindow * mainWindow )
slot

Definition at line 1059 of file KisApplication.cpp.

1060{
1062 const bool doTemplate = args.doTemplate();
1063 const bool doNewImage = args.doNewImage();
1064 const int argsCount = args.filenames().count();
1065 bool documentCreated = false;
1066
1067 // Create a new image, if needed
1068 if (doNewImage) {
1070 if (doc) {
1072 d->mainWindow->addViewAndNotifyLoadingCompleted(doc);
1073 }
1074 }
1075 if (argsCount > 0) {
1076 // Loop through arguments
1077 for (int argNumber = 0; argNumber < argsCount; ++argNumber) {
1078 QString filename = args.filenames().at(argNumber);
1079 // are we just trying to open a template?
1080 if (doTemplate) {
1081 documentCreated |= createNewDocFromTemplate(filename, mainWindow);
1082 }
1083 else if (QFile(filename).exists()) {
1084 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1085 documentCreated |= mainWindow->openDocument(filename, flags);
1086 }
1087 }
1088 }
1089
1090 //add an image as file-layer if called in another process and singleApplication is enabled
1091 if (!args.fileLayer().isEmpty()){
1092 if (argsCount > 0 && !documentCreated){
1093 //arg was passed but document was not created so don't add the file layer.
1094 QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"),
1095 i18n("Couldn't open file %1",args.filenames().at(argsCount - 1)));
1096 }
1097 else if (mainWindow->viewManager()->image()){
1098 KisFileLayer *fileLayer = new KisFileLayer(mainWindow->viewManager()->image(), "",
1099 args.fileLayer(), KisFileLayer::None, "Bicubic",
1100 mainWindow->viewManager()->image()->nextLayerName(i18n("File layer")), OPACITY_OPAQUE_U8);
1101 QFileInfo fi(fileLayer->path());
1102 if (fi.exists()){
1103 KisNodeCommandsAdapter adapter(d->mainWindow->viewManager());
1104 adapter.addNode(fileLayer, d->mainWindow->viewManager()->activeNode()->parent(),
1105 d->mainWindow->viewManager()->activeNode());
1106 }
1107 else{
1108 QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"),
1109 i18n("Cannot add %1 as a file layer: the file does not exist.", fileLayer->path()));
1110 }
1111 }
1112 else {
1113 QMessageBox::warning(mainWindow, i18nc("@title:window", "Krita:Warning"),
1114 i18n("Cannot add the file layer: no document is open."));
1115 }
1116 }
1117}
const quint8 OPACITY_OPAQUE_U8
bool createNewDocFromTemplate(const QString &fileName, KisMainWindow *m_mainWindow)
The KisFileLayer class loads a particular file as a layer into the layer stack.
QString path() const
QString nextLayerName(const QString &baseName="") const
Definition kis_image.cc:742
bool openDocument(const QString &path, OpenFlags flags)
KisViewManager * viewManager
static KisPart * instance()
Definition KisPart.cpp:130
void addDocument(KisDocument *document, bool notify=true)
Definition KisPart.cpp:209
KisImageWSP image() const
Return the image this view is displaying.
static KisApplicationArguments deserialize(QByteArray &serialized)
KisDocument * createDocumentFromArguments() const

References KisPart::addDocument(), KisNodeCommandsAdapter::addNode(), KisMainWindow::BatchMode, KisApplicationArguments::createDocumentFromArguments(), createNewDocFromTemplate(), d, KisApplicationArguments::deserialize(), KisApplicationArguments::doNewImage(), KisApplicationArguments::doTemplate, KisApplicationArguments::fileLayer, KisApplicationArguments::filenames, KisViewManager::image(), KisPart::instance(), KisImage::nextLayerName(), KisFileLayer::None, KisMainWindow::None, OPACITY_OPAQUE_U8, KisMainWindow::openDocument(), KisNode::parent, KisFileLayer::path(), and KisMainWindow::viewManager.

◆ extendedModifiersPluginInterface()

KisExtendedModifiersMapperPluginInterface * KisApplication::extendedModifiersPluginInterface ( )

Definition at line 1342 of file KisApplication.cpp.

1343{
1344 return d->extendedModifiersPluginInterface.data();
1345}

References d.

◆ fileOpenRequested

void KisApplication::fileOpenRequested ( const QString & url)
slot

Definition at line 1139 of file KisApplication.cpp.

1140{
1141 if (!d->mainWindow) {
1142 d->earlyFileOpenEvents.append(url);
1143 return;
1144 }
1145
1146 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1147 d->mainWindow->openDocument(url, flags);
1148}

References KisMainWindow::BatchMode, d, and KisMainWindow::None.

◆ hideSplashScreen()

void KisApplication::hideSplashScreen ( )

Definition at line 897 of file KisApplication.cpp.

898{
899#ifdef Q_OS_ANDROID
901#endif
902 if (d->splashScreen) {
903 // hide the splashscreen to see the dialog
904 d->splashScreen->hide();
905 }
906}
static void setLoaded(bool loaded)

References d, and KisAndroidDonations::setLoaded().

◆ initializeGlobals()

void KisApplication::initializeGlobals ( const KisApplicationArguments & args)

Definition at line 345 of file KisApplication.cpp.

346{
347 Q_UNUSED(args)
348 // There are no globals to initialize from the arguments now. There used
349 // to be the `dpi` argument, but it doesn't do anything anymore.
350}

◆ isStoreApplication()

bool KisApplication::isStoreApplication ( )
Returns
true if Krita has been acquired through an app store

Definition at line 979 of file KisApplication.cpp.

980{
981 if (qEnvironmentVariableIsSet("STEAMAPPID") || qEnvironmentVariableIsSet("SteamAppId")) {
982 return true;
983 }
984
985 if (applicationDirPath().toLower().contains("steam")) {
986 return true;
987 }
988
989#ifdef Q_OS_WIN
990 // This is also true for user-installed MSIX, but that's
991 // likely only true in institutional situations, where
992 // we don't want to show the beginning banner either.
994 return true;
995 }
996#endif
997
998#ifdef Q_OS_MACOS
999 KisMacosEntitlements entitlements;
1000 if (entitlements.sandbox()) {
1001 return true;
1002 }
1003#endif
1004
1005 return false;
1006}

References KisWindowsPackageUtils::isRunningInPackage(), and KisMacosEntitlements::sandbox().

◆ loadPlugins()

void KisApplication::loadPlugins ( )

Definition at line 470 of file KisApplication.cpp.

471{
472 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::loadPlugins"));
473
475 r->add(new KisShapeSelectionFactory());
484}
static KisActionRegistry * instance()
static KisFilterRegistry * instance()
static KisGeneratorRegistry * instance()
static KisMetadataBackendRegistry * instance()
static KisPaintOpRegistry * instance()
static KoDockRegistry * instance()
static KoShapeRegistry * instance()
static KoToolRegistry * instance()
static KoColorSpaceRegistry * instance()

References KoDockRegistry::instance(), KoShapeRegistry::instance(), KoToolRegistry::instance(), KisPaintOpRegistry::instance(), KisFilterRegistry::instance(), KisGeneratorRegistry::instance(), KisMetadataBackendRegistry::instance(), KoColorSpaceRegistry::instance(), and KisActionRegistry::instance().

◆ notify()

bool KisApplication::notify ( QObject * receiver,
QEvent * event )
override

Overridden to handle exceptions from event handlers.

KisApplication::notify() is called for every event loop processed in any thread, so we need to make sure our counters and postponed events queues are stored in a per-thread way.

Definition at line 909 of file KisApplication.cpp.

910{
911 try {
912 bool result = true;
913
919 AppRecursionInfo &info = s_recursionInfo->localData();
920
921 {
922 // QApplication::notify() can throw, so use RAII for counters
923 AppRecursionGuard guard(&info);
924
926
927 if (info.eventRecursionCount > 1) {
929 KIS_SAFE_ASSERT_RECOVER_NOOP(typedEvent->destination == receiver);
930
931 info.postponedSynchronizationEvents.emplace(KisSynchronizedConnectionEvent(*typedEvent));
932 } else {
933 result = QApplication::notify(receiver, event);
934 }
935 } else {
936 result = QApplication::notify(receiver, event);
937 }
938 }
939
940 if (!info.eventRecursionCount) {
942
943 }
944
945 return result;
946
947 } catch (std::exception &e) {
948 qWarning("Error %s sending event %i to object %s",
949 e.what(), event->type(), qPrintable(receiver->objectName()));
950 } catch (...) {
951 qWarning("Error <unknown> sending event %i to object %s",
952 event->type(), qPrintable(receiver->objectName()));
953 }
954 return false;
955}
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
Event type used for synchronizing connection in KisSynchronizedConnection.

References KisSynchronizedConnectionEvent::destination, event(), KisSynchronizedConnectionBase::eventType(), KIS_SAFE_ASSERT_RECOVER_NOOP, and processPostponedSynchronizationEvents().

◆ processPostponedSynchronizationEvents()

void KisApplication::processPostponedSynchronizationEvents ( )

We must pop event from the queue before we call QApplication::notify(), because it can throw!

Definition at line 957 of file KisApplication.cpp.

958{
959 AppRecursionInfo &info = s_recursionInfo->localData();
960
961 while (!info.postponedSynchronizationEvents.empty()) {
962 // QApplication::notify() can throw, so use RAII for counters
963 AppRecursionGuard guard(&info);
964
967 KisSynchronizedConnectionEvent typedEvent = info.postponedSynchronizationEvents.front();
968 info.postponedSynchronizationEvents.pop();
969
970 if (!typedEvent.destination) {
971 qWarning() << "WARNING: the destination object of KisSynchronizedConnection has been destroyed during postponed delivery";
972 continue;
973 }
974
975 QApplication::notify(typedEvent.destination, &typedEvent);
976 }
977}

References KisSynchronizedConnectionEvent::destination.

◆ registerResources()

bool KisApplication::registerResources ( )

Definition at line 401 of file KisApplication.cpp.

402{
403 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::registerResources"));
404
406
408 QStringList() << "application/x-krita-paintoppreset"));
409
410 reg->add(new KisResourceLoader<KisGbrBrush>(ResourceSubType::GbrBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush"));
411 reg->add(new KisResourceLoader<KisImagePipeBrush>(ResourceSubType::GihBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush-animated"));
412 reg->add(new KisResourceLoader<KisSvgBrush>(ResourceSubType::SvgBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/svg+xml"));
414
415 reg->add(new KisResourceLoader<KoSegmentGradient>(ResourceSubType::SegmentedGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "application/x-gimp-gradient"));
417
428
429
430 reg->add(new KisResourceLoader<KoPattern>(ResourceType::Patterns, ResourceType::Patterns, i18n("Patterns"), {"application/x-gimp-pattern", "image/x-gimp-pat", "application/x-gimp-pattern", "image/bmp", "image/jpeg", "image/png", "image/tiff"}));
431 reg->add(new KisResourceLoader<KisWorkspaceResource>(ResourceType::Workspaces, ResourceType::Workspaces, i18n("Workspaces"), QStringList() << "application/x-krita-workspace"));
432 reg->add(new KisResourceLoader<KoSvgSymbolCollectionResource>(ResourceType::Symbols, ResourceType::Symbols, i18n("SVG symbol libraries"), QStringList() << "image/svg+xml"));
433 reg->add(new KisResourceLoader<KisWindowLayoutResource>(ResourceType::WindowLayouts, ResourceType::WindowLayouts, i18n("Window layouts"), QStringList() << "application/x-krita-windowlayout"));
434 reg->add(new KisResourceLoader<KisSessionResource>(ResourceType::Sessions, ResourceType::Sessions, i18n("Sessions"), QStringList() << "application/x-krita-session"));
435 reg->add(new KisResourceLoader<KoGamutMask>(ResourceType::GamutMasks, ResourceType::GamutMasks, i18n("Gamut masks"), QStringList() << "application/x-krita-gamutmasks"));
436#if defined HAVE_SEEXPR
437 reg->add(new KisResourceLoader<KisSeExprScript>(ResourceType::SeExprScripts, ResourceType::SeExprScripts, i18n("SeExpr Scripts"), QStringList() << "application/x-krita-seexpr-script"));
438#endif
439 // XXX: this covers only individual styles, not the library itself!
442 i18nc("Resource type name", "Layer styles"),
443 QStringList() << "application/x-photoshop-style"));
444
445 reg->add(new KisResourceLoader<KoFontFamily>(ResourceType::FontFamilies, ResourceType::FontFamilies, i18n("Font Families"), QStringList() << "application/x-font-ttf" << "application/x-font-otf"));
446 reg->add(new KisResourceLoader<KoCssStylePreset>(ResourceType::CssStyles, ResourceType::CssStyles, i18n("Style Presets"), QStringList() << "image/svg+xml"));
447
449
450#ifndef Q_OS_ANDROID
451 QString databaseLocation = KoResourcePaths::getAppDataLocation();
452#else
453 // Sqlite doesn't support content URIs (obviously). So, we make database location unconfigurable on android.
454 QString databaseLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
455#endif
456
457 if (!KisResourceCacheDb::initialize(databaseLocation)) {
458 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), i18n("%1\n\nKrita will quit now.", KisResourceCacheDb::lastError()));
459 }
460
462 connect(KisResourceLocator::instance(), SIGNAL(progressMessage(const QString&)), this, SLOT(setSplashScreenLoadingText(const QString&)));
463 if (r != KisResourceLocator::LocatorError::Ok && qApp->inherits("KisApplication")) {
464 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), KisResourceLocator::instance()->errorMessages().join('\n') + i18n("\n\nKrita will quit now."));
465 return false;
466 }
467 return true;
468}
void setSplashScreenLoadingText(const QString &)
static QString mimeTypeForSuffix(const QString &suffix)
Find the mimetype for a given extension. The extension may have the form "*.xxx" or "xxx".
static bool initialize(const QString &location)
initializes the database and updates the scheme if necessary. Does not actually fill the database wit...
static QString lastError()
lastError returns the last SQL error.
The KisResourceLoaderRegistry class manages the loader plugins for resources. Every resource can be l...
static KisResourceLoaderRegistry * instance()
void registerFixup(int priority, ResourceCacheFixup *fixup)
LocatorError initialize(const QString &installationResourcesLocation)
initialize Setup the resource locator for use.
static KisResourceLocator * instance()
static QString getAppDataLocation()
static QString getApplicationRoot()
const QString GbrBrushes
const QString PngBrushes
const QString GihBrushes
const QString SvgBrushes
const QString StopGradients
const QString KritaPaintOpPresets
const QString SegmentedGradients
const QString Palettes
const QString Symbols
const QString FontFamilies
const QString CssStyles
const QString LayerStyles
const QString Brushes
const QString GamutMasks
const QString Patterns
const QString Gradients
const QString Workspaces
const QString WindowLayouts
const QString Sessions
const QString PaintOpPresets

References KoGenericRegistry< T >::add(), ResourceType::Brushes, ResourceType::CssStyles, ResourceType::FontFamilies, ResourceType::GamutMasks, ResourceSubType::GbrBrushes, KoResourcePaths::getAppDataLocation(), KoResourcePaths::getApplicationRoot(), ResourceSubType::GihBrushes, ResourceType::Gradients, KisResourceLocator::initialize(), KisResourceCacheDb::initialize(), KisResourceLoaderRegistry::instance(), KisResourceLocator::instance(), ResourceSubType::KritaPaintOpPresets, KisResourceCacheDb::lastError(), ResourceType::LayerStyles, KisMimeDatabase::mimeTypeForSuffix(), KisResourceLocator::Ok, ResourceType::PaintOpPresets, ResourceType::Palettes, ResourceType::Patterns, ResourceSubType::PngBrushes, KisResourceLoaderRegistry::registerFixup(), ResourceType::SeExprScripts, ResourceSubType::SegmentedGradients, ResourceType::Sessions, setSplashScreenLoadingText(), ResourceSubType::StopGradients, ResourceSubType::SvgBrushes, ResourceType::Symbols, ResourceType::WindowLayouts, and ResourceType::Workspaces.

◆ remoteArguments

void KisApplication::remoteArguments ( const QString & message)
slot

Definition at line 1120 of file KisApplication.cpp.

1121{
1122 // check if we have any mainwindow
1123 KisMainWindow *mw = qobject_cast<KisMainWindow*>(qApp->activeWindow());
1124
1125 if (!mw && KisPart::instance()->mainWindows().size() > 0) {
1126 mw = KisPart::instance()->mainWindows().first();
1127 }
1128
1129 const QByteArray unpackedMessage =
1130 QByteArray::fromBase64(message.toLatin1());
1131
1132 if (!mw) {
1133 d->earlyRemoteArguments << unpackedMessage;
1134 return;
1135 }
1136 executeRemoteArguments(unpackedMessage, mw);
1137}
void executeRemoteArguments(QByteArray message, KisMainWindow *mainWindow)
Main window for Krita.
QList< QPointer< KisMainWindow > > mainWindows
Definition KisPart.cpp:106
int size(const Forest< T > &forest)
Definition KisForest.h:1232

References d, executeRemoteArguments(), KisPart::instance(), and KisPart::mainWindows.

◆ resetConfig()

void KisApplication::resetConfig ( )
private

Definition at line 1268 of file KisApplication.cpp.

1269{
1270 KIS_ASSERT_RECOVER_RETURN(qApp->thread() == QThread::currentThread());
1271
1272 KSharedConfigPtr config = KSharedConfig::openConfig();
1273 config->markAsClean();
1274
1275 // find user settings file
1276 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
1277 QString kritarcPath = configPath + QStringLiteral("/kritarc");
1278
1279 QFile kritarcFile(kritarcPath);
1280
1281 if (kritarcFile.exists()) {
1282 if (kritarcFile.open(QFile::ReadWrite)) {
1283 QString backupKritarcPath = kritarcPath + QStringLiteral(".backup");
1284
1285 QFile backupKritarcFile(backupKritarcPath);
1286
1287 if (backupKritarcFile.exists()) {
1288 backupKritarcFile.remove();
1289 }
1290
1291 QMessageBox::information(qApp->activeWindow(),
1292 i18nc("@title:window", "Krita"),
1293 i18n("Krita configurations reset!\n\n"
1294 "Backup file was created at: %1\n\n"
1295 "Restart Krita for changes to take effect.",
1296 backupKritarcPath),
1297 QMessageBox::Ok, QMessageBox::Ok);
1298
1299 // clear file
1300 kritarcFile.rename(backupKritarcPath);
1301
1302 kritarcFile.close();
1303 }
1304 else {
1305 QMessageBox::warning(qApp->activeWindow(),
1306 i18nc("@title:window", "Krita"),
1307 i18n("Failed to clear %1\n\n"
1308 "Please make sure no other program is using the file and try again.",
1309 kritarcPath),
1310 QMessageBox::Ok, QMessageBox::Ok);
1311 }
1312 }
1313
1314 // reload from disk; with the user file settings cleared,
1315 // this should load any default configuration files shipping with the program
1316 config->reparseConfiguration();
1317 config->sync();
1318
1319 // Restore to default workspace
1320 KConfigGroup cfg = KSharedConfig::openConfig()->group("MainWindow");
1321
1322 QString currentWorkspace = cfg.readEntry<QString>("CurrentWorkspace", "Default");
1324 KisWorkspaceResourceSP workspace = rserver->resource("", "", currentWorkspace);
1325
1326 if (workspace) {
1327 d->mainWindow->restoreWorkspace(workspace);
1328 }
1329}
static KisResourceServerProvider * instance()
KoResourceServer< KisWorkspaceResource > * workspaceServer()
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75

References d, KisResourceServerProvider::instance(), KIS_ASSERT_RECOVER_RETURN, and KisResourceServerProvider::workspaceServer().

◆ setSplashScreen()

void KisApplication::setSplashScreen ( QWidget * splash)

Tell KisApplication to show this splashscreen when you call start(); when start returns, the splashscreen is hidden. Use KSplashScreen to have the splash show correctly on Xinerama displays.

Definition at line 881 of file KisApplication.cpp.

882{
883 d->splashScreen = qobject_cast<KisSplashScreen*>(splashScreen);
884}

References d.

◆ setSplashScreenLoadingText

void KisApplication::setSplashScreenLoadingText ( const QString & textToLoad)
slot

Definition at line 886 of file KisApplication.cpp.

887{
888 if (d->splashScreen) {
889 d->splashScreen->setLoadingText(textToLoad);
890 d->splashScreen->repaint();
891 }
892#ifdef Q_OS_ANDROID
894#endif
895}
static void setLoadingText(const QString &text)

References d, and KisAndroidDonations::setLoadingText().

◆ slotSetLongPress

void KisApplication::slotSetLongPress ( bool enabled)
privateslot

Definition at line 1151 of file KisApplication.cpp.

1152{
1153 if (enabled && !d->longPressEventFilter) {
1154 d->longPressEventFilter = new KisLongPressEventFilter(this);
1155 installEventFilter(d->longPressEventFilter);
1156 } else if (!enabled && d->longPressEventFilter) {
1157 removeEventFilter(d->longPressEventFilter);
1158 d->longPressEventFilter->deleteLater();
1159 d->longPressEventFilter = nullptr;
1160 }
1161}

References d.

◆ start()

bool KisApplication::start ( const KisApplicationArguments & args)
virtual

Call this to start the application.

Parses command line arguments and creates the initial main windows and docs from them (or an empty doc if no cmd-line argument is specified ).

You must call this method directly before calling QApplication::exec.

It is valid behaviour not to call this method at all. In this case you have to process your command line parameters by yourself.

Definition at line 486 of file KisApplication.cpp.

487{
488 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::start"));
489#ifdef Q_OS_ANDROID
491#endif
492
493 KisConfig cfg(false);
494
495 auto iconsInMenuMode = cfg.iconsInMenu();
496 if (iconsInMenuMode == KisConfig::IIM_Yes) {
497 QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, false);
498 } else if (iconsInMenuMode == KisConfig::IIM_No) {
499 QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, true);
500 }
501
502#if defined(Q_OS_WIN)
503#ifdef ENV32BIT
504
505 if (isWow64() && !cfg.readEntry("WarnedAbout32Bits", false)) {
506 QMessageBox::information(qApp->activeWindow(),
507 i18nc("@title:window", "Krita: Warning"),
508 i18n("You are running a 32 bits build on a 64 bits Windows.\n"
509 "This is not recommended.\n"
510 "Please download and install the x64 build instead."));
511 cfg.writeEntry("WarnedAbout32Bits", true);
512
513 }
514#endif
515#endif
516
517 QString opengl = cfg.canvasState();
518 if (opengl == "OPENGL_NOT_TRIED" ) {
519 cfg.setCanvasState("TRY_OPENGL");
520 }
521 else if (opengl != "OPENGL_SUCCESS" && opengl != "TRY_OPENGL") {
522 cfg.setCanvasState("OPENGL_FAILED");
523 }
524
525 setSplashScreenLoadingText(i18n("Initializing Globals..."));
526 processEvents();
527 initializeGlobals(args);
528
529#if defined(Q_OS_ANDROID) && KRITA_QT_HAS_ANDROID_QPLATFORMSCREEN_DENSITY_ADJUSTMENT
530 d->androidScaling = new KisAndroidScaling(cfg, this);
531#endif
532
533 const bool doNewImage = args.doNewImage();
534 const bool doTemplate = args.doTemplate();
535 const bool exportAs = args.exportAs();
536 const bool exportSequence = args.exportSequence();
537 const QString exportFileName = args.exportFileName();
538
539 d->batchRun = (exportAs || exportSequence || !exportFileName.isEmpty());
540 const bool needsMainWindow = (!exportAs && !exportSequence);
541 // only show the mainWindow when no command-line mode option is passed
542 bool showmainWindow = (!exportAs && !exportSequence); // would be !batchRun;
543
544#ifndef Q_OS_ANDROID
545 const bool showSplashScreen = !d->batchRun && qEnvironmentVariableIsEmpty("NOSPLASH");
546 if (showSplashScreen && d->splashScreen) {
547 d->splashScreen->show();
548 d->splashScreen->repaint();
549 processEvents();
550 }
551#endif
552
553 KConfigGroup group(KSharedConfig::openConfig(), "theme");
554#ifndef Q_OS_HAIKU
555 Digikam::ThemeManager themeManager;
556 themeManager.setCurrentTheme(group.readEntry("Theme", "Krita dark"));
557#endif
558
559 ResetStarting resetStarting(d->splashScreen, args.filenames().count()); // remove the splash when done
560 Q_UNUSED(resetStarting);
561
562 // Make sure we can save resources and tags
563 setSplashScreenLoadingText(i18n("Adding resource types..."));
564 processEvents();
566
567 setSplashScreenLoadingText(i18n("Loading plugins..."));
568 processEvents();
569 // Load the plugins
570 loadPlugins();
571
572 // Load all resources
573 setSplashScreenLoadingText(i18n("Loading resources..."));
574 processEvents();
575 if (!registerResources()) {
576 return false;
577 }
578
579 KisPart *kisPart = KisPart::instance();
580 if (needsMainWindow) {
581 // show a mainWindow asap, if we want that
582 setSplashScreenLoadingText(i18n("Loading Main Window..."));
583 processEvents();
584
585
586 bool sessionNeeded = true;
587 auto sessionMode = cfg.sessionOnStartup();
588
589 if (!args.session().isEmpty()) {
590 sessionNeeded = !kisPart->restoreSession(args.session());
591 } else if (sessionMode == KisConfig::SOS_ShowSessionManager) {
592 showmainWindow = false;
593 sessionNeeded = false;
594 kisPart->showSessionManager();
595 } else if (sessionMode == KisConfig::SOS_PreviousSession) {
596 KConfigGroup sessionCfg = KSharedConfig::openConfig()->group("session");
597 const QString &sessionName = sessionCfg.readEntry("previousSession");
598
599 sessionNeeded = !kisPart->restoreSession(sessionName);
600 }
601
602 if (sessionNeeded) {
603 kisPart->startBlankSession();
604 }
605
606 if (!args.windowLayout().isEmpty()) {
608 KisWindowLayoutResourceSP windowLayout = rserver->resource("", "", args.windowLayout());
609 if (windowLayout) {
610 windowLayout->applyLayout();
611 }
612 }
613
614 setSplashScreenLoadingText(i18n("Launching..."));
615
616 if (showmainWindow) {
617 d->mainWindow = kisPart->currentMainwindow();
618
619 if (!args.workspace().isEmpty()) {
621 KisWorkspaceResourceSP workspace = rserver->resource("", "", args.workspace());
622 if (workspace) {
623 d->mainWindow->restoreWorkspace(workspace);
624 }
625 }
626
627 if (args.canvasOnly()) {
628 d->mainWindow->viewManager()->switchCanvasOnly(true);
629 }
630
631 if (args.fullScreen()) {
632 d->mainWindow->showFullScreen();
633 }
634 } else {
635 d->mainWindow = kisPart->createMainWindow();
636 }
637 }
638
639 // Check for autosave files that can be restored, if we're not running a batch run (test)
640 if (!d->batchRun) {
642 }
643
644 setSplashScreenLoadingText(QString()); // done loading, so clear out label
645#ifdef Q_OS_ANDROID
647#endif
648 processEvents();
649
650 //configure the unit manager
652 connect(this, &KisApplication::aboutToQuit, &KisSpinBoxUnitManagerFactory::clearUnitManagerBuilder); //ensure the builder is destroyed when the application leave.
653 //the new syntax slot syntax allow to connect to a non q_object static method.
654
655 // Long-press emulation.
658 slotSetLongPress(cfg.longPressEnabled());
659
660 // Xiaomi workaround: their stylus inexplicably inputs page up and down keys
661 // when pressing stylus buttons. This flag causes the Android platform
662 // integration to turn those into right and middle clicks instead.
663#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN
664 auto setPageUpDownMouseButtonEmulationWorkaround = [](bool enabled) {
665 QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN, enabled);
666 };
667 connect(cfgNotifier,
668 &KisConfigNotifier::sigUsePageUpDownMouseButtonEmulationWorkaroundChanged,
669 this,
670 setPageUpDownMouseButtonEmulationWorkaround);
671 setPageUpDownMouseButtonEmulationWorkaround(cfg.usePageUpDownMouseButtonEmulationWorkaround());
672#endif
673
674 // OnePlus workaround: their stylus inexplicably inputs the F21 key when
675 // pressing the stylus button. This flag causes the Android platform
676 // integration to turn it into middle clicks instead. Currently
677 // unconditional because a setting requires translation-relevant text
678 // changes, but later versions of Krita let you toggle it like the Xiaomi
679 // workarounds above.
680#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS
681 QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS, true);
682 auto setHighFunctionKeyMouseButtonEmulationWorkaround = [](bool enabled) {
683 // QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS, enabled);
684 };
685 connect(cfgNotifier,
686 &KisConfigNotifier::sigUseHighFunctionKeyMouseButtonEmulationWorkaroundChanged,
687 this,
688 setHighFunctionKeyMouseButtonEmulationWorkaround);
689 setHighFunctionKeyMouseButtonEmulationWorkaround(cfg.useHighFunctionKeyMouseButtonEmulationWorkaround());
690#endif
691
692 // Xiaomi workaround: historic tablet motion events are garbage, they just
693 // connect the actual points that the tablet sampled with a straight line
694 // and no pressure emulation, leading to jagged curves that don't get
695 // smoothed out. This flag disables reading those historic events.
696#if KRITA_QT_HAS_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS
697 auto setIgnoreHistoricTabletEventsWorkaround = [](bool enabled) {
698 QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS, enabled);
699 };
700 connect(cfgNotifier,
701 &KisConfigNotifier::sigUseIgnoreHistoricTabletEventsWorkaroundChanged,
702 this,
703 setIgnoreHistoricTabletEventsWorkaround);
704 setIgnoreHistoricTabletEventsWorkaround(cfg.useIgnoreHistoricTabletEventsWorkaround());
705#endif
706
707 // Create a new image, if needed
708 if (doNewImage) {
710 if (doc) {
711 kisPart->addDocument(doc);
712 d->mainWindow->addViewAndNotifyLoadingCompleted(doc);
713 }
714 }
715
716 // Get the command line arguments which we have to parse
717 int argsCount = args.filenames().count();
718 if (argsCount > 0) {
719 // Loop through arguments
720 for (int argNumber = 0; argNumber < argsCount; argNumber++) {
721 QString fileName = args.filenames().at(argNumber);
722 // are we just trying to open a template?
723 if (doTemplate) {
724 // called in mix with batch options? ignore and silently skip
725 if (d->batchRun) {
726 continue;
727 }
728 createNewDocFromTemplate(fileName, d->mainWindow);
729 // now try to load
730 }
731 else {
732 if (exportAs) {
733 QString outputMimetype = KisMimeDatabase::mimeTypeForFile(exportFileName, false);
734 if (outputMimetype == "application/octetstream") {
735 dbgKrita << i18n("Mimetype not found, try using the -mimetype option") << Qt::endl;
736 return false;
737 }
738
739 KisDocument *doc = kisPart->createDocument();
740 doc->setFileBatchMode(d->batchRun);
741 bool result = doc->openPath(fileName);
742
743 if (!result) {
744 errKrita << "Could not load " << fileName << ":" << doc->errorMessage();
745 QTimer::singleShot(0, this, SLOT(quit()));
746 return false;
747 }
748
749 if (exportFileName.isEmpty()) {
750 errKrita << "Export destination is not specified for" << fileName << "Please specify export destination with --export-filename option";
751 QTimer::singleShot(0, this, SLOT(quit()));
752 return false;
753 }
754
755 qApp->processEvents(); // For vector layers to be updated
756
757 doc->setFileBatchMode(true);
758 doc->image()->waitForDone();
759
760 if (!doc->exportDocumentSync(exportFileName, outputMimetype.toLatin1())) {
761 errKrita << "Could not export " << fileName << "to" << exportFileName << ":" << doc->errorMessage();
762 }
763 QTimer::singleShot(0, this, SLOT(quit()));
764 return true;
765 }
766 else if (exportSequence) {
767 KisDocument *doc = kisPart->createDocument();
768 doc->setFileBatchMode(d->batchRun);
769 doc->openPath(fileName);
770 qApp->processEvents(); // For vector layers to be updated
771
772 if (!doc->image()->animationInterface()->hasAnimation()) {
773 errKrita << "This file has no animation." << Qt::endl;
774 QTimer::singleShot(0, this, SLOT(quit()));
775 return false;
776 }
777
778 doc->setFileBatchMode(true);
779 int sequenceStart = 0;
780
781
782 qDebug() << ppVar(exportFileName);
785 exportFileName,
786 sequenceStart,
787 false,
788 0);
789
790 exporter.setBatchMode(d->batchRun);
791
792 KisAsyncAnimationFramesSaveDialog::Result result = exporter.regenerateRange(nullptr);
793 qDebug() << ppVar(result);
794
796 errKrita << i18n("Failed to render animation frames!") << Qt::endl;
797 }
798
799 QTimer::singleShot(0, this, SLOT(quit()));
800 return true;
801 }
802 else if (d->mainWindow) {
803 if (QFileInfo(fileName).fileName().endsWith(".bundle", Qt::CaseInsensitive)) {
804 d->mainWindow->installBundle(fileName);
805 }
806 else {
807 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
808
809 d->mainWindow->openDocument(fileName, flags);
810 }
811 }
812 }
813 }
814 }
815
816 //add an image as file-layer
817 if (!args.fileLayer().isEmpty()){
818 if (d->mainWindow->viewManager()->image()){
819 KisFileLayer *fileLayer = new KisFileLayer(d->mainWindow->viewManager()->image(), "",
820 args.fileLayer(), KisFileLayer::None, "Bicubic",
821 d->mainWindow->viewManager()->image()->nextLayerName(i18n("File layer")), OPACITY_OPAQUE_U8);
822 QFileInfo fi(fileLayer->path());
823 if (fi.exists()){
824 KisNodeCommandsAdapter adapter(d->mainWindow->viewManager());
825 adapter.addNode(fileLayer, d->mainWindow->viewManager()->activeNode()->parent(),
826 d->mainWindow->viewManager()->activeNode());
827 }
828 else{
829 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita:Warning"),
830 i18n("Cannot add %1 as a file layer: the file does not exist.", fileLayer->path()));
831 }
832 }
833 else if (this->isRunning()){
834 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita:Warning"),
835 i18n("Cannot add the file layer: no document is open.\n\n"
836"You can create a new document using the --new-image option, or you can open an existing file.\n\n"
837"If you instead want to add the file layer to a document in an already running instance of Krita, check the \"Allow only one instance of Krita\" checkbox in the settings (Settings -> General -> Window)."));
838 }
839 else {
840 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita: Warning"),
841 i18n("Cannot add the file layer: no document is open.\n"
842 "You can either create a new file using the --new-image option, or you can open an existing file."));
843 }
844 }
845
846 // fixes BUG:369308 - Krita crashing on splash screen when loading.
847 // trying to open a file before Krita has loaded can cause it to hang and crash
848 if (d->splashScreen) {
849 d->splashScreen->displayLinks(true);
850 d->splashScreen->displayRecentFiles(true);
851 }
852
853 Q_FOREACH(const QByteArray &message, d->earlyRemoteArguments) {
854 executeRemoteArguments(message, d->mainWindow);
855 }
856
858
859 // process File open event files
860 if (!d->earlyFileOpenEvents.isEmpty()) {
862 Q_FOREACH(QString fileName, d->earlyFileOpenEvents) {
863 d->mainWindow->openDocument(fileName, QFlags<KisMainWindow::OpenFlag>());
864 }
865 }
866
868
869 // not calling this before since the program will quit there.
870 return true;
871}
void setCurrentTheme(const QString &name)
static void showDonationDialog(bool splash)
friend class ResetStarting
void slotSetLongPress(bool enabled)
void initializeGlobals(const KisApplicationArguments &args)
static void verifyMetatypeRegistration()
void sigLongPressChanged(bool enabled)
static KisConfigNotifier * instance()
@ SOS_PreviousSession
Definition kis_config.h:388
@ SOS_ShowSessionManager
Definition kis_config.h:389
void setFileBatchMode(const bool batchMode)
KisImageSP image
QString errorMessage() const
bool exportDocumentSync(const QString &path, const QByteArray &mimeType, KisPropertiesConfigurationSP exportConfiguration=0)
bool openPath(const QString &path, OpenFlags flags=None)
openPath Open a Path
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
void waitForDone()
KisImageAnimationInterface * animationInterface() const
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
bool restoreSession(const QString &sessionName)
Definition KisPart.cpp:643
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:457
void startBlankSession()
Definition KisPart.cpp:635
KisDocument * createDocument() const
Definition KisPart.cpp:228
void showSessionManager()
Definition KisPart.cpp:624
KisMainWindow * createMainWindow(QUuid id=QUuid())
Definition KisPart.cpp:258
KoResourceServer< KisWindowLayoutResource > * windowLayoutServer()
static void setDefaultUnitManagerBuilder(KisSpinBoxUnitManagerBuilder *pBuilder)
set a builder the factory can use. The factory should take on the lifecycle of the builder,...
static QString screenInformation()
Returns information about all available screens.
static void writeSysInfo(const QString &message)
Writes to the system information file and Krita log.
QSharedPointer< T > resource(const QString &md5, const QString &fileName, const QString &name)
resource retrieves a resource. If the md5sum is not empty, the resource will only be retrieved if a r...
#define dbgKrita
Definition kis_debug.h:48
#define errKrita
Definition kis_debug.h:111
#define ppVar(var)
Definition kis_debug.h:159
QAction * quit(const QObject *recvr, const char *slot, QObject *parent)

References KisPart::addDocument(), KisNodeCommandsAdapter::addNode(), addResourceTypes(), KisImage::animationInterface(), KisMainWindow::BatchMode, KisApplicationArguments::canvasOnly, KisConfig::canvasState(), checkAutosaveFiles(), KisSpinBoxUnitManagerFactory::clearUnitManagerBuilder(), KisPart::createDocument(), KisApplicationArguments::createDocumentFromArguments(), KisPart::createMainWindow(), createNewDocFromTemplate(), KisPart::currentMainwindow(), d, dbgKrita, KisImageAnimationInterface::documentPlaybackRange(), KisApplicationArguments::doNewImage(), KisApplicationArguments::doTemplate, errKrita, KisDocument::errorMessage(), executeRemoteArguments(), KisApplicationArguments::exportAs, KisDocument::exportDocumentSync(), KisApplicationArguments::exportFileName, KisApplicationArguments::exportSequence, KisApplicationArguments::fileLayer, KisApplicationArguments::filenames, KisApplicationArguments::fullScreen, KisImageAnimationInterface::hasAnimation(), hideSplashScreen(), KisConfig::iconsInMenu(), KisConfig::IIM_No, KisConfig::IIM_Yes, KisDocument::image, initializeGlobals(), KisConfigNotifier::instance(), KisPart::instance(), KisResourceServerProvider::instance(), QtSingleApplication::isRunning(), loadPlugins(), KisConfig::longPressEnabled(), KisMimeDatabase::mimeTypeForFile(), KisFileLayer::None, KisMainWindow::None, OPACITY_OPAQUE_U8, KisDocument::openPath(), KisNode::parent, KisFileLayer::path(), ppVar, KisConfig::readEntry(), KisAsyncAnimationFramesSaveDialog::regenerateRange(), registerResources(), KisAsyncAnimationRenderDialogBase::RenderComplete, KoResourceServer< T >::resource(), KisPart::restoreSession(), KisUsageLogger::screenInformation(), KisApplicationArguments::session, KisConfig::sessionOnStartup(), KisAsyncAnimationRenderDialogBase::setBatchMode(), KisConfig::setCanvasState(), Digikam::ThemeManager::setCurrentTheme(), KisSpinBoxUnitManagerFactory::setDefaultUnitManagerBuilder(), KisDocument::setFileBatchMode(), KisAndroidDonations::setLoaded(), setSplashScreenLoadingText(), KisAndroidDonations::showDonationDialog(), KisPart::showSessionManager(), KisConfigNotifier::sigLongPressChanged(), slotSetLongPress(), KisConfig::SOS_PreviousSession, KisConfig::SOS_ShowSessionManager, KisPart::startBlankSession(), verifyMetatypeRegistration(), KisImage::waitForDone(), KisApplicationArguments::windowLayout, KisResourceServerProvider::windowLayoutServer(), KisApplicationArguments::workspace, KisResourceServerProvider::workspaceServer(), KisConfig::writeEntry(), and KisUsageLogger::writeSysInfo().

◆ verifyMetatypeRegistration()

void KisApplication::verifyMetatypeRegistration ( )
static

Verify that all our statically registered types are actually registered. This check is skipped in release builds, when HIDE_SAFE_ASSERTS is defined

Definition at line 1008 of file KisApplication.cpp.

1009{
1014#if !defined(HIDE_SAFE_ASSERTS) || defined(CRASH_ON_SAFE_ASSERTS)
1015
1016 auto verifyTypeRegistered = [] (const char *type) {
1017 const int typeId = QMetaType::type(type);
1018
1019 if (typeId <= 0) {
1020 qFatal("ERROR: type-id for metatype %s is not found", type);
1021 }
1022
1023 if (!QMetaType::isRegistered(typeId)) {
1024 qFatal("ERROR: metatype %s is not registered", type);
1025 }
1026 };
1027
1028 verifyTypeRegistered("KisBrushSP");
1029 verifyTypeRegistered("KoSvgText::AutoValue");
1030 verifyTypeRegistered("KoSvgText::BackgroundProperty");
1031 verifyTypeRegistered("KoSvgText::StrokeProperty");
1032 verifyTypeRegistered("KoSvgText::TextTransformInfo");
1033 verifyTypeRegistered("KoSvgText::TextIndentInfo");
1034 verifyTypeRegistered("KoSvgText::TabSizeInfo");
1035 verifyTypeRegistered("KoSvgText::LineHeightInfo");
1036 verifyTypeRegistered("KisPaintopLodLimitations");
1037 verifyTypeRegistered("KisImageSP");
1038 verifyTypeRegistered("KisImageSignalType");
1039 verifyTypeRegistered("KisNodeSP");
1040 verifyTypeRegistered("KisNodeList");
1041 verifyTypeRegistered("KisPaintDeviceSP");
1042 verifyTypeRegistered("KisTimeSpan");
1043 verifyTypeRegistered("KoColor");
1044 verifyTypeRegistered("KoResourceSP");
1045 verifyTypeRegistered("KoResourceCacheInterfaceSP");
1046 verifyTypeRegistered("KisAsyncAnimationRendererBase::CancelReason");
1047 verifyTypeRegistered("KisGridConfig");
1048 verifyTypeRegistered("KisGuidesConfig");
1049 verifyTypeRegistered("KisUpdateInfoSP");
1050 verifyTypeRegistered("KisToolChangesTrackerDataSP");
1051 verifyTypeRegistered("QVector<QImage>");
1052 verifyTypeRegistered("SnapshotDirInfoList");
1053 verifyTypeRegistered("TransformTransactionProperties");
1054 verifyTypeRegistered("ToolTransformArgs");
1055 verifyTypeRegistered("QPainterPath");
1056#endif
1057}

Friends And Related Symbol Documentation

◆ ResetStarting

friend class ResetStarting
friend

Definition at line 125 of file KisApplication.h.

Member Data Documentation

◆ d

QScopedPointer<Private> KisApplication::d
private

Definition at line 123 of file KisApplication.h.


The documentation for this class was generated from the following files: