Compare commits

...

8 Commits

46 changed files with 1062 additions and 401 deletions

File diff suppressed because one or more lines are too long

View File

@ -99,6 +99,9 @@ namespace PPTX
SpTreeElem element;
std::wstring GetVmlXmlBySpid(smart_ptr<OOX::IFileContainer> & rels) const;
void ChartToOlePackageInStorage(OOX::IFileContainer* pRels, const std::wstring &sTempDirectory, const std::wstring &sOleFileName);
std::wstring ChartToXlsx(OOX::IFileContainer* pRels, const std::wstring &sTempDirectory);
protected:
virtual void FillParentPointersForChilds();
};

View File

@ -37,14 +37,12 @@
#include "ConvertationManager.h"
#include <boost/algorithm/string.hpp>
#include "../../../OfficeUtils/src/OfficeUtils.h"
HRESULT ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name)
void ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name)
{
HRESULT hr = S_FALSE;
Ole1FormatReader ole1Reader(pData, nSize);
Ole1FormatReaderWriter ole1Reader(pData, nSize);
bool bResult = false;
if (ole1Reader.NativeDataSize > 0)
{
NSFile::CFileBinary file;
@ -56,9 +54,13 @@ HRESULT ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name)
POLE::Storage * storageIn = new POLE::Storage(sOle2Name.c_str());
if ( (storageIn) && (storageIn->open(false, false))) //storage in storage
{
//test package stream??? xls ole -> xlsx ole
bResult = true;
storageIn->close();
}
else
delete storageIn;
if (!bResult)
{
POLE::Storage * storageOut = new POLE::Storage(sOle2Name.c_str());
if ( (storageOut) && (storageOut->open(true, true)))
@ -104,26 +106,37 @@ HRESULT ConvertOle1ToOle2(BYTE *pData, int nSize, std::wstring sOle2Name)
//Ole10Native
POLE::Stream streamData(storageOut, L"\001Ole10Native", true, ole1Reader.NativeDataSize + 4);
streamData.write((BYTE*)&ole1Reader.NativeDataSize, 4);
streamData.write(ole1Reader.NativeData, ole1Reader.NativeDataSize);
_UINT32 sz_write = 0;
_UINT32 sz = 4096;
while (sz_write < ole1Reader.NativeDataSize)
{
if (sz_write + sz > ole1Reader.NativeDataSize)
sz = ole1Reader.NativeDataSize - sz_write;
streamData.write(ole1Reader.NativeData + sz_write, sz);
sz_write += sz;
}
streamData.flush();
storageOut->close();
delete storageOut;
bResult = true;
}
}
}
else //conv_NI38P7GBIpw1aD84H3k.rtf
if (!bResult) //conv_NI38P7GBIpw1aD84H3k.rtf
{
NSFile::CFileBinary file;
file.CreateFileW(sOle2Name);
file.WriteFile(pData, nSize);
file.CloseFile();
bResult = true;
}
return S_FALSE;
}
//-----------------------------------------------------------------------------------------
bool RtfDocumentCommand::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, std::string sCommand, bool hasParameter, int parameter)
{
if ( "ansi" == sCommand ) oDocument.m_oProperty.m_eCodePage = RtfDocumentProperty::cp_ansi;
@ -1786,48 +1799,15 @@ bool RtfOleReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, st
if ( 0 != nSize && pData)
{
HRESULT hRes = S_FALSE;
boost::shared_array<BYTE> buffer(pData);
m_oOle.m_oOle1Data = std::make_pair(buffer, nSize);
//конвертация Ole1 в Ole2
#if 0//defined(_WIN32) || defined(_WIN64)
RtfOle1ToOle2Stream oStream;
oStream.lpstbl = new OLESTREAMVTBL();
oStream.lpstbl->Get = &OleGet1;
oStream.lpstbl->Put = &OlePut1;
oStream.pBuffer = pData;
oStream.nBufferSize = nSize;
oStream.nCurPos = 0;
std::wstring sOleStorageName = Utils::CreateTempFile( oReader.m_sTempFolder );
IStorage* piMSStorage = NULL;
if ( SUCCEEDED( StgCreateDocfile( sOleStorageName.c_str(), STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_TRANSACTED/* | STGM_DELETEONRELEASE*/, NULL, &piMSStorage) ) )
{
hRes = OleConvertOLESTREAMToIStorage( &oStream, piMSStorage, NULL );
piMSStorage->Commit( STGC_DEFAULT );
RELEASEINTERFACE( piMSStorage );
}
delete oStream.lpstbl;
#else
std::wstring sOleStorageName = NSDirectory::CreateTempFileWithUniqueName(oReader.m_sTempFolder, L"img");
hRes = ConvertOle1ToOle2(pData, nSize, sOleStorageName);
#endif
delete[] pData;
POLE::Storage * piRootStorage = new POLE::Storage(sOleStorageName.c_str());
if ( piRootStorage)
{
m_oOle.SetFilename( sOleStorageName.c_str() );
m_oOle.SetOle( piRootStorage );
hRes = S_OK;
}
if ( hRes != S_OK )
Utils::RemoveDirOrFile( sOleStorageName.c_str() );
//конвертация Ole1 в Ole2
ConvertOle1ToOle2(pData, nSize, sOleStorageName);
m_oOle.SetFilename( sOleStorageName.c_str() );
}
}
else if ( "result" == sCommand )
@ -1837,7 +1817,7 @@ bool RtfOleReader::ExecuteCommand(RtfDocument& oDocument, RtfReader& oReader, st
RtfAllPictReader oAllPictReader( *oNewShape );
StartSubReader( oAllPictReader, oDocument, oReader );
m_oOle.m_oResultPic = oNewShape;
m_oOle.m_oResultShape = oNewShape;
}
else
return false;

View File

@ -1148,12 +1148,16 @@ public:
RtfShapeReader oShapeReader(m_oShape);
StartSubReader( oShapeReader, oDocument, oReader );
}
if( "shppict" == sCommand )
else if( "shppict" == sCommand )
{
RtfShppictReader oShppictReader(m_oShape);
StartSubReader( oShppictReader, oDocument, oReader );
}
else if( "pict" == sCommand )
else if( "nonshppict" == sCommand )
{
Skip( oDocument, oReader );
}
else if( "pict" == sCommand )
{
m_oShape.m_eAnchorTypeShape = RtfShape::st_inline;
m_oShape.m_nShapeType = NSOfficeDrawing::sptPictureFrame;

View File

@ -58,7 +58,7 @@ public:
return pCur;
}
unsigned char ReadUChar()
unsigned char ReadUChar()
{
if (pCur + 1 >= pEnd)
return 0;
@ -67,6 +67,14 @@ public:
pCur++;
return unResult;
};
void WriteUChar(unsigned char val)
{
if (pCur + 1 >= pEnd)
return;
pCur[0] = val;
pCur++;
};
unsigned short ReadUShort()
{
if (pCur + 2 >= pEnd)
@ -76,15 +84,31 @@ public:
pCur += 2;
return ushResult;
};
unsigned int ReadULong()
void WriteUShort(unsigned short val)
{
if (pCur + 2 >= pEnd)
return;
((unsigned short*) pCur)[0] = val;
pCur += 2;
};
_UINT32 ReadULong()
{
if (pCur + 4 >= pEnd)
return 0;
unsigned int unResult = (unsigned int)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24));
_UINT32 unResult = (_UINT32)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24));
pCur += 4;
return unResult;
};
void WriteULong(_UINT32 val)
{
if (pCur + 4 >= pEnd)
return;
((_UINT32*)pCur)[0] = val;
pCur += 4;
};
double ReadDouble()
{
if (pCur + 4 >= pEnd)
@ -110,13 +134,25 @@ public:
{
return (char)ReadUChar();
};
short ReadShort()
void WriteChar(char val)
{
WriteUChar((unsigned char)val);
};
short ReadShort()
{
return (short)ReadUShort();
};
int ReadLong()
void WriteShort(short val)
{
return (int)ReadULong();
WriteUShort((unsigned short) val);
};
_INT32 ReadLong()
{
return (_INT32)ReadULong();
};
void WriteLong(_INT32 val)
{
WriteULong((_UINT32)val);
};
void ReadBytes(char* pBuffer, unsigned int ulSize)
{
@ -128,6 +164,16 @@ public:
pBuffer[ulIndex] = ReadChar();
}
};
void WriteBytes(char* pBuffer, unsigned int ulSize)
{
size_t ulRemainSize = (pEnd - pCur);
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
WriteChar(pBuffer[ulIndex]);
}
};
void ReadBytes(unsigned char* pBuffer, unsigned int ulSize)
{
size_t ulRemainSize = (pEnd - pCur);
@ -135,7 +181,17 @@ public:
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
pBuffer[ulIndex] = ReadChar();
pBuffer[ulIndex] = ReadUChar();
}
};
void WriteBytes(unsigned char* pBuffer, unsigned int ulSize)
{
size_t ulRemainSize = (pEnd - pCur);
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
WriteUChar(pBuffer[ulIndex]);
}
};
void ReadBytes(unsigned short* pBuffer, unsigned int ulSize)
@ -158,7 +214,7 @@ public:
pBuffer[ulIndex] = ReadShort();
}
}
void ReadBytes(unsigned int* pBuffer, unsigned int ulSize)
void ReadBytes(_UINT32* pBuffer, unsigned int ulSize)
{
size_t ulRemainSize = (pEnd - pCur) / 4;
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
@ -173,22 +229,32 @@ public:
nValue = ReadUChar();
return *this;
}
CDataStream& operator<<(unsigned char nValue)
{
WriteUChar(nValue);
return *this;
}
CDataStream& operator>>(unsigned short& nValue)
{
nValue = ReadUShort();
return *this;
}
CDataStream& operator>>(unsigned int& nValue)
CDataStream& operator<<(unsigned short nValue)
{
WriteUShort(nValue);
return *this;
}
CDataStream& operator>>(_UINT32& nValue)
{
nValue = ReadULong();
return *this;
}
CDataStream& operator>>(unsigned long& nValue)
CDataStream& operator<<(_UINT32 nValue)
{
nValue = ReadULong();
WriteULong(nValue);
return *this;
}
CDataStream& operator>>(double& dValue)
CDataStream& operator>>(double& dValue)
{
dValue = ReadDouble();
return *this;
@ -198,6 +264,11 @@ public:
nValue = ReadChar();
return *this;
}
CDataStream& operator<<(char nValue)
{
WriteChar(nValue);
return *this;
}
CDataStream& operator>>(bool& nValue)
{
nValue = !!ReadChar();
@ -208,17 +279,23 @@ public:
nValue = ReadShort();
return *this;
}
CDataStream& operator>>(int& nValue)
CDataStream& operator<<(short nValue)
{
WriteShort(nValue);
return *this;
}
CDataStream& operator>>(_INT32& nValue)
{
nValue = ReadLong();
return *this;
}
CDataStream& operator>>(long& nValue)
CDataStream& operator<<(_INT32 nValue)
{
nValue = ReadLong();
WriteLong(nValue);
return *this;
}
bool IsValid() const
{
if (NULL == pBuffer)
@ -255,7 +332,7 @@ public:
pCur = pBuffer;
}
unsigned int CanRead()
unsigned int CanReadWrite()
{
return (unsigned int)(pEnd - pCur);
}
@ -269,36 +346,55 @@ private:
};
struct LengthPrefixedAnsiString
{
_UINT32 size;
_UINT32 size = 0;
std::string val;
};
CDataStream & operator >> (CDataStream & strm, LengthPrefixedAnsiString & str)
static CDataStream & operator >> (CDataStream & strm, LengthPrefixedAnsiString & str)
{
strm >> str.size;
char *s = new char[str.size];
strm.ReadBytes(s, str.size);
str.val = std::string(s,str.size);
str.val = std::string(s, str.size);
delete []s;
return strm;
}
static CDataStream & operator << (CDataStream & strm, LengthPrefixedAnsiString str)
{
strm << str.size;
strm.WriteBytes((char*)str.val.c_str(), str.size - 1);
strm.WriteUChar(0);
return strm;
}
struct ObjectHeader
{
_UINT32 OLEVersion;
_UINT32 FormatID;
_UINT32 OLEVersion = 1281;
_UINT32 FormatID = 2;
LengthPrefixedAnsiString ClassName;
_UINT32 Width;
_UINT32 Height;
_UINT32 Width = 0;
_UINT32 Height = 0;
};
class Ole1FormatReader
class Ole1FormatReaderWriter
{
public:
Ole1FormatReader(BYTE *pData, int Size)
Ole1FormatReaderWriter() : NativeData(NULL), NativeDataSize(0), OtherData(NULL), OtherDataSize(0)
{
}
Ole1FormatReaderWriter(BYTE *pData, int Size) : NativeData(NULL), NativeDataSize(0), OtherData(NULL), OtherDataSize(0)
{
Read(pData, Size);
}
virtual ~Ole1FormatReaderWriter()
{
if (OtherData)
delete []OtherData;
OtherData = NULL;
}
void Read(BYTE *pData, int Size)
{
NativeDataSize = 0;
if (!pData || Size < 8) return;
@ -320,15 +416,57 @@ public:
NativeData = stream.GetCurPtr();
stream.Skip(NativeDataSize);
int sz = stream.CanRead();
if (stream.IsEof())
return;
// далее графическое представление
OtherDataSize = stream.CanReadWrite();
/// далее графическое представление
OtherData = new BYTE[OtherDataSize];
stream.ReadBytes(OtherData, OtherDataSize);
}
}
void Write(BYTE *pData, int &Size)
{
Size = 0;
if (!pData) return;
if (NativeDataSize < 1) return;
CDataStream stream(pData, NativeDataSize + 2048);
stream << Header.OLEVersion << Header.FormatID;
stream << Header.ClassName;
stream << Header.Width << Header.Height;
stream << NativeDataSize;
stream.WriteBytes(NativeData, NativeDataSize);
/// далее графическое представление
BYTE other[9] = {1, 5, 0, 0, 0, 0, 0, 0, 0};
Size = stream.Tell() - 1;
stream.WriteBytes(other, 9);
Size = stream.Tell() - 1;
//padding ???
char padding[8];
memset(padding, 0, 8);
stream.WriteBytes(padding, (Size / 8 + 1 ) * 8 - Size);
Size = stream.Tell() - 1;
}
ObjectHeader Header;
_UINT32 NativeDataSize;
BYTE *NativeData;
_UINT32 OtherDataSize;
BYTE *OtherData;
//PresentationObjectHeader PresentationHeader;
};

View File

@ -53,12 +53,16 @@ int OOXGraphicReader::Parse( ReaderParameter oParam , RtfShapePtr & pOutput)
return (shapeReader.Parse(oParam, pOutput) ? 1 : 0);
}
}
if (m_ooxGraphic->chartRec.IsInit())
{
//сгенерим ole (olePic)
std::wstring sOleFileName = L"oleObject" + std::to_wstring(++oParam.oReader->m_nCurOleChartId) + L".bin";
m_ooxGraphic->ChartToOlePackageInStorage(oParam.oReader->m_currentContainer, oParam.oReader->m_sTempFolder, sOleFileName);
}
if (m_ooxGraphic->olePic.IsInit())
{
pOutput->m_nShapeType = 75;
OOXShapeReader::Parse(oParam, pOutput, &m_ooxGraphic->olePic->blipFill); // тут если false приходит - картинка-потеряшка
return 1;
OOXShapeReader shapeReader(m_ooxGraphic->olePic.GetPointer());
return (shapeReader.Parse(oParam, pOutput) ? 1 : 0);
}
if (m_ooxGraphic->smartArt.IsInit())
{
@ -69,9 +73,10 @@ int OOXGraphicReader::Parse( ReaderParameter oParam , RtfShapePtr & pOutput)
return (groupReader.Parse(oParam, pOutput) ? 1 : 0);
}
}
//nullable_string spid;
//nullable<Table> table;
//nullable<ChartRec> chartRec;
return 0;
}

View File

