Kaydet (Commit) fdacaab2 authored tarafından Miklos Vajna's avatar Miklos Vajna

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
üst 706893eb
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/uno/XComponentContext.hpp> #include <com/sun/star/uno/XComponentContext.hpp>
#include <resourcemodel/WW8ResourceModel.hxx> #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/XParser.hpp>
#include <com/sun/star/xml/sax/XFastParser.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp>
#include <com/sun/star/xml/sax/XFastTokenHandler.hpp> #include <com/sun/star/xml/sax/XFastTokenHandler.hpp>
...@@ -269,7 +270,7 @@ public: ...@@ -269,7 +270,7 @@ public:
createStream(OOXMLStream::Pointer_t pStream, const OUString & rId); createStream(OOXMLStream::Pointer_t pStream, const OUString & rId);
static OOXMLDocument * static OOXMLDocument *
createDocument(OOXMLStream::Pointer_t pStream); createDocument(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator);
}; };
......
...@@ -105,7 +105,8 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes ...@@ -105,7 +105,8 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes
if( eType == writerfilter::dmapper::DOCUMENT_OOXML ) if( eType == writerfilter::dmapper::DOCUMENT_OOXML )
{ {
writerfilter::ooxml::OOXMLStream::Pointer_t pDocStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage); 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); uno::Reference<frame::XModel> xModel(m_xDstDoc, uno::UNO_QUERY_THROW);
pDocument->setModel(xModel); pDocument->setModel(xModel);
......
...@@ -17,8 +17,11 @@ ...@@ -17,8 +17,11 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * 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/xml/sax/XParser.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/xml/sax/SAXException.hpp> #include <com/sun/star/xml/sax/SAXException.hpp>
#include <com/sun/star/xml/dom/DocumentBuilder.hpp> #include <com/sun/star/xml/dom/DocumentBuilder.hpp>
#include <com/sun/star/embed/XHierarchicalStorageAccess.hpp> #include <com/sun/star/embed/XHierarchicalStorageAccess.hpp>
...@@ -30,6 +33,11 @@ ...@@ -30,6 +33,11 @@
#include "OOXMLPropertySetImpl.hxx" #include "OOXMLPropertySetImpl.hxx"
#include "ooxmlLoggers.hxx" #include "ooxmlLoggers.hxx"
#include <tools/resmgr.hxx>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <svx/dialogs.hrc>
#include <iostream> #include <iostream>
// this extern variable is declared in OOXMLStreamImpl.hxx // this extern variable is declared in OOXMLStreamImpl.hxx
...@@ -46,12 +54,17 @@ TagLogger::Pointer_t debug_logger(TagLogger::getInstance("DEBUG")); ...@@ -46,12 +54,17 @@ TagLogger::Pointer_t debug_logger(TagLogger::getInstance("DEBUG"));
using namespace ::std; using namespace ::std;
OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream) OOXMLDocumentImpl::OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator)
: mpStream(pStream) : mpStream(pStream)
, mxStatusIndicator(xStatusIndicator)
, mnXNoteId(0) , mnXNoteId(0)
, mXNoteType(0) , mXNoteType(0)
, mxThemeDom(0) , mxThemeDom(0)
, mbIsSubstream(false) , mbIsSubstream(false)
, mnPercentSize(0)
, mnProgressLastPos(0)
, mnProgressCurrentPos(0)
, mnProgressEndPos(0)
{ {
} }
...@@ -257,7 +270,8 @@ OOXMLDocumentImpl::getSubStream(const OUString & rId) ...@@ -257,7 +270,8 @@ OOXMLDocumentImpl::getSubStream(const OUString & rId)
(OOXMLDocumentFactory::createStream(mpStream, rId)); (OOXMLDocumentFactory::createStream(mpStream, rId));
OOXMLDocumentImpl * pTemp; 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->setModel(mxModel);
pTemp->setDrawPage(mxDrawPage); pTemp->setDrawPage(mxDrawPage);
pTemp->setIsSubstream( true ); pTemp->setIsSubstream( true );
...@@ -276,7 +290,8 @@ OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, const Id & rT ...@@ -276,7 +290,8 @@ OOXMLDocumentImpl::getXNoteStream(OOXMLStream::StreamType_t nType, const Id & rT
OOXMLStream::Pointer_t pStream = OOXMLStream::Pointer_t pStream =
(OOXMLDocumentFactory::createStream(mpStream, nType)); (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->setXNoteId(nId);
pDocument->setXNoteType(rType); pDocument->setXNoteType(rType);
...@@ -435,6 +450,30 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) ...@@ -435,6 +450,30 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
uno::Reference< xml::sax::XFastParser > xParser uno::Reference< xml::sax::XFastParser > xParser
(mpStream->getFastParser()); (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()) if (xParser.is())
{ {
uno::Reference<uno::XComponentContext> xContext(mpStream->getContext()); uno::Reference<uno::XComponentContext> xContext(mpStream->getContext());
...@@ -487,6 +526,19 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) ...@@ -487,6 +526,19 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
#endif #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) void OOXMLDocumentImpl::resolveCustomXmlStream(Stream & rStream)
{ {
// Resolving all item[n].xml files from CustomXml folder. // Resolving all item[n].xml files from CustomXml folder.
...@@ -863,9 +915,9 @@ uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( ) ...@@ -863,9 +915,9 @@ uno::Sequence<beans::PropertyValue > OOXMLDocumentImpl::getEmbeddingsList( )
OOXMLDocument * OOXMLDocument *
OOXMLDocumentFactory::createDocument 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);
} }
}} }}
......
...@@ -35,6 +35,7 @@ using namespace ::com::sun::star; ...@@ -35,6 +35,7 @@ using namespace ::com::sun::star;
class OOXMLDocumentImpl : public OOXMLDocument class OOXMLDocumentImpl : public OOXMLDocument
{ {
OOXMLStream::Pointer_t mpStream; OOXMLStream::Pointer_t mpStream;
uno::Reference<task::XStatusIndicator> mxStatusIndicator;
sal_Int32 mnXNoteId; sal_Int32 mnXNoteId;
Id mXNoteType; Id mXNoteType;
...@@ -53,6 +54,14 @@ class OOXMLDocumentImpl : public OOXMLDocument ...@@ -53,6 +54,14 @@ class OOXMLDocumentImpl : public OOXMLDocument
uno::Reference<io::XInputStream> mxEmbeddings; uno::Reference<io::XInputStream> mxEmbeddings;
uno::Sequence < beans::PropertyValue > mxEmbeddingsList; uno::Sequence < beans::PropertyValue > mxEmbeddingsList;
bool mbIsSubstream; 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: protected:
virtual void resolveFastSubStream(Stream & rStream, virtual void resolveFastSubStream(Stream & rStream,
...@@ -80,7 +89,7 @@ protected: ...@@ -80,7 +89,7 @@ protected:
void resolveGlossaryStream(Stream & rStream); void resolveGlossaryStream(Stream & rStream);
void resolveEmbeddingsStream(Stream & rStream); void resolveEmbeddingsStream(Stream & rStream);
public: public:
OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream); OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator);
virtual ~OOXMLDocumentImpl(); virtual ~OOXMLDocumentImpl();
virtual void resolve(Stream & rStream); virtual void resolve(Stream & rStream);
...@@ -131,6 +140,8 @@ public: ...@@ -131,6 +140,8 @@ public:
virtual uno::Reference<xml::dom::XDocument> getGlossaryDocDom(); virtual uno::Reference<xml::dom::XDocument> getGlossaryDocDom();
virtual uno::Sequence<uno::Sequence< uno::Any> > getGlossaryDomList(); virtual uno::Sequence<uno::Sequence< uno::Any> > getGlossaryDomList();
virtual uno::Sequence<beans::PropertyValue > getEmbeddingsList(); virtual uno::Sequence<beans::PropertyValue > getEmbeddingsList();
void incrementProgress();
}; };
}} }}
#endif // OOXML_DOCUMENT_IMPL_HXX #endif // OOXML_DOCUMENT_IMPL_HXX
......
...@@ -888,6 +888,8 @@ void OOXMLFastContextHandler::endOfParagraph() ...@@ -888,6 +888,8 @@ void OOXMLFastContextHandler::endOfParagraph()
startCharacterGroup(); startCharacterGroup();
if (isForwardEvents()) if (isForwardEvents())
mpStream->utext((const sal_uInt8*)&uCR, 1); mpStream->utext((const sal_uInt8*)&uCR, 1);
mpParserState->getDocument()->incrementProgress();
} }
void OOXMLFastContextHandler::startTxbxContent() void OOXMLFastContextHandler::startTxbxContent()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment