diff --git a/gemini/DocumentManager.cpp b/gemini/DocumentManager.cpp --- a/gemini/DocumentManager.cpp +++ b/gemini/DocumentManager.cpp @@ -100,6 +100,7 @@ d->part = part; d->temporaryFile = false; emit documentChanged(); + connect(document, SIGNAL(destroyed()), SIGNAL(aboutToDeleteDocument())); } RecentFileManager* DocumentManager::recentFileManager() const @@ -147,6 +148,7 @@ d->document->setProgressProxy(d->proxy); d->document->setSaveInBatchMode(true); part()->setDocument(d->document); + connect(d->document, SIGNAL(destroyed()), SIGNAL(aboutToDeleteDocument())); if(d->newDocOptions.isEmpty()) { @@ -193,7 +195,7 @@ closeDocument(); d->openDocumentFilename = document; d->importingDocument = import; - QTimer::singleShot(300, this, SLOT(delayedOpenDocument())); + QTimer::singleShot(0, this, SLOT(delayedOpenDocument())); } void DocumentManager::delayedOpenDocument() @@ -224,9 +226,8 @@ void DocumentManager::closeDocument() { if (d->document) { - emit aboutToDeleteDocument(); d->document->closeUrl(false); - //d->document->deleteLater(); + delete d->document; d->document = 0; } } @@ -251,7 +252,7 @@ // the save call happens late enough for a variety of UI things to happen first. // A second seems like a long time, but well, we do have file system interaction here, // so for now, we can get away with it. - QTimer::singleShot(300, this, SLOT(delayedSaveAs())); + QTimer::singleShot(0, this, SLOT(delayedSaveAs())); } void DocumentManager::delayedSaveAs() diff --git a/gemini/MainWindow.cpp b/gemini/MainWindow.cpp --- a/gemini/MainWindow.cpp +++ b/gemini/MainWindow.cpp @@ -310,6 +310,7 @@ connect(DocumentManager::instance(), SIGNAL(documentChanged()), SLOT(resetWindowTitle())); connect(DocumentManager::instance(), SIGNAL(documentSaved()), SLOT(resetWindowTitle())); connect(DocumentManager::instance(), SIGNAL(documentSaved()), SLOT(enableAltSaveAction())); + connect(DocumentManager::instance(), SIGNAL(aboutToDeleteDocument()), SLOT(closeWindow())); d->initTouchView(this); @@ -326,14 +327,16 @@ void MainWindow::resetWindowTitle() { - QUrl url = DocumentManager::instance()->document()->url(); + KoDocument* document = DocumentManager::instance()->document(); + if (!document) + return; + QUrl url = document->url(); QString fileName = url.fileName(); if(url.scheme() == "temp" || url.isEmpty()) fileName = i18n("Untitled"); KoDialog::CaptionFlags flags = KoDialog::HIGCompliantCaption; - KoDocument* document = DocumentManager::instance()->document(); - if (document && document->isModified() ) { + if ( document->isModified() ) { flags |= KoDialog::ModifiedCaption; } @@ -367,16 +370,14 @@ } d->syncObject = new ViewModeSynchronisationObject; - KoView* view = 0; if (d->desktopView && centralWidget() == d->desktopView) { - view = d->desktopView->rootView(); - - //Notify the view we are switching away from that we are about to switch away from it - //giving it the possibility to set up the synchronisation object. - ViewModeSwitchEvent aboutToSwitchEvent(ViewModeSwitchEvent::AboutToSwitchViewModeEvent, view, d->touchView, d->syncObject); - QApplication::sendEvent(view, &aboutToSwitchEvent); - + if (KoView* view = d->desktopView->rootView()) { + //Notify the view we are switching away from that we are about to switch away from it + //giving it the possibility to set up the synchronisation object. + ViewModeSwitchEvent aboutToSwitchEvent(ViewModeSwitchEvent::AboutToSwitchViewModeEvent, view, d->touchView, d->syncObject); + QApplication::sendEvent(view, &aboutToSwitchEvent); + } d->desktopView->setParent(0); } @@ -440,6 +441,10 @@ view = d->desktopView->rootView(); } + if (!view) { + return; + } + //Notify the view we are switching away from that we are about to switch away from it //giving it the possibility to set up the synchronisation object. ViewModeSwitchEvent aboutToSwitchEvent(ViewModeSwitchEvent::AboutToSwitchViewModeEvent, d->touchView, view, syncObject); @@ -453,12 +458,10 @@ setCentralWidget(d->desktopView); } - if (view) { - //Notify the new view that we just switched to it, passing our synchronisation object - //so it can use those values to sync with the old view. - ViewModeSwitchEvent switchedEvent(ViewModeSwitchEvent::SwitchedToDesktopModeEvent, d->touchView, view, syncObject); - QApplication::sendEvent(view, &switchedEvent); - } + //Notify the new view that we just switched to it, passing our synchronisation object + //so it can use those values to sync with the old view. + ViewModeSwitchEvent switchedEvent(ViewModeSwitchEvent::SwitchedToDesktopModeEvent, d->touchView, view, syncObject); + QApplication::sendEvent(view, &switchedEvent); qApp->processEvents(); d->toTouch->setEnabled(true); @@ -714,13 +717,18 @@ void MainWindow::closeWindow() { - d->desktopView->setNoCleanup(true); - //For some reason, close() does not work even if setAllowClose(true) was called just before this method. - //So instead just completely quit the application, since we are using a single window anyway. - DocumentManager::instance()->closeDocument(); - DocumentManager::instance()->part()->deleteLater(); - qApp->processEvents(); - QApplication::instance()->quit(); + if (d->desktopView) { + d->desktopView->setNoCleanup(true); + if (centralWidget() == d->desktopView) + d->allowClose = d->queryClose(); + } + + if (d->allowClose) + { + d->altSaveQuery(); + d->settings->setCurrentFile(""); + } + qApp->quit(); } bool MainWindow::Private::queryClose() @@ -768,7 +776,6 @@ void MainWindow::Private::altSaveQuery() { - qApp->processEvents(); if(alternativeSaveAction && alternativeSaveAction->isEnabled()) { int res = KMessageBox::warningYesNo(q, i18n("

The cloud copy of the document is out of date. Do you want to upload a new copy?

")); @@ -791,29 +798,15 @@ { if (centralWidget() == d->desktopView) { - if (DocumentManager::instance()->document()->isLoading()) { + KoDocument* document = DocumentManager::instance()->document(); + if (document && document->isLoading()) { event->ignore(); return; } - d->allowClose = d->queryClose(); } - if (d->allowClose) - { - d->altSaveQuery(); - d->settings->setCurrentFile(""); - qApp->processEvents(); - if (d->desktopView) - { - d->desktopView->setNoCleanup(true); - } - event->accept(); - } - else - { - event->ignore(); - emit closeRequested(); - } + event->accept(); + closeWindow(); } MainWindow::~MainWindow() diff --git a/gemini/desktopviewproxy.cpp b/gemini/desktopviewproxy.cpp --- a/gemini/desktopviewproxy.cpp +++ b/gemini/desktopviewproxy.cpp @@ -142,10 +142,12 @@ { if(DocumentManager::instance()->isTemporaryFile()) { if(d->desktopView->saveDocument(true)) { - DocumentManager::instance()->recentFileManager()->addRecent(DocumentManager::instance()->document()->url().toLocalFile()); - DocumentManager::instance()->settingsManager()->setCurrentFile(DocumentManager::instance()->document()->url().toLocalFile()); - DocumentManager::instance()->setTemporaryFile(false); - emit documentSaved(); + if (KoDocument* document = DocumentManager::instance()->document()) { + DocumentManager::instance()->recentFileManager()->addRecent(document->url().toLocalFile()); + DocumentManager::instance()->settingsManager()->setCurrentFile(document->url().toLocalFile()); + DocumentManager::instance()->setTemporaryFile(false); + emit documentSaved(); + } } } else { DocumentManager::instance()->save(); @@ -155,15 +157,19 @@ bool DesktopViewProxy::fileSaveAs() { + KoDocument* document = DocumentManager::instance()->document(); + if (!document) + return false; + if(d->desktopView->saveDocument(true)) { - DocumentManager::instance()->recentFileManager()->addRecent(DocumentManager::instance()->document()->url().toLocalFile()); - DocumentManager::instance()->settingsManager()->setCurrentFile(DocumentManager::instance()->document()->url().toLocalFile()); + DocumentManager::instance()->recentFileManager()->addRecent(document->url().toLocalFile()); + DocumentManager::instance()->settingsManager()->setCurrentFile(document->url().toLocalFile()); DocumentManager::instance()->setTemporaryFile(false); emit documentSaved(); return true; } - DocumentManager::instance()->settingsManager()->setCurrentFile(DocumentManager::instance()->document()->url().toLocalFile()); + DocumentManager::instance()->settingsManager()->setCurrentFile(document->url().toLocalFile()); return false; } diff --git a/libs/main/KoMainWindow.cpp b/libs/main/KoMainWindow.cpp --- a/libs/main/KoMainWindow.cpp +++ b/libs/main/KoMainWindow.cpp @@ -175,7 +175,7 @@ QByteArray nativeMimeType; KoMainWindow *parent; - KoDocument *rootDocument; + QPointer rootDocument; QList rootViews; // PartManager @@ -706,7 +706,7 @@ { if (d->rootViews.indexOf(d->activeView) != -1) return d->activeView; - return d->rootViews.first(); + return d->rootViews.empty() ? nullptr : d->rootViews.first(); } bool KoMainWindow::openDocument(const QUrl &url) diff --git a/libs/main/KoPart.cpp b/libs/main/KoPart.cpp --- a/libs/main/KoPart.cpp +++ b/libs/main/KoPart.cpp @@ -57,28 +57,25 @@ Private(const KoComponentData &componentData_, KoPart *_parent) : parent(_parent) , document(0) - , canvasItem(0) + , proxyWidget(0) , startUpWidget(0) , componentData(componentData_) { } ~Private() { - /// FIXME ok, so this is obviously bad to leave like this - // For now, this is undeleted, but only to avoid an odd double - // delete condition. Until that's discovered, we'll need this - // to avoid crashes in Gemini - //delete canvasItem; + if (proxyWidget) + proxyWidget->deleteLater(); } KoPart *parent; QList views; QList mainWindows; KoDocument *document; QList documents; - QGraphicsItem *canvasItem; + QPointer proxyWidget; QPointer startUpWidget; QString templatesResourcePath; @@ -186,19 +183,19 @@ QGraphicsItem *KoPart::canvasItem(KoDocument *document, bool create) { - if (create && !d->canvasItem) { - d->canvasItem = createCanvasItem(document); + if (create && !d->proxyWidget) { + return createCanvasItem(document); } - return d->canvasItem; + return d->proxyWidget; } QGraphicsItem *KoPart::createCanvasItem(KoDocument *document) { KoView *view = createView(document); - QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(); + d->proxyWidget = new QGraphicsProxyWidget(); QWidget *canvasController = view->findChild(); - proxy->setWidget(canvasController); - return proxy; + d->proxyWidget->setWidget(canvasController); + return d->proxyWidget; } void KoPart::addMainWindow(KoMainWindow *mainWindow) diff --git a/words/part/KWPageManager.cpp b/words/part/KWPageManager.cpp --- a/words/part/KWPageManager.cpp +++ b/words/part/KWPageManager.cpp @@ -431,7 +431,7 @@ KWPage KWPageManager::begin() { - if (d->pages.isEmpty()) + if (d->pages.isEmpty() || d->pageNumbers.empty()) return KWPage(); return KWPage(d, d->pageNumbers.begin().value()); }