Commit f43ef621 authored by ElenaSubbotina's avatar ElenaSubbotina

OoxFormat - add vba & activeX controls

parent 2f9a8eb7
...@@ -78,6 +78,7 @@ public: ...@@ -78,6 +78,7 @@ public:
std::wstring name; std::wstring name;
std::wstring location_ref; std::wstring location_ref;
std::wstring source_ref; std::wstring source_ref;
std::wstring source_table_name;
std::vector<_field> fields; std::vector<_field> fields;
std::vector<int> row_fields; std::vector<int> row_fields;
std::vector<int> page_fields; std::vector<int> page_fields;
...@@ -86,6 +87,7 @@ public: ...@@ -86,6 +87,7 @@ public:
}current_; }current_;
void serialize_view(std::wostream & strm); void serialize_view(std::wostream & strm);
void serialize_cache(std::wostream & strm);
}; };
xlsx_pivots_context::xlsx_pivots_context() : impl_(new xlsx_pivots_context::Impl()) xlsx_pivots_context::xlsx_pivots_context() : impl_(new xlsx_pivots_context::Impl())
...@@ -217,6 +219,96 @@ void xlsx_pivots_context::Impl::serialize_view(std::wostream & strm) ...@@ -217,6 +219,96 @@ void xlsx_pivots_context::Impl::serialize_view(std::wostream & strm)
} }
} }
void xlsx_pivots_context::Impl::serialize_cache(std::wostream & strm)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"pivotCacheDefinition")
{
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
//{ records file
// CP_XML_ATTR(L"r:id", L"rId1" );
//}
CP_XML_ATTR(L"enableRefresh", 1);
//CP_XML_ATTR(L"refreshedBy", db->rgb.value());
//CP_XML_ATTR(L"refreshedDate", db_ex->numDate.data.value);
CP_XML_ATTR(L"recordCount", 0);
//createdVersion="1"
//refreshedVersion="2"
//upgradeOnRefresh="1">
if (true)
{
CP_XML_NODE(L"cacheSource")
{
CP_XML_ATTR(L"type", L"worksheet");
CP_XML_NODE(L"worksheetSource")
{
CP_XML_ATTR(L"ref", current_.source_ref);
CP_XML_ATTR(L"sheet", current_.source_table_name);
}
}
}
if (current_.fields.empty() == false)
{
CP_XML_NODE(L"cacheFields")
{
CP_XML_ATTR(L"count", current_.fields.size());
for (size_t i = 0; i < current_.fields.size(); i++)
{
CP_XML_NODE(L"cacheField")
{
CP_XML_ATTR(L"name", current_.fields[i].name);
CP_XML_ATTR(L"numFmtId", 0);
if (current_.fields[i].caches.empty() == false)
{
CP_XML_NODE(L"sharedItems")
{
CP_XML_ATTR(L"count", current_.fields[i].caches.size());
//CP_XML_ATTR(L"containsSemiMixedTypes", );
CP_XML_ATTR(L"containsNonDate", 1);
CP_XML_ATTR(L"containsDate", 0);
CP_XML_ATTR(L"containsBlank", 0);
//CP_XML_ATTR(L"containsString", );
for (size_t j = 0; j < current_.fields[i].caches.size(); j++)
{
std::wstring node_name = L"s";
//switch(current_.fields[i].caches[j].type)
//{
//}
CP_XML_NODE(node_name)
{
CP_XML_ATTR(L"v", current_.fields[i].caches[j]);
}
}
}
}
}
}
}
}
//if (pivot_cache->m_arSXFORMULA.empty() == false)
//{
// CP_XML_NODE(L"calculatedItems")
// {
// CP_XML_ATTR(L"count", pivot_cache->m_arSXFORMULA.size());
// for (size_t i = 0; i < pivot_cache->m_arSXFORMULA.size(); i++)
// {
// pivot_cache->m_arSXFORMULA[i]->serialize(CP_XML_STREAM());
// }
// }
//}
}
}
}
int xlsx_pivots_context::get_count() int xlsx_pivots_context::get_count()
{ {
return (int)impl_->pivot_xmls_.size(); return (int)impl_->pivot_xmls_.size();
...@@ -278,6 +370,7 @@ int xlsx_pivots_context::end_table() ...@@ -278,6 +370,7 @@ int xlsx_pivots_context::end_table()
std::wstringstream rec_strm; std::wstringstream rec_strm;
impl_->serialize_view(view_strm); impl_->serialize_view(view_strm);
impl_->serialize_cache(cache_strm);
Impl::_pivot_xml v = {cache_strm.str(), rec_strm.str(), view_strm.str()}; Impl::_pivot_xml v = {cache_strm.str(), rec_strm.str(), view_strm.str()};
...@@ -340,8 +433,9 @@ void xlsx_pivots_context::end_field() ...@@ -340,8 +433,9 @@ void xlsx_pivots_context::end_field()
{ {
} }
void xlsx_pivots_context::set_source_range(std::wstring ref) void xlsx_pivots_context::set_source_range(std::wstring table_name, std::wstring ref)
{ {
impl_->current_.source_table_name = table_name;
impl_->current_.source_ref = ref; impl_->current_.source_ref = ref;
} }
......
...@@ -63,7 +63,7 @@ public: ...@@ -63,7 +63,7 @@ public:
void set_view_name(std::wstring name); void set_view_name(std::wstring name);
void set_view_target_range(std::wstring ref); void set_view_target_range(std::wstring ref);
void set_source_range(std::wstring ref); void set_source_range(std::wstring table_name, std::wstring ref);
void write_cache_definitions_to (int index, std::wostream & strm); void write_cache_definitions_to (int index, std::wostream & strm);
void write_cache_records_to (int index, std::wostream & strm); void write_cache_records_to (int index, std::wostream & strm);
......
...@@ -93,6 +93,8 @@ void table_data_pilot_table::xlsx_convert(oox::xlsx_conversion_context & Context ...@@ -93,6 +93,8 @@ void table_data_pilot_table::xlsx_convert(oox::xlsx_conversion_context & Context
Context.get_pivots_context().start_table(); Context.get_pivots_context().start_table();
source_->xlsx_convert(Context);
if (table_name_) Context.get_pivots_context().set_view_name(*table_name_); if (table_name_) Context.get_pivots_context().set_view_name(*table_name_);
if (table_target_range_address_) if (table_target_range_address_)
{ {
...@@ -106,7 +108,6 @@ void table_data_pilot_table::xlsx_convert(oox::xlsx_conversion_context & Context ...@@ -106,7 +108,6 @@ void table_data_pilot_table::xlsx_convert(oox::xlsx_conversion_context & Context
Context.get_pivots_context().set_view_target_range(ref); Context.get_pivots_context().set_view_target_range(ref);
//Context.get_pivots_context().set_view_target_table(table_index); //Context.get_pivots_context().set_view_target_table(table_index);
} }
source_->xlsx_convert(Context);
for (size_t i = 0; i < fields_.size(); i++) for (size_t i = 0; i < fields_.size(); i++)
{ {
...@@ -239,7 +240,7 @@ const wchar_t * table_source_cell_range::name = L"source-cell-range"; ...@@ -239,7 +240,7 @@ const wchar_t * table_source_cell_range::name = L"source-cell-range";
void table_source_cell_range::add_attributes( const xml::attributes_wc_ptr & Attributes ) void table_source_cell_range::add_attributes( const xml::attributes_wc_ptr & Attributes )
{ {
CP_APPLY_ATTR(L"table:cellrange-address", table_cellrange_address_); CP_APPLY_ATTR(L"table:cell-range-address", table_cell_range_address_);
} }
void table_source_cell_range::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name) void table_source_cell_range::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)
...@@ -248,14 +249,14 @@ void table_source_cell_range::add_child_element( xml::sax * Reader, const std::w ...@@ -248,14 +249,14 @@ void table_source_cell_range::add_child_element( xml::sax * Reader, const std::w
} }
void table_source_cell_range::xlsx_convert(oox::xlsx_conversion_context & Context) void table_source_cell_range::xlsx_convert(oox::xlsx_conversion_context & Context)
{ {
if (table_cellrange_address_) if (table_cell_range_address_)
{ {
formulasconvert::odf2oox_converter formulas_converter; formulasconvert::odf2oox_converter formulas_converter;
std::wstring ref = formulas_converter.convert_named_ref(*table_cellrange_address_, false); std::wstring ref = formulas_converter.convert_named_ref(*table_cell_range_address_, false);
std::wstring table_name = formulas_converter.get_table_name(); std::wstring table_name = formulas_converter.get_table_name();
Context.get_pivots_context().set_source_range(ref); Context.get_pivots_context().set_source_range(table_name, ref);
} }
} }
//------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------
......
...@@ -247,7 +247,7 @@ private: ...@@ -247,7 +247,7 @@ private:
virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name);
public: public:
_CP_OPT(std::wstring) table_cellrange_address_; _CP_OPT(std::wstring) table_cell_range_address_;
office_element_ptr_array content_; //filters office_element_ptr_array content_; //filters
}; };
......
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
#include "../../Common/DocxFormat/Source/DocxFormat/WritingElement.h" #include "../../Common/DocxFormat/Source/DocxFormat/WritingElement.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/ActiveX.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/Video.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/Video.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h"
#include "../../Common/Base64.h" #include "../../Common/Base64.h"
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#include "../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/Video.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/Video.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/ActiveX.h"
#include "../../Common/DocxFormat/Source/DocxFormat/External/HyperLink.h" #include "../../Common/DocxFormat/Source/DocxFormat/External/HyperLink.h"
#include "../../Common/DocxFormat/Source/DocxFormat/External/ExternalImage.h" #include "../../Common/DocxFormat/Source/DocxFormat/External/ExternalImage.h"
#include "../../Common/DocxFormat/Source/DocxFormat/External/ExternalAudio.h" #include "../../Common/DocxFormat/Source/DocxFormat/External/ExternalAudio.h"
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "../../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h" #include "../../../Common/DocxFormat/Source/DocxFormat/Media/Audio.h"
#include "../../../Common/DocxFormat/Source/DocxFormat/Media/Video.h" #include "../../../Common/DocxFormat/Source/DocxFormat/Media/Video.h"
#include "../../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h" #include "../../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h"
#include "../../../Common/DocxFormat/Source/DocxFormat/Media/ActiveX.h"
#include "../../../Common/DocxFormat/Source/MathEquation/MathEquation.h" #include "../../../Common/DocxFormat/Source/MathEquation/MathEquation.h"
......
...@@ -1183,6 +1183,10 @@ ...@@ -1183,6 +1183,10 @@
<Filter <Filter
Name="Media" Name="Media"
> >
<File
RelativePath="..\Source\DocxFormat\Media\ActiveX.h"
>
</File>
<File <File
RelativePath="..\Source\DocxFormat\Media\Audio.h" RelativePath="..\Source\DocxFormat\Media\Audio.h"
> >
...@@ -1514,6 +1518,10 @@ ...@@ -1514,6 +1518,10 @@
RelativePath="..\Source\XlsxFormat\Drawing\CellAnchor.h" RelativePath="..\Source\XlsxFormat\Drawing\CellAnchor.h"
> >
</File> </File>
<File
RelativePath="..\Source\XlsxFormat\Controls\Controls.h"
>
</File>
<File <File
RelativePath="..\Source\XlsxFormat\Drawing\Drawing.h" RelativePath="..\Source\XlsxFormat\Drawing\Drawing.h"
> >
...@@ -1523,11 +1531,11 @@ ...@@ -1523,11 +1531,11 @@
> >
</File> </File>
<File <File
RelativePath="..\Source\XlsxFormat\Ole\oleobjects.h" RelativePath="..\Source\XlsxFormat\Drawing\Pos.h"
> >
</File> </File>
<File <File
RelativePath="..\Source\XlsxFormat\Drawing\Pos.h" RelativePath="..\Source\DocxFormat\Media\VbaProject.h"
> >
</File> </File>
</Filter> </Filter>
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "External/HyperLink.h" #include "External/HyperLink.h"
#include "Media/Image.h" #include "Media/Image.h"
#include "Media/OleObject.h" #include "Media/OleObject.h"
#include "Media/ActiveX.h"
#include "HeaderFooter.h" #include "HeaderFooter.h"
#include "../../../../ASCOfficePPTXFile/PPTXFormat/Theme.h" #include "../../../../ASCOfficePPTXFile/PPTXFormat/Theme.h"
......
...@@ -44,9 +44,11 @@ ...@@ -44,9 +44,11 @@
#include "Footnote.h" #include "Footnote.h"
#include "Endnote.h" #include "Endnote.h"
#include "Media/Image.h" #include "Media/Image.h"
#include "Media/ActiveX.h"
#include "Media/OleObject.h" #include "Media/OleObject.h"
#include "Media/Audio.h" #include "Media/Audio.h"
#include "Media/Video.h" #include "Media/Video.h"
#include "Media/VbaProject.h"
#include "External/HyperLink.h" #include "External/HyperLink.h"
#include "External/ExternalVideo.h" #include "External/ExternalVideo.h"
#include "External/ExternalAudio.h" #include "External/ExternalAudio.h"
...@@ -136,6 +138,14 @@ namespace OOX ...@@ -136,6 +138,14 @@ namespace OOX
return smart_ptr<OOX::File>(new CVmlDrawing( oRootPath, oFileName )); return smart_ptr<OOX::File>(new CVmlDrawing( oRootPath, oFileName ));
else if ( oRelation.Type() == OOX::FileTypes::Chart ) else if ( oRelation.Type() == OOX::FileTypes::Chart )
return smart_ptr<OOX::File>(new OOX::Spreadsheet::CChartSpace( oRootPath, oFileName )); return smart_ptr<OOX::File>(new OOX::Spreadsheet::CChartSpace( oRootPath, oFileName ));
else if ( oRelation.Type() == OOX::FileTypes::ActiveX_xml)
return smart_ptr<OOX::File>(new OOX::ActiveX_xml( oRootPath, oFileName));
else if ( oRelation.Type() == OOX::FileTypes::ActiveX_bin)
return smart_ptr<OOX::File>(new OOX::ActiveX_bin( oFileName ));
else if ( oRelation.Type() == OOX::FileTypes::VbaProject)
return smart_ptr<OOX::File>(new OOX::VbaProject( oRootPath, oFileName ));
//else if ( oRelation.Type() == OOX::FileTypes::VbaData)
// return smart_ptr<OOX::File>(new OOX::VbaData( oFileName ));
return smart_ptr<OOX::File>( new UnknowTypeFile() ); return smart_ptr<OOX::File>( new UnknowTypeFile() );
} }
...@@ -220,6 +230,14 @@ namespace OOX ...@@ -220,6 +230,14 @@ namespace OOX
return smart_ptr<OOX::File>(new OleObject( oFileName, true )); return smart_ptr<OOX::File>(new OleObject( oFileName, true ));
else if ( pRelation->Type() == OOX::FileTypes::Chart ) else if ( pRelation->Type() == OOX::FileTypes::Chart )
return smart_ptr<OOX::File>(new OOX::Spreadsheet::CChartSpace( oRootPath, oFileName )); return smart_ptr<OOX::File>(new OOX::Spreadsheet::CChartSpace( oRootPath, oFileName ));
else if ( pRelation->Type() == FileTypes::ActiveX_xml)
return smart_ptr<OOX::File>(new ActiveX_xml( oRootPath, oFileName ));
else if ( pRelation->Type() == FileTypes::ActiveX_bin)
return smart_ptr<OOX::File>(new ActiveX_bin( oFileName ));
else if ( pRelation->Type() == FileTypes::VbaProject)
return smart_ptr<OOX::File>(new OOX::VbaProject( oRootPath, oFileName ));
//else if ( pRelation->Type() == FileTypes::VbaData)
// return smart_ptr<OOX::File>(new OOX::VbaData( oFileName ));
return smart_ptr<OOX::File>( new UnknowTypeFile() ); return smart_ptr<OOX::File>( new UnknowTypeFile() );
} }
......
...@@ -172,6 +172,22 @@ namespace OOX ...@@ -172,6 +172,22 @@ namespace OOX
_T("application/vnd.openxmlformats-officedocument.drawingml.chart+xml"), _T("application/vnd.openxmlformats-officedocument.drawingml.chart+xml"),
_T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"), true, true); _T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"), true, true);
const FileType ActiveX_xml(L"activeX", L"",
_T("application/vnd.ms-office.activeX+xml"),
_T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"));
const FileType ActiveX_bin(L"activeX", L"",
_T("application/vnd.ms-office.activeX"),
_T("http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"));
const FileType VbaProject(L"", L"vbaProject.bin",
_T("application/vnd.ms-office.vbaProject"),
_T("http://schemas.microsoft.com/office/2006/relationships/vbaProject"));
const FileType VbaData(L"", L"vbaData.xml",
_T("application/vnd.ms-word.vbaData+xml"),
_T("http://schemas.microsoft.com/office/2006/relationships/wordVbaData"));
const FileType MicrosoftOfficeUnknown(L"embeddings", L"", const FileType MicrosoftOfficeUnknown(L"embeddings", L"",
_T(""), _T(""),
_T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/package")); _T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"));
......
...@@ -64,8 +64,6 @@ namespace OOX ...@@ -64,8 +64,6 @@ namespace OOX
m_arrFootnote.clear(); m_arrFootnote.clear();
} }
public:
virtual void read(const CPath& oPath) virtual void read(const CPath& oPath)
{ {
//don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath)
...@@ -118,8 +116,6 @@ namespace OOX ...@@ -118,8 +116,6 @@ namespace OOX
oContent.Registration( type().OverrideType(), oDirectory, oPath ); oContent.Registration( type().OverrideType(), oDirectory, oPath );
IFileContainer::Write( oPath, oDirectory, oContent ); IFileContainer::Write( oPath, oDirectory, oContent );
} }
public:
virtual const OOX::FileType type() const virtual const OOX::FileType type() const
{ {
return FileTypes::FootNote; return FileTypes::FootNote;
...@@ -133,8 +129,6 @@ namespace OOX ...@@ -133,8 +129,6 @@ namespace OOX
return type().DefaultFileName(); return type().DefaultFileName();
} }
public:
OOX::CFtnEdn* Find(const OOX::Logic::CFootnoteReference& oReference) const OOX::CFtnEdn* Find(const OOX::Logic::CFootnoteReference& oReference) const
{ {
if ( !oReference.m_oId.IsInit() ) if ( !oReference.m_oId.IsInit() )
...@@ -157,7 +151,6 @@ namespace OOX ...@@ -157,7 +151,6 @@ namespace OOX
return (unsigned int)m_arrFootnote.size(); return (unsigned int)m_arrFootnote.size();
} }
public:
CPath m_oReadPath; CPath m_oReadPath;
std::vector<OOX::CFtnEdn*> m_arrFootnote; std::vector<OOX::CFtnEdn*> m_arrFootnote;
std::vector<std::wstring> m_arrShapeTypes; std::vector<std::wstring> m_arrShapeTypes;
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "External/HyperLink.h" #include "External/HyperLink.h"
#include "Media/Image.h" #include "Media/Image.h"
#include "Media/OleObject.h" #include "Media/OleObject.h"
#include "Media/ActiveX.h"
#include "../../../../ASCOfficePPTXFile/PPTXFormat/LegacyDiagramText.h" #include "../../../../ASCOfficePPTXFile/PPTXFormat/LegacyDiagramText.h"
#include "../XlsxFormat/FileFactory_Spreadsheet.h" #include "../XlsxFormat/FileFactory_Spreadsheet.h"
...@@ -260,6 +262,20 @@ namespace OOX ...@@ -260,6 +262,20 @@ namespace OOX
return pPair->second.smart_dynamic_cast<HyperLink>(); return pPair->second.smart_dynamic_cast<HyperLink>();
} }
smart_ptr<ActiveX_xml> IFileContainer::GetActiveX_xml(const RId& rId) const
{
std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = m_mContainer.find(rId.get());
if (pPair == m_mContainer.end ())
return smart_ptr<ActiveX_xml>();
return pPair->second.smart_dynamic_cast<ActiveX_xml>();
}
smart_ptr<ActiveX_bin> IFileContainer::GetActiveX_bin(const RId& rId) const
{
std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = m_mContainer.find(rId.get());
if (pPair == m_mContainer.end ())
return smart_ptr<ActiveX_bin>();
return pPair->second.smart_dynamic_cast<ActiveX_bin>();
}
smart_ptr<OleObject> IFileContainer::GetOleObject (const RId& rId) const smart_ptr<OleObject> IFileContainer::GetOleObject (const RId& rId) const
{ {
std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = m_mContainer.find(rId.get()); std::map<std::wstring, smart_ptr<OOX::File>>::const_iterator pPair = m_mContainer.find(rId.get());
......
...@@ -48,6 +48,8 @@ namespace OOX ...@@ -48,6 +48,8 @@ namespace OOX
class Image; class Image;
class HyperLink; class HyperLink;
class OleObject; class OleObject;
class ActiveX_xml;
class ActiveX_bin;
} }
namespace PPTX namespace PPTX
...@@ -85,6 +87,8 @@ namespace OOX ...@@ -85,6 +87,8 @@ namespace OOX
virtual smart_ptr<Image> GetImage (const RId& rId) const; virtual smart_ptr<Image> GetImage (const RId& rId) const;
virtual smart_ptr<HyperLink> GetHyperlink(const RId& rId) const; virtual smart_ptr<HyperLink> GetHyperlink(const RId& rId) const;
virtual smart_ptr<OleObject> GetOleObject(const RId& rId) const; virtual smart_ptr<OleObject> GetOleObject(const RId& rId) const;
virtual smart_ptr<ActiveX_xml> GetActiveX_xml(const RId& rId) const;
virtual smart_ptr<ActiveX_bin> GetActiveX_bin(const RId& rId) const;
virtual smart_ptr<PPTX::LegacyDiagramText> GetLegacyDiagramText (const OOX::RId& rId) const; virtual smart_ptr<PPTX::LegacyDiagramText> GetLegacyDiagramText (const OOX::RId& rId) const;
OOX::CRels* GetCurRls() OOX::CRels* GetCurRls()
......
...@@ -227,7 +227,6 @@ namespace ComplexTypes ...@@ -227,7 +227,6 @@ namespace ComplexTypes
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{ {
// Читаем атрибуты
WritingElement_ReadAttributes_Start( oReader ) WritingElement_ReadAttributes_Start( oReader )
WritingElement_ReadAttributes_Read_if ( oReader, (L"r:id"), m_oId ) WritingElement_ReadAttributes_Read_if ( oReader, (L"r:id"), m_oId )
WritingElement_ReadAttributes_Read_else_if( oReader, (L"w:type"), m_oType ) WritingElement_ReadAttributes_Read_else_if( oReader, (L"w:type"), m_oType )
......
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* 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 Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* 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
*
*/
#pragma once
#ifndef OOX_ACTIVEX_INCLUDE_H_
#define OOX_ACTIVEX_INCLUDE_H_
#include "Media.h"
#include "../../XlsxFormat/FileTypes_Spreadsheet.h"
#include "../../Common/SimpleTypes_Shared.h"
#include "../IFileContainer.h"
namespace OOX
{
class COcxPr : public WritingElement
{
public:
WritingElement_AdditionConstructors(COcxPr)
COcxPr()
{
}
virtual ~COcxPr()
{
}
virtual void fromXML(XmlUtils::CXmlNode& node)
{
}
virtual std::wstring toXML() const
{
return _T("");
}
virtual void toXML(NSStringUtils::CStringBuilder& writer) const
{
writer.WriteString(_T("<ocxPr>"));
writer.WriteString(_T("</ocxPr>"));
}
virtual void fromXML(XmlUtils::CXmlLiteReader& oReader)
{
ReadAttributes(oReader);
if ( !oReader.IsEmptyNode() )
oReader.ReadTillEnd();
}
virtual EElementType getType () const
{
return et_x_OcxPr;
}
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start(oReader)
WritingElement_ReadAttributes_Read_if (oReader, _T("ax:name") , m_oName)
WritingElement_ReadAttributes_Read_else_if (oReader, _T("ax:value") , m_oValue)
WritingElement_ReadAttributes_End(oReader)
}
nullable<std::wstring> m_oName;
nullable<std::wstring> m_oValue;
//font
//picture
};
class ActiveX_xml : public File, public OOX::IFileContainer
{
public:
ActiveX_xml()
{
m_bDocument = false;
}
ActiveX_xml(const CPath& oRootPath, const CPath& filename)
{
m_bDocument = false;
read( oRootPath, filename );
}
virtual ~ActiveX_xml()
{
ClearItems();
}
void ClearItems()
{
for (size_t nIndex = 0; nIndex < m_arrOcxPr.size(); ++nIndex)
{
delete m_arrOcxPr[nIndex];
}
m_arrOcxPr.clear();
}
virtual void read(const CPath& oPath)
{
CPath oRootPath;
read(oRootPath, oPath);
}
virtual void read(const CPath& oRootPath, const CPath& oPath)
{
m_oReadPath = oPath;
IFileContainer::Read( oRootPath, oPath );
XmlUtils::CXmlLiteReader oReader;
if ( !oReader.FromFile( oPath.GetPath() ) )
return;
if ( !oReader.ReadNextNode() )
return;
std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName());
if ( _T("ocx") == sName)
{
ReadAttributes(oReader);
if ( !oReader.IsEmptyNode() )
{
int nDocumentDepth = oReader.GetDepth();
while ( oReader.ReadNextSiblingNode( nDocumentDepth ) )
{
sName = XmlUtils::GetNameNoNS(oReader.GetName());
if ( _T("ocxPr") == sName )
{
COcxPr* pOcxPr = new COcxPr(oReader);
m_arrOcxPr.push_back(pOcxPr);
}
}
}
}
}
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{
WritingElement_ReadAttributes_Start(oReader)
WritingElement_ReadAttributes_Read_if (oReader, L"ax:classid" , m_oClassId)
WritingElement_ReadAttributes_Read_else_if (oReader, L"ax:persistence" , m_oPersistence)
WritingElement_ReadAttributes_Read_else_if (oReader, L"r:id" , m_oId)
WritingElement_ReadAttributes_Read_else_if (oReader, L"ax:license" , m_oLicense)
WritingElement_ReadAttributes_End(oReader)
}
virtual void write(const OOX::CPath& filename, const OOX::CPath& directory, CContentTypes& content) const
{
}
virtual const FileType type() const
{
return OOX::FileTypes::ActiveX_xml;
}
virtual const CPath DefaultDirectory() const
{
if (m_bDocument) return type().DefaultDirectory();
else return L"../" + type().DefaultDirectory();
}
virtual const CPath DefaultFileName() const
{
return type().DefaultFileName();
}
bool m_bDocument;
protected:
CPath m_oReadPath;
nullable<std::wstring> m_oClassId;
nullable<std::wstring> m_oLicense;
nullable<std::wstring> m_oPersistence; //(§3.6.2.1, ST_Persistence).
nullable<SimpleTypes::CRelationshipId > m_oId;
std::vector<OOX::COcxPr*> m_arrOcxPr;
};
class ActiveX_bin : public Media
{
public:
ActiveX_bin(bool bDocument = true) : Media (bDocument)
{
}
ActiveX_bin(const OOX::CPath& filename)
{
read(filename);
}
virtual void write(const OOX::CPath& filename, const OOX::CPath& directory, CContentTypes& content) const
{
}
virtual const FileType type() const
{
return OOX::FileTypes::ActiveX_bin;
}
virtual const CPath DefaultDirectory() const
{
if (m_bDocument) return type().DefaultDirectory();
else return L"../" + type().DefaultDirectory();
}
virtual const CPath DefaultFileName() const
{
return m_filename.GetFilename();
}
void set_filename_cache(const std::wstring & file_path)
{
m_filenameCache = file_path;
}
void set_filename_cache(CPath & file_path)
{
m_filenameCache = file_path;
}
CPath filename_cache()
{
return m_filenameCache;
}
protected:
CPath m_filenameCache; //image
};
} // namespace OOX
#endif // OOX_ACTIVEX_INCLUDE_H_
/*
* (c) Copyright Ascensio System SIA 2010-2017
*
* 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 Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* 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
*
*/
#pragma once
#ifndef OOX_VBA_PROJECT_INCLUDE_H_
#define OOX_VBA_PROJECT_INCLUDE_H_
#include "Media.h"
#include "../../XlsxFormat/FileTypes_Spreadsheet.h"
namespace OOX
{
class VbaProject : public Media, public OOX::IFileContainer
{
public:
VbaProject( )
{
}
VbaProject(const CPath& oRootPath, const CPath& filename)
{
read( oRootPath, filename );
}
virtual void read(const CPath& oRootPath, const CPath& oPath)
{
IFileContainer::Read( oRootPath, oPath );
Media::read(oPath);
}
virtual void write(const OOX::CPath& filename, const OOX::CPath& directory, CContentTypes& content) const
{
}
virtual const FileType type() const
{
return OOX::FileTypes::VbaProject;
}
virtual const CPath DefaultDirectory() const
{
return type().DefaultDirectory();
}
virtual const CPath DefaultFileName() const
{
return m_filename.GetFilename();
}
protected:
};
} // namespace OOX
#endif // OOX_VBA_PROJECT_INCLUDE_H_
...@@ -1063,7 +1063,11 @@ namespace OOX ...@@ -1063,7 +1063,11 @@ namespace OOX
et_x_OleObjects, et_x_OleObjects,
et_x_OleObject, et_x_OleObject,
et_x_OleObjectPr, et_x_OleObjectPr,
et_x_OleObjectAnchor, et_x_ExtAnchor,
et_x_Controls,
et_x_Control,
et_x_ControlPr,
et_x_OcxPr,
et_x_TableParts, et_x_TableParts,
et_x_TablePart, et_x_TablePart,
et_x_Table, et_x_Table,
......
This diff is collapsed.
...@@ -36,7 +36,8 @@ ...@@ -36,7 +36,8 @@
#include "../../../../ASCOfficePPTXFile/PPTXFormat/Theme.h" #include "../../../../ASCOfficePPTXFile/PPTXFormat/Theme.h"
#include "../DocxFormat/VmlDrawing.h" #include "../DocxFormat/VmlDrawing.h"
#include "../DocxFormat/Media/OleObject.h" #include "../DocxFormat/Media/OleObject.h"
#include "../DocxFormat/Media/ActiveX.h"
#include "../DocxFormat/Media/VbaProject.h"
#include "SharedStrings/SharedStrings.h" #include "SharedStrings/SharedStrings.h"
#include "Styles/Styles.h" #include "Styles/Styles.h"
...@@ -177,6 +178,12 @@ namespace OOX ...@@ -177,6 +178,12 @@ namespace OOX
return smart_ptr<OOX::File>(new OOX::CDiagramDrawing( oRootPath, oFileName )); return smart_ptr<OOX::File>(new OOX::CDiagramDrawing( oRootPath, oFileName ));
else if ( pRelation->Type() == OOX::FileTypes::MicrosoftOfficeUnknown) //ms package else if ( pRelation->Type() == OOX::FileTypes::MicrosoftOfficeUnknown) //ms package
return smart_ptr<OOX::File>(new OOX::OleObject( oFileName, true )); return smart_ptr<OOX::File>(new OOX::OleObject( oFileName, true ));
else if ( pRelation->Type() == OOX::FileTypes::ActiveX_xml)
return smart_ptr<OOX::File>(new OOX::ActiveX_xml( oRootPath, oFileName ));
else if ( pRelation->Type() == OOX::FileTypes::ActiveX_bin)
return smart_ptr<OOX::File>(new OOX::ActiveX_bin( oFileName ));
else if ( pRelation->Type() == OOX::FileTypes::VbaProject)
return smart_ptr<OOX::File>(new OOX::VbaProject( oFileName ));
return smart_ptr<OOX::File>( new UnknowTypeFile() ); return smart_ptr<OOX::File>( new UnknowTypeFile() );
} }
......
...@@ -40,14 +40,14 @@ namespace OOX ...@@ -40,14 +40,14 @@ namespace OOX
{ {
namespace Spreadsheet namespace Spreadsheet
{ {
class COleObjectAnchor : public WritingElement class CExtAnchor : public WritingElement
{ {
public: public:
WritingElement_AdditionConstructors(COleObjectAnchor) WritingElement_AdditionConstructors(CExtAnchor)
COleObjectAnchor() CExtAnchor()
{ {
} }
virtual ~COleObjectAnchor() virtual ~CExtAnchor()
{ {
} }
...@@ -100,7 +100,7 @@ namespace OOX ...@@ -100,7 +100,7 @@ namespace OOX
virtual EElementType getType () const virtual EElementType getType () const
{ {
return et_x_OleObjectAnchor; return et_x_ExtAnchor;
} }
private: private:
...@@ -219,7 +219,7 @@ namespace OOX ...@@ -219,7 +219,7 @@ namespace OOX
nullable<SimpleTypes::COnOff<>> m_oPrint; nullable<SimpleTypes::COnOff<>> m_oPrint;
nullable<SimpleTypes::COnOff<>> m_oUiObject; nullable<SimpleTypes::COnOff<>> m_oUiObject;
nullable<COleObjectAnchor> m_oAnchor; nullable<CExtAnchor> m_oAnchor;
}; };
class COleObject : public WritingElement class COleObject : public WritingElement
...@@ -255,7 +255,7 @@ namespace OOX ...@@ -255,7 +255,7 @@ namespace OOX
toXML2(writer, true); toXML2(writer, true);
} }
} }
virtual void toXML2(NSStringUtils::CStringBuilder& writer, bool ObjectPr) const virtual void toXML2(NSStringUtils::CStringBuilder& writer, bool bObjectPr) const
{ {
writer.WriteString(L"<oleObject"); writer.WriteString(L"<oleObject");
WritingStringNullableAttrEncodeXmlString(L"progId", m_oProgId, m_oProgId.get()); WritingStringNullableAttrEncodeXmlString(L"progId", m_oProgId, m_oProgId.get());
...@@ -265,7 +265,7 @@ namespace OOX ...@@ -265,7 +265,7 @@ namespace OOX
WritingStringNullableAttrBool(L"autoLoad", m_oAutoLoad); WritingStringNullableAttrBool(L"autoLoad", m_oAutoLoad);
WritingStringNullableAttrInt(L"shapeId", m_oShapeId, m_oShapeId->GetValue()); WritingStringNullableAttrInt(L"shapeId", m_oShapeId, m_oShapeId->GetValue());
WritingStringNullableAttrString(L"r:id", m_oRid, m_oRid->ToString()); WritingStringNullableAttrString(L"r:id", m_oRid, m_oRid->ToString());
if (ObjectPr && m_oObjectPr.IsInit()) if (bObjectPr && m_oObjectPr.IsInit())
{ {
writer.WriteString(L">"); writer.WriteString(L">");
m_oObjectPr->toXML(writer); m_oObjectPr->toXML(writer);
......
...@@ -53,8 +53,6 @@ namespace OOX ...@@ -53,8 +53,6 @@ namespace OOX
virtual ~CWorkbook() virtual ~CWorkbook()
{ {
} }
public:
virtual void read(const CPath& oPath) virtual void read(const CPath& oPath)
{ {
} }
...@@ -77,26 +75,19 @@ namespace OOX ...@@ -77,26 +75,19 @@ namespace OOX
{ {
return m_oReadPath; return m_oReadPath;
} }
public:
void ClearItems() void ClearItems()
{ {
} }
std::vector<WritingElement *> m_arrItems;
private: private:
CPath m_oReadPath; CPath m_oReadPath;
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{ {
// Читаем атрибуты
WritingElement_ReadAttributes_Start( oReader ) WritingElement_ReadAttributes_Start( oReader )
WritingElement_ReadAttributes_ReadSingle( oReader, _T("w:conformance"), m_oConformance ) WritingElement_ReadAttributes_ReadSingle( oReader, _T("w:conformance"), m_oConformance )
WritingElement_ReadAttributes_End( oReader ) WritingElement_ReadAttributes_End( oReader )
} }
public:
std::vector<WritingElement *> m_arrItems;
}; };
} //Spreadsheet } //Spreadsheet
} // namespace OOX } // namespace OOX
......
...@@ -225,7 +225,6 @@ namespace OOX ...@@ -225,7 +225,6 @@ namespace OOX
void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) void ReadAttributes(XmlUtils::CXmlLiteReader& oReader)
{ {
// Читаем атрибуты
WritingElement_ReadAttributes_Start(oReader) WritingElement_ReadAttributes_Start(oReader)
WritingElement_ReadAttributes_Read_if (oReader, _T("maxLength") , m_oMaxLength) WritingElement_ReadAttributes_Read_if (oReader, _T("maxLength") , m_oMaxLength)
...@@ -279,7 +278,6 @@ namespace OOX ...@@ -279,7 +278,6 @@ namespace OOX
return et_x_FormulaCF; return et_x_FormulaCF;
} }
public:
std::wstring m_sText; std::wstring m_sText;
}; };
......
...@@ -51,6 +51,8 @@ ...@@ -51,6 +51,8 @@
#include "../Table/Table.h" #include "../Table/Table.h"
#include "../Comments/Comments.h" #include "../Comments/Comments.h"
#include "../Ole/OleObjects.h" #include "../Ole/OleObjects.h"
#include "../Controls/Controls.h"
#include "../../../../../DesktopEditor/common/String.h" #include "../../../../../DesktopEditor/common/String.h"
namespace OOX namespace OOX
...@@ -60,12 +62,10 @@ namespace OOX ...@@ -60,12 +62,10 @@ namespace OOX
//необработанные child: //необработанные child:
//<cellWatches> //<cellWatches>
//<colBreaks> //<colBreaks>
//<controls>
//<customProperties> //<customProperties>
//<dataConsolidate> //<dataConsolidate>
//<dataValidations> //<dataValidations>
//<extLst> //<extLst>
//<oleObjects>
//<phoneticPr> //<phoneticPr>
//<protectedRanges> //<protectedRanges>
//<rowBreaks> //<rowBreaks>
...@@ -92,8 +92,6 @@ namespace OOX ...@@ -92,8 +92,6 @@ namespace OOX
{ {
ClearItems(); ClearItems();
} }
public:
virtual void read(const CPath& oPath) virtual void read(const CPath& oPath)
{ {
//don't use this. instead use read(const CPath& oRootPath, const CPath& oFilePath) //don't use this. instead use read(const CPath& oRootPath, const CPath& oFilePath)
...@@ -157,6 +155,8 @@ namespace OOX ...@@ -157,6 +155,8 @@ namespace OOX
m_oLegacyDrawingHF = oReader; m_oLegacyDrawingHF = oReader;
else if ( _T("oleObjects") == sName ) else if ( _T("oleObjects") == sName )
m_oOleObjects = oReader; m_oOleObjects = oReader;
else if ( _T("controls") == sName )
m_oControls = oReader;
else if ( _T("headerFooter") == sName ) else if ( _T("headerFooter") == sName )
m_oHeaderFooter = oReader; m_oHeaderFooter = oReader;
else if (_T("sheetPr") == sName) else if (_T("sheetPr") == sName)
...@@ -379,6 +379,8 @@ namespace OOX ...@@ -379,6 +379,8 @@ namespace OOX
m_oLegacyDrawingHF->toXML(sXml); m_oLegacyDrawingHF->toXML(sXml);
if(m_oOleObjects.IsInit()) if(m_oOleObjects.IsInit())
m_oOleObjects->toXML(sXml); m_oOleObjects->toXML(sXml);
if (m_oControls.IsInit())
m_oControls->toXML(sXml);
if(m_oTableParts.IsInit()) if(m_oTableParts.IsInit())
m_oTableParts->toXML(sXml); m_oTableParts->toXML(sXml);
if(m_oExtLst.IsInit()) if(m_oExtLst.IsInit())
...@@ -441,7 +443,6 @@ namespace OOX ...@@ -441,7 +443,6 @@ namespace OOX
} }
m_arrConditionalFormatting.clear(); m_arrConditionalFormatting.clear();
} }
private:
CPath m_oReadPath; CPath m_oReadPath;
public: public:
...@@ -460,6 +461,7 @@ namespace OOX ...@@ -460,6 +461,7 @@ namespace OOX
nullable<OOX::Spreadsheet::CTableParts> m_oTableParts; nullable<OOX::Spreadsheet::CTableParts> m_oTableParts;
nullable<OOX::Spreadsheet::CLegacyDrawingWorksheet> m_oLegacyDrawing; nullable<OOX::Spreadsheet::CLegacyDrawingWorksheet> m_oLegacyDrawing;
nullable<OOX::Spreadsheet::COleObjects> m_oOleObjects; nullable<OOX::Spreadsheet::COleObjects> m_oOleObjects;
nullable<OOX::Spreadsheet::CControls> m_oControls;
std::map<std::wstring, CCommentItem*> m_mapComments; std::map<std::wstring, CCommentItem*> m_mapComments;
std::vector<OOX::Spreadsheet::CConditionalFormatting*> m_arrConditionalFormatting; std::vector<OOX::Spreadsheet::CConditionalFormatting*> m_arrConditionalFormatting;
nullable<OOX::Spreadsheet::CSheetPr> m_oSheetPr; nullable<OOX::Spreadsheet::CSheetPr> m_oSheetPr;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "../../Common/DocxFormat/Source/SystemUtility/SystemUtility.h" #include "../../Common/DocxFormat/Source/SystemUtility/SystemUtility.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h" #include "../../Common/DocxFormat/Source/DocxFormat/Media/OleObject.h"
#include "../../Common/DocxFormat/Source/DocxFormat/Media/ActiveX.h"
#include "../../Common/OfficeFileFormats.h" #include "../../Common/OfficeFileFormats.h"
#include "../../Common/Base64.h" #include "../../Common/Base64.h"
...@@ -2959,7 +2960,7 @@ namespace BinXlsxRW ...@@ -2959,7 +2960,7 @@ namespace BinXlsxRW
bool bSetAnchor = false; bool bSetAnchor = false;
if (pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oAnchor.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) if (pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oAnchor.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit())
{ {
const OOX::Spreadsheet::COleObjectAnchor& oAnchor = pOleObject->m_oObjectPr->m_oAnchor.get(); const OOX::Spreadsheet::CExtAnchor& oAnchor = pOleObject->m_oObjectPr->m_oAnchor.get();
SimpleTypes::Spreadsheet::CCellAnchorType<> eAnchorType; SimpleTypes::Spreadsheet::CCellAnchorType<> eAnchorType;
eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment