[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [krita] libs/ui: Don't let the user close the document while saving is in progress
From:       Dmitry Kazakov <null () kde ! org>
Date:       2017-05-01 7:17:40
Message-ID: E1d55aW-00030e-A6 () code ! kde ! org
[Download RAW message or body]

Git commit 3ce218ca6674deeaa0539fe7b96d19577dc99641 by Dmitry Kazakov.
Committed on 01/05/2017 at 07:13.
Pushed by dkazakov into branch 'master'.

Don't let the user close the document while saving is in progress

Ideally, we should postpone closing till the saving is finished,
but it is impossible to do right now, because doc->setModified()
is called outside the saving lock held. Later, when we refactor
the saving code and the modified state will be cleared under
the lock, we can easily use KisSignalCompressor to close the
document.

The crash itself happened because the hack in KisPart::removeView()
just skipped the deinitialization of the view and the input manager
was still connected to the canvas that was destroyed.

BUG:378538

M  +6    -0    libs/ui/KisDocument.cpp
M  +7    -0    libs/ui/KisDocument.h
M  +0    -7    libs/ui/KisMainWindow.cpp
M  +1    -13   libs/ui/KisPart.cpp
M  +0    -2    libs/ui/KisPart.h
M  +7    -0    libs/ui/KisView.cpp

https://commits.kde.org/krita/3ce218ca6674deeaa0539fe7b96d19577dc99641

diff --git a/libs/ui/KisDocument.cpp b/libs/ui/KisDocument.cpp
index 4b2f0e64396..22abf325f4e 100644
--- a/libs/ui/KisDocument.cpp
+++ b/libs/ui/KisDocument.cpp
@@ -656,6 +656,12 @@ QByteArray KisDocument::serializeToNativeByteArray()
     return byteArray;
 }
 
+bool KisDocument::isInSaving() const
+{
+    std::unique_lock<StdLockableWrapper<QMutex>> l(d->savingLock, std::try_to_lock);
+    return !l.owns_lock();
+}
+
 bool KisDocument::saveFile(const QString &filePath, KisPropertiesConfigurationSP exportConfiguration)
 {
     if (!prepareLocksForSaving()) {
diff --git a/libs/ui/KisDocument.h b/libs/ui/KisDocument.h
index d831511d940..90994d64f00 100644
--- a/libs/ui/KisDocument.h
+++ b/libs/ui/KisDocument.h
@@ -381,6 +381,13 @@ public:
      */
     QByteArray serializeToNativeByteArray();
 
+
+    /**
+     * @brief isInSaving shown if the document has any (background) saving process or not
+     * @return true if there is some saving in action
+     */
+    bool isInSaving() const;
+
 public Q_SLOTS:
 
     /**
diff --git a/libs/ui/KisMainWindow.cpp b/libs/ui/KisMainWindow.cpp
index 37cba1e57e2..e33a5943d7c 100644
--- a/libs/ui/KisMainWindow.cpp
+++ b/libs/ui/KisMainWindow.cpp
@@ -1145,13 +1145,6 @@ void KisMainWindow::closeEvent(QCloseEvent *e)
         if (d->noCleanup)
             return;
 
-        Q_FOREACH (QMdiSubWindow *subwin, d->mdiArea->subWindowList()) {
-            KisView *view = dynamic_cast<KisView*>(subwin);
-            if (view) {
-                KisPart::instance()->removeView(view);
-            }
-        }
-
         if (!d->dockWidgetVisibilityMap.isEmpty()) { // re-enable dockers for persistency
             Q_FOREACH (QDockWidget* dockWidget, d->dockWidgetsMap)
                 dockWidget->setVisible(d->dockWidgetVisibilityMap.value(dockWidget));
diff --git a/libs/ui/KisPart.cpp b/libs/ui/KisPart.cpp
index ab28ebc4134..5ea6bb6866e 100644
--- a/libs/ui/KisPart.cpp
+++ b/libs/ui/KisPart.cpp
@@ -256,8 +256,6 @@ void KisPart::addView(KisView *view)
         d->views.append(view);
     }
 
-    connect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed()));
-
     emit sigViewAdded(view);
 }
 
@@ -271,9 +269,7 @@ void KisPart::removeView(KisView *view)
      *             document *before* the saving is completed, a crash
      *             will happen.
      */
-    if (view->mainWindow()->hackIsSaving()) {
-        return;
-    }
+    KIS_ASSERT_RECOVER_RETURN(!view->mainWindow()->hackIsSaving());
 
     emit sigViewRemoved(view);
 
@@ -464,14 +460,6 @@ void KisPart::openTemplate(const QUrl &url)
     qApp->restoreOverrideCursor();
 }
 
-void KisPart::viewDestroyed()
-{
-    KisView *view = qobject_cast<KisView*>(sender());
-    if (view) {
-        removeView(view);
-    }
-}
-
 void KisPart::addRecentURLToAllMainWindows(QUrl url)
 {
     // Add to recent actions list in our mainWindows
diff --git a/libs/ui/KisPart.h b/libs/ui/KisPart.h
index 2f40c5bc1da..1395aa4d710 100644
--- a/libs/ui/KisPart.h
+++ b/libs/ui/KisPart.h
@@ -179,8 +179,6 @@ public Q_SLOTS:
 
 private Q_SLOTS:
 
-    void viewDestroyed();
-
     void updateIdleWatcherConnections();
 
     void updateShortcuts();
diff --git a/libs/ui/KisView.cpp b/libs/ui/KisView.cpp
index ed4b7d8e712..2db67e1548a 100644
--- a/libs/ui/KisView.cpp
+++ b/libs/ui/KisView.cpp
@@ -695,6 +695,13 @@ bool KisView::queryClose()
     if (!document())
         return true;
 
+    if (document()->isInSaving()) {
+        viewManager()->showFloatingMessage(
+            i18n("Cannot close the document while saving is in progress"),
+            KisIconUtils::loadIcon("object-locked"), 1500 /* ms */);
+        return false;
+    }
+
     if (document()->isModified()) {
         QString name;
         if (document()->documentInfo()) {

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic