From dbf9b4a9983ee6c89477d9cc23710e876014961c Mon Sep 17 00:00:00 2001
From: "Elen.Subbotina" <Elen.Subbotina@onlyoffice.com>
Date: Mon, 14 Jul 2014 11:10:09 +0000
Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87?=
 =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=8D=D0=B2=D0=B5=D0=BD=D1=82=D1=8B=20?=
 =?UTF-8?q?=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82=D0=B0?=
 =?UTF-8?q?=D1=86=D0=B8=D1=8E=20odf->docx/xlsx/pptx=20=D0=B8=20xlsx/docx->?=
 =?UTF-8?q?odf?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@57311 954022d7-b5bf-4e40-9824-e11837661b57
---
 .../ASCOfficeOdfFile/ConvertOO2OOX.cpp        | 62 ++++++++------
 .../ASCOfficeOdfFile/ConvertOO2OOX.h          |  4 +-
 .../ASCOfficeOdfFile/OfficeOdfFile.cpp        | 33 +++++++-
 .../ASCOfficeOdfFile/OfficeOdfFile.h          | 33 +++-----
 ASCOfficeOdfFile/ASCOfficeOdfFile/stdafx.h    | 12 ++-
 ASCOfficeOdfFile/ASCOfficeOdfFile/version.h   |  6 +-
 .../ASCOfficeOdfFileTest.cpp                  | 82 +++++++++++++++++-
 .../include/cpdoccore/odf/odf_document.h      | 20 +++--
 ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp  |  2 +-
 ASCOfficeOdfFile/src/odf/draw_frame_pptx.cpp  |  2 +-
 ASCOfficeOdfFile/src/odf/draw_frame_xlsx.cpp  |  2 +-
 ASCOfficeOdfFile/src/odf/odf_document.cpp     | 16 ++--
 .../src/odf/odf_document_impl.cpp             | 71 +++++++++++++---
 ASCOfficeOdfFile/src/odf/odf_document_impl.h  | 25 +++---
 ASCOfficeOdfFileW/ASCOfficeOdfFileW.vcproj    |  4 +
 .../ASCOfficeOdfFileWTest.cpp                 | 84 +++++++++++++++++++
 ASCOfficeOdfFileW/OfficeOdfFileW.cpp          | 35 +++++++-
 ASCOfficeOdfFileW/OfficeOdfFileW.h            | 10 ++-
 .../source/Oox2OdfConverter/Converter.cpp     | 32 +++++--
 .../source/Oox2OdfConverter/Converter.h       | 12 ++-
 .../source/Oox2OdfConverter/DocxConverter.cpp | 15 +++-
 .../source/Oox2OdfConverter/DocxConverter.h   |  2 +-
 .../source/Oox2OdfConverter/XlsxConverter.cpp | 12 ++-
 .../source/Oox2OdfConverter/XlsxConverter.h   |  2 +-
 .../source/Oox2OdfConverter/stdafx.h          |  2 +-
 ASCOfficeOdfFileW/source/progressCallback.h   | 11 +++
 ASCOfficeOdfFileW/stdafx.h                    |  2 +
 ASCOfficeOdfFileW/version.h                   |  6 +-
 28 files changed, 482 insertions(+), 117 deletions(-)
 create mode 100644 ASCOfficeOdfFileW/source/progressCallback.h

diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.cpp b/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.cpp
index a3d7e6aeb..857ab95f0 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.cpp
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.cpp
@@ -14,43 +14,49 @@
 
 #include <cpdoccore/odf/odf_document.h>
 
-HRESULT ConvertOds2Xlsx(cpdoccore::odf::odf_document & inputDoc, const std::wstring & dstPath)
-{
-    cpdoccore::oox::package::xlsx_document xlsx;
-    cpdoccore::oox::xlsx_conversion_context conversionContext(&xlsx, &inputDoc);
-    inputDoc.xlsx_convert(conversionContext);
-    xlsx.write(dstPath);
 
+HRESULT ConvertOds2Xlsx(cpdoccore::odf::odf_document & inputOdf, const std::wstring & dstPath)
+{
+    cpdoccore::oox::package::xlsx_document outputXlsx;
+    
+	cpdoccore::oox::xlsx_conversion_context conversionContext(&outputXlsx, &inputOdf);
+   
+	if (inputOdf.xlsx_convert(conversionContext) == false) return S_FALSE;
+    
+	outputXlsx.write(dstPath);
     return S_OK;
 }
-HRESULT ConvertOdt2Docx(cpdoccore::odf::odf_document & inputDoc, const std::wstring & dstPath)
+HRESULT ConvertOdt2Docx(cpdoccore::odf::odf_document & inputOdf, const std::wstring & dstPath)
 {
-    cpdoccore::oox::package::docx_document docx;
-    cpdoccore::oox::docx_conversion_context conversionContext(&docx, &inputDoc);
-    inputDoc.docx_convert(conversionContext);
-    docx.write(dstPath);
-
+    cpdoccore::oox::package::docx_document	outputDocx;
+    cpdoccore::oox::docx_conversion_context conversionContext(&outputDocx, &inputOdf);
+   
+	if (inputOdf.docx_convert(conversionContext) == false) return S_FALSE;
+		
+    outputDocx.write(dstPath);
+		
     return S_OK;
 }
-HRESULT ConvertOdp2Pptx(cpdoccore::odf::odf_document & inputDoc, const std::wstring & dstPath)
+HRESULT ConvertOdp2Pptx(cpdoccore::odf::odf_document & inputOdf, const std::wstring & dstPath)
 {
-    cpdoccore::oox::package::pptx_document pptx;
-    cpdoccore::oox::pptx_conversion_context conversionContext(&pptx, &inputDoc);
-    inputDoc.pptx_convert(conversionContext);
-    pptx.write(dstPath);
+    cpdoccore::oox::package::pptx_document	outputPptx;
+    cpdoccore::oox::pptx_conversion_context conversionContext(&outputPptx, &inputOdf);
+    
+	if (inputOdf.pptx_convert(conversionContext) == false) return S_FALSE;
+    outputPptx.write(dstPath);
 
     return S_OK;
 }
-HRESULT ConvertOO2OOX(const std::wstring &ext, const std::wstring & srcPath, const std::wstring & dstPath, bool bOnlyPresentation)
+HRESULT ConvertOO2OOX(const std::wstring &ext, const std::wstring & srcPath, const std::wstring & dstPath, bool bOnlyPresentation, const ProgressCallback* CallBack)
 {
 	HRESULT hr = S_OK;
 
 	try 
     {
-		cpdoccore::odf::odf_document inputDoc(srcPath);
-
-		int type = inputDoc.get_office_mime_type();
-		bool encrypted = inputDoc.get_encrypted();
+		cpdoccore::odf::odf_document inputOdf(srcPath, CallBack);
+		
+		int type = inputOdf.get_office_mime_type();
+		bool encrypted = inputOdf.get_encrypted();
 
 		if (encrypted) return AVS_ERROR_DRM;
 
@@ -67,15 +73,21 @@ HRESULT ConvertOO2OOX(const std::wstring &ext, const std::wstring & srcPath, con
 		switch (type)
 		{
 		case 1:
-			hr = ConvertOdt2Docx(inputDoc,dstPath);
+			hr = ConvertOdt2Docx(inputOdf,dstPath);
 			break;
 		case 2:
-			hr = ConvertOds2Xlsx(inputDoc,dstPath);
+			hr = ConvertOds2Xlsx(inputOdf,dstPath);
 			break;
 		case 3:
-			hr = ConvertOdp2Pptx(inputDoc,dstPath);
+			hr = ConvertOdp2Pptx(inputOdf,dstPath);
 			break;
 		}
+		if (hr == S_OK)
+		{
+			hr = S_OK;
+			inputOdf.UpdateProgress(1000000);
+		}
+
 	}
 	catch(...)
 	{
diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.h b/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.h
index 7ad0696c2..abe9bab4d 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.h
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/ConvertOO2OOX.h
@@ -1,4 +1,6 @@
 #include <windows.h>
 #include <string>
 
-HRESULT ConvertOO2OOX(const std::wstring &ext, const std::wstring & srcPath, const std::wstring & dstPath, bool bOnlyPresentation);
\ No newline at end of file
+struct ProgressCallback;
+
+HRESULT ConvertOO2OOX(const std::wstring &ext, const std::wstring & srcPath, const std::wstring & dstPath, bool bOnlyPresentation, const ProgressCallback* CallBack);
\ No newline at end of file
diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.cpp b/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.cpp
index 8de792420..2714aa0f2 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.cpp
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.cpp
@@ -184,8 +184,13 @@ HRESULT COfficeOdfFile::LoadFromFileImpl(const std::wstring & srcFileName,
         NULL, 0))
         return hr;
 
+	ProgressCallback ffCallBack;
 
-	hr = ConvertOO2OOX(ext,srcTempPath, dstTempPath,bOnlyPresentation);
+	ffCallBack.OnProgress	=	OnProgressFunc;
+	ffCallBack.OnProgressEx	=	OnProgressExFunc;
+	ffCallBack.caller		=	this;
+
+	hr = ConvertOO2OOX(ext,srcTempPath, dstTempPath,bOnlyPresentation, &ffCallBack);
 
 	if (hr != S_OK)  return hr;
    
@@ -208,4 +213,28 @@ bool COfficeOdfFile::initialized()
     return (!!office_utils_);
 }
 
-// COfficeOdfFile3
+void COfficeOdfFile::OnProgressFunc (LPVOID lpParam, long nID, long nPercent)
+{
+	//g_oCriticalSection.Enter();
+
+	COfficeOdfFile* pOdfFile = reinterpret_cast<COfficeOdfFile*>(lpParam);
+	if (pOdfFile != NULL)
+	{
+		pOdfFile->OnProgress(nID, nPercent);
+	}
+
+	//g_oCriticalSection.Leave();
+}
+
+void COfficeOdfFile::OnProgressExFunc (LPVOID lpParam, long nID, long nPercent, short* pStop)
+{
+	//g_oCriticalSection.Enter();
+
+	COfficeOdfFile* pOdfFile = reinterpret_cast<COfficeOdfFile*>(lpParam);
+	if (pOdfFile != NULL)
+	{
+		pOdfFile->OnProgressEx(nID, nPercent, pStop);
+	}
+
+	//g_oCriticalSection.Leave();
+}
diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.h b/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.h
index b79b01e75..2ac3a505a 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.h
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/OfficeOdfFile.h
@@ -4,28 +4,13 @@
 #include "resource.h"       // main symbols
 #include <string>
 
-#import "../../Redist/ASCOfficeUtils.dll" rename_namespace("ASCOfficeUtils"), raw_interfaces_only
-
-////////////////////////////////////////////////////////////////
-// IASCOfficeFileTemplate
-[
-	object,
-	uuid("3FC4EC15-9467-4D66-AD6A-A0C0BAEDD3CD"),
-	dual,	helpstring("IASCOfficeFileTemplate Interface"),
-	pointer_default(unique)
-]
-__interface IASCOfficeFileTemplate : IDispatch
-{
-	[id(1), helpstring("method LoadFromFile")] HRESULT LoadFromFile([in] BSTR sSrcFileName, [in] BSTR sDstPath, [in] BSTR sXMLOptions);
-	[id(2), helpstring("method SaveToFile")] HRESULT SaveToFile([in] BSTR sDstFileName, [in] BSTR sSrcPath, [in] BSTR sXMLOptions);
-};
-////////////////////////////////////////////////////////////////
-
+#include "../../Common/OfficeFileTemplate.h"
 
 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
 #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
 #endif
 
+#import "../../Redist/ASCOfficeUtils.dll" rename_namespace("ASCOfficeUtils"), raw_interfaces_only
 
 // IOfficeOdfFile
 [
@@ -34,7 +19,7 @@ __interface IASCOfficeFileTemplate : IDispatch
 	dual,	helpstring("IOfficeOdfFile Interface"),
 	pointer_default(unique)
 ]
-__interface IOfficeOdfFile : IASCOfficeFileTemplate
+__interface IOfficeOdfFile : IAVSOfficeFileTemplate
 {
 };
 
@@ -54,7 +39,7 @@ __interface _IOfficeOdfFileEvents
 
 [
 	coclass,
-	default(IOfficeOdfFile, _IOfficeOdfFileEvents),
+	default(IOfficeOdfFile, _IAVSOfficeFileTemplateEvents),
 	threading(apartment),
 	support_error_info("IOfficeOdfFile"),
 	event_source(com),
@@ -70,7 +55,9 @@ class ATL_NO_VTABLE COfficeOdfFile :
 public:
 	COfficeOdfFile();
 
-	__event __interface _IOfficeOdfFileEvents;
+	__event __interface _IAVSOfficeFileTemplateEvents;
+	__event __interface _IAVSOfficeFileTemplateEvents2;
+
 
 
 	DECLARE_PROTECT_FINAL_CONSTRUCT()
@@ -91,7 +78,6 @@ public:
 private:
     ATL::CComPtr< ASCOfficeUtils::IOfficeUtils > office_utils_;
     
-private:
 	bool bOnlyPresentation;
 	bool loadOptionFromXML(CString parametr,BSTR sXMLOptions);
     bool initialized();
@@ -99,4 +85,9 @@ private:
         const std::wstring & srcTempPath,
         const std::wstring & dstTempPath,
         const std::wstring & dstPath);
+
+protected:
+
+	static void OnProgressFunc (LPVOID lpParam, long nID, long nPercent);
+	static void OnProgressExFunc (LPVOID lpParam, long nID, long nPercent, short* pStop);
 };
diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/stdafx.h b/ASCOfficeOdfFile/ASCOfficeOdfFile/stdafx.h
index 145959c64..c3822b597 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/stdafx.h
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/stdafx.h
@@ -43,4 +43,14 @@
 
 #include <windef.h>
 #include <wingdi.h>
-using namespace ATL;
\ No newline at end of file
+using namespace ATL;
+
+typedef void (*OnProgressCallback)( LPVOID lpParam, long nID, long nPercent );
+typedef void (*OnProgressExCallback)( LPVOID lpParam, long nID, long nPercent, short* Cancel );
+
+struct ProgressCallback
+{
+  OnProgressCallback OnProgress;
+  OnProgressExCallback OnProgressEx;
+  LPVOID caller;
+};
diff --git a/ASCOfficeOdfFile/ASCOfficeOdfFile/version.h b/ASCOfficeOdfFile/ASCOfficeOdfFile/version.h
index 87379b019..8e45e5d1d 100644
--- a/ASCOfficeOdfFile/ASCOfficeOdfFile/version.h
+++ b/ASCOfficeOdfFile/ASCOfficeOdfFile/version.h
@@ -2,6 +2,6 @@
 //1
 //0
 //1
-//202
-#define INTVER 1,0,1,202
-#define STRVER "1,0,1,202\0"
+//204
+#define INTVER 1,0,1,204
+#define STRVER "1,0,1,204\0"
diff --git a/ASCOfficeOdfFile/examples/ASCOfficeOdfFileTest/ASCOfficeOdfFileTest.cpp b/ASCOfficeOdfFile/examples/ASCOfficeOdfFileTest/ASCOfficeOdfFileTest.cpp
index 99c37d10a..ab94b3df4 100644
--- a/ASCOfficeOdfFile/examples/ASCOfficeOdfFileTest/ASCOfficeOdfFileTest.cpp
+++ b/ASCOfficeOdfFile/examples/ASCOfficeOdfFileTest/ASCOfficeOdfFileTest.cpp
@@ -11,12 +11,92 @@
 
 #define HR_RET(HR) if FAILED(hr = (HR)) { _ASSERTE(false); return -1; }
 
+class CCallback : public ASCOfficeOdfFile::_IAVSOfficeFileTemplateEvents  
+{
+public:
+
+	CCallback(){m_cnt=0;}
+	virtual ~CCallback(){}
+    STDMETHOD(GetTypeInfoCount)(UINT*) { return E_NOTIMPL; }
+    STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
+    STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return E_NOTIMPL; }
+
+    STDMETHOD(Invoke)(
+		DISPID		dispIdMember, 
+		REFIID		riid, 
+		LCID		lcid, 
+		WORD		wFlags, 
+		DISPPARAMS*	pDispParams, 
+		VARIANT*	pVarResult, 
+		EXCEPINFO*	pExcepInfo, 
+		UINT*		puArgErr) 
+	{
+		switch(dispIdMember)
+		{
+		case 1:
+			std::cout << "\nPercent : " << pDispParams->rgvarg[0].lVal / 10000. << "%\n";    
+			return(S_OK);
+			break;
+		default:
+			return(E_NOTIMPL); 
+		}
+	}
+
+    STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppv) 
+	{ 
+		if ((iid == __uuidof(ASCOfficeOdfFile::_IAVSOfficeFileTemplateEvents)) ||
+        (iid == __uuidof(IDispatch)) ||
+        (iid == __uuidof(IUnknown)))
+            *ppv = this;
+        else {
+            *ppv = 0;
+            return E_NOINTERFACE;
+        }
+        AddRef();
+        return S_OK;
+    }
+
+    STDMETHOD_(ULONG,AddRef)() { 
+		return InterlockedIncrement(&m_cnt); 
+	}
+
+    STDMETHOD_(ULONG,Release)() { 
+	    InterlockedDecrement(&m_cnt);
+		if (m_cnt!=0) return m_cnt;
+		delete this;
+		return 0;
+    }
+protected:
+	LONG   m_cnt;
+private:
+};
+
+
+
 int ConvertSingle(int argc, _TCHAR* argv[])
 {
-    ATL::CComPtr<ASCOfficeOdfFile::IASCOfficeFileTemplate> officeOdfFile;
+	ATL::CComPtr<ASCOfficeOdfFile::IAVSOfficeFileTemplate> officeOdfFile;
     HRESULT hr;
     HR_RET(officeOdfFile.CoCreateInstance(__uuidof(ASCOfficeOdfFile::COfficeOdfFile)));
+//_______________________________________________________________________________________________________
+		IUnknown *pUnk;
+		IConnectionPointContainer* pContainer;
+		IConnectionPoint* pCP;
+		CCallback *pEvents = NULL;
+		DWORD dwAdvise=0;
+
+		pEvents = new CCallback;
+		pEvents->AddRef();
+
+		HR_RET(officeOdfFile->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer));
+		HR_RET(pContainer->FindConnectionPoint(__uuidof(ASCOfficeOdfFile::_IAVSOfficeFileTemplateEvents),&pCP));	
+
+		HR_RET(pEvents->QueryInterface(IID_IUnknown,(VOID **)&pUnk));
+		HR_RET(pCP->Advise(pUnk,&dwAdvise));
 
+		pContainer->Release();pContainer=NULL;
+		pUnk->Release(); pUnk=NULL;
+//____________
     boost::timer t1;
     officeOdfFile->LoadFromFile(ATL::CComBSTR(argv[1]), ATL::CComBSTR(argv[2]), NULL);
     std::cout << "\n\nTime : " << t1.elapsed() << "\n";    
diff --git a/ASCOfficeOdfFile/include/cpdoccore/odf/odf_document.h b/ASCOfficeOdfFile/include/cpdoccore/odf/odf_document.h
index f5c99bc52..f833220f4 100644
--- a/ASCOfficeOdfFile/include/cpdoccore/odf/odf_document.h
+++ b/ASCOfficeOdfFile/include/cpdoccore/odf/odf_document.h
@@ -1,10 +1,12 @@
-#ifndef _CPDOCCORE_ODF_ODF_DOCUMENT_H_
-#define _CPDOCCORE_ODF_ODF_DOCUMENT_H_
+#pragma once
 
 #include <string>
 #include <cpdoccore/CPSharedPtr.h>
 #include <cpdoccore/CPScopedPtr.h>
 
+
+struct ProgressCallback;
+
 namespace cpdoccore { 
 
 namespace oox {
@@ -20,15 +22,15 @@ class odf_read_context;
 class odf_document
 {
 public:
-    odf_document(const std::wstring & Folder);
+    odf_document(const std::wstring & Folder, const ProgressCallback* CallBack);
     ~odf_document();
 
 public:
     odf_read_context & odf_context();
     
-	void docx_convert(oox::docx_conversion_context & Context);
-    void xlsx_convert(oox::xlsx_conversion_context & Context);
-	void pptx_convert(oox::pptx_conversion_context & Context);
+	bool docx_convert(oox::docx_conversion_context & Context);
+    bool xlsx_convert(oox::xlsx_conversion_context & Context);
+	bool pptx_convert(oox::pptx_conversion_context & Context);
 	
 	const std::wstring & get_folder() const;
 	
@@ -38,12 +40,12 @@ public:
     class Impl;   
     Impl * get_impl() { return impl_.get(); }
 
+	bool UpdateProgress(long Complete);
+
 private:
     _CP_SCOPED_PTR(Impl) impl_;
             
 };
 
 }
-}
-
-#endif // #ifndef _CPDOCCORE_ODF_ODF_DOCUMENT_H_
+}
\ No newline at end of file
diff --git a/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp b/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp
index 630ddc03d..185c4f293 100644
--- a/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp
+++ b/ASCOfficeOdfFile/src/odf/draw_frame_docx.cpp
@@ -1174,7 +1174,7 @@ void draw_object::docx_convert(oox::docx_conversion_context & Context)
        const std::wstring dbgObjectPathStr = objectPath.normalize().wstring();
 #endif
 
