summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-03-21 15:31:21 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-03-21 15:47:24 +0100
commitfdacaab2485fa42648ae96348b9ad6a9e1f49424 (patch)
treeb77c47d8bec671b40934f0fb57ca96e921a0ccf0
parent706893eb2d737e1475945f4204f95b7382992240 (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.hxx3
-rw-r--r--writerfilter/source/filter/ImportFilter.cxx3
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.cxx62
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.hxx13
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx2
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()