| 4950 | } |
| 4951 | |
| 4952 | bool Document::swapBackingFile(const QString &newFileName, const QUrl &url) |
| 4953 | { |
| 4954 | if (!d->m_generator) { |
| 4955 | return false; |
| 4956 | } |
| 4957 | |
| 4958 | if (!d->m_generator->hasFeature(Generator::SwapBackingFile)) { |
| 4959 | return false; |
| 4960 | } |
| 4961 | |
| 4962 | // Save metadata about the file we're about to close |
| 4963 | d->saveDocumentInfo(); |
| 4964 | |
| 4965 | d->clearAndWaitForRequests(); |
| 4966 | |
| 4967 | qCDebug(OkularCoreDebug) << "Swapping backing file to" << newFileName; |
| 4968 | QList<Page *> newPagesVector; |
| 4969 | Generator::SwapBackingFileResult result = d->m_generator->swapBackingFile(newFileName, newPagesVector); |
| 4970 | if (result != Generator::SwapBackingFileError) { |
| 4971 | QList<ObjectRect *> rectsToDelete; |
| 4972 | QList<Annotation *> annotationsToDelete; |
| 4973 | QSet<PagePrivate *> pagePrivatesToDelete; |
| 4974 | |
| 4975 | if (result == Generator::SwapBackingFileReloadInternalData) { |
| 4976 | // Here we need to replace everything that the old generator |
| 4977 | // had created with what the new one has without making it look like |
| 4978 | // we have actually closed and opened the file again |
| 4979 | |
| 4980 | // Simple sanity check |
| 4981 | if (newPagesVector.count() != d->m_pagesVector.count()) { |
| 4982 | return false; |
| 4983 | } |
| 4984 | |
| 4985 | // Update the undo stack contents |
| 4986 | for (int i = 0; i < d->m_undoStack->count(); ++i) { |
| 4987 | // Trust me on the const_cast ^_^ |
| 4988 | QUndoCommand *uc = const_cast<QUndoCommand *>(d->m_undoStack->command(i)); |
| 4989 | if (OkularUndoCommand *ouc = dynamic_cast<OkularUndoCommand *>(uc)) { |
| 4990 | const bool success = ouc->refreshInternalPageReferences(newPagesVector); |
| 4991 | if (!success) { |
| 4992 | qWarning() << "Document::swapBackingFile: refreshInternalPageReferences failed" << ouc; |
| 4993 | return false; |
| 4994 | } |
| 4995 | } else { |
| 4996 | qWarning() << "Document::swapBackingFile: Unhandled undo command" << uc; |
| 4997 | return false; |
| 4998 | } |
| 4999 | } |
| 5000 | |
| 5001 | for (int i = 0; i < d->m_pagesVector.count(); ++i) { |
| 5002 | // switch the PagePrivate* from newPage to oldPage |
| 5003 | // this way everyone still holding Page* doesn't get |
| 5004 | // disturbed by it |
| 5005 | Page *oldPage = d->m_pagesVector[i]; |
| 5006 | Page *newPage = newPagesVector[i]; |
| 5007 | newPage->d->adoptGeneratedContents(oldPage->d); |
| 5008 | |
| 5009 | pagePrivatesToDelete << oldPage->d; |
no test coverage detected