-        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr);    
+        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr,NULL);    
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //функциональная часть
 		const office_element *contentSubDoc = objectSubDoc.get_impl()->get_content();
diff --git a/ASCOfficeOdfFile/src/odf/draw_frame_pptx.cpp b/ASCOfficeOdfFile/src/odf/draw_frame_pptx.cpp
index 2aee856da..e3f7bd7ec 100644
--- a/ASCOfficeOdfFile/src/odf/draw_frame_pptx.cpp
+++ b/ASCOfficeOdfFile/src/odf/draw_frame_pptx.cpp
@@ -249,7 +249,7 @@ void draw_object::pptx_convert(oox::pptx_conversion_context & Context)
        const std::wstring dbgObjectPathStr = objectPath.normalize().wstring();
 #endif
 
-        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr);    
+        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr, NULL);    
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //в отдельных embd объектах чаще всего диаграммы, уравнения... но МОГУТ быть и обычные объекты подтипа frame!!! 
 		//пример RemanejamentoOrcamentario.ods
diff --git a/ASCOfficeOdfFile/src/odf/draw_frame_xlsx.cpp b/ASCOfficeOdfFile/src/odf/draw_frame_xlsx.cpp
index 075924699..53c89b52b 100644
--- a/ASCOfficeOdfFile/src/odf/draw_frame_xlsx.cpp
+++ b/ASCOfficeOdfFile/src/odf/draw_frame_xlsx.cpp
@@ -228,7 +228,7 @@ void draw_object::xlsx_convert(oox::xlsx_conversion_context & Context)
        const std::wstring dbgObjectPathStr = objectPath.normalize().wstring();
 #endif
 
-        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr);    
+        cpdoccore::odf::odf_document objectSubDoc(dbgObjectPathStr,NULL);    
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //в отдельных embd объектах чаще всего диаграммы... но МОГУТ быть и обычные объекты подтипа frame!!! пример RemanejamentoOrcamentario.ods
 ///////////////////////////////////////////////////////////////////////////
diff --git a/ASCOfficeOdfFile/src/odf/odf_document.cpp b/ASCOfficeOdfFile/src/odf/odf_document.cpp
index 2a2ef1fc7..e6303d249 100644
--- a/ASCOfficeOdfFile/src/odf/odf_document.cpp
+++ b/ASCOfficeOdfFile/src/odf/odf_document.cpp
@@ -1,17 +1,16 @@
 #include "precompiled_cpodf.h"
 #include <cpdoccore/odf/odf_document.h>
 
-
 #include "odf_document_impl.h"
+#include "..\progressCallback.h"
 
 namespace cpdoccore { 
 namespace odf {
 
 
-
 namespace fs = ::boost::filesystem;
 
-odf_document::odf_document(const std::wstring & Folder) : impl_(new Impl(Folder))
+odf_document::odf_document(const std::wstring & Folder, const ProgressCallback* CallBack) : impl_(new Impl(Folder,CallBack))
 {}
 
 odf_document::~odf_document()
@@ -22,16 +21,16 @@ odf_read_context & odf_document::odf_context()
     return impl_->odf_context();
 }
 
-void odf_document::docx_convert(oox::docx_conversion_context & Context)
+bool odf_document::docx_convert(oox::docx_conversion_context & Context)
 {
     return impl_->docx_convert(Context);
 }
 
-void odf_document::xlsx_convert(oox::xlsx_conversion_context & Context)
+bool odf_document::xlsx_convert(oox::xlsx_conversion_context & Context)
 {
     return impl_->xlsx_convert(Context);
 }
-void odf_document::pptx_convert(oox::pptx_conversion_context & Context)
+bool odf_document::pptx_convert(oox::pptx_conversion_context & Context)
 {
     return impl_->pptx_convert(Context);
 }
@@ -49,6 +48,11 @@ bool odf_document::get_encrypted()
 {
 	return impl_->get_encrypted();
 }
+bool odf_document::UpdateProgress(long Complete)
+{
+	if (!impl_) return true;
+	return impl_->UpdateProgress(Complete);
+}
 
 }
 }
diff --git a/ASCOfficeOdfFile/src/odf/odf_document_impl.cpp b/ASCOfficeOdfFile/src/odf/odf_document_impl.cpp
index e87a7c3a5..7f3e728e7 100644
--- a/ASCOfficeOdfFile/src/odf/odf_document_impl.cpp
+++ b/ASCOfficeOdfFile/src/odf/odf_document_impl.cpp
@@ -48,6 +48,9 @@
 
 #include "documentcontext.h"
 
