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
 
KisExtendedModifiersMapperPluginInterface * extendedModifiersPluginInterface ()
 
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< Private > d
 

Friends

class ResetStarting
 

Additional Inherited Members

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

Detailed Description

Base class for the Krita app.

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

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

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

Definition at line 38 of file KisApplication.h.

Constructor & Destructor Documentation

◆ KisApplication()

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

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

Load platform plugin for modifiers fetching

Definition at line 226 of file KisApplication.cpp.

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

References currentUnderlyingStyleNameProperty, d, defaultStyle, KisPlatformPluginInterfaceFactory::instance(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, KisIconUtils::loadIcon(), processPostponedSynchronizationEvents(), KisSynchronizedConnectionBase::registerSynchronizedEventBarrier(), setMouseCoalescingEnabled(), KisSRGBSurfaceColorSpaceManager::tryCreateForCurrentPlatform(), and KisConfig::widgetStyle().

◆ ~KisApplication()

KisApplication::~KisApplication ( )
override

Destructor.

Definition at line 862 of file KisApplication.cpp.

863{
864 if (!isRunning()) {
867 }
868}
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 348 of file KisApplication.cpp.

349{
350 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::addResourceTypes"));
351
352 // All Krita's resource types
353 KoResourcePaths::addAssetType("markers", "data", "/styles/");
354 KoResourcePaths::addAssetType("kis_pics", "data", "/pics/");
355 KoResourcePaths::addAssetType("kis_images", "data", "/images/");
356 KoResourcePaths::addAssetType("metadata_schema", "data", "/metadata/schemas/");
357 KoResourcePaths::addAssetType("gmic_definitions", "data", "/gmic/");
358 KoResourcePaths::addAssetType("kis_shortcuts", "data", "/shortcuts/");
359 KoResourcePaths::addAssetType("kis_actions", "data", "/actions");
360 KoResourcePaths::addAssetType("kis_actions", "data", "/pykrita");
361 KoResourcePaths::addAssetType("icc_profiles", "data", "/color/icc");
362 KoResourcePaths::addAssetType("icc_profiles", "data", "/profiles/");
363 KoResourcePaths::addAssetType("tags", "data", "/tags/");
364 KoResourcePaths::addAssetType("templates", "data", "/templates");
365 KoResourcePaths::addAssetType("pythonscripts", "data", "/pykrita");
366 KoResourcePaths::addAssetType("preset_icons", "data", "/preset_icons");
367#if defined HAVE_SEEXPR
368 KoResourcePaths::addAssetType(ResourceType::SeExprScripts, "data", "/seexpr_scripts/", true);
369#endif
370
371 // Make directories for all resources we can save, and tags
372 KoResourcePaths::saveLocation("data", "/asl/", true);
373 KoResourcePaths::saveLocation("data", "/css_styles/", true);
374 KoResourcePaths::saveLocation("data", "/input/", true);
375 KoResourcePaths::saveLocation("data", "/pykrita/", true);
376 KoResourcePaths::saveLocation("data", "/color-schemes/", true);
377 KoResourcePaths::saveLocation("data", "/preset_icons/", true);
378 KoResourcePaths::saveLocation("data", "/preset_icons/tool_icons/", true);
379 KoResourcePaths::saveLocation("data", "/preset_icons/emblem_icons/", true);
380}
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 1320 of file KisApplication.cpp.

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

References resetConfig().

◆ checkAutosaveFiles()

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

Definition at line 1152 of file KisApplication.cpp.

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

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

◆ createNewDocFromTemplate()

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

Definition at line 1212 of file KisApplication.cpp.

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

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

◆ event()

bool KisApplication::event ( QEvent * event)
override

Definition at line 383 of file KisApplication.cpp.

384{
385
386 #ifdef Q_OS_MACOS
387 if (event->type() == QEvent::FileOpen) {
388 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
389 fileOpenRequested(openEvent->file());
390 return true;
391 }
392 #endif
393 return QApplication::event(event);
394}
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 1048 of file KisApplication.cpp.

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

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

◆ extendedModifiersPluginInterface()

KisExtendedModifiersMapperPluginInterface * KisApplication::extendedModifiersPluginInterface ( )

Definition at line 1331 of file KisApplication.cpp.

1332{
1333 return d->extendedModifiersPluginInterface.data();
1334}

References d.

◆ fileOpenRequested

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

Definition at line 1128 of file KisApplication.cpp.

1129{
1130 if (!d->mainWindow) {
1131 d->earlyFileOpenEvents.append(url);
1132 return;
1133 }
1134
1135 KisMainWindow::OpenFlags flags = d->batchRun ? KisMainWindow::BatchMode : KisMainWindow::None;
1136 d->mainWindow->openDocument(url, flags);
1137}

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

◆ hideSplashScreen()

void KisApplication::hideSplashScreen ( )

Definition at line 886 of file KisApplication.cpp.

887{
888#ifdef Q_OS_ANDROID
890#endif
891 if (d->splashScreen) {
892 // hide the splashscreen to see the dialog
893 d->splashScreen->hide();
894 }
895}
static void setLoaded(bool loaded)

References d, and KisAndroidDonations::setLoaded().

◆ initializeGlobals()

void KisApplication::initializeGlobals ( const KisApplicationArguments & args)

Definition at line 341 of file KisApplication.cpp.

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

◆ isStoreApplication()

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

Definition at line 968 of file KisApplication.cpp.

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

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

◆ loadPlugins()

void KisApplication::loadPlugins ( )

Definition at line 466 of file KisApplication.cpp.

467{
468 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::loadPlugins"));
469
471 r->add(new KisShapeSelectionFactory());
480}
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 898 of file KisApplication.cpp.

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

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

References KisSynchronizedConnectionEvent::destination.

◆ registerResources()

bool KisApplication::registerResources ( )

Definition at line 397 of file KisApplication.cpp.

398{
399 KisScopedPerformanceLogger perfLog(QStringLiteral("KisApplication::registerResources"));
400
402
404 QStringList() << "application/x-krita-paintoppreset"));
405
406 reg->add(new KisResourceLoader<KisGbrBrush>(ResourceSubType::GbrBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush"));
407 reg->add(new KisResourceLoader<KisImagePipeBrush>(ResourceSubType::GihBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/x-gimp-brush-animated"));
408 reg->add(new KisResourceLoader<KisSvgBrush>(ResourceSubType::SvgBrushes, ResourceType::Brushes, i18n("Brush tips"), QStringList() << "image/svg+xml"));
410
411 reg->add(new KisResourceLoader<KoSegmentGradient>(ResourceSubType::SegmentedGradients, ResourceType::Gradients, i18n("Gradients"), QStringList() << "application/x-gimp-gradient"));
413
424
425
426 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"}));
427 reg->add(new KisResourceLoader<KisWorkspaceResource>(ResourceType::Workspaces, ResourceType::Workspaces, i18n("Workspaces"), QStringList() << "application/x-krita-workspace"));
428 reg->add(new KisResourceLoader<KoSvgSymbolCollectionResource>(ResourceType::Symbols, ResourceType::Symbols, i18n("SVG symbol libraries"), QStringList() << "image/svg+xml"));
429 reg->add(new KisResourceLoader<KisWindowLayoutResource>(ResourceType::WindowLayouts, ResourceType::WindowLayouts, i18n("Window layouts"), QStringList() << "application/x-krita-windowlayout"));
430 reg->add(new KisResourceLoader<KisSessionResource>(ResourceType::Sessions, ResourceType::Sessions, i18n("Sessions"), QStringList() << "application/x-krita-session"));
431 reg->add(new KisResourceLoader<KoGamutMask>(ResourceType::GamutMasks, ResourceType::GamutMasks, i18n("Gamut masks"), QStringList() << "application/x-krita-gamutmasks"));
432#if defined HAVE_SEEXPR
433 reg->add(new KisResourceLoader<KisSeExprScript>(ResourceType::SeExprScripts, ResourceType::SeExprScripts, i18n("SeExpr Scripts"), QStringList() << "application/x-krita-seexpr-script"));
434#endif
435 // XXX: this covers only individual styles, not the library itself!
438 i18nc("Resource type name", "Layer styles"),
439 QStringList() << "application/x-photoshop-style"));
440
441 reg->add(new KisResourceLoader<KoFontFamily>(ResourceType::FontFamilies, ResourceType::FontFamilies, i18n("Font Families"), QStringList() << "application/x-font-ttf" << "application/x-font-otf"));
442 reg->add(new KisResourceLoader<KoCssStylePreset>(ResourceType::CssStyles, ResourceType::CssStyles, i18n("Style Presets"), QStringList() << "image/svg+xml"));
443
445
446#ifndef Q_OS_ANDROID
447 QString databaseLocation = KoResourcePaths::getAppDataLocation();
448#else
449 // Sqlite doesn't support content URIs (obviously). So, we make database location unconfigurable on android.
450 QString databaseLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
451#endif
452
453 if (!KisResourceCacheDb::initialize(databaseLocation)) {
454 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), i18n("%1\n\nKrita will quit now.", KisResourceCacheDb::lastError()));
455 }
456
458 connect(KisResourceLocator::instance(), SIGNAL(progressMessage(const QString&)), this, SLOT(setSplashScreenLoadingText(const QString&)));
459 if (r != KisResourceLocator::LocatorError::Ok && qApp->inherits("KisApplication")) {
460 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita: Fatal error"), KisResourceLocator::instance()->errorMessages().join('\n') + i18n("\n\nKrita will quit now."));
461 return false;
462 }
463 return true;
464}
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 1109 of file KisApplication.cpp.

1110{
1111 // check if we have any mainwindow
1112 KisMainWindow *mw = qobject_cast<KisMainWindow*>(qApp->activeWindow());
1113
1114 if (!mw && KisPart::instance()->mainWindows().size() > 0) {
1115 mw = KisPart::instance()->mainWindows().first();
1116 }
1117
1118 const QByteArray unpackedMessage =
1119 QByteArray::fromBase64(message.toLatin1());
1120
1121 if (!mw) {
1122 d->earlyRemoteArguments << unpackedMessage;
1123 return;
1124 }
1125 executeRemoteArguments(unpackedMessage, mw);
1126}
void executeRemoteArguments(QByteArray message, KisMainWindow *mainWindow)
Main window for Krita.
QList< QPointer< KisMainWindow > > mainWindows
Definition KisPart.cpp:106
int size(const Forest< T > &forest)
Definition KisForest.h:1232

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

◆ resetConfig()

void KisApplication::resetConfig ( )
private

Definition at line 1257 of file KisApplication.cpp.

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

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

References d.

◆ setSplashScreenLoadingText

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

Definition at line 875 of file KisApplication.cpp.

876{
877 if (d->splashScreen) {
878 d->splashScreen->setLoadingText(textToLoad);
879 d->splashScreen->repaint();
880 }
881#ifdef Q_OS_ANDROID
883#endif
884}
static void setLoadingText(const QString &text)

References d, and KisAndroidDonations::setLoadingText().

◆ slotSetLongPress

void KisApplication::slotSetLongPress ( bool enabled)
privateslot

Definition at line 1140 of file KisApplication.cpp.

1141{
1142 if (enabled && !d->longPressEventFilter) {
1143 d->longPressEventFilter = new KisLongPressEventFilter(this);
1144 installEventFilter(d->longPressEventFilter);
1145 } else if (!enabled && d->longPressEventFilter) {
1146 removeEventFilter(d->longPressEventFilter);
1147 d->longPressEventFilter->deleteLater();
1148 d->longPressEventFilter = nullptr;
1149 }
1150}

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

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

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

◆ verifyMetatypeRegistration()

void KisApplication::verifyMetatypeRegistration ( )
static

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

Definition at line 997 of file KisApplication.cpp.

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

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: