Version: (using KDE KDE 3.3.1) Installed from: Gentoo Packages When I restore my session, KolourPaint re-opens, but doesn't load the document it had when the session saved.
Session restore is not currently implemented. I plan to implement it eventually but at the moment, it is not high on my priority list. Is this feature important to you? If so, I can prioritise it above some other goals I have in mind (mainly new features for 1.4).
Reassigning bugs to KolourPaint support email address.
http://developer.kde.org/documentation/library/kdeqt/kde3arch/session.html provides the needed programming info, including a link to Qt Session Management. We should implement this for KDE 4. If it's not too complicated, will also backport to KDE 3.5.
Reassigning bugs to KolourPaint support email address (again).
SVN commit 663465 by dang: Implement rudimentary global session management. It saves the URLs, which is the most I dare implement in the stable branch so as to not break anything. Local session save/restore is not implemented, although some psuedo-code exists for it. I don't intend to implement this since I don't think any other KDE app does. CCMAIL: 94651@bugs.kde.org M +4 -0 kolourpaint.cpp M +15 -0 kpdefs.h M +164 -1 kpmainwindow.cpp M +24 -0 kpmainwindow.h M +27 -11 kpmainwindow_file.cpp --- branches/KDE/3.5/kdegraphics/kolourpaint/kolourpaint.cpp #663464:663465 @@ -220,7 +220,11 @@ if (app.isRestored ()) + { + // Creates a kpMainWindow using the default constructor and then + // calls kpMainWindow::readProperties(). RESTORE (kpMainWindow) + } else { kpMainWindow *mainWindow; --- branches/KDE/3.5/kdegraphics/kolourpaint/kpdefs.h #663464:663465 @@ -132,5 +132,20 @@ #define kpSettingFlattenEffectColor2 QString::fromLatin1 ("Color2") +// +// Session Restore Setting +// + +// URL of the document in the main window. +// +// This key only exists if the document does. If it exists, it can be empty. +// The URL need not point to a file that exists e.g. "kolourpaint doesnotexist.png". +#define kpSessionSettingDocumentUrl QString::fromLatin1 ("Session Document Url") + +// The size of a document which is not from a URL e.g. "kolourpaint doesnotexist.png". +// This key does not exist for documents from URLs. +#define kpSessionSettingNotFromUrlDocumentSize QString::fromLatin1 ("Session Not-From-Url Document Size") + + #endif // __kp_defs_h__ --- branches/KDE/3.5/kdegraphics/kolourpaint/kpmainwindow.cpp #663464:663465 @@ -310,6 +310,170 @@ #endif } + +// private virtual [base KMainWindow] +void kpMainWindow::readProperties (KConfig *cfg) +{ +#if DEBUG_KP_MAIN_WINDOW + kdDebug () << "kpMainWindow<" << this << ">::readProperties()" << endl; +#endif + + // No document at all? + if (!cfg->hasKey (kpSessionSettingDocumentUrl)) + { + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\tno url - no document" << endl; + #endif + setDocument (0); + } + // Have a document. + else + { + const KURL url (cfg->readEntry (kpSessionSettingDocumentUrl)); + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\turl=" << url << endl; + #endif + + const QSize notFromURLDocSize = + cfg->readSizeEntry (kpSessionSettingNotFromUrlDocumentSize); + + // Is from URL? + if (notFromURLDocSize.isEmpty ()) + { + // If this fails, the empty document that kpMainWindow::kpMainWindow() + // created is left untouched. + openInternal (url, defaultDocSize (), + false/*show error message if url !exist*/); + } + // Not from URL? + else + { + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\tnot from url; doc size=" << notFromURLDocSize << endl; + #endif + // Either we have an empty URL or we have a "kolourpaint doesnotexist.png" + // URL. Regarding the latter case, if a file now actually exists at that + // URL, we do open it - ignoring notFromURLDocSize - to avoid putting + // the user in a situation where he might accidentally overwrite an + // existing file. + openInternal (url, notFromURLDocSize, + true/*create an empty doc with the same url if url !exist*/); + } + } + +} + +// private virtual [base KMainWindow] +// WARNING: KMainWindow API Doc says "No user interaction is allowed +// in this function!" +void kpMainWindow::saveProperties (KConfig *cfg) +{ +#if DEBUG_KP_MAIN_WINDOW + kdDebug () << "kpMainWindow<" << this << ">::saveProperties()" << endl; +#endif + + // No document at all? + if (!m_document) + { + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\tno url - no document" << endl; + #endif + } + // Have a document. + else + { + // Save URL in all cases: + // + // a) m_document->isFromURL() + // b) !m_document->isFromURL() [save size in this case] + // i) No URL + // ii) URL (from "kolourpaint doesnotexist.png") + + const KURL url = m_document->url (); + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\turl=" << url << endl; + #endif + cfg->writeEntry (kpSessionSettingDocumentUrl, url.url ()); + + // Not from URL e.g. "kolourpaint doesnotexist.png"? + // + // Note that "kolourpaint doesexist.png" is considered to be from + // a URL even if it was deleted in the background (hence the + // "false" arg to isFromURL()). This is because the user expects + // it to be from a URL, so when we session restore, we pop up a + // "cannot find file" dialog, instead of silently creating a new, + // blank document. + if (!m_document->isFromURL (false/*don't bother checking exists*/)) + { + // If we don't have a URL either: + // + // a) it was not modified - so we can use either width() or + // constructorWidth() (they'll be equal). + // b) the changes were discarded so we use the initial width, + // constructorWidth(). + // + // Similarly for height() and constructorHeight(). + const QSize docSize (m_document->constructorWidth (), + m_document->constructorHeight ()); + #if DEBUG_KP_MAIN_WINDOW + kdDebug () << "\tnot from url; doc size=" << docSize << endl; + #endif + cfg->writeEntry (kpSessionSettingNotFromUrlDocumentSize, docSize); + } + + + // Local session save i.e. queryClose() was not called beforehand + // (see QApplication::saveState())? + #if 0 + if (m_document->isModified ()) + { + // TODO: Implement by saving the current image to a persistent file. + // We do this instead of saving/mutating the backing image file + // as no one expects a file save on a session save without a + // "do you want to save" dialog first. + // + // I don't think any KDE application implements local session saving. + // + // --- The below code does not compile but shows you want to do --- + + // Create unique name for the document in this main window. + const KURL tempURL = homeDir + + "kolourpaint session " + sessionID + + mainWindowPtrToString + ".png"; + // TODO: Use lossless PNG saving options. + kpDocumentSaveOptions pngSaveOptions; + + if (kpDocument::savePixmapToFile (m_document->pixmapWithSelection (), + tempURL, + pngSaveOptions, *m_document->metaInfo (), + false/*no overwrite prompt*/, + false/*no lossy prompt*/, + this)) + { + // readProperties() will still open kpSessionSettingDocumentUrl + // (as that's the expected URL) and will then add commands to: + // + // 1. Resize the document to the size of image at + // kpSessionSettingDocumentUnsavedContentsUrl, if the sizes + // differ. + // 2. Paste the kpSessionSettingDocumentUnsavedContentsUrl image + // (setting the main window's selection mode to opaque beforehand). + // + // It will then delete the file at + // kpSessionSettingDocumentUnsavedContentsUrl. + cfg->writeEntry (kpSessionSettingDocumentUnsavedContentsUrl, + tempURL.url ()); + } + else + { + // Not much we can do - we aren't allowed to throw up a dialog. + } + } + #endif + } +} + + kpMainWindow::~kpMainWindow () { m_isFullyConstructed = false; @@ -885,4 +1049,3 @@ #include <kpmainwindow.moc> - --- branches/KDE/3.5/kdegraphics/kolourpaint/kpmainwindow.h #663464:663465 @@ -120,6 +120,15 @@ void readThumbnailSettings (); void init (); + // (only called for restoring a previous session e.g. starting KDE with + // a previously saved session; it's not called on normal KolourPaint + // startup) + virtual void readProperties (KConfig *cfg); + // (only called for saving the current session e.g. logging out of KDE + // with the KolourPaint window open; it's not called on normal KolourPaint + // exit) + virtual void saveProperties (KConfig *cfg); + public: ~kpMainWindow (); @@ -310,7 +319,22 @@ void setDocumentChoosingWindow (kpDocument *doc); private: + kpDocument *openInternal (const KURL &url, + const QSize &fallbackDocSize, + bool newDocSameNameIfNotExist); + // Same as above except that it: + // + // 1. Assumes a default fallback document size. + // 2. If the URL is successfully opened (with the special exception of + // the "kolourpaint doesnotexist.png" case), it is bubbled up to the + // top in the Recent Files Action. + // + // As a result of this behavior, this should only be called in response + // to a user open request e.g. File / Open or "kolourpaint doesexist.png". + // It should not be used for session restore - in that case, it does not + // make sense to bubble the Recent Files list. bool open (const KURL &url, bool newDocSameNameIfNotExist = false); + KURL::List askForOpenURLs (const QString &caption, const QString &startURL, bool allowMultipleURLs = true); --- branches/KDE/3.5/kdegraphics/kolourpaint/kpmainwindow_file.cpp #663464:663465 @@ -283,29 +283,45 @@ // private -bool kpMainWindow::open (const KURL &url, bool newDocSameNameIfNotExist) +kpDocument *kpMainWindow::openInternal (const KURL &url, + const QSize &fallbackDocSize, + bool newDocSameNameIfNotExist) { - QSize docSize = defaultDocSize (); - // create doc - kpDocument *newDoc = new kpDocument (docSize.width (), docSize.height (), this); - if (newDoc->open (url, newDocSameNameIfNotExist)) + kpDocument *newDoc = new kpDocument (fallbackDocSize.width (), + fallbackDocSize.height (), + this); + if (!newDoc->open (url, newDocSameNameIfNotExist)) { + delete newDoc; + return 0; + } + + // Send document to current or new window. + setDocumentChoosingWindow (newDoc); + + return newDoc; +} + +// private +bool kpMainWindow::open (const KURL &url, bool newDocSameNameIfNotExist) +{ + kpDocument *newDoc = openInternal (url, + defaultDocSize (), + newDocSameNameIfNotExist); + if (newDoc) + { if (newDoc->isFromURL (false/*don't bother checking exists*/)) addRecentURL (url); + return true; } else { - delete newDoc; return false; } +} - // Send document to current or new window. - setDocumentChoosingWindow (newDoc); - return true; -} - // private KURL::List kpMainWindow::askForOpenURLs (const QString &caption, const QString &startURL, bool allowMultipleURLs)
SVN commit 664228 by dang: Manual merge of branches/KDE/3.5/kdegraphics/kolourpaint/ -r662446:r663466: Implement rudimentary global session management. It saves the URLs - I'll probably get it to save other things like zoom level later. Local session save/restore is not implemented, although some psuedo-code exists for it. I don't intend to implement this since I don't think any other KDE app does. CCMAIL: 94651-done@bugs.kde.org [FORWARD PORT] Note: Global session saving crashes KolourPaint and XSM, at least on my build. I took a shortcut in the build process (timestamp-touched kpMainWindow.h so that I could override readProperties() and saveProperties() without a full rebuild) so this might be to blame. But if this is not the case, it's a null ptr deref in KMWSessionManager::commitData(). Next time I update from kdelibs and do a clean build, I'll test again. Commit message ends here and afterwards is the valgrind output: ==7693== ==7693== Use of uninitialised value of size 4 ==7693== at 0x80CFEAD: QWidget::testAttribute(Qt::WidgetAttribute) const (in /home/kde4/dist/bin/kolourpaint) ==7693== by 0x1C67CE12: KMWSessionManager::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1C5DC5C5: KApplication::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1CDD0BCC: sm_performSaveYourself(QSessionManagerPrivate*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDD0ED4: sm_saveYourselfCallback(_SmcConn*, void*, int, int, int, int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x4F6BAE: _SmcProcessMessage (in /usr/X11R6/lib/libSM.so.6.0) ==7693== by 0x510CBA: IceProcessMessages (in /usr/X11R6/lib/libICE.so.6.3) ==7693== by 0x1CDC100B: QSmSocketReceiver::socketActivated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDC10E9: QSmSocketReceiver::qt_metacall(QMetaObject::Call, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA60AB4: QMetaObject::activate(QObject*, int, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA60CB0: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA87DC2: QSocketNotifier::activated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA6C026: QSocketNotifier::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD60741: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD60A8B: QApplication::notify(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1C5DA78A: KApplication::notify(QObject*, QEvent*) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1BA4D111: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA510B4: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA78E34: socketNotifierSourceDispatch(_GSource*, int (*)(void*), void*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x6543ED: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6573F5: (within /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6578D7: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x1BA78CB2: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CDF688E: QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA4BF9B: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA4C236: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50E54: QCoreApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD5FBB4: QApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x80C080C: main (in /home/kde4/dist/bin/kolourpaint) ==7693== ==7693== Invalid read of size 4 ==7693== at 0x80CFEAD: QWidget::testAttribute(Qt::WidgetAttribute) const (in /home/kde4/dist/bin/kolourpaint) ==7693== by 0x1C67CE12: KMWSessionManager::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1C5DC5C5: KApplication::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1CDD0BCC: sm_performSaveYourself(QSessionManagerPrivate*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDD0ED4: sm_saveYourselfCallback(_SmcConn*, void*, int, int, int, int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x4F6BAE: _SmcProcessMessage (in /usr/X11R6/lib/libSM.so.6.0) ==7693== by 0x510CBA: IceProcessMessages (in /usr/X11R6/lib/libICE.so.6.3) ==7693== by 0x1CDC100B: QSmSocketReceiver::socketActivated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDC10E9: QSmSocketReceiver::qt_metacall(QMetaObject::Call, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA60AB4: QMetaObject::activate(QObject*, int, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA60CB0: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA87DC2: QSocketNotifier::activated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA6C026: QSocketNotifier::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD60741: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD60A8B: QApplication::notify(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1C5DA78A: KApplication::notify(QObject*, QEvent*) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1BA4D111: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA510B4: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA78E34: socketNotifierSourceDispatch(_GSource*, int (*)(void*), void*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x6543ED: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6573F5: (within /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6578D7: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x1BA78CB2: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CDF688E: QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA4BF9B: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA4C236: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50E54: QCoreApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD5FBB4: QApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x80C080C: main (in /home/kde4/dist/bin/kolourpaint) ==7693== Address 0x1D660010 is 16 bytes before a block of size 16 free'd ==7693== at 0x1B9098CF: operator delete(void*) (vg_replace_malloc.c:155) ==7693== by 0x1CEE3444: QRegion::cleanUp(QRegion::QRegionData*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CEE34F2: QRegion::~QRegion() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CEEB41F: QWidgetBackingStore::copyToScreen(QRegion const&, QWidget*, QPoint const&, bool) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CEEC906: QWidgetBackingStore::cleanRegion(QRegion const&, QWidget*, bool) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CEECFA8: qt_syncBackingStore(QWidget*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDB5C47: QWidget::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1D097F1F: QAbstractButton::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1D1732CF: QToolButton::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD60741: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD6258A: QApplication::notify(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1C5DA78A: KApplication::notify(QObject*, QEvent*) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1BA4D111: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA510B4: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50BFC: QCoreApplication::sendPostedEvents(QObject*, int) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA78DAA: postEventSourceDispatch(_GSource*, int (*)(void*), void*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x6543ED: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6573F5: (within /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6578D7: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x1BA78CB2: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CDF688E: QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA4BF9B: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA4C236: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50E54: QCoreApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD5FBB4: QApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x80C080C: main (in /home/kde4/dist/bin/kolourpaint) ==7693== ==7693== Invalid read of size 4 ==7693== at 0x80CFEB7: QWidget::testAttribute(Qt::WidgetAttribute) const (in /home/kde4/dist/bin/kolourpaint) ==7693== by 0x1C67CE12: KMWSessionManager::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1C5DC5C5: KApplication::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1CDD0BCC: sm_performSaveYourself(QSessionManagerPrivate*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDD0ED4: sm_saveYourselfCallback(_SmcConn*, void*, int, int, int, int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x4F6BAE: _SmcProcessMessage (in /usr/X11R6/lib/libSM.so.6.0) ==7693== by 0x510CBA: IceProcessMessages (in /usr/X11R6/lib/libICE.so.6.3) ==7693== by 0x1CDC100B: QSmSocketReceiver::socketActivated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDC10E9: QSmSocketReceiver::qt_metacall(QMetaObject::Call, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA60AB4: QMetaObject::activate(QObject*, int, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA60CB0: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA87DC2: QSocketNotifier::activated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA6C026: QSocketNotifier::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD60741: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD60A8B: QApplication::notify(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1C5DA78A: KApplication::notify(QObject*, QEvent*) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1BA4D111: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA510B4: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA78E34: socketNotifierSourceDispatch(_GSource*, int (*)(void*), void*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x6543ED: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6573F5: (within /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6578D7: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x1BA78CB2: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CDF688E: QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA4BF9B: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA4C236: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50E54: QCoreApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD5FBB4: QApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x80C080C: main (in /home/kde4/dist/bin/kolourpaint) ==7693== Address 0x4 is not stack'd, malloc'd or (recently) free'd ==7693== ==7693== Process terminating with default action of signal 11 (SIGSEGV) ==7693== Access not within mapped region at address 0x4 ==7693== at 0x80CFEB7: QWidget::testAttribute(Qt::WidgetAttribute) const (in /home/kde4/dist/bin/kolourpaint) ==7693== by 0x1C67CE12: KMWSessionManager::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1C5DC5C5: KApplication::commitData(QSessionManager&) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1CDD0BCC: sm_performSaveYourself(QSessionManagerPrivate*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDD0ED4: sm_saveYourselfCallback(_SmcConn*, void*, int, int, int, int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x4F6BAE: _SmcProcessMessage (in /usr/X11R6/lib/libSM.so.6.0) ==7693== by 0x510CBA: IceProcessMessages (in /usr/X11R6/lib/libICE.so.6.3) ==7693== by 0x1CDC100B: QSmSocketReceiver::socketActivated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CDC10E9: QSmSocketReceiver::qt_metacall(QMetaObject::Call, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA60AB4: QMetaObject::activate(QObject*, int, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA60CB0: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA87DC2: QSocketNotifier::activated(int) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA6C026: QSocketNotifier::event(QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD60741: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1CD60A8B: QApplication::notify(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1C5DA78A: KApplication::notify(QObject*, QEvent*) (in /home/kde4/dist/lib/libkdeui.so.5.0.0) ==7693== by 0x1BA4D111: QCoreApplication::notifyInternal(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA510B4: QCoreApplication::sendEvent(QObject*, QEvent*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA78E34: socketNotifierSourceDispatch(_GSource*, int (*)(void*), void*) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x6543ED: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6573F5: (within /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x6578D7: g_main_context_iteration (in /usr/lib/libglib-2.0.so.0.600.4) ==7693== by 0x1BA78CB2: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CDF688E: QGuiEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x1BA4BF9B: QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA4C236: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1BA50E54: QCoreApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtCore.so.4.3.0) ==7693== by 0x1CD5FBB4: QApplication::exec() (in /home/kde4/celerysvn/qt-copy/lib/libQtGui.so.4.3.0) ==7693== by 0x80C080C: main (in /home/kde4/dist/bin/kolourpaint) ==7693== ==7693== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 154 from 4) ==7693== malloc/free: in use at exit: 2757301 bytes in 55478 blocks. ==7693== malloc/free: 261781 allocs, 206303 frees, 175132418 bytes allocated. ==7693== For counts of detected errors, rerun with: -v ==7693== searching for pointers to 55478 not-freed blocks. ==7693== checked 4074156 bytes. ==7693== ==7693== LEAK SUMMARY: ==7693== definitely lost: 268 bytes in 3 blocks. ==7693== possibly lost: 70748 bytes in 2322 blocks. ==7693== still reachable: 2686285 bytes in 53153 blocks. ==7693== suppressed: 0 bytes in 0 blocks. ==7693== Use --leak-check=full to see details of leaked memory. M +4 -1 NEWS M +4 -0 kolourpaint.cpp M +15 -0 kpDefs.h M +170 -3 mainwindow/kpMainWindow.cpp M +26 -1 mainwindow/kpMainWindow.h M +38 -20 mainwindow/kpMainWindow_File.cpp --- branches/work/~dang/kdegraphics/kolourpaint/NEWS #664227:664228 @@ -14,6 +14,9 @@ * Add "File / Scan..." feature (Martin Koller) [also in branches/KDE/3.5/] + * Add global session save/restore (Bug #94651) + [also in branches/KDE/3.5/] + * Rectangles, rounded rectangles and ellipsed are now bounded by the dimensions of the dragged out rectangle @@ -27,7 +30,7 @@ (Bug #125116) * Fix crash triggered by rapidly deselecting a selection after - drag-scaling the selection (Bug 117866) + drag-scaling the selection (Bug #117866) [also in branches/KDE/3.[345]/, branches/kolourpaint/1.2_kde3/] * Add "Rotate 90 Degrees Counterclockwise" (CTRL+L) and --- branches/work/~dang/kdegraphics/kolourpaint/kolourpaint.cpp #664227:664228 @@ -203,7 +203,11 @@ if (app.isSessionRestored ()) + { + // Creates a kpMainWindow using the default constructor and then + // calls kpMainWindow::readProperties(). RESTORE (kpMainWindow) + } else { kpMainWindow *mainWindow; --- branches/work/~dang/kdegraphics/kolourpaint/kpDefs.h #664227:664228 @@ -133,5 +133,20 @@ #define kpSettingFlattenEffectColor2 QString::fromLatin1 ("Color2") +// +// Session Restore Setting +// + +// URL of the document in the main window. +// +// This key only exists if the document does. If it exists, it can be empty. +// The URL need not point to a file that exists e.g. "kolourpaint doesnotexist.png". +#define kpSessionSettingDocumentUrl QString::fromLatin1 ("Session Document Url") + +// The size of a document which is not from a URL e.g. "kolourpaint doesnotexist.png". +// This key does not exist for documents from URLs. +#define kpSessionSettingNotFromUrlDocumentSize QString::fromLatin1 ("Session Not-From-Url Document Size") + + #endif // KP_DEFS_H --- branches/work/~dang/kdegraphics/kolourpaint/mainwindow/kpMainWindow.cpp #664227:664228 @@ -42,6 +42,7 @@ #include <kmessagebox.h> #include <krecentfilesaction.h> #include <kconfiggroup.h> + #include <kpColorToolBar.h> #include <kpCommandHistory.h> #include <kpDefs.h> @@ -114,7 +115,7 @@ void kpMainWindow::readGeneralSettings () { #if DEBUG_KP_MAIN_WINDOW - kDebug () << "\tkpMainWindow(" << name () << ")::readGeneralSettings()" << endl; + kDebug () << "\tkpMainWindow(" << objectName () << ")::readGeneralSettings()" << endl; #endif KConfigGroup cfg (KGlobal::config (), kpSettingsGroupGeneral); @@ -162,7 +163,7 @@ void kpMainWindow::readThumbnailSettings () { #if DEBUG_KP_MAIN_WINDOW - kDebug () << "\tkpMainWindow(" << name () << ")::readThumbnailSettings()" << endl; + kDebug () << "\tkpMainWindow(" << objectName () << ")::readThumbnailSettings()" << endl; #endif KConfigGroup cfg (KGlobal::config (), kpSettingsGroupThumbnail); @@ -185,7 +186,7 @@ void kpMainWindow::init () { #if DEBUG_KP_MAIN_WINDOW - kDebug () << "kpMainWindow(" << name () << ")::init()" << endl; + kDebug () << "kpMainWindow(" << objectName () << ")::init()" << endl; QTime totalTime; totalTime.start (); QTime time; time.start (); #endif @@ -328,6 +329,172 @@ #endif } + +// private virtual [base KMainWindow] +void kpMainWindow::readProperties (const KConfigGroup &configGroup) +{ +#if DEBUG_KP_MAIN_WINDOW + kDebug () << "kpMainWindow<" << this << ">::readProperties()" << endl; +#endif + + // No document at all? + if (!configGroup.hasKey (kpSessionSettingDocumentUrl)) + { + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\tno url - no document" << endl; + #endif + setDocument (0); + } + // Have a document. + else + { + const KUrl url = configGroup.readEntry (kpSessionSettingDocumentUrl, + QString ()); + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\turl=" << url << endl; + #endif + + const QSize notFromURLDocSize = + configGroup.readEntry (kpSessionSettingNotFromUrlDocumentSize, + QSize ()); + + // Is from URL? + if (notFromURLDocSize.isEmpty ()) + { + // If this fails, the empty document that kpMainWindow::kpMainWindow() + // created is left untouched. + openInternal (url, defaultDocSize (), + false/*show error message if url !exist*/); + } + // Not from URL? + else + { + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\tnot from url; doc size=" << notFromURLDocSize << endl; + #endif + // Either we have an empty URL or we have a "kolourpaint doesnotexist.png" + // URL. Regarding the latter case, if a file now actually exists at that + // URL, we do open it - ignoring notFromURLDocSize - to avoid putting + // the user in a situation where he might accidentally overwrite an + // existing file. + openInternal (url, notFromURLDocSize, + true/*create an empty doc with the same url if url !exist*/); + } + } + +} + +// private virtual [base KMainWindow] +// WARNING: KMainWindow API Doc says "No user interaction is allowed +// in this function!" +void kpMainWindow::saveProperties (KConfigGroup &configGroup) +{ +#if DEBUG_KP_MAIN_WINDOW + kDebug () << "kpMainWindow<" << this << ">::saveProperties()" << endl; +#endif + + // No document at all? + if (!m_document) + { + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\tno url - no document" << endl; + #endif + } + // Have a document. + else + { + // Save URL in all cases: + // + // a) m_document->isFromURL() + // b) !m_document->isFromURL() [save size in this case] + // i) No URL + // ii) URL (from "kolourpaint doesnotexist.png") + + const KUrl url = m_document->url (); + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\turl=" << url << endl; + #endif + configGroup.writeEntry (kpSessionSettingDocumentUrl, url.url ()); + + // Not from URL e.g. "kolourpaint doesnotexist.png"? + // + // Note that "kolourpaint doesexist.png" is considered to be from + // a URL even if it was deleted in the background (hence the + // "false" arg to isFromURL()). This is because the user expects + // it to be from a URL, so when we session restore, we pop up a + // "cannot find file" dialog, instead of silently creating a new, + // blank document. + if (!m_document->isFromURL (false/*don't bother checking exists*/)) + { + // If we don't have a URL either: + // + // a) it was not modified - so we can use either width() or + // constructorWidth() (they'll be equal). + // b) the changes were discarded so we use the initial width, + // constructorWidth(). + // + // Similarly for height() and constructorHeight(). + const QSize docSize (m_document->constructorWidth (), + m_document->constructorHeight ()); + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\tnot from url; doc size=" << docSize << endl; + #endif + configGroup.writeEntry (kpSessionSettingNotFromUrlDocumentSize, docSize); + } + + + // Local session save i.e. queryClose() was not called beforehand + // (see QApplication::saveState())? + #if 0 + if (m_document->isModified ()) + { + // TODO: Implement by saving the current image to a persistent file. + // We do this instead of saving/mutating the backing image file + // as no one expects a file save on a session save without a + // "do you want to save" dialog first. + // + // I don't think any KDE application implements local session saving. + // + // --- The below code does not compile but shows you want to do --- + + // Create unique name for the document in this main window. + const KUrl tempURL = homeDir + + "kolourpaint session " + sessionID + + mainWindowPtrToString + ".png"; + // TODO: Use lossless PNG saving options. + kpDocumentSaveOptions pngSaveOptions; + + if (kpDocument::savePixmapToFile (m_document->pixmapWithSelection (), + tempURL, + pngSaveOptions, *m_document->metaInfo (), + false/*no overwrite prompt*/, + false/*no lossy prompt*/, + this)) + { + // readProperties() will still open kpSessionSettingDocumentUrl + // (as that's the expected URL) and will then add commands to: + // + // 1. Resize the document to the size of image at + // kpSessionSettingDocumentUnsavedContentsUrl, if the sizes + // differ. + // 2. Paste the kpSessionSettingDocumentUnsavedContentsUrl image + // (setting the main window's selection mode to opaque beforehand). + // + // It will then delete the file at + // kpSessionSettingDocumentUnsavedContentsUrl. + configGroup.writeEntry (kpSessionSettingDocumentUnsavedContentsUrl, + tempURL.url ()); + } + else + { + // Not much we can do - we aren't allowed to throw up a dialog. + } + } + #endif + } +} + + kpMainWindow::~kpMainWindow () { m_isFullyConstructed = false; --- branches/work/~dang/kdegraphics/kolourpaint/mainwindow/kpMainWindow.h #664227:664228 @@ -44,6 +44,7 @@ #include <kpPixmapFX.h> +class QAction; class QActionGroup; class QDragEnterEvent; class QDropEvent; @@ -57,7 +58,7 @@ class QStringList; class QUrl; -class QAction; +class KConfigGroup; class KFontAction; class KFontSizeAction; class KSelectAction; @@ -124,6 +125,15 @@ void readThumbnailSettings (); void init (); + // (only called for restoring a previous session e.g. starting KDE with + // a previously saved session; it's not called on normal KolourPaint + // startup) + virtual void readProperties (const KConfigGroup &configGroup); + // (only called for saving the current session e.g. logging out of KDE + // with the KolourPaint window open; it's not called on normal KolourPaint + // exit) + virtual void saveProperties (KConfigGroup &configGroup); + public: ~kpMainWindow (); @@ -314,7 +324,22 @@ void setDocumentChoosingWindow (kpDocument *doc); private: + kpDocument *openInternal (const KUrl &url, + const QSize &fallbackDocSize, + bool newDocSameNameIfNotExist); + // Same as above except that it: + // + // 1. Assumes a default fallback document size. + // 2. If the URL is successfully opened (with the special exception of + // the "kolourpaint doesnotexist.png" case), it is bubbled up to the + // top in the Recent Files Action. + // + // As a result of this behavior, this should only be called in response + // to a user open request e.g. File / Open or "kolourpaint doesexist.png". + // It should not be used for session restore - in that case, it does not + // make sense to bubble the Recent Files list. bool open (const KUrl &url, bool newDocSameNameIfNotExist = false); + KUrl::List askForOpenURLs (const QString &caption, const QString &startURL, bool allowMultipleURLs = true); --- branches/work/~dang/kdegraphics/kolourpaint/mainwindow/kpMainWindow_File.cpp #664227:664228 @@ -331,6 +331,38 @@ // private +kpDocument *kpMainWindow::openInternal (const KUrl &url, + const QSize &fallbackDocSize, + bool newDocSameNameIfNotExist) +{ + // If using OpenImagesInSameWindow mode, ask whether to close the + // current document. + if (!shouldOpen ()) + return 0; + + // Create/open doc. + kpDocument *newDoc = new kpDocument (fallbackDocSize.width (), + fallbackDocSize.height (), + this); + if (!newDoc->open (url, newDocSameNameIfNotExist)) + { + #if DEBUG_KP_MAIN_WINDOW + kDebug () << "\topen failed" << endl; + #endif + delete newDoc; + return 0; + } + +#if DEBUG_KP_MAIN_WINDOW + kDebug () << "\topen OK" << endl; +#endif + // Send document to current or new window. + setDocumentChoosingWindow (newDoc); + + return newDoc; +} + +// private bool kpMainWindow::open (const KUrl &url, bool newDocSameNameIfNotExist) { #if DEBUG_KP_MAIN_WINDOW @@ -339,37 +371,23 @@ << ")" << endl; #endif - // If using OpenImagesInSameWindow mode, ask whether to close the - // current document. - if (!shouldOpen ()) - return false; - - // Create/open doc. - const QSize docSize = defaultDocSize (); - kpDocument *newDoc = new kpDocument (docSize.width (), docSize.height (), this); - if (newDoc->open (url, newDocSameNameIfNotExist)) + kpDocument *newDoc = openInternal (url, + defaultDocSize (), + newDocSameNameIfNotExist); + if (newDoc) { - #if DEBUG_KP_MAIN_WINDOW - kDebug () << "\topen OK" << endl; - #endif if (newDoc->isFromURL (false/*don't bother checking exists*/)) addRecentURL (url); } else { - #if DEBUG_KP_MAIN_WINDOW - kDebug () << "\topen failed" << endl; - #endif - delete newDoc; return false; } - - // Send document to current or new window. - setDocumentChoosingWindow (newDoc); - + return true; } + // private KUrl::List kpMainWindow::askForOpenURLs (const QString &caption, const QString &startURL, bool allowMultipleURLs)