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

Base class for the Krita app. More...

#include <KisApplication.h>

+ Inheritance diagram for KisApplication:

Classes

class  Private
 
class  ResetStarting
 

Public Slots

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

Public Member Functions

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

Static Public Member Functions

static void verifyMetatypeRegistration ()
 

Private Slots

void slotSetLongPress (bool enabled)
 

Private Member Functions

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

Private Attributes

QScopedPointer< Privated
 

Friends

class ResetStarting
 

Additional Inherited Members

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

Detailed Description

Base class for the Krita app.

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

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

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

Definition at line 38 of file KisApplication.h.

Constructor & Destructor Documentation

◆ KisApplication()

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

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

Load platform plugin for modifiers fetching

Definition at line 225 of file KisApplication.cpp.

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

884{
885 if (!isRunning()) {
888 }
889}
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 374 of file KisApplication.cpp.

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

1342{
1343 bool ok = QMessageBox::question(qApp->activeWindow(),
1344 i18nc("@title:window", "Krita"),
1345 i18n("Do you want to clear the settings file?"),
1346 QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes;
1347 if (ok) {
1348 resetConfig();
1349 }
1350}

References resetConfig().

◆ checkAutosaveFiles()

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

Definition at line 1173 of file KisApplication.cpp.

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

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

◆ createNewDocFromTemplate()

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

Definition at line 1233 of file KisApplication.cpp.

1234{
1235 QString templatePath;
1236
1237 if (QFile::exists(fileName)) {
1238 templatePath = fileName;
1239 dbgUI << "using full path...";
1240 }
1241 else {
1242 QString desktopName(fileName);
1243 const QString templatesResourcePath = QStringLiteral("templates/");
1244
1245 QStringList paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + "*/" + desktopName);
1246 if (paths.isEmpty()) {
1247 paths = KoResourcePaths::findAllAssets("data", templatesResourcePath + desktopName);
1248 }
1249
1250 if (paths.isEmpty()) {
1251 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1252 i18n("No template found for: %1", desktopName));
1253 } else if (paths.count() > 1) {
1254 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1255 i18n("Too many templates found for: %1", desktopName));
1256 } else {
1257 templatePath = paths.at(0);
1258 }
1259 }
1260
1261 if (!templatePath.isEmpty()) {
1262 KDesktopFile templateInfo(templatePath);
1263
1264 KisMainWindow::OpenFlags batchFlags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1265 if (mainWindow->openDocument(templatePath, KisMainWindow::Import | batchFlags)) {
1266 dbgUI << "Template loaded...";
1267 return true;
1268 }
1269 else {
1270 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"),
1271 i18n("Template %1 failed to load.", fileName));
1272 }
1273 }
1274
1275 return false;
1276}
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 407 of file KisApplication.cpp.

408{
409
410 #ifdef Q_OS_MACOS
411 if (event->type() == QEvent::FileOpen) {
412 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
413 fileOpenRequested(openEvent->file());
414 return true;
415 }
416 #endif
417 return QApplication::event(event);
418}
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 1069 of file KisApplication.cpp.

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

1353{
1354 return d->extendedModifiersPluginInterface.data();
1355}

References d.

◆ fileOpenRequested

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

Definition at line 1149 of file KisApplication.cpp.

1150{
1151 if (!d->mainWindow) {
1152 d->earlyFileOpenEvents.append(url);
1153 return;
1154 }
1155
1156 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1157 d->mainWindow->openDocument(url, flags);
1158}

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

◆ hideSplashScreen()

void KisApplication::hideSplashScreen ( )

Definition at line 907 of file KisApplication.cpp.

908{
909#ifdef Q_OS_ANDROID
911#endif
912 if (d->splashScreen) {
913 // hide the splashscreen to see the dialog
914 d->splashScreen->hide();
915 }
916}
static void setLoaded(bool loaded)

References d, and KisAndroidDonations::setLoaded().

◆ initializeGlobals()

void KisApplication::initializeGlobals ( const KisApplicationArguments & args)

Definition at line 367 of file KisApplication.cpp.

368{
369 Q_UNUSED(args)
370 // There are no globals to initialize from the arguments now. There used
371 // to be the `dpi` argument, but it doesn't do anything anymore.
372}

◆ isStoreApplication()

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

Definition at line 989 of file KisApplication.cpp.

990{
991 if (qEnvironmentVariableIsSet("STEAMAPPID") || qEnvironmentVariableIsSet("SteamAppId")) {
992 return true;
993 }
994
995 if (applicationDirPath().toLower().contains("steam")) {
996 return true;
997 }
998
999#ifdef Q_OS_WIN
1000 // This is also true for user-installed MSIX, but that's
1001 // likely only true in institutional situations, where
1002 // we don't want to show the beginning banner either.
1004 return true;
1005 }
1006#endif
1007
1008#ifdef Q_OS_MACOS
1009 KisMacosEntitlements entitlements;
1010 if (entitlements.sandbox()) {
1011 return true;
1012 }
1013#endif
1014
1015 return false;
1016}

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

◆ loadPlugins()

void KisApplication::loadPlugins ( )

Definition at line 488 of file KisApplication.cpp.

489{
490 // qDebug() << "loadPlugins();";
491
493 r->add(new KisShapeSelectionFactory());
502}
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 919 of file KisApplication.cpp.

920{
921 try {
922 bool result = true;
923
929 AppRecursionInfo &info = s_recursionInfo->localData();
930
931 {
932 // QApplication::notify() can throw, so use RAII for counters
933 AppRecursionGuard guard(&info);
934
936
937 if (info.eventRecursionCount > 1) {
939 KIS_SAFE_ASSERT_RECOVER_NOOP(typedEvent->destination == receiver);
940
941 info.postponedSynchronizationEvents.emplace(KisSynchronizedConnectionEvent(*typedEvent));
942 } else {
943 result = QApplication::notify(receiver, event);
944 }
945 } else {
946 result = QApplication::notify(receiver, event);
947 }
948 }
949
950 if (!info.eventRecursionCount) {
952
953 }
954
955 return result;
956
957 } catch (std::exception &e) {
958 qWarning("Error %s sending event %i to object %s",
959 e.what(), event->type(), qPrintable(receiver->objectName()));
960 } catch (...) {
961 qWarning("Error <unknown> sending event %i to object %s",
962 event->type(), qPrintable(receiver->objectName()));
963 }
964 return false;
965}
#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 967 of file KisApplication.cpp.

968{
969 AppRecursionInfo &info = s_recursionInfo->localData();
970
971 while (!info.postponedSynchronizationEvents.empty()) {
972 // QApplication::notify() can throw, so use RAII for counters
973 AppRecursionGuard guard(&info);
974
977 KisSynchronizedConnectionEvent typedEvent = info.postponedSynchronizationEvents.front();
978 info.postponedSynchronizationEvents.pop();
979
980 if (!typedEvent.destination) {
981 qWarning() << "WARNING: the destination object of KisSynchronizedConnection has been destroyed during postponed delivery";
982 continue;
983 }
984
985 QApplication::notify(typedEvent.destination, &typedEvent);
986 }
987}

References KisSynchronizedConnectionEvent::destination.

◆ registerResources()

bool KisApplication::registerResources ( )

Definition at line 421 of file KisApplication.cpp.

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

1131{
1132 // check if we have any mainwindow
1133 KisMainWindow *mw = qobject_cast<KisMainWindow*>(qApp->activeWindow());
1134
1135 if (!mw && KisPart::instance()->mainWindows().size() > 0) {
1136 mw = KisPart::instance()->mainWindows().first();
1137 }
1138
1139 const QByteArray unpackedMessage =
1140 QByteArray::fromBase64(message.toLatin1());
1141
1142 if (!mw) {
1143 d->earlyRemoteArguments << unpackedMessage;
1144 return;
1145 }
1146 executeRemoteArguments(unpackedMessage, mw);
1147}
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 1278 of file KisApplication.cpp.

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

892{
893 d->splashScreen = qobject_cast<KisSplashScreen*>(splashScreen);
894}

References d.

◆ setSplashScreenLoadingText

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

Definition at line 896 of file KisApplication.cpp.

897{
898 if (d->splashScreen) {
899 d->splashScreen->setLoadingText(textToLoad);
900 d->splashScreen->repaint();
901 }
902#ifdef Q_OS_ANDROID
904#endif
905}
static void setLoadingText(const QString &text)

References d, and KisAndroidDonations::setLoadingText().

◆ slotSetLongPress

void KisApplication::slotSetLongPress ( bool enabled)
privateslot

Definition at line 1161 of file KisApplication.cpp.

1162{
1163 if (enabled && !d->longPressEventFilter) {
1164 d->longPressEventFilter = new KisLongPressEventFilter(this);
1165 installEventFilter(d->longPressEventFilter);
1166 } else if (!enabled && d->longPressEventFilter) {
1167 removeEventFilter(d->longPressEventFilter);
1168 d->longPressEventFilter->deleteLater();
1169 d->longPressEventFilter = nullptr;
1170 }
1171}

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

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

◆ verifyMetatypeRegistration()

void KisApplication::verifyMetatypeRegistration ( )
static

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

Definition at line 1018 of file KisApplication.cpp.

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

Friends And Related Symbol Documentation

◆ ResetStarting

friend class ResetStarting
friend

Definition at line 125 of file KisApplication.h.

Member Data Documentation

◆ d

QScopedPointer<Private> KisApplication::d
private

Definition at line 123 of file KisApplication.h.


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