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 37 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.

Initialize application info, it will be used by both, Qt and DrKonqi of the host system

Load platform plugin for modifiers fetching

Definition at line 220 of file KisApplication.cpp.

221 : QtSingleApplication(key, argc, argv)
222 , d(new Private)
223{
224#ifdef Q_OS_ANDROID
225 // The hardware renderer backend on Android doesn't support proper stacking,
226 // causing windows with QtQuick widgets to always stack behind everything
227 // else, including our own dialog decorations.
228 qputenv("QT_QUICK_BACKEND", "software");
229#endif
230#ifdef Q_OS_MACOS
232#endif
233
234 QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath());
235
236 {
239
240 KAboutData aboutData("krita",
241 i18n("Krita"),
243 i18nc("@title", "Krita is the full-featured digital art studio"),
244 KAboutLicense::GPL,
245 i18nc("@info:credit", "© 1999–2026 The Krita Developers"));
246 aboutData.setHomepage(QStringLiteral("https://krita.org"));
247 aboutData.setOrganizationDomain("krita.org");
248
249 // this call sets corresponding fields of QApplication as well
250 KAboutData::setApplicationData(aboutData);
251
252 // Note: Qt docs suggest we set organization name, but if we do, we get resource
253 // paths of the form of krita/krita, which is weird.
254 KIS_SAFE_ASSERT_RECOVER(this->organizationName().isEmpty()) {
255 this->setOrganizationName("");
256 }
257 }
258
259#ifndef Q_OS_MACOS
260 setWindowIcon(KisIconUtils::loadIcon("krita-branding"));
261#endif
262
263 if (qgetenv("KRITA_NO_STYLE_OVERRIDE").isEmpty()) {
264
265#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
266 QStringList styles = QStringList() << "haiku" << "macintosh" << "breeze" << "fusion";
267#else
268 QStringList styles = QStringList() << "haiku" << "macos" << "breeze" << "fusion";
269#endif
270 if (!styles.contains(style()->objectName().toLower())) {
271 Q_FOREACH (const QString & style, styles) {
272 if (!setStyle(style)) {
273 qDebug() << "No" << style << "available.";
274 }
275 else {
276 qDebug() << "Set style" << style;
277 break;
278 }
279 }
280 }
281
282 // if style is set from config, try to load that
283 KisConfig cfg(true);
284 QString widgetStyleFromConfig = cfg.widgetStyle();
285 if(widgetStyleFromConfig != "") {
286 qApp->setStyle(widgetStyleFromConfig);
287#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
288 } else if (style()->objectName().toLower() == "macintosh") {
289 // if no configured style on macOS, default to Fusion
290 qApp->setStyle("fusion");
291 }
292#else
293 } else if (style()->objectName().toLower() == "macos") {
294 // if no configured style on macOS, default to Fusion
295 qApp->setStyle("fusion");
296 }
297#endif
298
299 }
300 else {
301 qDebug() << "Style override disabled, using" << style()->objectName();
302 }
303
307 {
308 d->extendedModifiersPluginInterface.reset(KisPlatformPluginInterfaceFactory::instance()->createExtendedModifiersMapper());
309 }
310
311 // store the style name
312 qApp->setProperty(currentUnderlyingStyleNameProperty, style()->objectName());
314
315
316#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
317
322 struct PlatformWindowCreationFilter : QObject
323 {
324 using QObject::QObject;
325
326 bool eventFilter(QObject *watched, QEvent *event) override {
327 if (event->type() == QEvent::PlatformSurface) {
328 QWidget *widget = qobject_cast<QWidget*>(watched);
329 if (!widget) return false;
330
335 if (watched->property("krita_skip_srgb_surface_manager_assignment").toBool()) {
336 return false;
337 }
338
339 QPlatformSurfaceEvent *surfaceEvent = static_cast<QPlatformSurfaceEvent*>(event);
340 if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
341 QWindow *nativeWindow = widget->windowHandle();
342 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(widget->windowHandle(), false);
343
344 if (!nativeWindow->findChild<KisSRGBSurfaceColorSpaceManager*>()) {
346 }
347 }
348 }
349
350 return false;
351 }
352 };
353
354 this->installEventFilter(new PlatformWindowCreationFilter(this));
355#endif /* KRITA_USE_SURFACE_COLOR_MANAGEMENT_API */
356}
QList< QString > QStringList
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(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
constexpr const char * currentUnderlyingStyleNameProperty
Definition kis_global.h:116
QIcon loadIcon(const QString &name)
KRITAVERSION_EXPORT QString versionString(bool checkGit=false)
void setMouseCoalescingEnabled(bool enabled)
Definition osx.mm:17

References KIS_SAFE_ASSERT_RECOVER, KisIconUtils::loadIcon(), setMouseCoalescingEnabled(), KritaVersionWrapper::versionString(), and KisConfig::widgetStyle().

◆ ~KisApplication()

KisApplication::~KisApplication ( )
override

Destructor.

Definition at line 876 of file KisApplication.cpp.

877{
878 if (!isRunning()) {
881 }
882}
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 392 of file KisApplication.cpp.

393{
394 // All Krita's resource types
395 KoResourcePaths::addAssetType("markers", "data", "/styles/");
396 KoResourcePaths::addAssetType("kis_pics", "data", "/pics/");
397 KoResourcePaths::addAssetType("kis_images", "data", "/images/");
398 KoResourcePaths::addAssetType("metadata_schema", "data", "/metadata/schemas/");
399 KoResourcePaths::addAssetType("gmic_definitions", "data", "/gmic/");
400 KoResourcePaths::addAssetType("kis_shortcuts", "data", "/shortcuts/");
401 KoResourcePaths::addAssetType("kis_actions", "data", "/actions");
402 KoResourcePaths::addAssetType("kis_actions", "data", "/pykrita");
403 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc");
404 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/");
405 KoResourcePaths::addAssetType("tags", "data", "/tags/");
406 KoResourcePaths::addAssetType("templates", "data", "/templates");
407 KoResourcePaths::addAssetType("pythonscripts", "data", "/pykrita");
408 KoResourcePaths::addAssetType("preset_icons", "data", "/preset_icons");
409#if defined HAVE_SEEXPR
410 KoResourcePaths::addAssetType(ResourceType::SeExprScripts, "data", "/seexpr_scripts/", true);
411#endif
412
413 // Make directories for all resources we can save, and tags
414 KoResourcePaths::saveLocation("data", "/asl/", true);
415 KoResourcePaths::saveLocation("data", "/css_styles/", true);
416 KoResourcePaths::saveLocation("data", "/input/", true);
417 KoResourcePaths::saveLocation("data", "/pykrita/", true);
418 KoResourcePaths::saveLocation("data", "/color-schemes/", true);
419 KoResourcePaths::saveLocation("data", "/preset_icons/", true);
420 KoResourcePaths::saveLocation("data", "/preset_icons/tool_icons/", true);
421 KoResourcePaths::saveLocation("data", "/preset_icons/emblem_icons/", true);
422}
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 1328 of file KisApplication.cpp.

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

References resetConfig().

◆ checkAutosaveFiles()

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

Definition at line 1160 of file KisApplication.cpp.

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

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

◆ createNewDocFromTemplate()

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

Definition at line 1220 of file KisApplication.cpp.

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

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

◆ event()

bool KisApplication::event ( QEvent * event)
override

Definition at line 425 of file KisApplication.cpp.

426{
427
428 #ifdef Q_OS_MACOS
429 if (event->type() == QEvent::FileOpen) {
430 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
431 fileOpenRequested(openEvent->file());
432 return true;
433 }
434 #endif
435 return QApplication::event(event);
436}
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 1056 of file KisApplication.cpp.

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

1340{
1341 return d->extendedModifiersPluginInterface.data();
1342}

References d.

◆ fileOpenRequested

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

Definition at line 1136 of file KisApplication.cpp.

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

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

◆ hideSplashScreen()

void KisApplication::hideSplashScreen ( )

Definition at line 897 of file KisApplication.cpp.

898{
899 if (d->splashScreen) {
900 // hide the splashscreen to see the dialog
901 d->splashScreen->hide();
902 }
903}

References d.

◆ initializeGlobals()

void KisApplication::initializeGlobals ( const KisApplicationArguments & args)

Definition at line 385 of file KisApplication.cpp.

386{
387 Q_UNUSED(args)
388 // There are no globals to initialize from the arguments now. There used
389 // to be the `dpi` argument, but it doesn't do anything anymore.
390}

◆ isStoreApplication()

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

Definition at line 976 of file KisApplication.cpp.

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

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

◆ loadPlugins()

void KisApplication::loadPlugins ( )

Definition at line 506 of file KisApplication.cpp.

507{
508 // qDebug() << "loadPlugins();";
509
511 r->add(new KisShapeSelectionFactory());
520}
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 906 of file KisApplication.cpp.

907{
908 try {
909 bool result = true;
910
916 AppRecursionInfo &info = s_recursionInfo->localData();
917
918 {
919 // QApplication::notify() can throw, so use RAII for counters
920 AppRecursionGuard guard(&info);
921
923
924 if (info.eventRecursionCount > 1) {
926 KIS_SAFE_ASSERT_RECOVER_NOOP(typedEvent->destination == receiver);
927
928 info.postponedSynchronizationEvents.emplace(KisSynchronizedConnectionEvent(*typedEvent));
929 } else {
930 result = QApplication::notify(receiver, event);
931 }
932 } else {
933 result = QApplication::notify(receiver, event);
934 }
935 }
936
937 if (!info.eventRecursionCount) {
939
940 }
941
942 return result;
943
944 } catch (std::exception &e) {
945 qWarning("Error %s sending event %i to object %s",
946 e.what(), event->type(), qPrintable(receiver->objectName()));
947 } catch (...) {
948 qWarning("Error <unknown> sending event %i to object %s",
949 event->type(), qPrintable(receiver->objectName()));
950 }
951 return false;
952}
#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 954 of file KisApplication.cpp.

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

References KisSynchronizedConnectionEvent::destination.

◆ registerResources()

bool KisApplication::registerResources ( )

Definition at line 439 of file KisApplication.cpp.

440{
442
444 QStringList() << "application/x-krita-paintoppreset"));
445
446 reg->add(new KisResourceLoader<KisGbrBrush>(ResourceSubType::GbrBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush"));
447 reg->add(new KisResourceLoader<KisImagePipeBrush>(ResourceSubType::GihBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush-animated"));
448 reg->add(new KisResourceLoader<KisSvgBrush>(ResourceSubType::SvgBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/svg+xml"));
450
451 reg->add(new KisResourceLoader<KoSegmentGradient>(ResourceSubType::SegmentedGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "application/x-gimp-gradient"));
453
464
465
466 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"}));
467 reg->add(new KisResourceLoader<KisWorkspaceResource>(ResourceType::Workspaces, ResourceType::Workspaces, i18n("Workspaces"), QStringList() << "application/x-krita-workspace"));
468 reg->add(new KisResourceLoader<KoSvgSymbolCollectionResource>(ResourceType::Symbols, ResourceType::Symbols, i18n("SVG symbol libraries"), QStringList() << "image/svg+xml"));
469 reg->add(new KisResourceLoader<KisWindowLayoutResource>(ResourceType::WindowLayouts, ResourceType::WindowLayouts, i18n("Window layouts"), QStringList() << "application/x-krita-windowlayout"));
470 reg->add(new KisResourceLoader<KisSessionResource>(ResourceType::Sessions, ResourceType::Sessions, i18n("Sessions"), QStringList() << "application/x-krita-session"));
471 reg->add(new KisResourceLoader<KoGamutMask>(ResourceType::GamutMasks, ResourceType::GamutMasks, i18n("Gamut masks"), QStringList() << "application/x-krita-gamutmasks"));
472#if defined HAVE_SEEXPR
473 reg->add(new KisResourceLoader<KisSeExprScript>(ResourceType::SeExprScripts, ResourceType::SeExprScripts, i18n("SeExpr Scripts"), QStringList() << "application/x-krita-seexpr-script"));
474#endif
475 // XXX: this covers only individual styles, not the library itself!
478 i18nc("Resource type name", "Layer styles"),
479 QStringList() << "application/x-photoshop-style"));
480
481 reg->add(new KisResourceLoader<KoFontFamily>(ResourceType::FontFamilies, ResourceType::FontFamilies, i18n("Font Families"), QStringList() << "application/x-font-ttf" << "application/x-font-otf"));
482 reg->add(new KisResourceLoader<KoCssStylePreset>(ResourceType::CssStyles, ResourceType::CssStyles, i18n("Style Presets"), QStringList() << "image/svg+xml"));
483
485
486#ifndef Q_OS_ANDROID
487 QString databaseLocation = KoResourcePaths::getAppDataLocation();
488#else
489 // Sqlite doesn't support content URIs (obviously). So, we make database location unconfigurable on android.
490 QString databaseLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
491#endif
492
493 if (!KisResourceCacheDb::initialize(databaseLocation)) {
494 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), i18n("%1\n\nKrita will quit now.", KisResourceCacheDb::lastError()));
495 }
496
498 connect(KisResourceLocator::instance(), SIGNAL(progressMessage(const QString&)), this, SLOT(setSplashScreenLoadingText(const QString&)));
499 if (r != KisResourceLocator::LocatorError::Ok && qApp->inherits("KisApplication")) {
500 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), KisResourceLocator::instance()->errorMessages().join('\n') + i18n("\n\nKrita will quit now."));
501 return false;
502 }
503 return true;
504}
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 1117 of file KisApplication.cpp.