+#include "..\progressCallback.h"
+#define PROGRESSEVENT_ID 0
+
 namespace cpdoccore { 
 namespace odf {
 
@@ -73,7 +76,7 @@ content_xml_t_ptr read_file_content(const fs::wpath & Path)
 }
 }
 
-odf_document::Impl::Impl(const std::wstring & Folder) : context_(new odf_read_context()), base_folder_(Folder)
+odf_document::Impl::Impl(const std::wstring & Folder, const ProgressCallback* CallBack) : context_(new odf_read_context()), base_folder_(Folder), pCallBack(CallBack), bUserStopConvert (0)
 {
 	office_mime_type_ = 0;
 	encrypted = false;
@@ -107,8 +110,22 @@ odf_document::Impl::Impl(const std::wstring & Folder) : context_(new odf_read_co
     _CP_LOG(info) << L"[info] parse manifest" << std::endl;
     parse_manifests();
 
+	UpdateProgress(400000);
 }
+bool odf_document::Impl::UpdateProgress(long nComplete)
+{
+	if (pCallBack)
+	{
+		pCallBack->OnProgress (pCallBack->caller, PROGRESSEVENT_ID, nComplete);
+
+		bUserStopConvert = 0;
+		pCallBack->OnProgressEx (pCallBack->caller, PROGRESSEVENT_ID, nComplete, &bUserStopConvert);
 
+		if (bUserStopConvert !=0 ) return true;
+	}
+
+	return false;
+}
 void odf_document::Impl::parse_fonts()
 {
     do 
@@ -529,8 +546,7 @@ void odf_document::Impl::parse_styles()
             {
                 const number_style_base * style = dynamic_cast<const number_style_base *>(elm.get());
 
-                if (!style)
-                    continue;
+                if (!style)  continue;
 
                 context_->numberStyles().add(style->get_style_name(), elm);
             }
@@ -541,16 +557,23 @@ void odf_document::Impl::parse_styles()
     while (false);
 }
 
-void odf_document::Impl::docx_convert(oox::docx_conversion_context & Context)
+bool odf_document::Impl::docx_convert(oox::docx_conversion_context & Context)
 {
-    Context.process_styles();
+ 	if (bUserStopConvert !=0 ) return false;
+
+	Context.process_styles();	
+	if (UpdateProgress(450000)) return false;
+
     Context.process_fonts();
     Context.process_headers_footers();
+	if (UpdateProgress(500000)) return false;
 
     Context.start_document();
 	
 	if (content_xml_)
         content_xml_->docx_convert(Context);
+
+	if (UpdateProgress(800000)) return false;
     
 	Context.end_document();
 
@@ -558,20 +581,32 @@ void odf_document::Impl::docx_convert(oox::docx_conversion_context & Context)
     // так как в процессе конвертации документа у нас могу добавиться стили — 
     // в случае если используется text:start-value (начинаем нумерацию заново)
     Context.process_list_styles();
+	if (UpdateProgress(850000)) return false;
+
+	return true;
 }
-void odf_document::Impl::xlsx_convert(oox::xlsx_conversion_context & Context) 
+bool odf_document::Impl::xlsx_convert(oox::xlsx_conversion_context & Context) 
 {
-    try
+ 	if (bUserStopConvert !=0 ) return false;
+
+	try
     {
         _CP_LOG(info) << L"[info] convert content" << std::endl;
-        Context.start_document();
-        if (content_xml_)
+       
+		Context.start_document();
+ 		if (UpdateProgress(450000)) return false;
+      
+		if (content_xml_)
             content_xml_->xlsx_convert(Context);
+		if (UpdateProgress(700000)) return false;
+
         Context.end_document();
+		if (UpdateProgress(750000)) return false;
 
         _CP_LOG(info) << L"[info] process styles" << std::endl;
         Context.process_styles();
-       
+ 		if (UpdateProgress(800000)) return false;
+      
     }
     catch(boost::exception & ex)
     {
@@ -590,22 +625,33 @@ void odf_document::Impl::xlsx_convert(oox::xlsx_conversion_context & Context)
         _CP_LOG(info) << L"\n[error]: undefined\n";
         throw;
     }
+
+	return true;
 }
 
-void odf_document::Impl::pptx_convert(oox::pptx_conversion_context & Context) 
+bool odf_document::Impl::pptx_convert(oox::pptx_conversion_context & Context) 
 {
+	if (bUserStopConvert !=0 ) return false;
+
     try
     {
         _CP_LOG(info) << L"[info] convert content" << std::endl;
 	
 		Context.start_document();
-        if (content_xml_)
+		if (UpdateProgress(450000)) return false;
+       
+		if (content_xml_)
             content_xml_->pptx_convert(Context);
+		if (UpdateProgress(700000)) return false;
 		
 		Context.process_layouts();
+		if (UpdateProgress(750000)) return false;
+		
 		Context.process_master_pages();
+		if (UpdateProgress(800000)) return false;
 
         Context.end_document();
+		if (UpdateProgress(850000)) return false;
 	}
     catch(boost::exception & ex)
     {
@@ -624,6 +670,7 @@ void odf_document::Impl::pptx_convert(oox::pptx_conversion_context & Context)
         _CP_LOG(info) << L"\n[error]: undefined\n";
         throw;
     }
+	return true;
 }
 
 odf_read_context & odf_document::Impl::odf_context() 
diff --git a/ASCOfficeOdfFile/src/odf/odf_document_impl.h b/ASCOfficeOdfFile/src/odf/odf_document_impl.h
index d865a4764..323c2879e 100644
--- a/ASCOfficeOdfFile/src/odf/odf_document_impl.h
+++ b/ASCOfficeOdfFile/src/odf/odf_document_impl.h
@@ -1,13 +1,8 @@
-#ifndef CPDOCCORE_ODF_DOCUMENT_IMPL_H_
-#define CPDOCCORE_ODF_DOCUMENT_IMPL_H_
+#pragma once
 
-#include <cpdoccore/odf/odf_document.h>
 #include <string>
 #include "odf_content_xml.h"
-
-#ifdef _MSC_VER
-#pragma once
-#endif
+#include <cpdoccore/odf/odf_document.h>
 
 namespace cpdoccore { 
 
@@ -28,12 +23,12 @@ typedef shared_ptr<content_xml_t>::Type content_xml_t_ptr;
 class odf_document::Impl
 {
 public:
-    Impl(const std::wstring & Folder);
+    Impl(const std::wstring & Folder, const ProgressCallback* CallBack);
     odf_read_context & odf_context();
    
-	void docx_convert(oox::docx_conversion_context & Context);
-    void xlsx_convert(oox::xlsx_conversion_context & Context);
-    void pptx_convert(oox::pptx_conversion_context & Context);
+	bool docx_convert(oox::docx_conversion_context & Context);
+    bool xlsx_convert(oox::xlsx_conversion_context & Context);
+    bool pptx_convert(oox::pptx_conversion_context & Context);
 
     const std::wstring & get_folder() const { return base_folder_; }
     const office_element * get_content() const;
@@ -41,9 +36,14 @@ public:
 	long get_office_mime_type() {return office_mime_type_;}
 
 	bool get_encrypted(){return encrypted;}
+
+	bool UpdateProgress(long Complete);
     
 private:
-    odf_read_context_ptr context_;
+	const ProgressCallback* pCallBack;
+	short bUserStopConvert;
+   
+	odf_read_context_ptr context_;
     void parse_styles();
     void parse_fonts();
 	void parse_manifests();
@@ -65,4 +65,3 @@ private:
 }
 }
 
-#endif
diff --git a/ASCOfficeOdfFileW/ASCOfficeOdfFileW.vcproj b/ASCOfficeOdfFileW/ASCOfficeOdfFileW.vcproj
index 8c6c98e6b..cd70ac3f1 100644
--- a/ASCOfficeOdfFileW/ASCOfficeOdfFileW.vcproj
+++ b/ASCOfficeOdfFileW/ASCOfficeOdfFileW.vcproj
@@ -258,6 +258,10 @@
 				RelativePath=".\OfficeOdfFileW.h"
 				>
 			</File>
+			<File
+				RelativePath=".\source\progressCallback.h"
+				>
+			</File>
 			<File
 				RelativePath=".\Resource.h"
 				>
diff --git a/ASCOfficeOdfFileW/ASCOfficeOdfFileWTest/ASCOfficeOdfFileWTest.cpp b/ASCOfficeOdfFileW/ASCOfficeOdfFileWTest/ASCOfficeOdfFileWTest.cpp
index 7a99231e9..188af58f2 100644
--- a/ASCOfficeOdfFileW/ASCOfficeOdfFileWTest/ASCOfficeOdfFileWTest.cpp
+++ b/ASCOfficeOdfFileW/ASCOfficeOdfFileWTest/ASCOfficeOdfFileWTest.cpp
@@ -11,16 +11,100 @@
 
 #define HR_RET(HR) if FAILED(hr = (HR)) { _ASSERTE(false); return -1; }
 
+class CCallback : public ASCOfficeOdfFileW::_IAVSOfficeFileTemplateEvents  
+{
+public:
+
+	CCallback(){m_cnt=0;}
+	virtual ~CCallback(){}
+    STDMETHOD(GetTypeInfoCount)(UINT*) { return E_NOTIMPL; }
+    STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
+    STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return E_NOTIMPL; }
+
+    STDMETHOD(Invoke)(
+		DISPID		dispIdMember, 
+		REFIID		riid, 
+		LCID		lcid, 
+		WORD		wFlags, 
+		DISPPARAMS*	pDispParams, 
+		VARIANT*	pVarResult, 
+		EXCEPINFO*	pExcepInfo, 
+		UINT*		puArgErr) 
+	{
+		switch(dispIdMember)
+		{
+		case 1:
+			std::cout << "\nPercent : " << pDispParams->rgvarg[0].lVal / 10000. << "%\n";    
+			return(S_OK);
+			break;
+		default:
+			return(E_NOTIMPL); 
+		}
+	}
+
+    STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppv) 
+	{ 
+		if ((iid == __uuidof(ASCOfficeOdfFileW::_IAVSOfficeFileTemplateEvents)) ||
+        (iid == __uuidof(IDispatch)) ||
+        (iid == __uuidof(IUnknown)))
+            *ppv = this;
+        else {
+            *ppv = 0;
+            return E_NOINTERFACE;
+        }
+        AddRef();
+        return S_OK;
+    }
+
+    STDMETHOD_(ULONG,AddRef)() { 
+		return InterlockedIncrement(&m_cnt); 
+	}
+
+    STDMETHOD_(ULONG,Release)() { 
+	    InterlockedDecrement(&m_cnt);
+		if (m_cnt!=0) return m_cnt;
+		delete this;
+		return 0;
+    }
+protected:
+	LONG   m_cnt;
+private:
+};
+
+
 int ConvertSingle(int argc, _TCHAR* argv[])
 {
     ATL::CComPtr<ASCOfficeOdfFileW::IAVSOfficeFileTemplate> officeOdfFileW;
     HRESULT hr;
 	HR_RET(officeOdfFileW.CoCreateInstance(__uuidof(ASCOfficeOdfFileW::COfficeOdfFileW)));
+//_______________________________________________________________________________________________________
+		IUnknown *pUnk;
+		IConnectionPointContainer* pContainer;
+		IConnectionPoint* pCP;
+		CCallback *pEvents = NULL;
+		DWORD dwAdvise=0;
+
+		pEvents = new CCallback;
+		pEvents->AddRef();
 
+		HR_RET(officeOdfFileW->QueryInterface(IID_IConnectionPointContainer, (void**)&pContainer));
+		HR_RET(pContainer->FindConnectionPoint(__uuidof(ASCOfficeOdfFileW::_IAVSOfficeFileTemplateEvents),&pCP));	
+
+		HR_RET(pEvents->QueryInterface(IID_IUnknown,(VOID **)&pUnk));
+		HR_RET(pCP->Advise(pUnk,&dwAdvise));
+
+		pContainer->Release();pContainer=NULL;
+		pUnk->Release(); pUnk=NULL;
+//_________________________________________________________________________________________________________
     boost::timer t1;
 	officeOdfFileW->SaveToFile(ATL::CComBSTR(argv[2]), ATL::CComBSTR(argv[1]), NULL);
 
     std::cout << "\n\nTime : " << t1.elapsed() << "\n";    
+//____________________________________________________________________________________________________
+
+	pCP->Unadvise(dwAdvise);
+	pCP->Release();
+	pEvents->Release();
     return 0;
 }
 
diff --git a/ASCOfficeOdfFileW/OfficeOdfFileW.cpp b/ASCOfficeOdfFileW/OfficeOdfFileW.cpp
index 24ce76ce5..de2da457d 100644
--- a/ASCOfficeOdfFileW/OfficeOdfFileW.cpp
+++ b/ASCOfficeOdfFileW/OfficeOdfFileW.cpp
@@ -140,8 +140,15 @@ HRESULT COfficeOdfFileW::SaveToFileImpl(const std::wstring & srcPath,
 	{
 		std::wstring type = DetectTypeDocument(srcTempPath);
 
-		Oox2Odf::Converter converter(srcTempPath, type);
+		ProgressCallback ffCallBack;
+
+		ffCallBack.OnProgress	=	OnProgressFunc;
+		ffCallBack.OnProgressEx	=	OnProgressExFunc;
+		ffCallBack.caller		=	this;
+		
+		Oox2Odf::Converter converter(srcTempPath, type, &ffCallBack);
 		
+
 		converter.convert();
 		converter.write(dstTempPath);
 	}
@@ -201,4 +208,30 @@ std::wstring COfficeOdfFileW::DetectTypeDocument(const std::wstring & Path)
 		}
 	}
 	return L"";
+}
+
+void COfficeOdfFileW::OnProgressFunc (LPVOID lpParam, long nID, long nPercent)
+{
+	//g_oCriticalSection.Enter();
+
+	COfficeOdfFileW* pOdfFile = reinterpret_cast<COfficeOdfFileW*>(lpParam);
+	if (pOdfFile != NULL)
+	{
+		pOdfFile->OnProgress(nID, nPercent);
+	}
+
+	//g_oCriticalSection.Leave();
+}
+
+void COfficeOdfFileW::OnProgressExFunc (LPVOID lpParam, long nID, long nPercent, short* pStop)
+{
+	//g_oCriticalSection.Enter();
+
+	COfficeOdfFileW* pOdfFile = reinterpret_cast<COfficeOdfFileW*>(lpParam);
+	if (pOdfFile != NULL)
+	{
+		pOdfFile->OnProgressEx(nID, nPercent, pStop);
+	}
+
+	//g_oCriticalSection.Leave();
 }
\ No newline at end of file
diff --git a/ASCOfficeOdfFileW/OfficeOdfFileW.h b/ASCOfficeOdfFileW/OfficeOdfFileW.h
index 0533b4fc1..f6668f2c1 100644
--- a/ASCOfficeOdfFileW/OfficeOdfFileW.h
+++ b/ASCOfficeOdfFileW/OfficeOdfFileW.h
@@ -45,7 +45,7 @@ __interface _IOfficeOdfFileWEvents
 
 [
 	coclass,
-	default(IOfficeOdfFileW, _IOfficeOdfFileWEvents),
+	default(IOfficeOdfFileW, _IAVSOfficeFileTemplateEvents),
 	threading(apartment),
 	event_source(com),
 	vi_progid("ASCOfficeOdfFileW.OfficeOdfFileW"),
@@ -62,7 +62,8 @@ public:
 	{
 	}
 
-	__event __interface _IOfficeOdfFileWEvents;
+	__event __interface _IAVSOfficeFileTemplateEvents;
+	__event __interface _IAVSOfficeFileTemplateEvents2;
 
 
 	DECLARE_PROTECT_FINAL_CONSTRUCT()
@@ -92,5 +93,10 @@ private:
 
 	std::wstring DetectTypeDocument(const std::wstring & Path);
 
+protected:
+
+	static void OnProgressFunc (LPVOID lpParam, long nID, long nPercent);
+	static void OnProgressExFunc (LPVOID lpParam, long nID, long nPercent, short* pStop);
+
 };
 
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.cpp
index 3167787b5..c62d2257f 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.cpp
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.cpp
@@ -17,18 +17,20 @@
 #include <XlsxFormat\Xlsx.h>
 #include <DocxFormat\Docx.h>
 
+#define PROGRESSEVENT_ID	0
+
 namespace Oox2Odf
 {
 	static double pt2emu(double Val)
 	{
 		return (Val * 360000 * 2.54) / 72;
 	}
-	Converter::Converter(const std::wstring & path, std::wstring  type) 
+	Converter::Converter(const std::wstring & path, std::wstring  type, const ProgressCallback* CallBack) 
     {
 		impl_ = NULL;
 		
-		if (type == L"text")			impl_ = new DocxConverter(path);
-		if (type == L"spreadsheet")		impl_ = new XlsxConverter(path);
+		if (type == L"text")			impl_ = new DocxConverter(path, CallBack);
+		if (type == L"spreadsheet")		impl_ = new XlsxConverter(path, CallBack);
 	}
 
 	Converter::~Converter() 
@@ -38,15 +40,35 @@ namespace Oox2Odf
     void Converter::convert()
     {
 		if (!impl_)return;
-        impl_->convertDocument();
+		
+		if (impl_->bUserStopConvert) return;
+       
+		impl_->convertDocument();
     }
     void Converter::write(const std::wstring & path) const
     {
 		if (!impl_)return;
-        return impl_->write(path);
+
+		if (impl_->bUserStopConvert) return;
+
+		return impl_->write(path);
     }
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
+BOOL  OoxConverter::UpdateProgress(long nComplete)
+{
+	if (pCallBack)
+	{
+		pCallBack->OnProgress (pCallBack->caller, PROGRESSEVENT_ID, nComplete);
+
+		bUserStopConvert = 0;
+		pCallBack->OnProgressEx (pCallBack->caller, PROGRESSEVENT_ID, nComplete, &bUserStopConvert);
+
+		if (bUserStopConvert !=0 ) return TRUE;
+	}
+
+	return FALSE;
+}
 void OoxConverter::convert(OOX::WritingElement  *oox_unknown)
 {
 	if (oox_unknown == NULL)return;
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.h b/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.h
index eb5f609a9..ecceec696 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.h
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/Converter.h
@@ -6,6 +6,9 @@
 
 #include <atlcoll.h>
 
+#include "..\progressCallback.h"
+
+
 static std::wstring string2std_string(CString val)
 {
 	return std::wstring(val.GetBuffer());
@@ -240,7 +243,9 @@ public:
 		virtual void convertDocument() = 0;
 		virtual void write(const std::wstring & path) = 0;
 		
-		OoxConverter(){oox_current_chart = NULL;}
+		OoxConverter(const ProgressCallback* CallBack = NULL){oox_current_chart = NULL; pCallBack = CallBack;bUserStopConvert = 0;}
+	
+		BOOL UpdateProgress(long nComplete);
 
 		virtual cpdoccore::odf::odf_conversion_context		*odf_context() = 0;
 		virtual OOX::CTheme									*oox_theme() = 0;
@@ -337,13 +342,16 @@ public:
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
 		void convert(double oox_font_size,			cpdoccore::_CP_OPT(cpdoccore::odf::font_size) & odf_font_size);
+
+		const ProgressCallback* pCallBack;
+		short bUserStopConvert;
 	};
 
 	class Converter
 	{
 
 	public:
-		Converter(const std::wstring & path, std::wstring  type);
+		Converter(const std::wstring & path, std::wstring  type, const ProgressCallback* ffCallBack);
         virtual ~Converter();
 
 	public:
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp
index 3145d07d7..5601122c5 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.cpp
@@ -29,22 +29,27 @@ using namespace cpdoccore;
 
 namespace Oox2Odf
 {
-DocxConverter::DocxConverter(const std::wstring & path)
+DocxConverter::DocxConverter(const std::wstring & path, const ProgressCallback* CallBack)
 {
 	output_document = new  odf::package::odf_document(L"text");
 
+	pCallBack = CallBack;
+
 	const OOX::CPath oox_path(CString(path.c_str()));	
 	docx_document = new OOX::CDocx(oox_path);	
 
 //set flags to default
 	m_bKeepNextParagraph = false;
+	
+	if (UpdateProgress(400000))return;
 }
 void DocxConverter::write(const std::wstring & path)
 {
 	if (!output_document)return;
 
 	output_document->write(path);
-
+		
+	if (UpdateProgress(1000000))return;
 }
 odf::odf_conversion_context* DocxConverter::odf_context()
 {
@@ -114,13 +119,17 @@ void DocxConverter::convertDocument()
 	odt_context->start_document();
 
 	convert_styles();
+	if (UpdateProgress(500000))return;
+
 	convert_document();
 
+	if (UpdateProgress(800000))return;
 	//удалим уже ненужный документ docx 
 	delete docx_document; docx_document = NULL;
 
 	odt_context->end_document();
- 
+ 	
+	if (UpdateProgress(850000))return;
 }
 
 void DocxConverter::convert_document()
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.h b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.h
index b2b92aefb..416a39688 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.h
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/DocxConverter.h
@@ -80,7 +80,7 @@ namespace Oox2Odf
 	class DocxConverter : public OoxConverter
 	{
 	public:
-		DocxConverter(const std::wstring & path);
+		DocxConverter(const std::wstring & path, const ProgressCallback* ffCallBack);
 
 		virtual void convertDocument();
 		virtual void write(const std::wstring & path);
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp
index 217b70fef..3a7a2fb7e 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.cpp
@@ -26,14 +26,18 @@ using namespace cpdoccore;
 namespace Oox2Odf
 {
 
-XlsxConverter::XlsxConverter(const std::wstring & path) 
+XlsxConverter::XlsxConverter(const std::wstring & path, const ProgressCallback* CallBack) 
 {
 	const OOX::CPath oox_path(CString(path.c_str()));			
 
+	pCallBack = CallBack;
+
 	xlsx_document = new OOX::Spreadsheet::CXlsx(oox_path);	
 	output_document = new odf::package::odf_document(L"spreadsheet");
 
 	xlsx_current_drawing = NULL;
+
+	if (UpdateProgress(400000))return;
 }
 
 void XlsxConverter::write(const std::wstring & path)
@@ -42,6 +46,8 @@ void XlsxConverter::write(const std::wstring & path)
 	output_document->write(path);
 
 	delete output_document; output_document = NULL;
+
+	if (UpdateProgress(1000000))return;
 }
 odf::odf_conversion_context* XlsxConverter::odf_context()
 {
@@ -97,13 +103,17 @@ void XlsxConverter::convertDocument()
 	ods_context->start_document();
 
 	convert_styles();
+	if (UpdateProgress(500000))return;
+
 	convert_sheets();
 
 	//удалим уже ненужный документ xlsx 
+	if (UpdateProgress(800000))return;
 	delete xlsx_document; xlsx_document = NULL;
 
 	ods_context->end_document();
 
+	if (UpdateProgress(850000))return;
 }
 void XlsxConverter::convert_sheets()
 {
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.h b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.h
index aeb7cb9d0..00c9a739c 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.h
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/XlsxConverter.h
@@ -90,7 +90,7 @@ namespace Oox2Odf
 	class XlsxConverter : public OoxConverter
 	{
 	public:
-		XlsxConverter(const std::wstring & path);
+		XlsxConverter(const std::wstring & path, const ProgressCallback* ffCallBack);
 
 		virtual void convertDocument();
 		virtual void write(const std::wstring & path);
diff --git a/ASCOfficeOdfFileW/source/Oox2OdfConverter/stdafx.h b/ASCOfficeOdfFileW/source/Oox2OdfConverter/stdafx.h
index 58484e6c5..e9a95ed86 100644
--- a/ASCOfficeOdfFileW/source/Oox2OdfConverter/stdafx.h
+++ b/ASCOfficeOdfFileW/source/Oox2OdfConverter/stdafx.h
@@ -14,4 +14,4 @@
 #include <atlbase.h>
 #include <atlstr.h>
 
-// TODO: reference additional headers your program requires here
+
diff --git a/ASCOfficeOdfFileW/source/progressCallback.h b/ASCOfficeOdfFileW/source/progressCallback.h
new file mode 100644
index 000000000..5977168a5
--- /dev/null
+++ b/ASCOfficeOdfFileW/source/progressCallback.h
@@ -0,0 +1,11 @@
+#pragma once
+
+typedef void (*OnProgressCallback)( LPVOID lpParam, long nID, long nPercent );
+typedef void (*OnProgressExCallback)( LPVOID lpParam, long nID, long nPercent, short* Cancel );
+
+struct ProgressCallback
+{
+  OnProgressCallback OnProgress;
+  OnProgressExCallback OnProgressEx;
+  LPVOID caller;
+};
diff --git a/ASCOfficeOdfFileW/stdafx.h b/ASCOfficeOdfFileW/stdafx.h
index 2fa84c31e..18a957f18 100644
--- a/ASCOfficeOdfFileW/stdafx.h
+++ b/ASCOfficeOdfFileW/stdafx.h
@@ -40,3 +40,5 @@ using namespace ATL;
 [
 	importidl(ASCOfficeOdfFileW.idl)
 ];
+
+#include "source\progressCallback.h"
diff --git a/ASCOfficeOdfFileW/version.h b/ASCOfficeOdfFileW/version.h
index baebf98da..be3ca3410 100644
--- a/ASCOfficeOdfFileW/version.h
+++ b/ASCOfficeOdfFileW/version.h
@@ -2,6 +2,6 @@
 //1
 //2
 //0
-//89
-#define INTVER 1,2,0,89
-#define STRVER "1,2,0,89\0"
+//92
+#define INTVER 1,2,0,92
+#define STRVER "1,2,0,92\0"
-- 
2.30.9