@ -597,142 +597,40 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap
case OOX::et_w_object:
{
OOX::Logic::CObject * ooxObject = dynamic_cast<OOX::Logic::CObject*>(ooxItem);
RtfShapePtr pNewShape ( new RtfShape() );
if (ooxObject)
{
long nOleWidth = PROP_DEF;
long nOleHeight = PROP_DEF;
RtfShapePtr aPictShape;
RtfOlePtr oCurOle;
if (ooxObject->m_oShape.IsInit())
{//важна последовательность обработки
OOXShapeReader oShapeReaderType(ooxObject->m_oShapeType.GetPointer());
oShapeReaderType.Parse( oParam, pNewShape );
OOXShapeReader oShapeReaderShape(ooxObject->m_oShape.GetPointer());
oShapeReaderShape.Parse( oParam, pNewShape );
for (size_t i = 0; i < ooxObject->m_arrItems.size(); ++i)
{
RtfShapePtr oNewShape ( new RtfShape() );
oNewShape->m_eAnchorTypeShape = RtfShape::st_inline;
oNewShape->m_oCharProperty = oNewProperty;
OOXShapeReader oShapeReader(ooxObject->m_oShape.GetPointer());
if( true == oShapeReader.Parse( oParam, oNewShape ) )
aPictShape = oNewShape;
}
OOXShapeReader oShapeReader(ooxObject->m_arrItems[i]);
oShapeReader.Parse( oParam, pNewShape );
}
if (ooxObject->m_oOleObject.IsInit())
{
RtfOlePtr oNewOle ( new RtfOle() );
oNewOle->m_nWidth = nOleWidth; //?? todooo
oNewOle->m_nHeight = nOleHeight;
int nShapeId = PROP_DEF;
if (ooxObject->m_oOleObject->m_sShapeId.IsInit())
nShapeId = oParam.oReader->m_oOOXIdGenerator.GetId(ooxObject->m_oOleObject->m_sShapeId.get2());
if( PROP_DEF != nShapeId )
{
oNewOle->m_nShapeId = nShapeId;
//ставим соответствующий shape
if( NULL != aPictShape && aPictShape->m_nID == nShapeId )
aPictShape->m_bIsOle = true;
}
if( ooxObject->m_oOleObject->m_sProgId.IsInit() )
oNewOle->m_sOleClass = ooxObject->m_oOleObject->m_sProgId.get2();
if(ooxObject->m_oOleObject->m_oType.IsInit())
{
switch( ooxObject->m_oOleObject->m_oType->GetValue())
{
case SimpleTypes::oletypeLink: oNewOle->m_eOleType = RtfOle::ot_link; break;
case SimpleTypes::oletypeEmbed: oNewOle->m_eOleType = RtfOle::ot_emb; break;
}
}
if(ooxObject->m_oOleObject->m_oId.IsInit())
{
std::wstring sRelativePath;
if (oParam.oReader->m_currentContainer)
{
smart_ptr<OOX::File> oFile = oParam.oReader->m_currentContainer->Find(ooxObject->m_oOleObject->m_oId->GetValue());
if ((oFile.IsInit() && (OOX::FileTypes::OleObject == oFile->type())))
{
OOX::OleObject* pO = (OOX::OleObject*)oFile.operator->();
sRelativePath = pO->filename().m_strFilename;
}
}
//todooo проверить что тут за путь ..
std::wstring sOlePath = sRelativePath;
POLE::Storage *storage = new POLE::Storage(sOlePath.c_str());
if (storage)
{
//RtfOle2ToOle1Stream oStream;
//oStream.lpstbl = new OLESTREAMVTBL();
//oStream.lpstbl->Get = &OleGet2;
//oStream.lpstbl->Put = &OlePut2;
//todooo convert ole2 to ole1
//if( SUCCEEDED( OleConvertIStorageToOLESTREAM( piStorage, &oStream ) ) )
//{
// //сохраняем в файл
// std::wstring sOleStorageName = Utils::CreateTempFile( oParam.oReader->m_sTempFolder );
// HANDLE hFile = CreateFile ( sOleStorageName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
// if( INVALID_HANDLE_VALUE != hFile )
// {
// DWORD dwByteWrite = 0;
// WriteFile( hFile, oStream.aBuffer.GetData(), (DWORD)oStream.aBuffer.size(), &dwByteWrite, NULL );
// CloseHandle( hFile );
// oNewOle->SetFilename( sOleStorageName );
// //только сейчас запоминаем
// oCurOle = oNewOle;
// }
// else
// Utils::RemoveDirOrFile( sOleStorageName );
//}
delete( storage );
}
}
}
if( NULL != aPictShape)
{
aPictShape->m_nShapeType = 75;//NSOfficeDrawing::sptPictureFrame;
//надо пересчитать размеры картинки так чтобы scalex == 100 и scaley = 100
//если scalex != 100, то после редактирование ole киртинка сжимается(растягивается)
if( NULL != aPictShape->m_oPicture )
{
if( PROP_DEF != (int)aPictShape->m_oPicture->m_dScaleX && PROP_DEF != (int)aPictShape->m_oPicture->m_dScaleY &&
PROP_DEF != aPictShape->m_oPicture->m_nWidthGoal && PROP_DEF != aPictShape->m_oPicture->m_nHeightGoal )
{
if( 100 != (int)aPictShape->m_oPicture->m_dScaleX )
{
aPictShape->m_oPicture->m_nWidthGoal = long (( aPictShape->m_oPicture->m_dScaleX / 100.0 ) * aPictShape->m_oPicture->m_nWidthGoal );
aPictShape->m_oPicture->m_dScaleX = 100;
}
if( 100 != (int)aPictShape->m_oPicture->m_dScaleY )
{
aPictShape->m_oPicture->m_nHeightGoal = long (( aPictShape->m_oPicture->m_dScaleY / 100.0 ) * aPictShape->m_oPicture->m_nHeightGoal );
aPictShape->m_oPicture->m_dScaleY = 100;
}
}
}
}
if( NULL != aPictShape && NULL != oCurOle )
{
TextItemContainerPtr oNewTextItemContainer ( new TextItemContainer() );
RtfParagraphPtr pNewPar ( new RtfParagraph() );
pNewPar->AddItem( oCurOle );
oNewTextItemContainer->AddItem( pNewPar );
aPictShape->m_aTextItems = oNewTextItemContainer;
oCurOle->m_oResultPic = aPictShape;
oOutputParagraph.AddItem( oCurOle );
}
else if (NULL != aPictShape)
{
oOutputParagraph.AddItem( aPictShape );
}
OOXShapeReader oShapeReaderControl(ooxObject->m_oControl.GetPointer());
oShapeReaderControl.Parse( oParam, pNewShape );
OOXShapeReader oShapeReaderObject(ooxObject->m_oOleObject.GetPointer());
oShapeReaderObject.Parse( oParam, pNewShape );
}
if (pNewShape->m_bIsOle && pNewShape->m_pOleObject)
{
if (ooxObject->m_oDxaOrig.IsInit()) pNewShape->m_pOleObject->m_nWidth = *ooxObject->m_oDxaOrig;
if (ooxObject->m_oDyaOrig.IsInit()) pNewShape->m_pOleObject->m_nHeight = *ooxObject->m_oDyaOrig;
pNewShape->m_pOleObject->m_oResultShape = pNewShape;
oOutputParagraph.AddItem( pNewShape->m_pOleObject );
}
else
oOutputParagraph.AddItem( pNewShape );
}break;
case OOX::et_w_drawing:
{
@ -748,8 +646,15 @@ bool OOXRunReader::Parse( ReaderParameter oParam , RtfParagraph& oOutputParagrap
if (result == 1)
{
oOutputParagraph.AddItem( pNewDrawing );
bAddDrawing = true;
if (pNewDrawing->m_bIsOle && pNewDrawing->m_pOleObject)
{
pNewDrawing->m_pOleObject->m_oResultShape = pNewDrawing;
oOutputParagraph.AddItem( pNewDrawing->m_pOleObject );
}
else
oOutputParagraph.AddItem( pNewDrawing );
bAddDrawing = true;
}
if (!bAddDrawing)
{

View File

@ -80,19 +80,19 @@ public:
if( m_ooxAnchor->m_oSimplePos.IsInit())
{
nLeft = (int)m_ooxAnchor->m_oSimplePos->m_oX.ToTwips() ;
nTop = (int)m_ooxAnchor->m_oSimplePos->m_oY.ToTwips();
pOutput->m_nLeft = (int)m_ooxAnchor->m_oSimplePos->m_oX.ToTwips() ;
pOutput->m_nTop = (int)m_ooxAnchor->m_oSimplePos->m_oY.ToTwips();
}
if( m_ooxAnchor->m_oExtent.IsInit() )
{
nWidth = (int)m_ooxAnchor->m_oExtent->m_oCx.ToTwips();
nHeight = (int)m_ooxAnchor->m_oExtent->m_oCy.ToTwips();
pOutput->m_nWidth = (int)m_ooxAnchor->m_oExtent->m_oCx.ToTwips();
pOutput->m_nHeight = (int)m_ooxAnchor->m_oExtent->m_oCy.ToTwips();
if( PROP_DEF != pOutput->m_nLeft && PROP_DEF != pOutput->m_nTop )//всегда !!
{
pOutput->m_nRight = pOutput->m_nLeft + nWidth;
pOutput->m_nBottom = pOutput->m_nTop + nHeight;
pOutput->m_nRight = pOutput->m_nLeft + pOutput->m_nWidth;
pOutput->m_nBottom = pOutput->m_nTop + pOutput->m_nHeight;
}
}
if( m_ooxAnchor->m_oPositionH.IsInit() )

View File

@ -44,6 +44,8 @@ OOXReader::OOXReader( RtfDocument& oDocument, std::wstring path ): m_oDocument(
{
m_sPath = path;
m_nCurItap = 0;
m_nCurOleChartId = 0;
m_nCurFittextId = 0;
m_convertationManager = NULL;
m_currentContainer = NULL;

View File

@ -64,6 +64,7 @@ public:
int m_nCurItap; //для определение вложенности таблицы
int m_nCurOleChartId;
int m_nCurFittextId;
std::map<int, std::wstring> m_aBookmarks;

View File

@ -31,6 +31,8 @@
*/
#include "OOXShapeReader.h"
#include "OOXTextItemReader.h"
#include "../Ole1FormatReader.h"
#include "../RtfOle.h"
#include "../../../../ASCOfficePPTXFile/Editor/Drawing/Shapes/Shape.h"
#include "../../../../ASCOfficePPTXFile/PPTXFormat/Logic/SpTree.h"
@ -44,7 +46,7 @@
#define RGB(r,g,b) ((_UINT32)(((BYTE)(r)|((_UINT16)((BYTE)(g))<<8))|(((_UINT32)(BYTE)(b))<<16)))
#endif
bool ParseVmlStyle(RtfShapePtr pShape, SimpleTypes::Vml::CCssProperty* prop)
bool OOXShapeReader::ParseVmlStyle(RtfShapePtr pShape, SimpleTypes::Vml::CCssProperty* prop)
{
if (pShape == NULL) return false;
if (prop == NULL) return false;
@ -316,7 +318,7 @@ bool OOXShapeReader::ParseVmlChild( ReaderParameter oParam , RtfShapePtr& pOutpu
std::wstring sImagePath = pImage->filename().GetPath();
pOutput->m_oPicture = RtfPicturePtr( new RtfPicture() );
WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sPath );
WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sTempFolder );
pOutput->m_nFillType = 2;
}
@ -402,7 +404,7 @@ bool OOXShapeReader::ParseVmlChild( ReaderParameter oParam , RtfShapePtr& pOutpu
OOX::Image* pImage = (OOX::Image*)oFile.operator->();
std::wstring sImagePath = pImage->filename().GetPath();
WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sPath );
WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sTempFolder );
}
}
int nCropedWidthGoal = pOutput->m_oPicture->m_nWidthGoal;
@ -738,7 +740,7 @@ bool OOXShapeReader::Parse(ReaderParameter oParam, RtfShapePtr& pOutput, PPTX::L
OOX::Image* pImage = (OOX::Image*)oFile.operator->();
std::wstring sImagePath = pImage->filename().GetPath();
result = WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sPath);
result = WriteDataToPicture( sImagePath, *pOutput->m_oPicture, oParam.oReader->m_sTempFolder);
}
}
else if (oox_bitmap_fill->blip->link.IsInit())
@ -1344,6 +1346,16 @@ bool OOXShapeReader::ParsePic( ReaderParameter oParam, RtfShapePtr& pOutput)
Parse(oParam, pOutput, &ooxPic->blipFill);
if (pOutput->m_oPicture->m_sPicFilename.empty() && !ooxPic->blipFill.blip->oleFilepathImage.empty())
{
pOutput->m_oPicture->eDataType = RtfPicture::dt_png;
pOutput->m_oPicture->m_sPicFilename = ooxPic->blipFill.blip->oleFilepathImage;
pOutput->m_oPicture->m_bIsCopy = false; //не удалять
pOutput->m_oPicture->m_nWidthGoal = pOutput->m_nWidth;
pOutput->m_oPicture->m_nHeightGoal = pOutput->m_nHeight;
}
if ((oox_sp_style) && (oox_sp_style->lnRef.idx.IsInit()))
{
Parse(oParam, pOutput, &oox_sp_style->lnRef, 2);
@ -1364,6 +1376,63 @@ bool OOXShapeReader::ParsePic( ReaderParameter oParam, RtfShapePtr& pOutput)
pOutput->m_oPicture->m_dScaleY = (pOutput->m_nBottom - pOutput->m_nTop)* 100. / pOutput->m_oPicture->m_nHeightGoal;
}
}
if (ooxPic->oleObject.IsInit())
{
pOutput->m_bIsOle = true;
pOutput->m_pOleObject = RtfOlePtr(new RtfOle());
if (ooxPic->oleObject->m_oDxaOrig.IsInit())
pOutput->m_pOleObject->m_nWidth = *ooxPic->oleObject->m_oDxaOrig;
if (ooxPic->oleObject->m_oDyaOrig.IsInit())
pOutput->m_pOleObject->m_nHeight = *ooxPic->oleObject->m_oDyaOrig;
if (ooxPic->oleObject->m_sProgId.IsInit() )
pOutput->m_pOleObject->m_sOleClass = *ooxPic->oleObject->m_sProgId;
if (ooxPic->oleObject->m_oType.IsInit())
{
switch( ooxPic->oleObject->m_oType->GetBYTECode())
{
case SimpleTypes::oletypeLink: pOutput->m_pOleObject->m_eOleType = RtfOle::ot_link; break;
case SimpleTypes::oletypeEmbed: pOutput->m_pOleObject->m_eOleType = RtfOle::ot_emb; break;
}
}
std::wstring sOlePath;
if (ooxPic->oleObject->m_OleObjectFile.IsInit())
{
sOlePath = ooxPic->oleObject->m_OleObjectFile->filename().GetPath();
}
else if(ooxPic->oleObject->m_oId.IsInit() && oParam.oReader->m_currentContainer)
{
smart_ptr<OOX::File> pFile = oParam.oReader->m_currentContainer->Find(*ooxPic->oleObject->m_oId);
smart_ptr<OOX::OleObject> pOleFile = pFile.smart_dynamic_cast<OOX::OleObject>();
if (pOleFile.IsInit())
{
sOlePath= pOleFile->filename().GetPath();
}
}
if (pOutput->m_pOleObject->m_nWidth == PROP_DEF)
{
pOutput->m_pOleObject->m_nWidth = pOutput->m_nWidth;
}
if (pOutput->m_pOleObject->m_nHeight == PROP_DEF)
{
pOutput->m_pOleObject->m_nHeight = pOutput->m_nHeight;
}
if (!sOlePath.empty())
{
ConvertOle2ToOle1(sOlePath, pOutput->m_pOleObject);
std::wstring ole1FileName = Utils::CreateTempFile( oParam.oReader->m_sTempFolder );
RtfUtility::WriteDataToFileBinary( ole1FileName, pOutput->m_pOleObject->m_oOle1Data.first.get(), pOutput->m_pOleObject->m_oOle1Data.second );
pOutput->m_pOleObject->SetFilename(ole1FileName);
}
}
return true;
}
bool OOXShapeReader::Parse( ReaderParameter oParam, RtfShapePtr& pOutput)
@ -1377,16 +1446,75 @@ bool OOXShapeReader::Parse( ReaderParameter oParam, RtfShapePtr& pOutput)
if (m_vmlElement || m_arrElement) return ParseVml(oParam , pOutput);
PPTX::Logic::Shape * ooxShape = dynamic_cast<PPTX::Logic::Shape*> (m_ooxShape);
// PPTX::Logic::CxnSp * cxnShape = dynamic_cast<PPTX::Logic::CxnSp*> (m_ooxShape);
PPTX::Logic::Pic * ooxPic = dynamic_cast<PPTX::Logic::Pic*> (m_ooxShape);
PPTX::Logic::Shape *ooxShape = dynamic_cast<PPTX::Logic::Shape*> (m_ooxShape);
// PPTX::Logic::CxnSp *cxnShape = dynamic_cast<PPTX::Logic::CxnSp*> (m_ooxShape);
PPTX::Logic::Pic *ooxPic = dynamic_cast<PPTX::Logic::Pic*> (m_ooxShape);
OOX::VmlOffice::COLEObject *vmlOLE = dynamic_cast<OOX::VmlOffice::COLEObject*> (m_ooxShape);
if (ooxShape) return ParseShape(oParam, pOutput);
if (ooxPic) return ParsePic(oParam, pOutput);
//if (cxnShape) return ParseConnector(oParam, pOutput);
if (vmlOLE) return ParseVmlObject(oParam, pOutput);
return false;
}
bool OOXShapeReader::ParseVmlObject ( ReaderParameter oParam , RtfShapePtr& pOutput)
{
OOX::VmlOffice::COLEObject *vmlOLE = dynamic_cast<OOX::VmlOffice::COLEObject*> (m_ooxShape);
if (!vmlOLE) return false;
pOutput->m_bIsOle = true;
pOutput->m_pOleObject = RtfOlePtr(new RtfOle());
if( vmlOLE->m_sProgId.IsInit() )
pOutput->m_pOleObject->m_sOleClass = vmlOLE->m_sProgId.get2();
if(vmlOLE->m_oType.IsInit())
{
switch( vmlOLE->m_oType->GetValue())
{
case SimpleTypes::oletypeLink: pOutput->m_pOleObject->m_eOleType = RtfOle::ot_link; break;
case SimpleTypes::oletypeEmbed: pOutput->m_pOleObject->m_eOleType = RtfOle::ot_emb; break;
}
}
std::wstring sOlePath;
if (vmlOLE->m_oId.IsInit() && oParam.oReader->m_currentContainer)
{
smart_ptr<OOX::File> oFile = oParam.oReader->m_currentContainer->Find(vmlOLE->m_oId->GetValue());
if ((oFile.IsInit() && (OOX::FileTypes::OleObject == oFile->type())))
{
OOX::OleObject* pO = (OOX::OleObject*)oFile.operator->();
sOlePath = pO->filename().m_strFilename;
}
}
if (pOutput->m_nWidth == PROP_DEF && pOutput->m_nRight != PROP_DEF)
{
pOutput->m_nWidth = pOutput->m_nRight - (pOutput->m_nLeft == PROP_DEF ? 0 : pOutput->m_nLeft);
}
if (pOutput->m_nHeight == PROP_DEF && pOutput->m_nBottom != PROP_DEF)
{
pOutput->m_nHeight = pOutput->m_nBottom - (pOutput->m_nTop == PROP_DEF ? 0 : pOutput->m_nTop);
}
if (pOutput->m_nWidth != PROP_DEF) pOutput->m_pOleObject->m_nWidth = pOutput->m_nWidth;
if (pOutput->m_nHeight != PROP_DEF) pOutput->m_pOleObject->m_nHeight = pOutput->m_nHeight;
if (!sOlePath.empty())
{
ConvertOle2ToOle1(sOlePath, pOutput->m_pOleObject);
std::wstring ole1FileName = Utils::CreateTempFile( oParam.oReader->m_sTempFolder );
RtfUtility::WriteDataToFileBinary( ole1FileName, pOutput->m_pOleObject->m_oOle1Data.first.get(), pOutput->m_pOleObject->m_oOle1Data.second );
pOutput->m_pOleObject->SetFilename(ole1FileName);
}
return true;
}
void OOXShapeReader::Parse(ReaderParameter oParam, RtfShapePtr& pOutput, PPTX::Logic::UniFill *oox_fill, std::wstring *change_sheme_color)
{
if (!oox_fill) return;
@ -1906,6 +2034,7 @@ bool OOXBackgroundReader::Parse( ReaderParameter oParam , RtfShapePtr& pOutput)
}
return true;
}
bool OOXShapeReader::WriteDataToPicture( std::wstring sPath, RtfPicture& pOutput, std::wstring sTempPath)
{
OOX::CPath ooxPath = sPath; //для target
@ -2051,4 +2180,92 @@ void OOXShapeReader::Parse(ReaderParameter oParam, PPTX::Logic::UniFill *uni_fil
Parse(oParam, fill->GsLst[0].color.Color.operator ->(), nColor, opacity);
}
}
}
}
void OOXShapeReader::ConvertOle2ToOle1(const std::wstring &oleFilePath, RtfOlePtr object)
{
if (!object) return;
if (oleFilePath.empty()) return;
Ole1FormatReaderWriter ole1Writer;
ole1Writer.Header.ClassName.val = std::string(object->m_sOleClass.begin(), object->m_sOleClass.end());
ole1Writer.Header.ClassName.size = ole1Writer.Header.ClassName.val.length() + 1;
//ole1Writer.Header.Width = object->m_nWidth;
//ole1Writer.Header.Height = object->m_nHeight;
DWORD size = 0;
if (false == NSFile::CFileBinary::ReadAllBytes(oleFilePath, &ole1Writer.NativeData, size))
return;
ole1Writer.NativeDataSize = size;
int ole1DataSize = ole1Writer.NativeDataSize + 2048;
BYTE* ole1Data = new BYTE[ole1DataSize];
if (ole1Data)
{
ole1Writer.Write(ole1Data, ole1DataSize);
boost::shared_array<BYTE> buffer(ole1Data);
object->m_oOle1Data = std::make_pair(buffer, ole1DataSize);
}
delete []ole1Writer.NativeData;
}
void OOXShapeReader::ConvertOle2ToOle1(POLE::Storage *storage, RtfOlePtr object)
{
if (!object) return;
if (!storage) return;
Ole1FormatReaderWriter ole1Writer;
ole1Writer.Header.ClassName.val = std::string(object->m_sOleClass.begin(), object->m_sOleClass.end());
ole1Writer.Header.ClassName.size = ole1Writer.Header.ClassName.val.length();
//ole1Writer.Header.Width = object->m_nWidth;
//ole1Writer.Header.Height = object->m_nHeight;
std::list<std::wstring> entries;
entries = storage->entries( L"/" );
for( std::list<std::wstring>::iterator it = entries.begin(); it != entries.end(); ++it )
{
std::wstring name = XmlUtils::GetLower(*it);
if (std::wstring::npos != name.find(L"ole")) continue;
if (std::wstring::npos != name.find(L"compobj")) continue;
if (std::wstring::npos != name.find(L"objinfo")) continue;
if (std::wstring::npos != name.find(L"native") ||
std::wstring::npos != name.find(L"content") ||
std::wstring::npos != name.find(L"package"))
{
POLE::Stream *stream = new POLE::Stream(storage, *it);
if (stream)
{
ole1Writer.NativeDataSize = stream->size();
ole1Writer.NativeData = new unsigned char[ole1Writer.NativeDataSize];
stream->read(ole1Writer.NativeData, ole1Writer.NativeDataSize);
delete stream;
break;
}
}
}
if (ole1Writer.NativeData)
{
int ole1DataSize = ole1Writer.NativeDataSize + 2048;
BYTE* ole1Data = new BYTE[ole1DataSize];
if (ole1Data)
{
ole1Writer.Write(ole1Data, ole1DataSize);
boost::shared_array<BYTE> buffer(ole1Data);
object->m_oOle1Data = std::make_pair(buffer, ole1DataSize);
}
delete []ole1Writer.NativeData;
}
}

