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

List:       kde-core-devel
Subject:    [PATCH] ReadWritePart::queryClose()
From:       John Firebaugh <jfire () uclink ! berkeley ! edu>
Date:       2002-12-01 22:00:46
[Download RAW message or body]

The attached patch factors out portions of ReadWritePart::closeURL() into a 
separate function that is appropriate to call from KMainWindow::queryClose(). 
This is a prerequisite for fixing http://bugs.kde.org/show_bug.cgi?id=49270 
properly. It should be functionally equivalent to the existing behavior 
except that setModified( false ) is not called if the user elects not to save 
changes, which can't easily happen after the refactoring, and seems wrong to 
me anyway. (What if the close is somehow canceled after that? Shouldn't the 
document still be marked modified?) The patch also adds additional 
documentation for KMainWindow::queryClose(), noting a potential 'gotcha'. The 
new method is marked @since 3.2 but I will backport and change that to 3.1.1 
if people think it necessary.

-John
["queryClose.diff" (text/x-diff)]

Index: kdeui/kmainwindow.h
===================================================================
RCS file: /home/kde/kdelibs/kdeui/kmainwindow.h,v
retrieving revision 1.58
diff -u -3 -p -r1.58 kmainwindow.h
--- kdeui/kmainwindow.h	2002/10/31 16:17:42	1.58
+++ kdeui/kmainwindow.h	2002/12/01 21:11:30
@@ -589,7 +589,6 @@ protected:
        Reimplement this function to prevent the user from losing data.
        Example:
        <pre>
-
            switch ( KMessageBox::warningYesNoCancel( this,
 				   i18n("Save changes to Document Foo?")) ) {
            case KMessageBox::Yes :
@@ -599,13 +598,18 @@ protected:
              return TRUE;
            default: // cancel
              return FALSE;
-
-    </pre>
-
-   @see queryExit()
+       </pre>
+       
+       Note that you should probably @em not actually close the document from
+       within this method, as it may be called by the session manager before the
+       session is saved. If the document is closed before the session save occurs,
+       its location might not be properly saved. In addition, the session shutdown
+       may be cancelled, in which case the document should remain open.
 
+       @see queryExit()
     */
     virtual bool queryClose();
+    
     /**
      * Save your instance-specific properties. The function is
      * invoked when the session manager requests your application
Index: kparts/part.cpp
===================================================================
RCS file: /home/kde/kdelibs/kparts/part.cpp,v
retrieving revision 1.119
diff -u -3 -p -r1.119 part.cpp
--- kparts/part.cpp	2002/07/17 18:01:54	1.119
+++ kparts/part.cpp	2002/12/01 21:11:38
@@ -462,36 +462,45 @@ void ReadWritePart::setModified()
   setModified( true );
 }
 
+bool ReadWritePart::queryClose()
+{
+  if ( !isReadWrite() || !isModified() )
+    return true;
+
+  int res = KMessageBox::warningYesNoCancel( widget(),
+          i18n( "The document \"%1\" has been modified.\n"
+                "Do you want to save it?" ).arg( url().fileName() ),
+          i18n( "Save Document?" ), KStdGuiItem::save(), KStdGuiItem::discard() );
+
+  switch(res) {
+  case KMessageBox::Yes :
+    if (m_url.isEmpty())
+    {
+        KURL url = KFileDialog::getSaveURL();
+        if (url.isEmpty())
+        {
+          m_bClosing = false;
+          return false;
+        }
+        return saveAs( url );
+    }
+    return save();
+  case KMessageBox::No :
+    m_bClosing = false;
+    return true;
+  default : // case KMessageBox::Cancel :
+    m_bClosing = false;
+    return false;
+  }
+}
+
 bool ReadWritePart::closeURL()
 {
   abortLoad(); //just in case
-  if ( m_bModified && m_bReadWrite )
+  if ( isReadWrite() && isModified() )
   {
-    int res = KMessageBox::warningYesNoCancel( widget(),
-            i18n( "The document \"%1\" has been modified.\n"
-                  "Do you want to save it?" ).arg( url().fileName() ),
-            i18n( "Save Document?" ), KStdGuiItem::save(), KStdGuiItem::discard() );
-
-    switch(res) {
-    case KMessageBox::Yes :
-      m_bClosing = true; // remember to clean up the temp file
-      if (m_url.isEmpty())
-      {
-          KURL url = KFileDialog::getSaveURL();
-          if (url.isEmpty())
-          {
-            m_bClosing = false;
-            return false;
-          }
-          return saveAs( url );
-      }
-      return save();
-    case KMessageBox::No :
-      setModified( false ); // the user isn't interested in the changes, forget them
-      return true;
-    default : // case KMessageBox::Cancel :
-      return false;
-    }
+    m_bClosing = true; // remember to clean up the temp file
+    return queryClose();
   }
   // Not modified => ok and delete temp file.
   return ReadOnlyPart::closeURL();
Index: kparts/part.h
===================================================================
RCS file: /home/kde/kdelibs/kparts/part.h,v
retrieving revision 1.93
diff -u -3 -p -r1.93 part.h
--- kparts/part.h	2002/07/15 09:25:31	1.93
+++ kparts/part.h	2002/12/01 21:11:38
@@ -531,6 +531,18 @@ public:
   bool isModified() const { return m_bModified; }
 
   /**
+   * If the document has been modified, ask the user to save changes.
+   * This method is meant to be called from @ref KMainWindow::queryClose().
+   * It will also be called from closeURL().
+   *
+   * @return true if closeURL() can be called without the user losing
+   * important data, false if the user chooses to cancel.
+   *
+   * @since 3.2
+   */
+  bool queryClose();
+
+  /**
    * Called when closing the current url (e.g. document), for instance
    * when switching to another url (note that @ref openURL() calls it
    * automatically in this case).


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

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