14#include <config-mlt.h>
40#include <QScopedPointer>
42#include <QRegularExpression>
45#include <klocalizedstring.h>
48#include <kconfiggroup.h>
49#include <QKeySequence>
51#include <QApplication>
52#include <QDomDocument>
54#include <QGlobalStatic>
94 , animationCachePopulator(_part)
95 , playbackEngine(nullptr)
113 bool closingSession{
false};
119 Q_FOREACH(
auto view, views) {
120 if (view && view->isVisible() && view->document() == document) {
121 return view->queryClose();
138 const int busyWaitDelay = 1000;
141 dialog.blockIfImageIsBusy();
161 connect(&
d->idleWatcher, SIGNAL(startedIdleMode()),
162 &
d->animationCachePopulator, SLOT(slotRequestRegeneration()));
163 connect(&
d->idleWatcher, SIGNAL(startedIdleMode()),
170 d->animationCachePopulator.slotRequestRegeneration();
176 while (!
d->documents.isEmpty()) {
177 delete d->documents.takeFirst();
180 while (!
d->views.isEmpty()) {
181 delete d->views.takeFirst();
184 while (!
d->mainWindows.isEmpty()) {
185 delete d->mainWindows.takeFirst();
196 if (document->image()) {
197 images << document->image();
201 d->idleWatcher.setTrackedImages(images);
206 d->idleWatcher.forceImageModified();
213 if (!
d->documents.contains(document)) {
214 d->documents.append(document);
219 connect(document, SIGNAL(sigSavingFinished(QString)), SLOT(
slotDocumentSaved(QString)));
243 return d->documents.size();
249 d->documents.removeAll(document);
252 if (deleteDocument) {
253 document->deleteLater();
261 dbgUI <<
"mainWindow" << (
void*)mw <<
"added to view" <<
this;
262 d->mainWindows.append(mw);
281 KConfigGroup grp( KSharedConfig::openConfig(),
"crashprevention");
282 if (grp.readEntry(
"CreatingCanvas",
false)) {
288 grp.writeEntry(
"CreatingCanvas",
true);
293 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
294 view =
new KisView(document, viewManager, parent);
298 grp.writeEntry(
"CreatingCanvas",
false);
311 if (!
d->views.contains(view)) {
312 d->views.append(view);
333 d->views.removeAll(view);
338 if (view && view->document() == doc) {
357 return d->views.count();
362 if (view && view->isVisible() && view->document() == doc) {
372 return d->closingSession;
377 return s_instance.exists();
382 d->closingSession =
true;
384 Q_FOREACH(
auto document,
d->documents) {
385 if (!
d->queryCloseDocument(document.data())) {
386 d->closingSession =
false;
391 if (
d->currentSession) {
395 d->currentSession->storeCurrentWindows();
400 KConfigGroup cfg = KSharedConfig::openConfig()->group(
"session");
401 cfg.writeEntry(
"previousSession",
d->currentSession->name());
404 d->currentSession =
nullptr;
408 Q_FOREACH (
auto window,
d->mainWindows) {
412 if (
d->sessionManager) {
413 d->sessionManager->close();
417 d->closingSession =
false;
429 QUrl url = QUrl::fromLocalFile(filePath);
431 if (!
d->pendingAddRecentUrlMap.contains(url)) {
434 QUrl oldUrl =
d->pendingAddRecentUrlMap.take(url);
440 dbgUI <<
"mainWindow" << (
void*)mainWindow <<
"removed from doc" <<
this;
442 d->mainWindows.removeAll(mainWindow);
448 return d->mainWindows;
453 return d->mainWindows.count();
459 QWidget *widget = qApp->activeWindow();
460 KisMainWindow *mainWindow = qobject_cast<KisMainWindow*>(widget);
461 while (!mainWindow && widget) {
462 widget = widget->parentWidget();
463 mainWindow = qobject_cast<KisMainWindow*>(widget);
481 if (mainWindow->id() ==
id) {
491 return &
d->idleWatcher;
496 return &
d->animationCachePopulator;
501 return d->playbackEngine.get();
507 d->animationCachePopulator.requestRegenerationWithPriorityFrame(image, frame);
534 KisCursorOverrideLock cursorLock(Qt::BusyCursor);
538 bool ok = document->loadNativeFormat(url.toLocalFile());
539 document->setModified(
false);
540 document->undoStack()->clear();
541 document->documentInfo()->resetMetaData();
546 mimeType.remove( QRegularExpression(
"-template$" ) );
547 document->setMimeTypeAfterLoading(mimeType);
548 document->resetPath();
549 document->setReadWrite(
true);
552 if (document->errorMessage().isEmpty()) {
553 QMessageBox::critical(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"), i18n(
"Could not create document from template\n%1", document->localFilePath()));
556 QMessageBox::critical(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"), i18n(
"Could not create document from template\n%1\nReason: %2", document->localFilePath(), document->errorMessage()));
561 QMap<QString, QString> dictionary;
564 document->image()->rootLayer()->accept(
v);
576 if (!url.isEmpty()) {
578 if (url.isLocalFile()) {
579 QString path = url.adjusted(QUrl::StripTrailingSlash).toLocalFile();
580 const QStringList tmpDirs = QStandardPaths::locateAll(QStandardPaths::TempLocation,
"", QStandardPaths::LocateDirectory);
581 for (QStringList::ConstIterator it = tmpDirs.begin() ; ok && it != tmpDirs.end() ; ++it) {
582 if (path.contains(*it)) {
588 for (QStringList::ConstIterator it = templateDirs.begin() ; ok && it != templateDirs.end() ; ++it) {
589 if (path.contains(*it)) {
596 if (!oldUrl.isEmpty()) {
606 d->pendingAddRecentUrlMap.insert(url, oldUrl);
626 if (
d->sessionManager.isNull()) {
628 d->sessionManager->setAttribute(Qt::WA_DeleteOnClose);
631 d->sessionManager->show();
632 d->sessionManager->activateWindow();
645 if (sessionName.isNull())
return false;
649 if (!session || !session->valid())
return false;
657 d->currentSession = session;
663 d->currentSession = session;
672 if (
d->playbackEngine->supportsAudio()) {
679 d->playbackEngine->setObservedCanvas(
canvas);
689 d->playbackEngine.reset();
698 std::unique_ptr<KisPlaybackEngine> backup(p_playbackEngine);
699 d->playbackEngine.swap(backup);
703 KisUsageLogger::log(
"Animation Playback Engine: " + QString(p_playbackEngine->metaObject()->className()));
708#include "moc_KisPart.cpp"
quint64 part(quint64 n1, quint64 n2, int p)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
static KisActionRegistry * instance()
void setFeedbackCallback(std::function< void(KisImageSP)> callback)
static KisBusyWaitBroker * instance()
void disableOpenGL() const
QString canvasState(bool defaultValue=false) const
bool saveSessionOnQuit(bool defaultValue) const
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
KisImageAnimationInterface * animationInterface() const
A container for a set of QAction objects.
virtual KisKActionCollection * actionCollection() const
bool openDocument(const QString &path, OpenFlags flags)
KisView * addViewAndNotifyLoadingCompleted(KisDocument *document, QMdiSubWindow *subWindow=0)
KisViewManager * viewManager
bool hackIsSaving() const
void initializeGeometry()
void synchronizeDynamicActions()
static QString mimeTypeForFile(const QString &file, bool checkExistingFiles=true)
Find the mimetype for the given filename. The filename must include a suffix.
KisAnimationCachePopulator animationCachePopulator
bool closeSession(bool keepWindows=false)
void sigDocumentSaved(const QString &url)
QList< QPointer< KisDocument > > documents
void sigViewAdded(KisView *view)
void removeMainWindow(KisMainWindow *mainWindow)
QPointer< KisSessionManagerDialog > sessionManager
bool queryCloseDocument(KisDocument *document)
void upgradeToPlaybackEngineMLT(class KoCanvasBase *canvas)
QList< QPointer< KisMainWindow > > mainWindows
void addRecentURLToAllMainWindows(QUrl url, QUrl oldUrl=QUrl())
void setPlaybackEngine(KisPlaybackEngine *p_playbackEngine)
void documentClosed(const QString &ref)
KisView * createView(KisDocument *document, KisViewManager *viewManager, QWidget *parent)
void openTemplate(const QUrl &url)
KisInputManager * currentInputManager()
KisSessionResourceSP currentSession
static KisPart * instance()
void sigDocumentAdded(KisDocument *document)
std::unique_ptr< KisPlaybackEngine > playbackEngine
bool restoreSession(const QString &sessionName)
void slotDocumentSaved(const QString &filePath)
void addView(KisView *view)
void removeView(KisView *view)
QMap< QUrl, QUrl > pendingAddRecentUrlMap
void addDocument(KisDocument *document, bool notify=true)
void queueAddRecentURLToAllMainWindowsOnFileSaved(QUrl url, QUrl oldUrl=QUrl())
int documentCount() const
int viewCount(KisDocument *doc) const
void playbackEngineChanged(KisPlaybackEngine *newPlaybackEngine)
KisAnimationCachePopulator * cachePopulator() const
KisMainWindow * currentMainwindow() const
void prioritizeFrameForCache(KisImageSP image, int frame)
KisIdleWatcher idleWatcher
KisMainWindow * windowById(QUuid id) const
void removeDocument(KisDocument *document, bool deleteDocument=true)
KisDocument * createTemporaryDocument() const
void sigViewRemoved(KisView *view)
QWidget * currentMainwindowAsQWidget() const
void startCustomDocument(KisDocument *doc)
startCustomDocument adds the given document to the document list and deletes the sender()
KisDocument * createDocument() const
QList< QPointer< KisView > > views
void setCurrentSession(KisSessionResourceSP session)
void documentOpened(const QString &ref)
void updateIdleWatcherConnections()
void openExistingFile(const QString &path)
void sigDocumentRemoved(const QString &filename)
int mainwindowCount() const
void unloadPlaybackEngine()
void showSessionManager()
void sigMainWindowIsBeingCreated(KisMainWindow *window)
void notifyMainWindowIsBeingCreated(KisMainWindow *mainWindow)
notifyMainWindowIsBeingCreated emits the sigMainWindowCreated signal
KisMainWindow * createMainWindow(QUuid id=QUuid())
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 add(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
QPointer< KisDocument > document
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)
#define KIS_ASSERT_RECOVER_RETURN(cond)
static KisMemoryStatisticsServer * instance()
static KoResourceServerProvider * instance()