View File

@ -62,6 +62,9 @@ public:
bool Parse ( ReaderParameter oParam , RtfShapePtr& oOutput);
bool ParseVmlChild ( ReaderParameter oParam , RtfShapePtr& oOutput);
bool ParseVml ( ReaderParameter oParam , RtfShapePtr& oOutput);
bool ParseVmlObject ( ReaderParameter oParam , RtfShapePtr& oOutput);
static bool ParseVmlStyle(RtfShapePtr pShape, SimpleTypes::Vml::CCssProperty* prop);
void ParseAdjustment(RtfShape& oShape, std::wstring sAdjustment);
@ -102,6 +105,8 @@ private:
return true;
}
void ConvertOle2ToOle1(POLE::Storage *storage, RtfOlePtr object);
void ConvertOle2ToOle1(const std::wstring &oleFilePath, RtfOlePtr object);
};
class OOXShapeGroupReader
@ -124,7 +129,7 @@ public:
{
for (size_t i = 0; i < props.size(); i++)
{
ParseVmlStyle( pGroupShape, props[i].get());
OOXShapeReader::ParseVmlStyle( pGroupShape, props[i].get());
}
return true;
}

View File

@ -50,7 +50,7 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter)
}
else
{
RtfCharProperty * pCharProps = m_oResultPic ? &m_oResultPic->m_oCharProperty : &m_oCharProperty;
RtfCharProperty * pCharProps = &m_oCharProperty;
//------------------------------------------
// todooo общая часть с RtfChar
bool bInsert = false;
@ -94,12 +94,11 @@ std::wstring RtfOle::RenderToOOX(RenderParameter oRenderParameter)
RenderParameter oNewRenderParameter = oRenderParameter;
oNewRenderParameter.nType = RENDER_TO_OOX_PARAM_SHAPE_WSHAPE2;
if (m_oResultPic)
if (m_oResultShape)
{
m_oResultPic->m_bIsOle = true;
sResult += m_oResultPic->RenderToOOX(oNewRenderParameter);
sResult += m_oResultShape->RenderToOOX(oNewRenderParameter);
oNewRenderParameter.nValue = m_oResultPic->m_nID;
oNewRenderParameter.nValue = m_oResultShape->m_nID;
}
sResult += RenderToOOXOnlyOle(oNewRenderParameter);
@ -171,6 +170,9 @@ std::wstring RtfOle::RenderToRtf(RenderParameter oRenderParameter)
case ot_link: sResult += L"\\objlink"; break;
}
}
//sResult += L"\\f13";
sResult += L"\\objsetsize";
RENDER_RTF_INT( m_nWidth, sResult, L"objw" );
RENDER_RTF_INT( m_nHeight, sResult, L"objh" );
@ -182,39 +184,17 @@ std::wstring RtfOle::RenderToRtf(RenderParameter oRenderParameter)
std::wstring str = RtfUtility::RtfInternalEncoder::Encode( m_sOleFilename );
sResult += L"{\\*\\objdata " + str + L"}";
}
if( NULL != m_oResultPic )
//-------------------------------------
if( NULL != m_oResultShape )
{
std::wstring str = m_oResultPic->RenderToRtf( oRenderParameter );
sResult += L"{\\result \\pard\\plain" + str + L"}";
std::wstring str = m_oResultShape->RenderToRtf( oRenderParameter );
sResult += L"{\\result {\\pard\\plain" + str + L"}}";
}
//else if( NULL != m_oResultPicture )
//{
// std::wstring str = m_oResultPicture->RenderToRtf( oRenderParameter );
// sResult += L"{\\result {\\*\\shppict" + str + L"}}";
//}
sResult += L"}";
return sResult;
}
#if defined(_WIN32) || defined(_WIN64)
DWORD CALLBACK OlePut1(LPOLESTREAM oStream, const void FAR* pTarget, DWORD dwRead)
{
return 0;
}
DWORD CALLBACK OleGet2(LPOLESTREAM oStream, void FAR* pTarget, DWORD dwRead)
{
return 0;
}
DWORD CALLBACK OleGet1(LPOLESTREAM oStream, void FAR* pTarget, DWORD dwRead)
{
RtfOle1ToOle2Stream* piStream = static_cast<RtfOle1ToOle2Stream*>(oStream);
if( piStream->nCurPos + (int)dwRead > piStream->nBufferSize )
return 0;
memcpy( pTarget, (piStream->pBuffer + piStream->nCurPos) , dwRead );
piStream->nCurPos += dwRead;
return dwRead;
}
DWORD CALLBACK OlePut2(LPOLESTREAM oStream, const void FAR* pTarget, DWORD dwWrite)
{
RtfOle2ToOle1Stream* piStream = static_cast<RtfOle2ToOle1Stream*>(oStream);
BYTE* pSource = (BYTE*)pTarget;
for( DWORD i = 0; i < dwWrite; i++ )
piStream->aBuffer.push_back( pSource[i] );
return dwWrite;
}
#endif

View File

@ -33,6 +33,8 @@
#include "RtfParagraph.h"
#include "RtfShape.h"
#include <boost/smart_ptr/shared_array.hpp>
class RtfOle : public IDocumentElement
{
public:
@ -42,13 +44,15 @@ public:
int m_nShapeId;
int m_nWidth;
int m_nHeight;
std::wstring m_sOleClass;
RtfShapePtr m_oResultPic;
std::wstring m_sOleClass;
RtfShapePtr m_oResultShape;
std::pair<boost::shared_array<unsigned char>, size_t> m_oOle1Data;
RtfCharProperty m_oCharProperty; // тут могут быть track changes ....
RtfOle()
{
m_piStorage = NULL;
SetDefault();
}
~RtfOle()
@ -71,12 +75,6 @@ public:
{
m_sOleFilename = sFilename;
}
void SetOle( POLE::Storage* piOle )
{
if (piOle == NULL) return;
m_piStorage = piOle;
}
void SetDefault()
{
m_eOleType = ot_none;
@ -84,48 +82,15 @@ public:
m_nWidth = PROP_DEF;
m_nHeight = PROP_DEF;
RELEASEOBJECT( m_piStorage );
Utils::RemoveDirOrFile( m_sOleFilename );
m_sOleFilename = L"";
m_oCharProperty.SetDefault();
}
private:
POLE::Storage* m_piStorage;
std::wstring m_sOleFilename;
std::wstring RenderToOOXOnlyOle(RenderParameter oRenderParameter);
};
typedef boost::shared_ptr<RtfOle> RtfOlePtr;
#if defined (_WIN32) || defined (_WIN64)
struct RtfOle1ToOle2Stream : OLESTREAM
{
BYTE* pBuffer;
long nBufferSize;
long nCurPos;
};
struct RtfOle2ToOle1Stream : OLESTREAM
{
std::vector<BYTE> aBuffer;
};
DWORD CALLBACK OleGet1(LPOLESTREAM oStream, void FAR* pTarget, DWORD dwRead);;
DWORD CALLBACK OlePut1(LPOLESTREAM, const void FAR*, DWORD);
DWORD CALLBACK OleGet2(LPOLESTREAM oStream, void FAR* pTarget, DWORD dwRead);;
DWORD CALLBACK OlePut2(LPOLESTREAM, const void FAR*, DWORD);
#else
struct RtfOle1ToOle2Stream : POLE::Stream
{
BYTE* pBuffer;
long nBufferSize;
long nCurPos;
};
struct RtfOle2ToOle1Stream : POLE::Stream
{
std::vector<BYTE> aBuffer;
};
#endif

View File

