[Libreoffice-commits] core.git: writerfilter/inc writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Mar 21 07:47:48 PDT 2014


 writerfilter/inc/ooxml/OOXMLDocument.hxx              |    3 
 writerfilter/source/filter/ImportFilter.cxx           |    3 
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx       |   62 ++++++++++++++++--
 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx       |   13 +++
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |    2 
 5 files changed, 75 insertions(+), 8 deletions(-)

New commits:
commit fdacaab2485fa42648ae96348b9ad6a9e1f49424
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Mar 21 15:31:21 2014 +0100

    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

diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 4bbc31b..7f104ab 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 b6615a9..d75e56b 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 60ac009..83cdb58 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 0c4cd01b..4af7570 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 ce4b3a9..667646b 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()


More information about the Libreoffice-commits mailing list