mirror of
https://invent.kde.org/graphics/okular
synced 2024-07-05 00:58:46 +00:00
Fallback behavior for documents whose generator provides native annotation editing support without saveAs support
The only affected generator is poppler. Note that: Document has /Encrypt <=iff=> SaveInterface supportsOption(SaveChanges) is false This patch enforces the following behavior (and warns the user the first time he edits an annotation). - If the document has /Encrypt, warn that "Save as" is not available, but it's possible to export as okular archive. New annotations will be automatically saved to XML as usual. Note that the previous patch already made all existing annotations uneditable, because there's no way to save them. - If the document has no /Encrypt and there are existing external annotations, warn that changes won't be saved automatically. The user needs to "Save as" or changes will be lost. - If the document has no /Encrypt and there aren't existing external annotations, don't show any warning. New annotations will be automatically saved to XML as usual and to file if "Save as" is pressed.
This commit is contained in:
parent
b33d71ef81
commit
b3782d82a1
|
@ -771,6 +771,24 @@ DocumentViewport DocumentPrivate::nextDocumentViewport() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
void DocumentPrivate::warnLimitedAnnotSupport()
|
||||
{
|
||||
if ( !m_showWarningLimitedAnnotSupport )
|
||||
return;
|
||||
m_showWarningLimitedAnnotSupport = false; // Show the warning once
|
||||
|
||||
if ( canAddAnnotationsNatively() )
|
||||
{
|
||||
// Show only if there are external annotations (we follow the usual XML path otherwise)
|
||||
if ( m_containsExternalAnnotations )
|
||||
KMessageBox::sorry( m_parent->widget(), i18n("Your changes will not be saved automatically. Use File -> Save As... or your changes will be lost") );
|
||||
}
|
||||
else
|
||||
{
|
||||
KMessageBox::information( m_parent->widget(), i18n("You can save the annotated document using File -> Export As -> Document Archive"), QString(), "annotExportAsArchive" );
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentPrivate::saveDocumentInfo() const
|
||||
{
|
||||
if ( m_xmlFileName.isEmpty() )
|
||||
|
@ -791,10 +809,13 @@ void DocumentPrivate::saveDocumentInfo() const
|
|||
// 2.1. Save page attributes (bookmark state, annotations, ... ) to DOM
|
||||
QDomElement pageList = doc.createElement( "pageList" );
|
||||
root.appendChild( pageList );
|
||||
PageItems saveWhat = AllPageItems;
|
||||
if ( canAddAnnotationsNatively() && m_containsExternalAnnotations )
|
||||
saveWhat &= ~AnnotationPageItems; // Don't save local annotations in this case
|
||||
// <page list><page number='x'>.... </page> save pages that hold data
|
||||
QVector< Page * >::const_iterator pIt = m_pagesVector.constBegin(), pEnd = m_pagesVector.constEnd();
|
||||
for ( ; pIt != pEnd; ++pIt )
|
||||
(*pIt)->d->saveLocalContents( pageList, doc );
|
||||
(*pIt)->d->saveLocalContents( pageList, doc, saveWhat );
|
||||
|
||||
// 2.2. Save document info (current viewport, history, ... ) to DOM
|
||||
QDomElement generalInfo = doc.createElement( "generalInfo" );
|
||||
|
@ -1657,12 +1678,16 @@ bool Document::openDocument( const QString & docFile, const KUrl& url, const KMi
|
|||
}
|
||||
|
||||
d->m_generatorName = offer->name();
|
||||
d->m_containsExternalAnnotations = false;
|
||||
d->m_showWarningLimitedAnnotSupport = true;
|
||||
foreach ( Page * p, d->m_pagesVector )
|
||||
{
|
||||
p->d->m_doc = d;
|
||||
if ( !p->annotations().empty() )
|
||||
d->m_containsExternalAnnotations = true;
|
||||
}
|
||||
|
||||
// 2. load Additional Data (our bookmarks and metadata) about the document
|
||||
// 2. load Additional Data (bookmarks, local annotations and metadata) about the document
|
||||
if ( d->m_archiveData )
|
||||
{
|
||||
d->loadDocumentInfo( d->m_archiveData->metadataFileName );
|
||||
|
@ -2358,6 +2383,8 @@ void Document::addPageAnnotation( int page, Annotation * annotation )
|
|||
// Redraw everything, including ExternallyDrawn annotations
|
||||
d->refreshPixmaps( page );
|
||||
}
|
||||
|
||||
d->warnLimitedAnnotSupport();
|
||||
}
|
||||
|
||||
bool Document::canModifyPageAnnotation( const Annotation * annotation ) const
|
||||
|
@ -2426,6 +2453,10 @@ void Document::modifyPageAnnotation( int page, Annotation * annotation, bool app
|
|||
// Redraw everything, including ExternallyDrawn annotations
|
||||
d->refreshPixmaps( page );
|
||||
}
|
||||
|
||||
// If the user is moving the annotation, don't steal the focus
|
||||
if ( (annotation->flags() & Annotation::BeingMoved) == 0 )
|
||||
d->warnLimitedAnnotSupport();
|
||||
}
|
||||
|
||||
bool Document::canRemovePageAnnotation( const Annotation * annotation ) const
|
||||
|
@ -2484,6 +2515,8 @@ void Document::removePageAnnotation( int page, Annotation * annotation )
|
|||
d->refreshPixmaps( page );
|
||||
}
|
||||
}
|
||||
|
||||
d->warnLimitedAnnotSupport();
|
||||
}
|
||||
|
||||
void Document::removePageAnnotations( int page, const QList< Annotation * > &annotations )
|
||||
|
@ -2530,6 +2563,19 @@ void Document::removePageAnnotations( int page, const QList< Annotation * > &ann
|
|||
d->refreshPixmaps( page );
|
||||
}
|
||||
}
|
||||
|
||||
d->warnLimitedAnnotSupport();
|
||||
}
|
||||
|
||||
bool DocumentPrivate::canAddAnnotationsNatively() const
|
||||
{
|
||||
Okular::SaveInterface * iface = qobject_cast< Okular::SaveInterface * >( m_generator );
|
||||
|
||||
if ( iface && iface->supportsOption(Okular::SaveInterface::SaveChanges) &&
|
||||
iface->annotationProxy() && iface->annotationProxy()->supports(AnnotationProxy::Addition) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DocumentPrivate::canModifyExternalAnnotations() const
|
||||
|
@ -3608,8 +3654,32 @@ bool Document::saveDocumentArchive( const QString &fileName )
|
|||
filesNode.appendChild( metadataFileNameNode );
|
||||
metadataFileNameNode.appendChild( contentDoc.createTextNode( "metadata.xml" ) );
|
||||
|
||||
// If the generator can save annotations natively, do it
|
||||
KTemporaryFile modifiedFile;
|
||||
bool annotationsSavedNatively = false;
|
||||
if ( d->canAddAnnotationsNatively() )
|
||||
{
|
||||
if ( !modifiedFile.open() )
|
||||
return false;
|
||||
|
||||
modifiedFile.close(); // We're only interested in the file name
|
||||
|
||||
QString errorText;
|
||||
if ( saveChanges( modifiedFile.fileName(), &errorText ) )
|
||||
{
|
||||
docPath = modifiedFile.fileName(); // Save this instead of the original file
|
||||
annotationsSavedNatively = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
kWarning(OkularDebug) << "saveChanges failed: " << errorText;
|
||||
kDebug(OkularDebug) << "Falling back to saving a copy of the original file";
|
||||
}
|
||||
}
|
||||
|
||||
KTemporaryFile metadataFile;
|
||||
if ( !d->savePageDocumentInfo( &metadataFile, AnnotationPageItems ) )
|
||||
PageItems saveWhat = annotationsSavedNatively ? None : AnnotationPageItems;
|
||||
if ( !d->savePageDocumentInfo( &metadataFile, saveWhat ) )
|
||||
return false;
|
||||
|
||||
const QByteArray contentDocXml = contentDoc.toByteArray();
|
||||
|
|
|
@ -115,8 +115,10 @@ class DocumentPrivate
|
|||
bool openDocumentInternal( const KService::Ptr& offer, bool isstdin, const QString& docFile, const QByteArray& filedata );
|
||||
bool savePageDocumentInfo( KTemporaryFile *infoFile, int what ) const;
|
||||
DocumentViewport nextDocumentViewport() const;
|
||||
bool canAddAnnotationsNatively() const;
|
||||
bool canModifyExternalAnnotations() const;
|
||||
bool canRemoveExternalAnnotations() const;
|
||||
void warnLimitedAnnotSupport();
|
||||
|
||||
// private slots
|
||||
void saveDocumentInfo() const;
|
||||
|
@ -232,6 +234,8 @@ class DocumentPrivate
|
|||
QSet< View * > m_views;
|
||||
|
||||
bool m_annotationBeingMoved; // is an annotation currently being moved?
|
||||
bool m_containsExternalAnnotations; // set on opening and never changed
|
||||
bool m_showWarningLimitedAnnotSupport;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user