1118{
1119 // check if we have any mainwindow
1120 KisMainWindow *mw = qobject_cast<KisMainWindow*>(qApp->activeWindow());
1121
1122 if (!mw && KisPart::instance()->mainWindows().size() > 0) {
1123 mw = KisPart::instance()->mainWindows().first();
1124 }
1125
1126 const QByteArray unpackedMessage =
1127 QByteArray::fromBase64(message.toLatin1());
1128
1129 if (!mw) {
1130 d->earlyRemoteArguments << unpackedMessage;
1131 return;
1132 }
1133 executeRemoteArguments(unpackedMessage, mw);
1134}
void executeRemoteArguments(QByteArray message, KisMainWindow *mainWindow)
Main window for Krita.
QList< QPointer< KisMainWindow > > mainWindows
Definition KisPart.cpp:107
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 1265 of file KisApplication.cpp.

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

885{
886 d->splashScreen = qobject_cast<KisSplashScreen*>(splashScreen);
887}

References d.

◆ setSplashScreenLoadingText

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

Definition at line 889 of file KisApplication.cpp.

890{
891 if (d->splashScreen) {
892 d->splashScreen->setLoadingText(textToLoad);
893 d->splashScreen->repaint();
894 }
895}

References d.

◆ slotSetLongPress

void KisApplication::slotSetLongPress ( bool enabled)
privateslot

Definition at line 1148 of file KisApplication.cpp.

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

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 522 of file KisApplication.cpp.

523{
524 KisConfig cfg(false);
525
526#if defined(Q_OS_WIN)
527#ifdef ENV32BIT
528
529 if (isWow64() && !cfg.readEntry("WarnedAbout32Bits", false)) {
530 QMessageBox::information(qApp->activeWindow(),
531 i18nc("@title:window", "Krita: Warning"),
532 i18n("You are running a 32 bits build on a 64 bits Windows.\n"
533 "This is not recommended.\n"
534 "Please download and install the x64 build instead."));
535 cfg.writeEntry("WarnedAbout32Bits", true);
536
537 }
538#endif
539#endif
540
541 QString opengl = cfg.canvasState();
542 if (opengl == "OPENGL_NOT_TRIED" ) {
543 cfg.setCanvasState("TRY_OPENGL");
544 }
545 else if (opengl != "OPENGL_SUCCESS" && opengl != "TRY_OPENGL") {
546 cfg.setCanvasState("OPENGL_FAILED");
547 }
548
549 setSplashScreenLoadingText(i18n("Initializing Globals..."));
550 processEvents();
551 initializeGlobals(args);
552
553 const bool doNewImage = args.doNewImage();
554 const bool doTemplate = args.doTemplate();
555 const bool exportAs = args.exportAs();
556 const bool exportSequence = args.exportSequence();
557 const QString exportFileName = args.exportFileName();
558
559 d->batchRun = (exportAs || exportSequence || !exportFileName.isEmpty());
560 const bool needsMainWindow = (!exportAs && !exportSequence);
561 // only show the mainWindow when no command-line mode option is passed
562 bool showmainWindow = (!exportAs && !exportSequence); // would be !batchRun;
563
564 const bool showSplashScreen = !d->batchRun && qEnvironmentVariableIsEmpty("NOSPLASH");
565 if (showSplashScreen && d->splashScreen) {
566 d->splashScreen->show();
567 d->splashScreen->repaint();
568 processEvents();
569 }
570
571 KConfigGroup group(KSharedConfig::openConfig(), "theme");
572#ifndef Q_OS_HAIKU
573 Digikam::ThemeManager themeManager;
574 themeManager.setCurrentTheme(group.readEntry("Theme", "Krita dark"));
575#endif
576
577 ResetStarting resetStarting(d->splashScreen, args.filenames().count()); // remove the splash when done
578 Q_UNUSED(resetStarting);
579
580 // Make sure we can save resources and tags
581 setSplashScreenLoadingText(i18n("Adding resource types..."));
582 processEvents();
584
585 setSplashScreenLoadingText(i18n("Loading plugins..."));
586 processEvents();
587 // Load the plugins
588 loadPlugins();
589
590 // Load all resources
591 setSplashScreenLoadingText(i18n("Loading resources..."));
592 processEvents();
593 if (!registerResources()) {
594 return false;
595 }
596
597 KisPart *kisPart = KisPart::instance();
598 if (needsMainWindow) {
599 // show a mainWindow asap, if we want that
600 setSplashScreenLoadingText(i18n("Loading Main Window..."));
601 processEvents();
602
603
604 bool sessionNeeded = true;
605 auto sessionMode = cfg.sessionOnStartup();
606
607 if (!args.session().isEmpty()) {
608 sessionNeeded = !kisPart->restoreSession(args.session());
609 } else if (sessionMode == KisConfig::SOS_ShowSessionManager) {
610 showmainWindow = false;
611 sessionNeeded = false;
612 kisPart->showSessionManager();
613 } else if (sessionMode == KisConfig::SOS_PreviousSession) {
614 KConfigGroup sessionCfg = KSharedConfig::openConfig()->group("session");
615 const QString &sessionName = sessionCfg.readEntry("previousSession");
616
617 sessionNeeded = !kisPart->restoreSession(sessionName);
618 }
619
620 if (sessionNeeded) {
621 kisPart->startBlankSession();
622 }
623
624 if (!args.windowLayout().isEmpty()) {
626 KisWindowLayoutResourceSP windowLayout = rserver->resource("", "", args.windowLayout());
627 if (windowLayout) {
628 windowLayout->applyLayout();
629 }
630 }
631
632 setSplashScreenLoadingText(i18n("Launching..."));
633
634 if (showmainWindow) {
635 d->mainWindow = kisPart->currentMainwindow();
636
637 if (!args.workspace().isEmpty()) {
639 KisWorkspaceResourceSP workspace = rserver->resource("", "", args.workspace());
640 if (workspace) {
641 d->mainWindow->restoreWorkspace(workspace);
642 }
643 }
644
645 if (args.canvasOnly()) {
646 d->mainWindow->viewManager()->switchCanvasOnly(true);
647 }
648
649 if (args.fullScreen()) {
650 d->mainWindow->showFullScreen();
651 }
652 } else {
653 d->mainWindow = kisPart->createMainWindow();
654 }
655 }
656 short int numberOfOpenDocuments = 0; // number of documents open
657
658 // Check for autosave files that can be restored, if we're not running a batch run (test)
659 if (!d->batchRun) {
661 }
662
663 setSplashScreenLoadingText(QString()); // done loading, so clear out label
664 processEvents();
665
666 //configure the unit manager
668 connect(this, &KisApplication::aboutToQuit, &KisSpinBoxUnitManagerFactory::clearUnitManagerBuilder); //ensure the builder is destroyed when the application leave.
669 //the new syntax slot syntax allow to connect to a non q_object static method.
670
671 // Long-press emulation.
674 slotSetLongPress(cfg.longPressEnabled());
675
676 // Xiaomi workaround: their stylus inexplicably inputs page up and down keys
677 // when pressing stylus buttons. This flag causes the Android platform
678 // integration to turn those into right and middle clicks instead.
679#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN
680 auto setPageUpDownMouseButtonEmulationWorkaround = [](bool enabled) {
681 QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN, enabled);
682 };
683 connect(cfgNotifier,
684 &KisConfigNotifier::sigUsePageUpDownMouseButtonEmulationWorkaroundChanged,
685 this,
686 setPageUpDownMouseButtonEmulationWorkaround);
687 setPageUpDownMouseButtonEmulationWorkaround(cfg.usePageUpDownMouseButtonEmulationWorkaround());
688#endif
689
690 // Xiaomi workaround: historic tablet motion events are garbage, they just
691 // connect the actual points that the tablet sampled with a straight line
692 // and no pressure emulation, leading to jagged curves that don't get
693 // smoothed out. This flag disables reading those historic events.
694#if KRITA_QT_HAS_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS
695 auto setIgnoreHistoricTabletEventsWorkaround = [](bool enabled) {
696 QCoreApplication::setKritaAttribute(KRITA_QATTRIBUTE_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS, enabled);
697 };
698 connect(cfgNotifier,
699 &KisConfigNotifier::sigUseIgnoreHistoricTabletEventsWorkaroundChanged,
700 this,
701 setIgnoreHistoricTabletEventsWorkaround);
702 setIgnoreHistoricTabletEventsWorkaround(cfg.usePageUpDownMouseButtonEmulationWorkaround());
703#endif
704
705 // Create a new image, if needed
706 if (doNewImage) {
708 if (doc) {
709 kisPart->addDocument(doc);
710 d->mainWindow->addViewAndNotifyLoadingCompleted(doc);
711 }
712 }
713
714 // Get the command line arguments which we have to parse
715 int argsCount = args.filenames().count();
716 if (argsCount > 0) {
717 // Loop through arguments
718 for (int argNumber = 0; argNumber < argsCount; argNumber++) {
719 QString fileName = args.filenames().at(argNumber);
720 // are we just trying to open a template?
721 if (doTemplate) {
722 // called in mix with batch options? ignore and silently skip
723 if (d->batchRun) {
724 continue;
725 }
726 if (createNewDocFromTemplate(fileName, d->mainWindow)) {
727 ++numberOfOpenDocuments;
728 }
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 if (d->mainWindow->openDocument(fileName, flags)) {
810 // Normal case, success
811 numberOfOpenDocuments++;
812 }
813 }
814 }
815 }
816 }
817 }
818
819 //add an image as file-layer
820 if (!args.fileLayer().isEmpty()){
821 if (d->mainWindow->viewManager()->image()){
822 KisFileLayer *fileLayer = new KisFileLayer(d->mainWindow->viewManager()->image(), "",
823 args.fileLayer(), KisFileLayer::None, "Bicubic",
824 d->mainWindow->viewManager()->image()->nextLayerName(i18n("File layer")), OPACITY_OPAQUE_U8);
825 QFileInfo fi(fileLayer->path());
826 if (fi.exists()){
827 KisNodeCommandsAdapter adapter(d->mainWindow->viewManager());
828 adapter.addNode(fileLayer, d->mainWindow->viewManager()->activeNode()->parent(),
829 d->mainWindow->viewManager()->activeNode());
830 }
831 else{
832 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita:Warning"),
833 i18n("Cannot add %1 as a file layer: the file does not exist.", fileLayer->path()));
834 }
835 }
836 else if (this->isRunning()){
837 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita:Warning"),
838 i18n("Cannot add the file layer: no document is open.\n\n"
839"You can create a new document using the --new-image option, or you can open an existing file.\n\n"
840"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)."));
841 }
842 else {
843 QMessageBox::warning(qApp->activeWindow(), i18nc("@title:window", "Krita: Warning"),
844 i18n("Cannot add the file layer: no document is open.\n"
845 "You can either create a new file using the --new-image option, or you can open an existing file."));
846 }
847 }
848
849 // fixes BUG:369308 - Krita crashing on splash screen when loading.
850 // trying to open a file before Krita has loaded can cause it to hang and crash
851 if (d->splashScreen) {
852 d->splashScreen->displayLinks(true);
853 d->splashScreen->displayRecentFiles(true);
854 }
855
856 Q_FOREACH(const QByteArray &message, d->earlyRemoteArguments) {
857 executeRemoteArguments(message, d->mainWindow);
858 }
859
861
862 // process File open event files
863 if (!d->earlyFileOpenEvents.isEmpty()) {
865 Q_FOREACH(QString fileName, d->earlyFileOpenEvents) {
866 d->mainWindow->openDocument(fileName, QFlags<KisMainWindow::OpenFlag>());
867 }
868 }
869
871
872 // not calling this before since the program will quit there.
873 return true;
874}
void setCurrentTheme(const QString &name)
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:371
@ SOS_ShowSessionManager
Definition kis_config.h:372
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:644
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:459
void startBlankSession()
Definition KisPart.cpp:636
KisDocument * createDocument() const
Definition KisPart.cpp:230
void showSessionManager()
Definition KisPart.cpp:626
KisMainWindow * createMainWindow(QUuid id=QUuid())
Definition KisPart.cpp:260
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:45
#define errKrita
Definition kis_debug.h:107
#define ppVar(var)
Definition kis_debug.h:155
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(), 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(), setSplashScreenLoadingText(), 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 1005 of file KisApplication.cpp.

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

Friends And Related Symbol Documentation

◆ ResetStarting

friend class ResetStarting
friend

Definition at line 123 of file KisApplication.h.

Member Data Documentation

◆ d

QScopedPointer<Private> KisApplication::d
private

Definition at line 121 of file KisApplication.h.


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