Krita Source Code Documentation
Loading...
Searching...
No Matches
KisPart.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 1998-1999 Torben Weis <weis@kde.org>
3 * SPDX-FileCopyrightText: 2000-2005 David Faure <faure@kde.org>
4 * SPDX-FileCopyrightText: 2007-2008 Thorsten Zachmann <zachmann@kde.org>
5 * SPDX-FileCopyrightText: 2010-2012 Boudewijn Rempt <boud@valdyas.org>
6 * SPDX-FileCopyrightText: 2011 Inge Wallin <ingwa@kogmbh.com>
7 * SPDX-FileCopyrightText: 2015 Michael Abrahams <miabraha@gmail.com>
8 *
9 * SPDX-License-Identifier: LGPL-2.0-or-later
10 */
11
12#include "KisPart.h"
13
14#include <config-mlt.h>
15
16#include "KoProgressProxy.h"
17#include <KoCanvasController.h>
19#include <KoColorSpaceEngine.h>
20#include <KoCanvasBase.h>
21#include <KoToolManager.h>
24#include <kis_icon.h>
25
26#include "KisApplication.h"
27#include "KisMainWindow.h"
28#include "KisDocument.h"
29#include "KisView.h"
30#include "KisViewManager.h"
32#include "KoDocumentInfo.h"
33#include "KisUsageLogger.h"
34
35#include <kis_debug.h>
36#include <KoResourcePaths.h>
37#include <KoDialog.h>
38#include <QMessageBox>
39#include <QMenu>
40#include <QScopedPointer>
41#include <QMap>
42#include <QRegularExpression>
43
44#include <QMenuBar>
45#include <klocalizedstring.h>
46#include <kactioncollection.h>
47#include <kconfig.h>
48#include <kconfiggroup.h>
49#include <QKeySequence>
50
51#include <QApplication>
52#include <QDomDocument>
53#include <QDomElement>
54#include <QGlobalStatic>
55#include <KisMimeDatabase.h>
57
58#include <kis_group_layer.h>
59#include "kis_config.h"
64#include "kis_time_span.h"
65#include "kis_idle_watcher.h"
66#include "kis_image.h"
68#include "kis_color_manager.h"
69
71#include "kis_action.h"
72#include "kis_action_registry.h"
73#include "KisSessionResource.h"
74#include "KisBusyWaitBroker.h"
79#include "KisPlaybackEngine.h"
80#include "KisPlaybackEngineQT.h"
81
82#ifdef HAVE_MLT
84#endif
85
86Q_GLOBAL_STATIC(KisPart, s_instance)
87
88
89class Q_DECL_HIDDEN KisPart::Private
90{
91public:
93 : part(_part)
94 , idleWatcher(2500)
95 , animationCachePopulator(_part)
96 , playbackEngine(nullptr)
97 {
98 }
99
101 {
102 }
103
105
111 QScopedPointer<KisPlaybackEngine> playbackEngine;
112
114 bool closingSession{false};
115 QScopedPointer<KisSessionManagerDialog> sessionManager;
116
117 QMap<QUrl, QUrl> pendingAddRecentUrlMap;
118
120 Q_FOREACH(auto view, views) {
121 if (view && view->isVisible() && view->document() == document) {
122 return view->queryClose();
123 }
124 }
125
126 return true;
127 }
128};
129
130
132{
133 return s_instance;
134}
135
136namespace {
137void busyWaitWithFeedback(KisImageSP image)
138{
139 const int busyWaitDelay = 1000;
140 if (KisPart::instance()->currentMainwindow()) {
141 KisDelayedSaveDialog dialog(image, KisDelayedSaveDialog::ForcedDialog, busyWaitDelay, KisPart::instance()->currentMainwindow());
142 dialog.blockIfImageIsBusy();
143 }
144}
145}
146
148 : d(new Private(this))
149{
150 // Preload all the resources in the background
153 Q_UNUSED(KisColorManager::instance());
154
155 connect(this, SIGNAL(documentOpened(QString)),
156 this, SLOT(updateIdleWatcherConnections()));
157
158 connect(this, SIGNAL(documentClosed(QString)),
159 this, SLOT(updateIdleWatcherConnections()));
160
161 connect(KisActionRegistry::instance(), SIGNAL(shortcutsUpdated()),
162 this, SLOT(updateShortcuts()));
163 connect(&d->idleWatcher, SIGNAL(startedIdleMode()),
164 &d->animationCachePopulator, SLOT(slotRequestRegeneration()));
165 connect(&d->idleWatcher, SIGNAL(startedIdleMode()),
166 KisMemoryStatisticsServer::instance(), SLOT(tryForceUpdateMemoryStatisticsWhileIdle()));
167
168 // We start by loading the simple QTimer-based anim playback engine first.
169 // To save RAM, the MLT-based engine will be loaded later, once the KisImage in question becomes animated.
171
172 d->animationCachePopulator.slotRequestRegeneration();
173 KisBusyWaitBroker::instance()->setFeedbackCallback(&busyWaitWithFeedback);
174}
175
177{
178 while (!d->documents.isEmpty()) {
179 delete d->documents.takeFirst();
180 }
181
182 while (!d->views.isEmpty()) {
183 delete d->views.takeFirst();
184 }
185
186 while (!d->mainWindows.isEmpty()) {
187 delete d->mainWindows.takeFirst();
188 }
189
190 delete d;
191}
192
194{
195 QVector<KisImageSP> images;
196
197 Q_FOREACH (QPointer<KisDocument> document, documents()) {
198 if (document->image()) {
199 images << document->image();
200 }
201 }
202
203 d->idleWatcher.setTrackedImages(images);
204
208 d->idleWatcher.forceImageModified();
209}
210
211void KisPart::addDocument(KisDocument *document, bool notify)
212{
213 //dbgUI << "Adding document to part list" << document;
214 Q_ASSERT(document);
215 if (!d->documents.contains(document)) {
216 d->documents.append(document);
217 if (notify){
218 Q_EMIT documentOpened('/'+ objectName());
219 Q_EMIT sigDocumentAdded(document);
220 }
221 connect(document, SIGNAL(sigSavingFinished(QString)), SLOT(slotDocumentSaved(QString)));
222 }
223}
224
226{
227 return d->documents;
228}
229
231{
232 KisDocument *doc = new KisDocument();
233 return doc;
234}
235
237{
238 KisDocument *doc = new KisDocument(false);
239 return doc;
240}
241
242
244{
245 return d->documents.size();
246}
247
248void KisPart::removeDocument(KisDocument *document, bool deleteDocument)
249{
250 if (document) {
251 d->documents.removeAll(document);
252 Q_EMIT documentClosed('/' + objectName());
253 Q_EMIT sigDocumentRemoved(document->path());
254 if (deleteDocument) {
255 document->deleteLater();
256 }
257 }
258}
259
261{
262 KisMainWindow *mw = new KisMainWindow(id);
263 dbgUI <<"mainWindow" << (void*)mw << "added to view" << this;
264 d->mainWindows.append(mw);
265
266 // Add all actions with a menu property to the main window
267 Q_FOREACH(QAction *action, mw->actionCollection()->actions()) {
268 QString menuLocation = action->property("menulocation").toString();
269 if (!menuLocation.isEmpty()) {
270 QAction *found = 0;
271 QList<QAction *> candidates = mw->menuBar()->actions();
272 Q_FOREACH(const QString &name, menuLocation.split("/")) {
273 Q_FOREACH(QAction *candidate, candidates) {
274 if (candidate->objectName().toLower() == name.toLower()) {
275 found = candidate;
276 candidates = candidate->menu()->actions();
277 break;
278 }
279 }
280 if (candidates.isEmpty()) {
281 break;
282 }
283 }
284
285 if (found && found->menu()) {
286 found->menu()->addAction(action);
287 }
288 }
289 }
290
291
292 return mw;
293}
294
299
300
302 KisViewManager *viewManager,
303 QWidget *parent)
304{
305 // If creating the canvas fails, record this and disable OpenGL next time
306 KisConfig cfg(false);
307 KConfigGroup grp( KSharedConfig::openConfig(), "crashprevention");
308 if (grp.readEntry("CreatingCanvas", false)) {
309 cfg.disableOpenGL();
310 }
311 if (cfg.canvasState() == "OPENGL_FAILED") {
312 cfg.disableOpenGL();
313 }
314 grp.writeEntry("CreatingCanvas", true);
315 grp.sync();
316
317 KisView *view = nullptr;
318 {
319 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
320 view = new KisView(document, viewManager, parent);
321 }
322
323 // Record successful canvas creation
324 grp.writeEntry("CreatingCanvas", false);
325 grp.sync();
326
327 addView(view);
328
329 return view;
330}
331
333{
334 if (!view)
335 return;
336
337 if (!d->views.contains(view)) {
338 d->views.append(view);
339 }
340
341 Q_EMIT sigViewAdded(view);
342}
343
345{
346 if (!view) return;
347
355
356 Q_EMIT sigViewRemoved(view);
357
358 QPointer<KisDocument> doc = view->document();
359 d->views.removeAll(view);
360
361 if (doc) {
362 bool found = false;
363 Q_FOREACH (QPointer<KisView> view, d->views) {
364 if (view && view->document() == doc) {
365 found = true;
366 break;
367 }
368 }
369 if (!found) {
370 removeDocument(doc);
371 }
372 }
373}
374
376{
377 return d->views;
378}
379
381{
382 if (!doc) {
383 return d->views.count();
384 }
385 else {
386 int count = 0;
387 Q_FOREACH (QPointer<KisView> view, d->views) {
388 if (view && view->isVisible() && view->document() == doc) {
389 count++;
390 }
391 }
392 return count;
393 }
394}
395
396bool KisPart::closingSession() const
397{
398 return d->closingSession;
399}
400
402{
403 return s_instance.exists();
404}
405
406bool KisPart::closeSession(bool keepWindows)
407{
408 d->closingSession = true;
409
410 Q_FOREACH(auto document, d->documents) {
411 if (!d->queryCloseDocument(document.data())) {
412 d->closingSession = false;
413 return false;
414 }
415 }
416
417 if (d->currentSession) {
418 KisConfig kisCfg(false);
419 if (kisCfg.saveSessionOnQuit(false)) {
420
421 d->currentSession->storeCurrentWindows();
423 bool result = model.updateResource(d->currentSession);
424 Q_UNUSED(result);
425
426 KConfigGroup cfg = KSharedConfig::openConfig()->group("session");
427 cfg.writeEntry("previousSession", d->currentSession->name());
428 }
429
430 d->currentSession = nullptr;
431 }
432
433 if (!keepWindows) {
434 Q_FOREACH (auto window, d->mainWindows) {
435 window->close();
436 }
437
438 if (d->sessionManager) {
439 d->sessionManager->close();
440 }
441 }
442
443 d->closingSession = false;
444 return true;
445}
446
447void KisPart::slotDocumentSaved(const QString &filePath)
448{
449 // We used to use doc->path(), but it does not contain the correct output
450 // file path when doing an export, therefore we now pass it directly from
451 // the sigSavingFinished signal.
452 // KisDocument *doc = qobject_cast<KisDocument*>(sender());
453 Q_EMIT sigDocumentSaved(filePath);
454
455 QUrl url = QUrl::fromLocalFile(filePath);
457 if (!d->pendingAddRecentUrlMap.contains(url)) {
458 return;
459 }
460 QUrl oldUrl = d->pendingAddRecentUrlMap.take(url);
461 addRecentURLToAllMainWindows(url, oldUrl);
462}
463
465{
466 dbgUI <<"mainWindow" << (void*)mainWindow <<"removed from doc" << this;
467 if (mainWindow) {
468 d->mainWindows.removeAll(mainWindow);
469 }
470}
471
473{
474 return d->mainWindows;
475}
476
478{
479 return d->mainWindows.count();
480}
481
482
484{
485 QWidget *widget = qApp->activeWindow();
486 KisMainWindow *mainWindow = qobject_cast<KisMainWindow*>(widget);
487 while (!mainWindow && widget) {
488 widget = widget->parentWidget();
489 mainWindow = qobject_cast<KisMainWindow*>(widget);
490 }
491
492 if (!mainWindow && mainWindows().size() > 0) {
493 mainWindow = mainWindows().first();
494 }
495 return mainWindow;
496
497}
498
500{
501 return currentMainwindow();
502}
503
505{
506 Q_FOREACH(QPointer<KisMainWindow> mainWindow, d->mainWindows) {
507 if (mainWindow->id() == id) {
508 return mainWindow;
509 }
510 }
511
512 return nullptr;
513}
514
516{
517 return &d->idleWatcher;
518}
519
521{
522 return &d->animationCachePopulator;
523}
524
526{
527 return d->playbackEngine.data();
528}
529
531 KisImageAnimationInterface* animInterface = image->animationInterface();
532 if ( animInterface && animInterface->documentPlaybackRange().contains(frame)) {
533 d->animationCachePopulator.requestRegenerationWithPriorityFrame(image, frame);
534 }
535}
536
537void KisPart::openExistingFile(const QString &path)
538{
539 // TODO: refactor out this method!
540
543
545}
546
548{
549 // Update the UI actions. KisActionRegistry also takes care of updating
550 // shortcut hints in tooltips.
551 Q_FOREACH (KisMainWindow *mainWindow, d->mainWindows) {
552 KisKActionCollection *ac = mainWindow->actionCollection();
553
554 ac->updateShortcuts();
555 }
556}
557
558void KisPart::openTemplate(const QUrl &url)
559{
560 KisCursorOverrideLock cursorLock(Qt::BusyCursor);
561
562 KisDocument *document = createDocument();
563
564 bool ok = document->loadNativeFormat(url.toLocalFile());
565 document->setModified(false);
566 document->undoStack()->clear();
567 document->documentInfo()->resetMetaData();
568
569 if (ok) {
570 QString mimeType = KisMimeDatabase::mimeTypeForFile(url.toLocalFile());
571 // in case this is a open document template remove the -template from the end
572 mimeType.remove( QRegularExpression( "-template$" ) );
573 document->setMimeTypeAfterLoading(mimeType);
574 document->resetPath();
575 document->setReadWrite(true);
576 }
577 else {
578 if (document->errorMessage().isEmpty()) {
579 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"), i18n("Could not create document from template\n%1", document->localFilePath()));
580 }
581 else {
582 QMessageBox::critical(qApp->activeWindow(), i18nc("@title:window", "Krita"), i18n("Could not create document from template\n%1\nReason: %2", document->localFilePath(), document->errorMessage()));
583 }
584 delete document;
585 return;
586 }
587 QMap<QString, QString> dictionary;
588 // XXX: fill the dictionary from the desktop file
590 document->image()->rootLayer()->accept(v);
591
592 addDocument(document);
593
596}
597
598void KisPart::addRecentURLToAllMainWindows(QUrl url, QUrl oldUrl)
599{
600 // Add entry to recent documents list
601 // (call coming from KisDocument because it must work with cmd line, template dlg, file/open, etc.)
602 if (!url.isEmpty()) {
603 bool ok = true;
604 if (url.isLocalFile()) {
605 QString path = url.adjusted(QUrl::StripTrailingSlash).toLocalFile();
606 const QStringList tmpDirs = QStandardPaths::locateAll(QStandardPaths::TempLocation, "", QStandardPaths::LocateDirectory);
607 for (QStringList::ConstIterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it) {
608 if (path.contains(*it)) {
609 ok = false; // it's in the tmp resource
610 }
611 }
612
613 const QStringList templateDirs = KoResourcePaths::findDirs("templates");
614 for (QStringList::ConstIterator it = templateDirs.begin() ; ok && it != templateDirs.end() ; ++it) {
615 if (path.contains(*it)) {
616 ok = false; // it's in the templates directory.
617 break;
618 }
619 }
620 }
621 if (ok) {
622 if (!oldUrl.isEmpty()) {
624 }
626 }
627 }
628}
629
631{
632 d->pendingAddRecentUrlMap.insert(url, oldUrl);
633}
634
642
644{
646 KisViewManager *manager = mw ? mw->viewManager() : 0;
647 return manager ? manager->inputManager() : 0;
648}
649
651{
652 if (d->sessionManager.isNull()) {
653 d->sessionManager.reset(new KisSessionManagerDialog());
654 }
655
656 d->sessionManager->show();
657 d->sessionManager->activateWindow();
658}
659
661{
663 window->initializeGeometry();
664 window->show();
665
666}
667
668bool KisPart::restoreSession(const QString &sessionName)
669{
670 if (sessionName.isNull()) return false;
671
673 KisSessionResourceSP session = rserver->resource("", "", sessionName);
674 if (!session || !session->valid()) return false;
675
676 return restoreSession(session);
677}
678
680{
681 session->restore();
682 d->currentSession = session;
683 return true;
684}
685
687{
688 d->currentSession = session;
689}
690
692{
693#ifdef HAVE_MLT
694
695 // TODO: This is a slightly hacky workaround to loading the MLT engine over itself,
696 // as the QT-based engine no longer supports audio. Is there a better way?
697 if (d->playbackEngine->supportsAudio()) {
698 return;
699 }
700
702
703 if (canvas) {
704 d->playbackEngine->setObservedCanvas(canvas);
705 }
706
707#endif //HAVE_MLT
708}
709
711{
712#ifdef HAVE_MLT
713
714 d->playbackEngine.reset();
715
716#endif //HAVE_MLT
717}
718
720{
721 // make sure that the old engine is still alive until the end
722 // of the emitted signal
723 QScopedPointer backup(p_playbackEngine);
724 d->playbackEngine.swap(backup);
725
726 // Log all changes to playback engine for easier debugging.
727 // (See `krita.log` or `Help > Show Krita log for bug reports`.)
728 KisUsageLogger::log("Audio Playback Engine: " + QString(p_playbackEngine->metaObject()->className()));
729
730 Q_EMIT playbackEngineChanged(p_playbackEngine);
731}
732
733#include "moc_KisPart.cpp"
qreal v
quint64 part(quint64 n1, quint64 n2, int p)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisActionRegistry * instance()
void setFeedbackCallback(std::function< void(KisImageSP)> callback)
static KisBusyWaitBroker * instance()
static KisColorManager * instance()
void disableOpenGL() const
QString canvasState(bool defaultValue=false) const
bool saveSessionOnQuit(bool defaultValue) const
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
KisImageAnimationInterface * animationInterface() const
Central object to manage canvas input.
A container for a set of QAction objects.
QList< QAction * > actions() const
virtual KisKActionCollection * actionCollection() const
Main window for Krita.
bool openDocument(const QString &path, OpenFlags flags)
KisView * addViewAndNotifyLoadingCompleted(KisDocument *document, QMdiSubWindow *subWindow=0)
KisViewManager * viewManager
bool hackIsSaving() const
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
KisAnimationCachePopulator animationCachePopulator
Definition KisPart.cpp:110
bool closeSession(bool keepWindows=false)
Definition KisPart.cpp:406
void sigDocumentSaved(const QString &url)
QList< QPointer< KisDocument > > documents
Definition KisPart.cpp:108
Private(KisPart *_part)
Definition KisPart.cpp:92
void sigViewAdded(KisView *view)
void removeMainWindow(KisMainWindow *mainWindow)
Definition KisPart.cpp:464
void updateShortcuts()
Definition KisPart.cpp:547
bool queryCloseDocument(KisDocument *document)
Definition KisPart.cpp:119
void upgradeToPlaybackEngineMLT(class KoCanvasBase *canvas)
Definition KisPart.cpp:691
QList< QPointer< KisMainWindow > > mainWindows
Definition KisPart.cpp:107
void addRecentURLToAllMainWindows(QUrl url, QUrl oldUrl=QUrl())
Definition KisPart.cpp:598
void setPlaybackEngine(KisPlaybackEngine *p_playbackEngine)
Definition KisPart.cpp:719
void documentClosed(const QString &ref)
KisView * createView(KisDocument *document, KisViewManager *viewManager, QWidget *parent)
Definition KisPart.cpp:301
void openTemplate(const QUrl &url)
Definition KisPart.cpp:558
KisInputManager * currentInputManager()
Definition KisPart.cpp:643
QScopedPointer< KisSessionManagerDialog > sessionManager
Definition KisPart.cpp:115
KisSessionResourceSP currentSession
Definition KisPart.cpp:113
static KisPart * instance()
Definition KisPart.cpp:131
void sigDocumentAdded(KisDocument *document)
QScopedPointer< KisPlaybackEngine > playbackEngine
Definition KisPart.cpp:111
bool restoreSession(const QString &sessionName)
Definition KisPart.cpp:668
Private *const d
Definition KisPart.h:328
void slotDocumentSaved(const QString &filePath)
Definition KisPart.cpp:447
void addView(KisView *view)
Definition KisPart.cpp:332
void removeView(KisView *view)
Definition KisPart.cpp:344
QMap< QUrl, QUrl > pendingAddRecentUrlMap
Definition KisPart.cpp:117
void addDocument(KisDocument *document, bool notify=true)
Definition KisPart.cpp:211
void queueAddRecentURLToAllMainWindowsOnFileSaved(QUrl url, QUrl oldUrl=QUrl())
Definition KisPart.cpp:630
int documentCount() const
Definition KisPart.cpp:243
int viewCount(KisDocument *doc) const
Definition KisPart.cpp:380
void playbackEngineChanged(KisPlaybackEngine *newPlaybackEngine)
static bool exists()
Definition KisPart.cpp:401
KisAnimationCachePopulator * cachePopulator() const
Definition KisPart.cpp:520
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:483
void prioritizeFrameForCache(KisImageSP image, int frame)
Definition KisPart.cpp:530
KisIdleWatcher idleWatcher
Definition KisPart.cpp:109
void startBlankSession()
Definition KisPart.cpp:660
~KisPart() override
Definition KisPart.cpp:176
KisMainWindow * windowById(QUuid id) const
Definition KisPart.cpp:504
void removeDocument(KisDocument *document, bool deleteDocument=true)
Definition KisPart.cpp:248
KisDocument * createTemporaryDocument() const
Definition KisPart.cpp:236
void sigViewRemoved(KisView *view)
QWidget * currentMainwindowAsQWidget() const
Definition KisPart.cpp:499
void startCustomDocument(KisDocument *doc)
startCustomDocument adds the given document to the document list and deletes the sender()
Definition KisPart.cpp:635
KisDocument * createDocument() const
Definition KisPart.cpp:230
bool closingSession
Definition KisPart.cpp:114
QList< QPointer< KisView > > views
Definition KisPart.cpp:106
void setCurrentSession(KisSessionResourceSP session)
Definition KisPart.cpp:686
void documentOpened(const QString &ref)
void updateIdleWatcherConnections()
Definition KisPart.cpp:193
void openExistingFile(const QString &path)
Definition KisPart.cpp:537
void sigDocumentRemoved(const QString &filename)
int mainwindowCount() const
Definition KisPart.cpp:477
void unloadPlaybackEngine()
Definition KisPart.cpp:710
void showSessionManager()
Definition KisPart.cpp:650
void sigMainWindowIsBeingCreated(KisMainWindow *window)
void notifyMainWindowIsBeingCreated(KisMainWindow *mainWindow)
notifyMainWindowIsBeingCreated emits the sigMainWindowCreated signal
Definition KisPart.cpp:295
KisPart * part
Definition KisPart.cpp:104
KisMainWindow * createMainWindow(QUuid id=QUuid())
Definition KisPart.cpp:260
The KisPlaybackEngineMLT class is an implementation of KisPlaybackEngine that uses MLT (Media Lovin' ...
The KisPlaybackEngineQT class is an implementation of KisPlaybackEngine that drives animation playbac...
Krita's base animation playback engine for producing image frame changes and associated audio.
static KisRecentFileIconCache * instance()
void reloadFileIcon(const QUrl &url)
void remove(const QUrl &url)
static KisRecentFilesManager * instance()
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
bool updateResource(KoResourceSP resource) override
updateResource creates a new version of the resource in the storage and in the database....
static KisResourceServerProvider * instance()
KoResourceServer< KisSessionResource > * sessionServer()
bool contains(int time) const
KisTranslateLayerNamesVisitor::KisTranslateLayerNamesVisitor translates layer names from templates.
static void log(const QString &message)
Logs with date/time.
KisInputManager * inputManager() const
Filters events and sends them to canvas actions.
KisMainWindow * mainWindow() const
Definition KisView.cpp:1093
QPointer< KisDocument > document
Definition KisView.cpp:121
static QStringList findDirs(const QString &type)
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 KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define dbgUI
Definition kis_debug.h:52
const QString Sessions
static KisMemoryStatisticsServer * instance()
static KoResourceServerProvider * instance()
KisCanvas2 * canvas