diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-21 15:31:21 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-21 15:47:24 +0100 |
commit | fdacaab2485fa42648ae96348b9ad6a9e1f49424 (patch) | |
tree | b77c47d8bec671b40934f0fb57ca96e921a0ccf0 | |
parent | 706893eb2d737e1475945f4204f95b7382992240 (diff) |
DOCX import: implement progressbar
The design follows what we do in case of ODT import already: read the
number of paragraphs from the document statistics metadata, and then
estimate progress based on the number of already imported paragraphs.
Change-Id: I042cc6014c05ca7456fdf1c8d7247b615ba3a244
-rw-r--r-- | writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/filter/ImportFilter.cxx | 3 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 62 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 13 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 2 |
5 files changed, 75 insertions, 8 deletions
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 4bbc31bacda1..7f104ab6aa6a 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <resourcemodel/WW8ResourceModel.hxx> +#include <com/sun/star/task/XStatusIndicator.hpp> #include <com/sun/star/xml/sax/XParser.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp> @@ -269,7 +270,7 @@ public: createStream(OOXMLStream::Pointer_t pStream, const OUString & rId); static OOXMLDocument * - createDocument(OOXMLStream::Pointer_t pStream); + createDocument(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator); }; diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index b6615a92ffb4..d75e56b6c75b 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -105,7 +105,8 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes if( eType == writerfilter::dmapper::DOCUMENT_OOXML ) { writerfilter::ooxml::OOXMLStream::Pointer_t pDocStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage); - writerfilter::ooxml::OOXMLDocument::Pointer_t pDocument(writerfilter::ooxml::OOXMLDocumentFactory::createDocument(pDocStream)); + uno::Reference<task::XStatusIndicator> xStatusIndicator = aMediaDesc.getUnpackedValueOrDefault(MediaDescriptor::PROP_STATUSINDICATOR(), uno::Reference<task::XStatusIndicator>()); + writerfilter::ooxml::OOXMLDocument::Pointer_t pDocument(writerfilter::ooxml::OOXMLDocumentFactory::createDocument(pDocStream, xStatusIndicator)); uno::Reference<frame::XModel> xModel(m_xDstDoc, uno::UNO_QUERY_THROW); pDocument->setModel(xModel); diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 60ac009aaa52..83cdb58c2ea5 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -17,8 +17,11 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <comphelper/sequenceashashmap.hxx> + #include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/xml/sax/SAXException.hpp> #include <com/sun/star/xml/dom/DocumentBuilder.hpp> #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> @@ -30,6 +33,11 @@ #include "OOXMLPropertySetImpl.hxx" #include "ooxmlLoggers.hxx" +#include <tools/resmgr.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <svx/dialogs.hrc> + #include <iostream> // this extern variable is declared in OOXMLStreamImpl.hxx @@ -46,12 +54,17 @@ TagLogger::Pointer_t debug_logger(TagLogger::getInstance("DEBUG")); using namespace ::std; -OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream) +OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator) : mpStream(pStream) + , mxStatusIndicator(xStatusIndicator) , mnXNoteId(0) , mXNoteType(0) , mxThemeDom(0) , mbIsSubstream(false) + , mnPercentSize(0) + , mnProgressLastPos(0) + , mnProgressCurrentPos(0) + , mnProgressEndPos(0) { } @@ -257,7 +270,8 @@ OOXMLDocumentImpl::getSubStream(const OUString & rId) (OOXMLDocumentFactory::createStream(mpStream, rId)); OOXMLDocumentImpl * pTemp; - writerfilter::Reference<Stream>::Pointer_t pRet( pTemp = new OOXMLDocumentImpl(pStream) ); + // Do not pass status indicator to sub-streams: they are typically marginal in size, so we just track the main document for now. + writerfilter::Reference<Stream>::Pointer_t pRet( pTemp = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>()) ); pTemp->setModel(mxModel); pTemp->setDrawPage(mxDrawPage); pTemp->setIsSubstream( true ); @@ -276,7 +290,8 @@ OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, const Id & rT OOXMLStream::Pointer_t pStream = (OOXMLDocumentFactory::createStream(mpStream, nType)); - OOXMLDocumentImpl * pDocument = new OOXMLDocumentImpl(pStream); + // See above, no status indicator for the note stream, either. + OOXMLDocumentImpl * pDocument = new OOXMLDocumentImpl(pStream, uno::Reference<task::XStatusIndicator>()); pDocument->setXNoteId(nId); pDocument->setXNoteType(rType); @@ -435,6 +450,30 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) uno::Reference< xml::sax::XFastParser > xParser (mpStream->getFastParser()); + if (mxModel.is()) + { + uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxModel, uno::UNO_QUERY); + uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties(); + comphelper::SequenceAsHashMap aMap(xDocumentProperties->getDocumentStatistics()); + if (aMap.find("ParagraphCount") != aMap.end()) + { + sal_Int32 nValue; + if (aMap["ParagraphCount"] >>= nValue) + { + if (mxStatusIndicator.is()) + { + // We want to care about the progress if we know the estimated paragraph count and we have given a status indicator as well. + // Set the end position only here, so later it's enough to check if that is non-zero in incrementProgress(). + mnProgressEndPos = nValue; + static ResMgr* pResMgr = ResMgr::CreateResMgr("svx", Application::GetSettings().GetUILanguageTag()); + OUString aDocLoad(ResId(RID_SVXSTR_DOC_LOAD, *pResMgr).toString()); + mxStatusIndicator->start(aDocLoad, mnProgressEndPos); + mnPercentSize = mnProgressEndPos / 100; + } + } + } + } + if (xParser.is()) { uno::Reference<uno::XComponentContext> xContext(mpStream->getContext()); @@ -487,6 +526,19 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) #endif } +void OOXMLDocumentImpl::incrementProgress() +{ + mnProgressCurrentPos++; + // 1) If we know the end + // 2) We progressed enough that updating makes sense + // 3) We did not reach the end yet (possible in case the doc stat is is misleading) + if (mnProgressEndPos && mnProgressCurrentPos > (mnProgressLastPos + mnPercentSize) && mnProgressLastPos < mnProgressEndPos) + { + mnProgressLastPos = mnProgressCurrentPos; + mxStatusIndicator->setValue(mnProgressLastPos); + } +} + void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream) { // Resolving all item[n].xml files from CustomXml folder. @@ -863,9 +915,9 @@ uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( ) OOXMLDocument * OOXMLDocumentFactory::createDocument -(OOXMLStream::Pointer_t pStream) +(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator) { - return new OOXMLDocumentImpl(pStream); + return new OOXMLDocumentImpl(pStream, xStatusIndicator); } }} diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index 0c4cd01b1049..4af757030bbb 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -35,6 +35,7 @@ using namespace ::com::sun::star; class OOXMLDocumentImpl : public OOXMLDocument { OOXMLStream::Pointer_t mpStream; + uno::Reference<task::XStatusIndicator> mxStatusIndicator; sal_Int32 mnXNoteId; Id mXNoteType; @@ -53,6 +54,14 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Reference<io::XInputStream> mxEmbeddings; uno::Sequence < beans::PropertyValue > mxEmbeddingsList; bool mbIsSubstream; + /// How many paragraphs equal to 1 percent? + sal_Int32 mnPercentSize; + /// Position progress when it was last updated, possibly not after every paragraph in case of large documents. + sal_Int32 mnProgressLastPos; + /// Current position progress, updated after every paragraph. + sal_Int32 mnProgressCurrentPos; + /// End position, i.e. the estimated number of paragraphs. + sal_Int32 mnProgressEndPos; protected: virtual void resolveFastSubStream(Stream & rStream, @@ -80,7 +89,7 @@ protected: void resolveGlossaryStream(Stream & rStream); void resolveEmbeddingsStream(Stream & rStream); public: - OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream); + OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator); virtual ~OOXMLDocumentImpl(); virtual void resolve(Stream & rStream); @@ -131,6 +140,8 @@ public: virtual uno::Reference<xml::dom::XDocument> getGlossaryDocDom(); virtual uno::Sequence<uno::Sequence< uno::Any> > getGlossaryDomList(); virtual uno::Sequence<beans::PropertyValue > getEmbeddingsList(); + + void incrementProgress(); }; }} #endif // OOXML_DOCUMENT_IMPL_HXX diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index ce4b3a9a7965..667646ba5c8a 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -888,6 +888,8 @@ void OOXMLFastContextHandler::endOfParagraph() startCharacterGroup(); if (isForwardEvents()) mpStream->utext((const sal_uInt8*)&uCR, 1); + + mpParserState->getDocument()->incrementProgress(); } void OOXMLFastContextHandler::startTxbxContent() |