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>
95 , animationCachePopulator(_part)
96 , playbackEngine(nullptr)
114 bool closingSession{
false};
120 Q_FOREACH(
auto view, views) {
121 if (view && view->isVisible() && view->document() == document) {
122 return view->queryClose();
139 const int busyWaitDelay = 1000;
142 dialog.blockIfImageIsBusy();
163 connect(&
d->idleWatcher, SIGNAL(startedIdleMode()),
164 &
d->animationCachePopulator, SLOT(slotRequestRegeneration()));
165 connect(&
d->idleWatcher, SIGNAL(startedIdleMode()),
172 d->animationCachePopulator.slotRequestRegeneration();
178 while (!
d->documents.isEmpty()) {
179 delete d->documents.takeFirst();
182 while (!
d->views.isEmpty()) {
183 delete d->views.takeFirst();
186 while (!
d->mainWindows.isEmpty()) {
187 delete d->mainWindows.takeFirst();
198 if (document->image()) {
199 images << document->image();
203 d->idleWatcher.setTrackedImages(images);
208 d->idleWatcher.forceImageModified();
215 if (!
d->documents.contains(document)) {
216 d->documents.append(document);
245 return d->documents.size();
251 d->documents.removeAll(document);
254 if (deleteDocument) {
255 document->deleteLater();
263 dbgUI <<
"mainWindow" << (
void*)mw <<
"added to view" <<
this;
264 d->mainWindows.append(mw);
268 QString menuLocation = action->property(
"menulocation").toString();
269 if (!menuLocation.isEmpty()) {
272 Q_FOREACH(
const QString &name, menuLocation.split(
"/")) {
273 Q_FOREACH(QAction *candidate, candidates) {
274 if (candidate->objectName().toLower() == name.toLower()) {
276 candidates = candidate->menu()->actions();
280 if (candidates.isEmpty()) {
285 if (found && found->menu()) {
286 found->menu()->addAction(action);
307 KConfigGroup grp( KSharedConfig::openConfig(),
"crashprevention");
308 if (grp.readEntry(
"CreatingCanvas",
false)) {
314 grp.writeEntry(
"CreatingCanvas",
true);
319 KisCursorOverrideLock cursorLock(Qt::WaitCursor);
320 view =
new KisView(document, viewManager, parent);
324 grp.writeEntry(
"CreatingCanvas",
false);
337 if (!
d->views.contains(view)) {
338 d->views.append(view);
359 d->views.removeAll(view);
364 if (view && view->document() == doc) {
383 return d->views.count();
388 if (view && view->isVisible() && view->document() == doc) {
398 return d->closingSession;
403 return s_instance.exists();
408 d->closingSession =
true;
410 Q_FOREACH(
auto document,
d->documents) {
411 if (!
d->queryCloseDocument(document.data())) {
412 d->closingSession =
false;
417 if (
d->currentSession) {
421 d->currentSession->storeCurrentWindows();
426 KConfigGroup cfg = KSharedConfig::openConfig()->group(
"session");
427 cfg.writeEntry(
"previousSession",
d->currentSession->name());
430 d->currentSession =
nullptr;
434 Q_FOREACH (
auto window,
d->mainWindows) {
438 if (
d->sessionManager) {
439 d->sessionManager->close();
443 d->closingSession =
false;
455 QUrl url = QUrl::fromLocalFile(filePath);
457 if (!
d->pendingAddRecentUrlMap.contains(url)) {
460 QUrl oldUrl =
d->pendingAddRecentUrlMap.take(url);
466 dbgUI <<
"mainWindow" << (
void*)mainWindow <<
"removed from doc" <<
this;
468 d->mainWindows.removeAll(mainWindow);
474 return d->mainWindows;
479 return d->mainWindows.count();
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);
507 if (mainWindow->id() ==
id) {
517 return &
d->idleWatcher;
522 return &
d->animationCachePopulator;
527 return d->playbackEngine.data();
533 d->animationCachePopulator.requestRegenerationWithPriorityFrame(image, frame);
560 KisCursorOverrideLock cursorLock(Qt::BusyCursor);
564 bool ok = document->loadNativeFormat(url.toLocalFile());
565 document->setModified(
false);
566 document->undoStack()->clear();
567 document->documentInfo()->resetMetaData();
572 mimeType.remove( QRegularExpression(
"-template$" ) );
573 document->setMimeTypeAfterLoading(mimeType);
574 document->resetPath();
575 document->setReadWrite(
true);
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()));
582 QMessageBox::critical(qApp->activeWindow(), i18nc(
"@title:window",
"Krita"), i18n(
"Could not create document from template\n%1\nReason: %2", document->localFilePath(), document->errorMessage()));
587 QMap<QString, QString> dictionary;
590 document->image()->rootLayer()->accept(
v);
602 if (!url.isEmpty()) {
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)) {
614 for (QStringList::ConstIterator it = templateDirs.begin() ; ok && it != templateDirs.end() ; ++it) {
615 if (path.contains(*it)) {
622 if (!oldUrl.isEmpty()) {
632 d->pendingAddRecentUrlMap.insert(url, oldUrl);
652 if (
d->sessionManager.isNull()) {
656 d->sessionManager->show();
657 d->sessionManager->activateWindow();
670 if (sessionName.isNull())
return false;
674 if (!session || !session->valid())
return false;
682 d->currentSession = session;
688 d->currentSession = session;
697 if (
d->playbackEngine->supportsAudio()) {
704 d->playbackEngine->setObservedCanvas(
canvas);
714 d->playbackEngine.reset();
723 QScopedPointer backup(p_playbackEngine);
724 d->playbackEngine.swap(backup);
728 KisUsageLogger::log(
"Audio Playback Engine: " + QString(p_playbackEngine->metaObject()->className()));
733#include "moc_KisPart.cpp"
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
A container for a set of QAction objects.
QList< QAction * > actions() const
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()
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)
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()
QScopedPointer< KisSessionManagerDialog > sessionManager
KisSessionResourceSP currentSession
static KisPart * instance()
void sigDocumentAdded(KisDocument *document)
QScopedPointer< 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()