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.

Load platform plugin for modifiers fetching

Definition at line 218 of file KisApplication.cpp.

219 : QtSingleApplication(key, argc, argv)
220 , d(new Private)
221{
222#ifdef Q_OS_ANDROID
223 // The hardware renderer backend on Android doesn't support proper stacking,
224 // causing windows with QtQuick widgets to always stack behind everything
225 // else, including our own dialog decorations.
226 qputenv("QT_QUICK_BACKEND", "software");
227#endif
228#ifdef Q_OS_MACOS
230#endif
231
232 QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath());
233
234#ifndef Q_OS_MACOS
235 setWindowIcon(KisIconUtils::loadIcon("krita-branding"));
236#endif
237
238 if (qgetenv("KRITA_NO_STYLE_OVERRIDE").isEmpty()) {
239
240#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
241 QStringList styles = QStringList() << "haiku" << "macintosh" << "breeze" << "fusion";
242#else
243 QStringList styles = QStringList() << "haiku" << "macos" << "breeze" << "fusion";
244#endif
245 if (!styles.contains(style()->objectName().toLower())) {
246 Q_FOREACH (const QString & style, styles) {
247 if (!setStyle(style)) {
248 qDebug() << "No" << style << "available.";
249 }
250 else {
251 qDebug() << "Set style" << style;
252 break;
253 }
254 }
255 }
256
257 // if style is set from config, try to load that
258 KisConfig cfg(true);
259 QString widgetStyleFromConfig = cfg.widgetStyle();
260 if(widgetStyleFromConfig != "") {
261 qApp->setStyle(widgetStyleFromConfig);
262#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
263 } else if (style()->objectName().toLower() == "macintosh") {
264 // if no configured style on macOS, default to Fusion
265 qApp->setStyle("fusion");
266 }
267#else
268 } else if (style()->objectName().toLower() == "macos") {
269 // if no configured style on macOS, default to Fusion
270 qApp->setStyle("fusion");
271 }
272#endif
273
274 }
275 else {
276 qDebug() << "Style override disabled, using" << style()->objectName();
277 }
278
282 {
283 d->extendedModifiersPluginInterface.reset(KisPlatformPluginInterfaceFactory::instance()->createExtendedModifiersMapper());
284 }
285
286 // store the style name
287 qApp->setProperty(currentUnderlyingStyleNameProperty, style()->objectName());
289
290
291#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
292
297 struct PlatformWindowCreationFilter : QObject
298 {
299 using QObject::QObject;
300
301 bool eventFilter(QObject *watched, QEvent *event) override {
302 if (event->type() == QEvent::PlatformSurface) {
303 QWidget *widget = qobject_cast<QWidget*>(watched);
304 if (!widget) return false;
305
310 if (watched->property("krita_skip_srgb_surface_manager_assignment").toBool()) {
311 return false;
312 }
313
314 QPlatformSurfaceEvent *surfaceEvent = static_cast<QPlatformSurfaceEvent*>(event);
315 if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
316 QWindow *nativeWindow = widget->windowHandle();
317 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(widget->windowHandle(), false);
318
319 if (!nativeWindow->findChild<KisSRGBSurfaceColorSpaceManager*>()) {
321 }
322 }
323 }
324
325 return false;
326 }
327 };
328
329 this->installEventFilter(new PlatformWindowCreationFilter(this));
330#endif /* KRITA_USE_SURFACE_COLOR_MANAGEMENT_API */
331}
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_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
constexpr const char * currentUnderlyingStyleNameProperty
Definition kis_global.h:116
QIcon loadIcon(const QString &name)
void setMouseCoalescingEnabled(bool enabled)
Definition osx.mm:17

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

◆ ~KisApplication()

KisApplication::~KisApplication ( )
override

Destructor.

Definition at line 863 of file KisApplication.cpp.

864{
865 if (!isRunning()) {
868 }
869}
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 367 of file KisApplication.cpp.

368{
369 // All Krita's resource types
370 KoResourcePaths::addAssetType("markers", "data", "/styles/");
371 KoResourcePaths::addAssetType("kis_pics", "data", "/pics/");
372 KoResourcePaths::addAssetType("kis_images", "data", "/images/");
373 KoResourcePaths::addAssetType("metadata_schema", "data", "/metadata/schemas/");
374 KoResourcePaths::addAssetType("gmic_definitions", "data", "/gmic/");
375 KoResourcePaths::addAssetType("kis_shortcuts", "data", "/shortcuts/");
376 KoResourcePaths::addAssetType("kis_actions", "data", "/actions");
377 KoResourcePaths::addAssetType("kis_actions", "data", "/pykrita");
378 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc");
379 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/");
380 KoResourcePaths::addAssetType("tags", "data", "/tags/");
381 KoResourcePaths::addAssetType("templates", "data", "/templates");
382 KoResourcePaths::addAssetType("pythonscripts", "data", "/pykrita");
383 KoResourcePaths::addAssetType("preset_icons", "data", "/preset_icons");
384#if defined HAVE_SEEXPR
385 KoResourcePaths::addAssetType(ResourceType::SeExprScripts, "data", "/seexpr_scripts/", true);
386#endif
387
388 // Make directories for all resources we can save, and tags
389 KoResourcePaths::saveLocation("data", "/asl/", true);
390 KoResourcePaths::saveLocation("data", "/css_styles/", true);
391 KoResourcePaths::saveLocation("data", "/input/", true);
392 KoResourcePaths::saveLocation("data", "/pykrita/", true);
393 KoResourcePaths::saveLocation("data", "/color-schemes/", true);
394 KoResourcePaths::saveLocation("data", "/preset_icons/", true);
395 KoResourcePaths::saveLocation("data", "/preset_icons/tool_icons/", true);
396 KoResourcePaths::saveLocation("data", "/preset_icons/emblem_icons/", true);
397}
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 1315 of file KisApplication.cpp.

1316{
1317 bool ok = QMessageBox::question(qApp->activeWindow(),
1318 i18nc("@title:window", "Krita"),
1319 i18n("Do you want to clear the settings file?"),
1320 QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes;
1321 if (ok) {
1322 resetConfig();
1323 }
1324}

References resetConfig().

◆ checkAutosaveFiles()

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

Definition at line 1147 of file KisApplication.cpp.

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

1208{
1209 QString templatePath;
1210
1211 if (QFile::exists(fileName)) {
1212 templatePath = fileName;
1213 dbgUI << "using full path...";
1214 }
1215 else {
1216 QString desktopName(fileName);
1217 const QString templatesResourcePath = QStringLiteral("templates/");
1218
1219 QStringList paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + "*/" + desktopName);
1220 if (paths.isEmpty()) {
1221 paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + desktopName);
1222 }
1223
1224 if (paths.isEmpty()) {
1225 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1226 i18n("No template found for: %1", desktopName));
1227 } else if (paths.count() > 1) {
1228 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1229 i18n("Too many templates found for: %1", desktopName));
1230 } else {
1231 templatePath = paths.at(0);
1232 }
1233 }
1234
1235 if (!templatePath.isEmpty()) {
1236 KDesktopFile templateInfo(templatePath);
1237
1238 KisMainWindow::OpenFlags batchFlags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1239 if (mainWindow->openDocument(templatePath, KisMainWindow::Import | batchFlags)) {
1240 dbgUI << "Template loaded...";
1241 return true;
1242 }
1243 else {
1244 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1245 i18n("Template %1 failed to load.", fileName));
1246 }
1247 }
1248
1249 return false;
1250}
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 400 of file KisApplication.cpp.

401{
402
403 #ifdef Q_OS_MACOS
404 if (event->type() == QEvent::FileOpen) {
405 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
406 fileOpenRequested(openEvent->file());
407 return true;
408 }
409 #endif
410 return QApplication::event(event);
411}
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 1043 of file KisApplication.cpp.

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

1327{
1328 return d->extendedModifiersPluginInterface.data();
1329}

References d.

◆ fileOpenRequested

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

Definition at line 1123 of file KisApplication.cpp.

1124{
1125 if (!d->mainWindow) {
1126 d->earlyFileOpenEvents.append(url);
1127 return;
1128 }
1129
1130 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1131 d->mainWindow->openDocument(url, flags);
1132}

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

◆ hideSplashScreen()

void KisApplication::hideSplashScreen ( )

Definition at line 884 of file KisApplication.cpp.

885{
886 if (d->splashScreen) {
887 // hide the splashscreen to see the dialog
888 d->splashScreen->hide();
889 }
890}

References d.

◆ initializeGlobals()

void KisApplication::initializeGlobals ( const KisApplicationArguments & args)

Definition at line 360 of file KisApplication.cpp.

361{
362 Q_UNUSED(args)
363 // There are no globals to initialize from the arguments now. There used
364 // to be the `dpi` argument, but it doesn't do anything anymore.
365}

◆ isStoreApplication()

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

Definition at line 963 of file KisApplication.cpp.

964{
965 if (qEnvironmentVariableIsSet("STEAMAPPID") || qEnvironmentVariableIsSet("SteamAppId")) {
966 return true;
967 }
968
969 if (applicationDirPath().toLower().contains("steam")) {
970 return true;
971 }
972
973#ifdef Q_OS_WIN
974 // This is also true for user-installed MSIX, but that's
975 // likely only true in institutional situations, where
976 // we don't want to show the beginning banner either.
978 return true;
979 }
980#endif
981
982#ifdef Q_OS_MACOS
983 KisMacosEntitlements entitlements;
984 if (entitlements.sandbox()) {
985 return true;
986 }
987#endif
988
989 return false;
990}

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

◆ loadPlugins()

void KisApplication::loadPlugins ( )

Definition at line 481 of file KisApplication.cpp.

482{
483 // qDebug() << "loadPlugins();";
484
486 r->add(new KisShapeSelectionFactory());
495}
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 893 of file KisApplication.cpp.

894{
895 try {
896 bool result = true;
897
903 AppRecursionInfo &info = s_recursionInfo->localData();
904
905 {
906 // QApplication::notify() can throw, so use RAII for counters
907 AppRecursionGuard guard(&info);
908
910
911 if (info.eventRecursionCount > 1) {
913 KIS_SAFE_ASSERT_RECOVER_NOOP(typedEvent->destination == receiver);
914
915 info.postponedSynchronizationEvents.emplace(KisSynchronizedConnectionEvent(*typedEvent));
916 } else {
917 result = QApplication::notify(receiver, event);
918 }
919 } else {
920 result = QApplication::notify(receiver, event);
921 }
922 }
923
924 if (!info.eventRecursionCount) {
926
927 }
928
929 return result;
930
931 } catch (std::exception &e) {
932 qWarning("Error %s sending event %i to object %s",
933 e.what(), event->type(), qPrintable(receiver->objectName()));
934 } catch (...) {
935 qWarning("Error <unknown> sending event %i to object %s",
936 event->type(), qPrintable(receiver->objectName()));
937 }
938 return false;
939}
#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 941 of file KisApplication.cpp.

942{
943 AppRecursionInfo &info = s_recursionInfo->localData();
944
945 while (!info.postponedSynchronizationEvents.empty()) {
946 // QApplication::notify() can throw, so use RAII for counters
947 AppRecursionGuard guard(&info);
948
951 KisSynchronizedConnectionEvent typedEvent = info.postponedSynchronizationEvents.front();
952 info.postponedSynchronizationEvents.pop();
953
954 if (!typedEvent.destination) {
955 qWarning() << "WARNING: the destination object of KisSynchronizedConnection has been destroyed during postponed delivery";
956 continue;
957 }
958
959 QApplication::notify(typedEvent.destination, &typedEvent);
960 }
961}

References KisSynchronizedConnectionEvent::destination.

◆ registerResources()

bool KisApplication::registerResources ( )

Definition at line 414 of file KisApplication.cpp.

415{
417
419 QStringList() << "application/x-krita-paintoppreset"));
420
421 reg->add(new KisResourceLoader<KisGbrBrush>(ResourceSubType::GbrBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush"));
422 reg->add(new KisResourceLoader<KisImagePipeBrush>(ResourceSubType::GihBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush-animated"));
423 reg->add(new KisResourceLoader<KisSvgBrush>(ResourceSubType::SvgBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/svg+xml"));
425
426 reg->add(new KisResourceLoader<KoSegmentGradient>(ResourceSubType::SegmentedGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "application/x-gimp-gradient"));
428
439
440
441 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"}));
442 reg->add(new KisResourceLoader<KisWorkspaceResource>(ResourceType::Workspaces, ResourceType::Workspaces, i18n("Workspaces"), QStringList() << "application/x-krita-workspace"));
443 reg->add(new KisResourceLoader<KoSvgSymbolCollectionResource>(ResourceType::Symbols, ResourceType::Symbols, i18n("SVG symbol libraries"), QStringList() << "image/svg+xml"));
444 reg->add(new KisResourceLoader<KisWindowLayoutResource>(ResourceType::WindowLayouts, ResourceType::WindowLayouts, i18n("Window layouts"), QStringList() << "application/x-krita-windowlayout"));
445 reg->add(new KisResourceLoader<KisSessionResource>(ResourceType::Sessions, ResourceType::Sessions, i18n("Sessions"), QStringList() << "application/x-krita-session"));
446 reg->add(new KisResourceLoader<KoGamutMask>(ResourceType::GamutMasks, ResourceType::GamutMasks, i18n("Gamut masks"), QStringList() << "application/x-krita-gamutmasks"));
447#if defined HAVE_SEEXPR
448 reg->add(new KisResourceLoader<KisSeExprScript>(ResourceType::SeExprScripts, ResourceType::SeExprScripts, i18n("SeExpr Scripts"), QStringList() << "application/x-krita-seexpr-script"));
449#endif
450 // XXX: this covers only individual styles, not the library itself!
453 i18nc("Resource type name", "Layer styles"),
454 QStringList() << "application/x-photoshop-style"));
455
456 reg->add(new KisResourceLoader<KoFontFamily>(ResourceType::FontFamilies, ResourceType::FontFamilies, i18n("Font Families"), QStringList() << "application/x-font-ttf" << "application/x-font-otf"));
457 reg->add(new KisResourceLoader<KoCssStylePreset>(ResourceType::CssStyles, ResourceType::CssStyles, i18n("Style Presets"), QStringList() << "image/svg+xml"));
458
460
461#ifndef Q_OS_ANDROID
462 QString databaseLocation = KoResourcePaths::getAppDataLocation();
463#else
464 // Sqlite doesn't support content URIs (obviously). So, we make database location unconfigurable on android.
465 QString databaseLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
466#endif
467
468 if (!KisResourceCacheDb::initialize(databaseLocation)) {
469 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), i18n("%1\n\nKrita will quit now.", KisResourceCacheDb::lastError()));
470 }
471
473 connect(KisResourceLocator::instance(), SIGNAL(progressMessage(const QString&)), this, SLOT(setSplashScreenLoadingText(const QString&)));
474 if (r != KisResourceLocator::LocatorError::Ok && qApp->inherits("KisApplication")) {
475 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), KisResourceLocator::instance()->errorMessages().join('\n') + i18n("\n\nKrita will quit now."));
476 return false;
477 }
478 return true;
479}
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 1104 of file KisApplication.cpp.

1105{
1106 // check if we have any mainwindow
1107 KisMainWindow *mw = qobject_cast<KisMainWindow*>(qApp->activeWindow());
1108
1109 if (!mw && KisPart::instance()->mainWindows().size() > 0) {
1110 mw = KisPart::instance()->mainWindows().first();
1111 }
1112
1113 const QByteArray unpackedMessage =
1114 QByteArray::fromBase64(message.toLatin1());
1115
1116 if (!mw) {
1117 d->earlyRemoteArguments << unpackedMessage;
1118 return;
1119 }
1120 executeRemoteArguments(unpackedMessage, mw);
1121}
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 1252 of file KisApplication.cpp.

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

872{
873 d->splashScreen = qobject_cast<KisSplashScreen*>(splashScreen);
874}

References d.

◆ setSplashScreenLoadingText

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

Definition at line 876 of file KisApplication.cpp.

877{
878 if (d->splashScreen) {
879 d->splashScreen->setLoadingText(textToLoad);
880 d->splashScreen->repaint();
881 }
882}

References d.

◆ slotSetLongPress

void KisApplication::slotSetLongPress ( bool enabled)
privateslot

Definition at line 1135 of file KisApplication.cpp.

1136{
1137 if (enabled && !d->longPressEventFilter) {
1138 d->longPressEventFilter = new KisLongPressEventFilter(this);
1139 installEventFilter(d->longPressEventFilter);
1140 } else if (!enabled && d->longPressEventFilter) {
1141 removeEventFilter(d->longPressEventFilter);
1142 d->longPressEventFilter->deleteLater();
1143 d->longPressEventFilter = nullptr;
1144 }
1145}

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

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

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

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: