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:
Fabio D'Urso 2012-05-14 15:51:58 +02:00 committed by Albert Astals Cid
parent b33d71ef81
commit b3782d82a1
2 changed files with 77 additions and 3 deletions

View File

@ -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();

View File

@ -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;
};
}