/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #include "VmlDrawing.h" #include #include "../../DesktopEditor/common/StringBuilder.h" namespace OOX { //в файле VmlDrawing могут быть как отобразительная часть комментариев Xlsx, так и просто обычные объекты void CVmlDrawing::ClearShapeTypes() { for ( size_t i = 0; i < m_arrShapeTypes.size(); ++i) { if ( m_arrShapeTypes[i].pElement ) delete m_arrShapeTypes[i].pElement; } m_arrShapeTypes.clear(); } void CVmlDrawing::read(std::wstring & fileContent) { XmlUtils::CXmlLiteReader oReader; if ( !oReader.FromString( fileContent)) return; if ( !oReader.ReadNextNode() ) return; std::wstring sName1 = XmlUtils::GetNameNoNS(oReader.GetName()); if ( L"xml" == sName1 ) { ReadAttributes( oReader ); std::wstring elementContent; bool bReadyElement = false;//собираем все до нахождения собственно элемента if ( !oReader.IsEmptyNode() ) { int nStylesDepth = oReader.GetDepth(); while ( oReader.ReadNextSiblingNode( nStylesDepth ) )// { std::wstring NodeContent = oReader.GetOuterXml(); std::wstring strXml = L""; strXml += NodeContent; strXml += L""; XmlUtils::CXmlLiteReader oSubReader;//нам нужны xml и сами объекты if (oSubReader.FromString(strXml) == false) continue; oSubReader.ReadNextNode(); OOX::WritingElement *pItem = NULL; int nStylesDepth1 = oSubReader.GetDepth(); while ( oSubReader.ReadNextSiblingNode( nStylesDepth1 ) )// { std::wstring sName = oSubReader.GetName(); switch (sName[0])// вынесены только объекты .. { case 'v': { wchar_t wChar2 = sName[2]; // v:_ switch ( wChar2 ) { case 'a': if ( L"v:arc" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CArc, oSubReader) bReadyElement = true; } break; case 'c': if ( L"v:curve" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CCurve, oSubReader) bReadyElement = true; } break; case 'g': if ( L"v:group" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CGroup, oSubReader) bReadyElement = true; } break; case 'i': if ( L"v:image" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CImage, oSubReader) bReadyElement = true; } break; case 'l': if ( L"v:line" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CLine, oSubReader) bReadyElement = true; } break; case 'o': if ( L"v:oval" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::COval, oSubReader) bReadyElement = true; } break; case 'p': if ( L"v:polyline" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CPolyLine, oSubReader) bReadyElement = true; } break; case 'r': if ( L"v:rect" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CRect, oSubReader) bReadyElement = true; } else if ( L"v:roundrect" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CRoundRect, oSubReader) bReadyElement = true; } break; case 's': if ( L"v:shape" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CShape, oSubReader) bReadyElement = true; } else if ( L"v:shapetype" == sName ) { AssignPtrXmlContent(pItem, OOX::Vml::CShapeType, oSubReader) } break; } }break; } } elementContent += NodeContent; if ( pItem ) { m_arrItems.push_back( pItem ); OOX::Vml::CVmlCommonElements* common = dynamic_cast(pItem); std::wstring sSpid; bool bComment = false; if (common) { if (common->m_sSpId.IsInit()) sSpid = *common->m_sSpId; else if (common->m_sId.IsInit())sSpid = *common->m_sId; bComment = common->m_bComment; } else { OOX::Vml::CGroup *group = dynamic_cast(pItem); if (group) { if (group->m_sSpId.IsInit()) sSpid = *group->m_sSpId; else if (group->m_sId.IsInit()) sSpid = *group->m_sId; } } if (bReadyElement) { if (!sSpid.empty()) { _vml_shape element; element.nId = (int)m_arrItems.size()-1; element.sXml = elementContent; element.pElement = pItem; element.bComment = bComment; m_mapShapes.insert(std::make_pair(sSpid, element)); } elementContent.clear(); bReadyElement = false; bComment = false; } else { _vml_shape element; element.nId = -1; element.sXml = elementContent; element.pElement = pItem; element.bUsed = false; m_arrShapeTypes.push_back(element); } } } } } } void CVmlDrawing::read(const CPath& oRootPath, const CPath& oPath) { m_oReadPath = oPath; IFileContainer::Read( oRootPath, oPath ); //так как это не совсем xml - поправим NSFile::CFileBinary file; if (file.OpenFile(oPath.GetPath())) { DWORD DataSize = file.GetFileSize(); BYTE* Data = new BYTE[DataSize]; if (Data) { file.ReadFile(Data, DataSize, DataSize); m_sFileContent = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(Data,DataSize); delete []Data; } file.CloseFile(); } if (false == m_sFileContent.empty()) { // элементы вида
без
// test_vml4.xlsx XmlUtils::replace_all(m_sFileContent, L"
", L""); // элементы вида , // Zigmunds.pptx while(true) { size_t res1 = m_sFileContent.find(L"", res1); if (res1 != std::wstring::npos && res2 != std::wstring::npos) { m_sFileContent = m_sFileContent.erase(res1, res2 - res1 + 1); } } read(m_sFileContent); } } void CVmlDrawing::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { if ((!m_mapComments || m_mapComments->empty()) && m_arObjectXml.empty() && m_arControlXml.empty()) { if (false == m_sFileContent.empty()) { NSFile::CFileBinary::SaveToFile(oPath.GetPath(), m_sFileContent); oContent.AddDefault(oPath.GetExtention(false)); IFileContainer::Write(oPath, oDirectory, oContent); } return; } //for Comment SpreadsheetML & others vml (hf, objects, ...) !! NSStringUtils::CStringBuilder sXml; sXml.WriteString(L""); for (size_t i = 0; i < m_arObjectXml.size(); ++i) { sXml.WriteString(m_arObjectXml[i]); } if (false == m_arControlXml.empty() || ((NULL != m_mapComments) && (false == m_mapComments->empty()))) { int data = (int)((m_lObjectIdVML + 4096) / 1024); sXml.WriteString(L""); } if (false == m_arControlXml.empty()) { sXml.WriteString(L""); sXml.WriteString(L""); sXml.WriteString(L""); for (size_t i = 0; i < m_arControlXml.size(); ++i) { sXml.WriteString(m_arControlXml[i]); } } long nIndex = 4096 + m_lObjectIdVML; if ((NULL != m_mapComments) && (false == m_mapComments->empty())) { sXml.WriteString(L""); sXml.WriteString(L""); for (std::map::const_iterator it = m_mapComments->begin(); it != m_mapComments->end(); ++it) { OOX::Spreadsheet::CCommentItem* comment = it->second; std::wstring sStyle; if(comment->m_dLeftMM.IsInit()) { SimpleTypes::CPoint oPoint; oPoint.FromMm(comment->m_dLeftMM.get()); sStyle += L"margin-left:" + XmlUtils::ToString(oPoint.ToPoints()) + L"pt;"; } if(comment->m_dTopMM.IsInit()) { SimpleTypes::CPoint oPoint; oPoint.FromMm(comment->m_dTopMM.get()); sStyle += L"margin-top:" + XmlUtils::ToString(oPoint.ToPoints()) + L"pt;"; } if(comment->m_dWidthMM.IsInit()) { SimpleTypes::CPoint oPoint; oPoint.FromMm(comment->m_dWidthMM.get()); sStyle += L"width:" + XmlUtils::ToString(oPoint.ToPoints()) + L"pt;"; } if(comment->m_dHeightMM.IsInit()) { SimpleTypes::CPoint oPoint; oPoint.FromMm(comment->m_dHeightMM.get()); sStyle += L"height:" + XmlUtils::ToString(oPoint.ToPoints()) + L"pt;"; } std::wstring sClientData = L""; if(comment->m_bMove.IsInit() && true == comment->m_bMove.get()) sClientData += L""; if(comment->m_bSize.IsInit() && true == comment->m_bSize.get()) sClientData += L""; if( comment->m_nLeft.IsInit() && comment->m_nLeftOffset.IsInit() && comment->m_nTop.IsInit() && comment->m_nTopOffset.IsInit() && comment->m_nRight.IsInit() && comment->m_nRightOffset.IsInit() && comment->m_nBottom.IsInit() && comment->m_nBottomOffset.IsInit()) { sClientData += L""; sClientData += std::to_wstring(comment->m_nLeft.get()) + L","; sClientData += std::to_wstring(comment->m_nLeftOffset.get()) + L","; sClientData += std::to_wstring(comment->m_nTop.get()) + L","; sClientData += std::to_wstring(comment->m_nTopOffset.get()) + L","; sClientData += std::to_wstring(comment->m_nRight.get()) + L","; sClientData += std::to_wstring(comment->m_nRightOffset.get()) + L","; sClientData += std::to_wstring(comment->m_nBottom.get()) + L","; sClientData += std::to_wstring(comment->m_nBottomOffset.get()); sClientData += L""; } sClientData += L"False"; if(comment->m_nRow.IsInit()) sClientData += L"" + std::to_wstring(comment->m_nRow.get()) + L""; if(comment->m_nCol.IsInit()) sClientData += L"" + std::to_wstring(comment->m_nCol.get()) + L""; sClientData += L""; std::wstring sGfxdata; if(comment->m_sGfxdata.IsInit()) sGfxdata = L"o:gfxdata=\"" + *comment->m_sGfxdata + L"\""; std::wstring sShape; sShape += L""; sXml.WriteString(sShape); } } sXml.WriteString(L""); NSFile::CFileBinary::SaveToFile( oPath.GetPath(), sXml.GetData() ); oContent.AddDefault( oPath.GetExtention(false) ); IFileContainer::Write(oPath, oDirectory, oContent); } bool CVmlDrawing::IsEmpty() { return m_arObjectXml.empty() && m_arControlXml.empty() && (!m_mapComments || ((m_mapComments) && (m_mapComments->empty()))); } smart_ptr CVmlDrawing::FindVmlObject(const std::wstring &spid) { smart_ptr oElement; std::map::iterator pFind = m_mapShapes.find(spid); if (pFind != m_mapShapes.end()) { oElement.reset(pFind->second.pElement); oElement.AddRef(); } return oElement; } } // namespace OOX