@ -34,7 +34,7 @@
#include "RtfWriter.h"
#include "Utils.h"
std::wstring RtfPicture::GenerateWMF(RenderParameter oRenderParameter)
std::wstring RtfPicture::GenerateWMF(RenderParameter oRenderParameter) //копия растра в векторе
{
std::wstring sResult;
sResult += L"{\\pict";
@ -145,6 +145,10 @@ std::wstring RtfPicture::RenderToOOX(RenderParameter oRenderParameter)
else
m_bIsCopy = false;
if( true == m_bIsCopy && !m_sPicFilename.empty() )
{
Utils::RemoveDirOrFile( m_sPicFilename );
}
poOOXWriter->m_oContentTypes.AddExtension( sMime, sExtension);
std::wstring srId = poRelsWriter->AddRelationship( L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", sFilenameRels);

View File

@ -32,13 +32,11 @@
#pragma once
#include "RtfProperty.h"
#include "Utils.h"
//#include "../Common/MediaFormatDefine.h"
class RtfPicture : public IDocumentElement
{
public:
typedef enum {dt_none, dt_png, dt_jpg, dt_emf, dt_wmf, dt_apm, dt_macpict}DataType;
// RtfShape m_oShapeProp;
DataType eDataType;
@ -108,10 +106,6 @@ public:
DEFAULT_PROPERTY( m_nCropR )
DEFAULT_PROPERTY( m_nCropB )
if( true == m_bIsCopy && !m_sPicFilename.empty() )
{
Utils::RemoveDirOrFile( m_sPicFilename );
}
m_sPicFilename = L"";
}
std::wstring RenderToRtf(RenderParameter oRenderParameter);

View File

@ -42,10 +42,14 @@ void RtfShape::SetDefault()
m_eAnchorTypeShape = st_none;
//Common
DEFAULT_PROPERTY( m_nWidth )
DEFAULT_PROPERTY( m_nHeight )
DEFAULT_PROPERTY( m_nLeft )
DEFAULT_PROPERTY( m_nTop )
DEFAULT_PROPERTY( m_nBottom )
DEFAULT_PROPERTY( m_nRight )
DEFAULT_PROPERTY( m_nID )
DEFAULT_PROPERTY( m_nZOrder )
DEFAULT_PROPERTY( m_nHeader )
@ -224,7 +228,12 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter)
sResult += m_oCharProperty.RenderToRtf( oRenderParameter );
if( st_inline == m_eAnchorTypeShape || st_none == m_eAnchorTypeShape)
if (m_bIsOle)
{
m_oPicture->dump_shape_properties = RenderToRtfShapeProperty( oRenderParameter );
sResult += m_oPicture->RenderToRtf( oRenderParameter );
}
else if (( st_inline == m_eAnchorTypeShape || st_none == m_eAnchorTypeShape) && !m_bIsOle)
{
if( NULL != m_oPicture && m_nShapeType == NSOfficeDrawing::sptPictureFrame)
{
@ -329,7 +338,7 @@ std::wstring RtfShape::RenderToRtf(RenderParameter oRenderParameter)
sResult += L"}";
}
}
else // anchor
else // anchor or ole
{
sResult += L"{\\shp";
sResult += L"{\\*\\shpinst";
@ -453,12 +462,12 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter
if (m_sName.empty() == false)
{
sResult += L"{\\sp{\\sn wzName}{\\sv ";
sResult += RtfChar::renderRtfText( m_sName, oRenderParameter.poDocument, -1 ) + L"}}";
sResult += RtfChar::renderRtfText( m_sName, oRenderParameter.poDocument, 48 ) + L"}}"; //utf-16
}
if (m_sDescription.empty() == false)
{
sResult += L"{\\sp{\\sn wzDescription}{\\sv ";
sResult += RtfChar::renderRtfText(m_sDescription, oRenderParameter.poDocument, -1 ) + L"}}";
sResult += RtfChar::renderRtfText(m_sDescription, oRenderParameter.poDocument, 48 ) + L"}}"; //utf-16
}
//Rehydration
//RENDER_RTF_SHAPE_PROP(L"metroBlob", sResult, m_sMetroBlob);
@ -608,7 +617,7 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter
{
RENDER_RTF_SHAPE_PROP(L"fGtext", sResult, m_bGtext );
int nCodePage = -1;
int nCodePage = 48; //utf-16
if( m_sGtextFont.empty() == false)
{
@ -648,31 +657,31 @@ std::wstring RtfShape::RenderToRtfShapeProperty(RenderParameter oRenderParameter
if( !m_sSigSetupId.empty() )
{
sResult += L"{\\sp{\\sn wzSigSetupId}{\\sv ";
sResult += RtfChar::renderRtfText(m_sSigSetupId, oRenderParameter.poDocument, 0);
sResult += RtfChar::renderRtfText(m_sSigSetupId, oRenderParameter.poDocument, 48); //utf-16
sResult += L"}}";
}
if( !m_sSigSetupProvId.empty() )
{
sResult += L"{\\sp{\\sn wzSigSetupProvId}{\\sv ";
sResult += RtfChar::renderRtfText(m_sSigSetupProvId, oRenderParameter.poDocument, 0);
sResult += RtfChar::renderRtfText(m_sSigSetupProvId, oRenderParameter.poDocument, 48); //utf-16
sResult += L"}}";
}
if( !m_sSigSetupSuggSigner.empty() )
{
sResult += L"{\\sp{\\sn wzSigSetupSuggSigner}{\\sv ";
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner, oRenderParameter.poDocument, 0);
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner, oRenderParameter.poDocument, 48); //utf-16
sResult += L"}}";
}
if( !m_sSigSetupSuggSigner2.empty() )
{
sResult += L"{\\sp{\\sn wzSigSetupSuggSigner2}{\\sv ";
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner2, oRenderParameter.poDocument, 0);
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSigner2, oRenderParameter.poDocument, 48); //utf-16
sResult += L"}}";
}
if( !m_sSigSetupSuggSignerEmail.empty() )
{
sResult += L"{\\sp{\\sn wzSigSetupSuggSignerEmail}{\\sv ";
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSignerEmail, oRenderParameter.poDocument, 0);
sResult += RtfChar::renderRtfText(m_sSigSetupSuggSignerEmail, oRenderParameter.poDocument, 48); //utf-16
sResult += L"}}";
}
}
@ -696,8 +705,6 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter)
if( 0 != aTempTextItems )
{//пишем только Ole обьект
//ищем первый ole обьект
RtfOlePtr poFirstOle;
int nTempTextItemsCount = aTempTextItems->GetCount();
for (size_t i = 0; i < nTempTextItemsCount; i++ )
{
@ -725,6 +732,7 @@ std::wstring RtfShape::RenderToOOX(RenderParameter oRenderParameter)
m_sOle += poCurOle->RenderToOOX( oNewParam );
if (!m_sOle.empty())
{
m_pOleObject = poCurOle;
m_bIsOle = true;
break;
}

View File

@ -35,6 +35,9 @@
class RtfShape;
typedef boost::shared_ptr<RtfShape> RtfShapePtr;
class RtfOle;
typedef boost::shared_ptr<RtfOle> RtfOlePtr;
class RtfShape: public IRenderableProperty, public ItemContainer<RtfShapePtr>
{
private:
@ -48,6 +51,7 @@ public:
std::wstring m_sOle;
bool m_bIsOle;
RtfOlePtr m_pOleObject;
//-----------------------------
enum _AnchorTypeShape { st_none, st_inline, st_anchor };
enum _AnchorX
@ -73,10 +77,14 @@ public:
std::wstring m_sName;
std::wstring m_sDescription;
int m_nWidth;
int m_nHeight;
int m_nLeft; //shpleftN Specifies position of shape from the left of the anchor. The value N is in twips.
int m_nTop; //shptopN Specifies position of shape from the top of the anchor. The value N is in twips.
int m_nBottom; //shpbottomN Specifies position of shape from the bottom of the anchor. The value N is in twips.
int m_nRight; //shprightN Specifies position of shape from the right of the anchor. The value N is in twips.
int m_nID; //shplidN A number that is unique to each shape. This keyword is primarily used for linked text boxes. The value N is a long integer.
int m_nZOrder; //shpzN Describes the z-order of the shape. It starts at 0 for the shape that is furthest from the top, and proceeds to the top most shape (N). The shapes that appear inside the header document will have a separate z-order, compared to the z-order of the shapes in the main document. For instance, both the back-most shape in the header and the back-most main-document shape will have a z-order of 0.
int m_nHeader; //shpfhdrN Set to 0 if the shape is in the main document. Set to 1 if the shape is in the header document.

View File

@ -695,14 +695,21 @@ public:
break;
}
}
if (sCodePage.empty())
if (sCodePage.empty() && nCodepage > 0)
sCodePage = "CP" + std::to_string(nCodepage);
unsigned int insize = (unsigned int)(end - start);
const char* inptr = (const char*)start.operator ->();
NSUnicodeConverter::CUnicodeConverter oConverter;
return oConverter.toUnicode(inptr, insize, sCodePage.c_str());
if (sCodePage.empty())
{
return std::wstring(start, end);
}
else
{
unsigned int insize = (unsigned int)(end - start);
const char* inptr = (const char*)start.operator ->();
NSUnicodeConverter::CUnicodeConverter oConverter;
return oConverter.toUnicode(inptr, insize, sCodePage.c_str());
}
}
static std::string convert_string(std::wstring::const_iterator start, std::wstring::const_iterator end, int nCodepage = 0)
{

View File

@ -40,17 +40,14 @@
#include <algorithm>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
HRESULT convert_single(std::wstring srcFileName)
{
if (argc < 2) return 1;
std::wstring srcFileName = argv[1];
int n1 = srcFileName.rfind(_T('.'));
std::wstring ext_1 = n1 >= 0 ? srcFileName.substr(n1+1, srcFileName.length() - n1) : _T("");
std::wstring ext_1 = n1 >= 0 ? srcFileName.substr(n1 + 1, srcFileName.length() - n1) : _T("");
std::transform(ext_1.begin(), ext_1.end(), ext_1.begin(), ::tolower);
std::wstring dstFileName = argc > 2 ? argv[2] : srcFileName + L"_my." + (ext_1 == L"rtf" ? L"docx" : L"rtf");
std::wstring dstFileName = srcFileName + L"_my." + (ext_1 == L"rtf" ? L"docx" : L"rtf");
std::wstring outputDir = NSDirectory::GetFolderPath(dstFileName);
std::wstring dstTempPath = NSDirectory::CreateDirectoryWithUniqueName(outputDir);
@ -84,3 +81,33 @@ int _tmain(int argc, _TCHAR* argv[])
return 0;
}
HRESULT convert_directory(std::wstring pathName)
{
HRESULT hr = S_OK;
std::vector<std::wstring> arFiles = NSDirectory::GetFiles(pathName, false);
for (size_t i = 0; i < arFiles.size(); i++)
{
convert_single(arFiles[i]);
}
return S_OK;
}
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2) return 1;
HRESULT hr = -1;
if (NSFile::CFileBinary::Exists(argv[1]))
{
hr = convert_single(argv[1]);
}
else if (NSDirectory::Exists(argv[1]))
{
hr = convert_directory(argv[1]);
}
return hr;
}

View File

@ -31,7 +31,7 @@
*/
#include "Compat12.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "CompressPictures.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "CrtLayout12.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -32,6 +32,8 @@
#include "CrtLayout12A.h"
#include <simple_xml_writer.h>
namespace XLS
{
@ -39,12 +41,10 @@ CrtLayout12A::CrtLayout12A()
{
}
CrtLayout12A::~CrtLayout12A()
{
}
BaseObjectPtr CrtLayout12A::clone()
{
return BaseObjectPtr(new CrtLayout12A(*this));
@ -52,10 +52,88 @@ BaseObjectPtr CrtLayout12A::clone()
void CrtLayout12A::readFields(CFRecord& record)
{
#pragma message("####################### CrtLayout12A record is not implemented")
Log::error("CrtLayout12A record is not implemented.");
unsigned short flags, reserved;
record >> frtheader >> dwCheckSum >> flags;
record.skipNunBytes(record.getDataSize() - record.getRdPtr());
fLayoutTargetInner = GETBIT(flags, 0);
record >> xTL >> yTL >> xBR >> yBR;
record >> wXMode >> wYMode >> wWidthMode >> wHeightMode;
record >> x >> y >> dx >> dy >> reserved;
}
int CrtLayout12A::serialize (std::wostream & _stream)
{
CP_XML_WRITER(_stream)
{
CP_XML_NODE(L"c:layout")
{
if (wXMode == 0 && wYMode == 0 && wWidthMode == 0 && wHeightMode == 0)
{
}
else
{
CP_XML_NODE(L"c:manualLayout")
{
CP_XML_NODE(L"c:layoutTarget"){CP_XML_ATTR(L"val", fLayoutTargetInner ? L"inner" : L"outer");}
if (wXMode > 0)
{
CP_XML_NODE(L"c:xMode")
{
if (wXMode == 1) CP_XML_ATTR(L"val", L"factor");
else CP_XML_ATTR(L"val", L"edge");
}
}
if (wYMode > 0)
{
CP_XML_NODE(L"c:yMode")
{
if (wYMode == 1) CP_XML_ATTR(L"val", L"factor");
else CP_XML_ATTR(L"val", L"edge");
}
}
if (wXMode > 0)
{
CP_XML_NODE(L"c:x") {CP_XML_ATTR(L"val", x.data.value);}
}
if (wYMode > 0)
{
CP_XML_NODE(L"c:y") {CP_XML_ATTR(L"val", y.data.value);}
}
if (wWidthMode > 0)
{
CP_XML_NODE(L"c:wMode")
{
if (wWidthMode == 1)CP_XML_ATTR(L"val", L"factor");
else CP_XML_ATTR(L"val", L"edge");
}
}
if (wHeightMode > 0)
{
CP_XML_NODE(L"c:hMode")
{
if (wHeightMode == 1)CP_XML_ATTR(L"val", L"factor");
else CP_XML_ATTR(L"val", L"edge");
}
}
if (wWidthMode > 0)
{
CP_XML_NODE(L"c:w") {CP_XML_ATTR(L"val", dx.data.value);}
}
if (wHeightMode > 0)
{
CP_XML_NODE(L"c:h") {CP_XML_ATTR(L"val", dy.data.value);}
}
}
}
}
}
return 0;
}
} // namespace XLS

View File

@ -32,12 +32,11 @@
#pragma once
#include "BiffRecord.h"
#include "../Biff_structures/FrtHeader.h"
#include "../Biff_structures/Xnum.h"
namespace XLS
{
// Logical representation of CrtLayout12A record in BIFF8
class CrtLayout12A: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(CrtLayout12A)
@ -47,12 +46,32 @@ public:
~CrtLayout12A();
BaseObjectPtr clone();
void readFields(CFRecord& record);
void readFields (CFRecord& record);
int serialize (std::wostream & _stream);
static const ElementType type = typeCrtLayout12A;
static const ElementType type = typeCrtLayout12A;
FrtHeader frtheader;
_UINT32 dwCheckSum;
bool fLayoutTargetInner;
short xTL;
short yTL;
short xBR;
short yBR;
CrtLayout12Mode wXMode;
CrtLayout12Mode wYMode;
CrtLayout12Mode wWidthMode;
CrtLayout12Mode wHeightMode;
Xnum x;
Xnum y;
Xnum dx;
Xnum dy;
};
} // namespace XLS

View File

@ -31,7 +31,7 @@
*/
#include "DataLabExt.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "DataLabExtContents.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "DropDownObjIds.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "FeatHdr.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "HFPicture.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,7 +31,7 @@
*/
#include "HeaderFooter.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
//#include <Exception/AttributeDataWrong.h>
namespace XLS

View File

@ -31,7 +31,7 @@
*/
#include "NameCmt.h"
#include <Logic/Biff_structures/FrtHeader.h>
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -31,8 +31,8 @@
*/
#pragma once
#include <Logic/Biff_structures/FrtHeader.h>
#include "BiffRecord.h"
#include "../Biff_structures/FrtHeader.h"
namespace XLS
{

View File

@ -79,17 +79,18 @@ bool AI::empty()
BRAI* brai = dynamic_cast<BRAI*>(m_BRAI.get());
bool bEmpty = true;
if (brai)
{
std::wstring forumla = brai->formula.getAssembledFormula();
return forumla.empty();
bEmpty = forumla.empty();
}
SeriesText * text = dynamic_cast<SeriesText *>(m_SeriesText.get());
if (text)
if (text && bEmpty)
{
return text->stText.value().empty();
bEmpty = text->stText.value().empty();
}
return false;
return bEmpty;
}
int AI::serialize(std::wostream & _stream)

View File

@ -237,6 +237,10 @@ const bool CHARTFORMATS::loadContent(BinProcessor& proc)
elements_.pop_back();
count--;
}
if (!m_CrtLayout12A && proc.optional<CrtLayout12A>()) // RP_2064.xls
{
m_CrtLayout12A = elements_.back(); elements_.pop_back();
}
if (proc.optional<CRTMLFRT>())
{
elements_.pop_back();

View File

@ -791,34 +791,42 @@ int ChartSheetSubstream::serialize_plot_area (std::wostream & _stream)
}
}
ShtProps *sht_props = dynamic_cast<ShtProps*>(chart_formats->m_ShtProps.get());
ShtProps *sht_props = dynamic_cast<ShtProps*>(chart_formats->m_ShtProps.get());
std::wstringstream stream_legend_entries;
CP_XML_WRITER(_stream)
{
CP_XML_NODE(L"c:plotArea")
{
for (size_t i = 0; i < chart_formats->m_arAXISPARENT.size(); i++)
{
AXISPARENT* parent = dynamic_cast<AXISPARENT*> (chart_formats->m_arAXISPARENT[i].get());
ax_parent = dynamic_cast<AxisParent*> (parent->m_AxisParent.get());
axes = dynamic_cast<AXES*> (parent->m_AXES.get());
//for (size_t i = 0; i < chart_formats->m_arAXISPARENT.size(); i++)
//{
// AXISPARENT* parent = dynamic_cast<AXISPARENT*> (chart_formats->m_arAXISPARENT[i].get());
// ax_parent = dynamic_cast<AxisParent*> (parent->m_AxisParent.get());
// axes = dynamic_cast<AXES*> (parent->m_AXES.get());
//if (((bool)ax_parent->iax == false) && axes) //primary axes
//{
// PlotAreaFRAME = dynamic_cast<FRAME*> (axes->m_PlotArea_FRAME.get());
// PlotAreaPos = dynamic_cast<Pos*> (parent->m_Pos.get());
//
// if (PlotAreaFRAME && PlotAreaPos)
// {
// PlotAreaPos->m_Frame = PlotAreaFRAME->m_Frame;
// }
//}
}
// if (((bool)ax_parent->iax == false) && axes) //primary axes
// {
// PlotAreaFRAME = dynamic_cast<FRAME*> (axes->m_PlotArea_FRAME.get());
// PlotAreaPos = dynamic_cast<Pos*> (parent->m_Pos.get());
//
// //if (PlotAreaFRAME && PlotAreaPos)
// //{
// // PlotAreaPos->m_Frame = PlotAreaFRAME->m_Frame;
// //}
// }
//}
if (PlotAreaPos && (sht_props) && (sht_props->fAlwaysAutoPlotArea != false))
if ((sht_props) && (sht_props->fAlwaysAutoPlotArea != false))
{
PlotAreaPos->serialize(CP_XML_STREAM());
if (chart_formats->m_CrtLayout12A)
{
chart_formats->m_CrtLayout12A->serialize(CP_XML_STREAM());
}
else if (PlotAreaPos && (sht_props) && (sht_props->fAlwaysAutoPlotArea != false))
{
PlotAreaPos->serialize(CP_XML_STREAM());
}
}
int series_order = 0;

View File

@ -349,7 +349,7 @@ namespace oox
//case msosptLeftRightArrowCallout : return L"leftRightArrowCallout";
//case msosptUpDownArrowCallout : return L"upDownArrowCallout";
//case msosptQuadArrowCallout : return L"quadArrowCallout";
//case msosptBevel : return L"bevel";
case msosptBevel : return L"bevel";
//case msosptLeftBracket : return L"leftBracket";
//case msosptRightBracket : return L"rightBracket";
//case msosptLeftBrace : return L"leftBrace";

View File

@ -449,12 +449,10 @@ namespace OOX
virtual ~CObject()
{
}
public:
virtual void fromXML(XmlUtils::CXmlNode& oNode)
virtual void fromXML(XmlUtils::CXmlNode& oNode)
{
}
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
{
if ( oReader.IsEmptyNode() )
return;
@ -473,6 +471,8 @@ namespace OOX
oSubReader.ReadNextNode();//root
oSubReader.ReadNextNode();//pict
ReadAttributes(oSubReader);
int nCurDepth = oSubReader.GetDepth();
while ( oSubReader.ReadNextSiblingNode( nCurDepth ) )
{
@ -634,26 +634,37 @@ namespace OOX
}
}
}
virtual std::wstring toXML() const
virtual std::wstring toXML() const
{
return _T("<w:object />");
return _T("<w:object/>");
}
virtual EElementType getType() const
{
return et_w_object;
}
nullable<std::wstring> m_sXml;
// Childs
nullable<std::wstring> m_sXml;
//-----------------------------------------------------------------------
nullable_int m_oDxaOrig;
nullable_int m_oDyaOrig;
nullable<OOX::Logic::CControl> m_oControl;
//top childs
nullable<OOX::Vml::CShapeType> m_oShapeType;//?? нужен ли отдельно тута???
nullable<OOX::Vml::CShapeType> m_oShapeType;
nullable<OOX::VmlOffice::COLEObject> m_oOleObject;
nullable<OOX::Vml::CShape> m_oShape;
//minor childs
private:
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start( oReader )
WritingElement_ReadAttributes_Read_if ( oReader, _T("w:dxaOrig"), m_oDxaOrig )
WritingElement_ReadAttributes_Read_else_if ( oReader, _T("w:dxyOrig"), m_oDyaOrig )
WritingElement_ReadAttributes_End( oReader )
}
};

View File

@ -241,3 +241,4 @@
#define AVS_FILEUTILS_ERROR_CONVERT_DRM (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005a)
#define AVS_FILEUTILS_ERROR_CONVERT_PASSWORD (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005b)
#define AVS_FILEUTILS_ERROR_CONVERT_ICU (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005c)
#define AVS_FILEUTILS_ERROR_CONVERT_LIMITS (AVS_ERROR_FIRST + AVS_FILEUTILS_ERROR_FIRST + 0x005d)

View File

@ -151,3 +151,15 @@ HRESULT COfficeUtils::CompressFilesFromMemory(const std::wstring& zipFile, const
*result = ZLibZipUtils::CompressFiles(zipFile.c_str(), data_source, pParam, compression_level) ? true : false;
return S_OK;
}
HRESULT COfficeUtils::GetFilesSize(const std::wstring& zipFile, const std::wstring& searchPattern, ULONG& nCommpressed, ULONG& nUncommpressed)
{
if (ZLibZipUtils::GetFilesSize(zipFile.c_str(), searchPattern, nCommpressed, nUncommpressed))
{
return S_OK;
}
else
{
return S_FALSE;
}
}

View File

@ -52,6 +52,7 @@ public:
HRESULT LoadFileFromArchive (const std::wstring& zipFile, const std::wstring& filePath, BYTE** fileInBytes, ULONG& nFileSize);
HRESULT ExtractFilesToMemory (const std::wstring& zipFile, const ExtractedFileCallback& data_receiver, void* pParam, bool* result);
HRESULT CompressFilesFromMemory (const std::wstring& zipFile, const RequestFileCallback& data_source, void* pParam, short compression_level, bool* result);
HRESULT GetFilesSize (const std::wstring& zipFile, const std::wstring& searchPattern, ULONG& nCommpressed, ULONG& nUncommpressed);
};

View File

@ -102,7 +102,9 @@ namespace ZLibZipUtils
int nBufferSize = MultiByteToWideChar( CP_OEMCP, 0, sVal, -1, NULL, 0 );
wchar_t* pBuffer = new wchar_t[nBufferSize];
MultiByteToWideChar( CP_OEMCP, 0, sVal, -1, pBuffer, nBufferSize );
std::wstring sRes(pBuffer, nBufferSize);
//If this parameter is -1, the function processes the entire input string, including the terminating null character.
//Therefore, the resulting Unicode string has a terminating null character, and the length returned by the function includes this character.
std::wstring sRes(pBuffer, nBufferSize - 1);
RELEASEARRAYOBJECTS(pBuffer);
return sRes;
#else
@ -953,6 +955,37 @@ int ZipDir( const WCHAR* dir, const WCHAR* outputFile, const OnProgressCallback*
return false;
}
bool GetFilesSize(const WCHAR* zip_file_path, const std::wstring& searchPattern, ULONG& nCommpressed, ULONG& nUncommpressed)
{
nCommpressed = 0;
nUncommpressed = 0;
unzFile unzip_file_handle = unzOpenHelp(zip_file_path);
if (unzip_file_handle != NULL)
{
//todo implement true pattern
std::wstring searchExt = searchPattern.substr(2);
bool isEmptyPattern = 0 == searchExt.length();
do
{
char filename_inzip[256];
unz_file_info file_info;
unzGetCurrentFileInfo(unzip_file_handle, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
std::wstring filenameW = codepage_issue_fixFromOEM(filename_inzip);
std::transform(filenameW.begin(), filenameW.end(), filenameW.begin(), ::tolower);
if (isEmptyPattern || NSFile::GetFileExtention(filenameW) == searchExt)
{
nCommpressed += file_info.compressed_size;
nUncommpressed += file_info.uncompressed_size;
}
// else just skip the erroneous file
} while (UNZ_OK == unzGoToNextFile(unzip_file_handle));
unzClose (unzip_file_handle);
return true;
}
return false;
}
/*========================================================================================================*/
static unsigned int get_files_count( const WCHAR* dirname )

View File

@ -65,4 +65,5 @@ namespace ZLibZipUtils
bool LoadFileFromArchive(const WCHAR* zipFile, const WCHAR* filePathInZip, BYTE** fileInBytes, ULONG& nFileSize);
bool ExtractFiles(const WCHAR* zip_file_path, const ExtractedFileCallback& callback, void* pParam);
bool CompressFiles(const WCHAR* zip_file_path, const RequestFileCallback& callback, void* pParam, int compression_level);
bool GetFilesSize(const WCHAR* zip_file_path, const std::wstring& searchPattern, ULONG& nCommpressed, ULONG& nUncommpressed);
}

View File

@ -3888,6 +3888,11 @@ namespace NExtractTools
return AVS_FILEUTILS_ERROR_UNKNOWN;
}
if (!oInputParams.checkInputLimits())
{
return AVS_FILEUTILS_ERROR_CONVERT_LIMITS;
}
int result = 0;
switch(conversion)
{

View File

@ -471,4 +471,26 @@ namespace NExtractTools
return 0;
}
#endif
bool InputParams::checkInputLimits()
{
std::wstring& sFrom = *this->m_sFileFrom;
int nFormatFrom = *this->m_nFormatFrom;
boost::unordered_map<int, InputLimit>::const_iterator itLimit = this->m_mapInputLimits.find(nFormatFrom);
if(itLimit != this->m_mapInputLimits.end())
{
const InputLimit& oLimit = itLimit->second;
if(oLimit.compressed > 0 || oLimit.uncompressed > 0)
{
ULONG nCompressed = 0;
ULONG nUncompressed = 0;
COfficeUtils oCOfficeUtils(NULL);
oCOfficeUtils.GetFilesSize(sFrom, oLimit.pattern, nCompressed, nUncompressed);
if((oLimit.compressed > 0 && nCompressed > oLimit.compressed) || (oLimit.uncompressed > 0 && nUncompressed > oLimit.uncompressed))
{
return false;
}
}
}
return true;
}
}

View File

@ -43,6 +43,9 @@
#include "../../DesktopEditor/common/StringBuilder.h"
#include "../../DesktopEditor/common/Path.h"
#include <boost/unordered_map.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <fstream>
@ -360,6 +363,19 @@ namespace NExtractTools
}
};
class InputLimit
{
public:
UINT compressed;
UINT uncompressed;
std::wstring pattern;
InputLimit()
{
compressed = 0;
uncompressed = 0;
}
};
class InputParams
{
public:
@ -385,6 +401,7 @@ namespace NExtractTools
std::wstring* m_sSavePassword;
std::wstring* m_sTempDir;
bool* m_bIsNoBase64;
boost::unordered_map<int, InputLimit> m_mapInputLimits;
//output params
mutable bool m_bOutputConvertCorrupted;
public:
@ -488,6 +505,10 @@ namespace NExtractTools
m_oThumbnail = new InputParamsThumbnail();
m_oThumbnail->FromXmlNode(oXmlNode);
}
else if(_T("m_oInputLimits") == sName)
{
FromLimitsNode(oXmlNode);
}
else
{
std::wstring sValue;
@ -609,6 +630,41 @@ namespace NExtractTools
}
return true;
}
bool FromLimitsNode(XmlUtils::CXmlNode& oXmlNode)
{
XmlUtils::CXmlNodes oLimitsNode;
if (oXmlNode.GetNodes(L"m_oInputLimit", oLimitsNode))
{
for(int i = 0; i < oLimitsNode.GetCount(); ++i)
{
XmlUtils::CXmlNode oLimitNode;
if(oLimitsNode.GetAt(i, oLimitNode))
{
std::wstring sType;
if (oLimitNode.GetAttributeIfExist(L"type", sType))
{
std::vector<std::wstring> aTypes;
boost::algorithm::split(aTypes, sType, boost::algorithm::is_any_of(L";"), boost::algorithm::token_compress_on);
InputLimit oLimit;
XmlUtils::CXmlNode oZipNode;
if (oLimitNode.GetNode(L"m_oZip", oZipNode))
{
oLimit.compressed = std::stoul(oZipNode.GetAttribute(L"compressed", L"0"));
oLimit.uncompressed = std::stoul(oZipNode.GetAttribute(L"uncompressed", L"0"));
oLimit.pattern = oZipNode.GetAttribute(L"template", L"");
}
for (int j = 0; j < aTypes.size(); ++j)
{
m_mapInputLimits[COfficeFileFormatChecker::GetFormatByExtension(L"." + aTypes[j])] = oLimit;
}
}
}
}
}
return true;
}
bool hasPassword() const
{
return NULL != m_sPassword;
@ -900,6 +956,7 @@ namespace NExtractTools
{
return NULL != m_bDontSaveAdditional && *m_bDontSaveAdditional;
}
bool checkInputLimits();
};
static std::wstring string_replaceAll(std::wstring str, const std::wstring& from, const std::wstring& to)