Compare commits

..

8 Commits

Author SHA1 Message Date
4201bcecc6 OdfFormatWriter - presentation notes masters 2017-05-07 11:04:36 +03:00
7b7bfbc5dd fix bug 34916 2017-05-07 09:36:56 +03:00
a70255e500 . 2017-05-06 09:17:04 +03:00
7e9dede9b3 xml sec classes (mscrypto) 2017-05-05 17:37:41 +03:00
9b7ad03465 OdfFormatWriter - presentation notes 2017-05-04 15:12:48 +03:00
3162bb0bfe open/save csv with user defined delimiters 2017-05-04 14:01:01 +03:00
ec95648c43 fix bug 34910 2017-05-04 11:21:05 +03:00
72ac11ac07 fix bug 34901 2017-05-04 11:03:49 +03:00
42 changed files with 1706 additions and 1616 deletions

View File

@ -7196,6 +7196,8 @@ namespace BinDocxRW
}
void WriteColorSchemeMapping(const PPTX::Logic::ClrMap& oColorSchemeMapping)
{
int re_index[] = {0, 1, 2, 3, 4, 5, 10, 11, 6, 7, 8, 9, 10, 11, 10, 6, 7};
int nCurPos = 0;
std::map<std::wstring, PPTX::Limit::ColorSchemeIndex>::const_iterator pFind;
@ -7204,84 +7206,84 @@ namespace BinDocxRW
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent1);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"accent2");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent2);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"accent3");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent3);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"accent4");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent4);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"accent5");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent5);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"accent6");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Accent6);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"bg1");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Bg1);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"bg2");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Bg2);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"folHlink");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::FollowedHyperlink);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"hlink");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::Hyperlink);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"tx1");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::T1);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
pFind = oColorSchemeMapping.ColorMap.find(L"tx2");
if(pFind != oColorSchemeMapping.ColorMap.end())
{
m_oBcw.m_oStream.WriteBYTE(c_oSer_ClrSchemeMappingType::T2);
m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte);
m_oBcw.m_oStream.WriteBYTE(pFind->second.GetBYTECode());
m_oBcw.m_oStream.WriteBYTE(re_index[pFind->second.GetBYTECode()]);
}
};
};

View File

@ -385,6 +385,7 @@ void _oox_drawing::serialize_shape(std::wostream & strm)
odf_reader::GetProperty(additional, L"custom_path_w", w);
odf_reader::GetProperty(additional, L"custom_path_h", h);
CP_XML_NODE(L"a:pathLst")
{
CP_XML_NODE(L"a:path")
@ -392,7 +393,10 @@ void _oox_drawing::serialize_shape(std::wostream & strm)
CP_XML_ATTR(L"w", w ? *w : cx);
CP_XML_ATTR(L"h", h ? *h : cy);
CP_XML_STREAM() << *sCustomPath;
if (sCustomPath)
{
CP_XML_STREAM() << *sCustomPath;
}
}
}
}

View File

@ -530,6 +530,48 @@ void pptx_conversion_context::end_page()
get_slide_context().end_slide();
}
bool pptx_conversion_context::start_note(const std::wstring & pageName, const std::wstring & pageStyleName,
const std::wstring & pageLayoutName,
const std::wstring & pageMasterName)
{
// create_new_slide(pageName);
//get_slide_context().start_note();//pageName, pageStyleName);
//current_master_page_name_ = pageMasterName;
//current_layout_page_name_ = pageLayoutName;
//
////const std::wstring masterPageNameLayout = root()->odf_context().pageLayoutContainer().page_layout_name_by_style(current_master_page_name_);
//std::pair<int,std::wstring> layout_id =
// root()->odf_context().styleContainer().presentation_layouts().add_or_find(pageLayoutName,pageMasterName);
//current_slide().Rels().add(relationship(layout_id.second, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout",
// std::wstring(L"../slideLayouts/slideLayout") + boost::lexical_cast<std::wstring>(layout_id.first) + L".xml"));
return true;
}
void pptx_conversion_context::end_note()
{
//if (!get_comments_context().empty())
// {
// std::wstringstream strm;
// get_comments_context().serialize(strm);
//
// const std::pair<std::wstring, std::wstring> commentsName =
// comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments() );
// get_slide_context().add_rels(false, commentsName.second, L"../comments/" + commentsName.first, typeComment);
// }
//get_slide_context().serialize_background(current_slide().Background());
//get_slide_context().serialize_objects (current_slide().Data());
//get_slide_context().serialize_animations(current_slide().Timing());
//
//get_slide_context().dump_rels(current_slide().Rels());//hyperlinks, mediaitems, ...
//get_slide_context().end_slide();
}
void pptx_conversion_context::end_layout()
{
get_slide_context().serialize_objects(current_layout().Data());

View File

@ -88,6 +88,12 @@ public:
const std::wstring & pageMasterName);
void end_page();
bool start_note(const std::wstring & pageName,
const std::wstring & pageStyleName,
const std::wstring & pageLayoutName,
const std::wstring & pageMasterName);
void end_note();
bool start_layout( int layout_index);
void end_layout();

View File

@ -32,18 +32,14 @@
#include "anim_elements.h"
#include <boost/make_shared.hpp>
#include <cpdoccore/xml/xmlchar.h>
#include <cpdoccore/xml/attributes.h>
#include <boost/lexical_cast.hpp>
#include "serialize_elements.h"
#include "odfcontext.h"
#include <cpdoccore/odf/odf_document.h>
#include "draw_common.h"
#include <cpdoccore/xml/simple_xml_writer.h>
@ -74,16 +70,16 @@ void anim_par::pptx_convert(oox::pptx_conversion_context & Context)
}
///////////////////////// последовательности .. (если один элемент - основная последовательность, иное - взаимодействующая анимация)
//slide_context().animation_context().start_sequence();
BOOST_FOREACH(const office_element_ptr& elm, anim_seq_array_)
for (size_t i = 0; i < anim_seq_array_.size(); i++)
{
elm->pptx_convert(Context);
anim_seq_array_[i]->pptx_convert(Context);
}
//slide_context().animation_context().end_sequence();
/////////////////////////////////////////////////////////////////
//внутренние эффекты - те что внутри одной последовательности
BOOST_FOREACH(const office_element_ptr& elm, content_)
for (size_t i = 0; i < content_.size(); i++)
{
elm->pptx_convert(Context);
content_[i]->pptx_convert(Context);
}
}
void anim_par::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)
@ -106,9 +102,9 @@ void anim_seq::add_attributes( const xml::attributes_wc_ptr & Attributes )
void anim_seq::pptx_convert(oox::pptx_conversion_context & Context)
{
BOOST_FOREACH(const office_element_ptr& elm, anim_par_array_)
for (size_t i = 0; i < anim_par_array_.size(); i++)
{
elm->pptx_convert(Context);
anim_par_array_[i]->pptx_convert(Context);
}
}
void anim_seq::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)

View File

@ -126,13 +126,15 @@ std::wstring presentation_class::get_type_ms()
res = L"sldNum";
break;
case subtitle:
case page:
case notes:
case handout:
case outline:
case text:
res = L"body";
break;
case page:
res = L"sldImg";
break;
}
return res;
}

View File

@ -32,13 +32,9 @@
#include "draw_page.h"
#include <boost/make_shared.hpp>
#include <cpdoccore/xml/xmlchar.h>
#include <cpdoccore/xml/attributes.h>
#include <boost/lexical_cast.hpp>
#include "serialize_elements.h"
#include "odfcontext.h"
#include <cpdoccore/odf/odf_document.h>
@ -84,7 +80,7 @@ void draw_page::add_child_element( xml::sax * Reader, const std::wstring & Ns, c
void draw_page::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
draw_page_attr_.add_attributes(Attributes);
attlist_.add_attributes(Attributes);
}
void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context, std::wstring styleName, presentation_class::type PresentationClass)
@ -96,7 +92,7 @@ void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context,
int index=-1;
const std::wstring masterName = draw_page_attr_.master_page_name_.get_value_or(L"");
const std::wstring masterName = attlist_.master_page_name_.get_value_or(L"");
style_master_page * master = Context.root()->odf_context().pageLayoutContainer().master_page_by_name(masterName);
if (master)
@ -129,16 +125,16 @@ void draw_page::pptx_convert_placeHolder(oox::pptx_conversion_context & Context,
void draw_page::pptx_convert(oox::pptx_conversion_context & Context)
{
const std::wstring pageStyleName = draw_page_attr_.draw_style_name_.get_value_or(L"");
const std::wstring pageName = draw_page_attr_.draw_name_.get_value_or(L"");
const std::wstring layoutName = draw_page_attr_.page_layout_name_.get_value_or(L"");
const std::wstring masterName = draw_page_attr_.master_page_name_.get_value_or(L"");
const std::wstring pageStyleName = attlist_.draw_style_name_.get_value_or(L"");
const std::wstring pageName = attlist_.draw_name_.get_value_or(L"");
const std::wstring layoutName = attlist_.page_layout_name_.get_value_or(L"");
const std::wstring masterName = attlist_.master_page_name_.get_value_or(L"");
_CP_LOG << L"[info][xlsx] process page(slide) \"" << pageName /*L"" */<< L"\"" << std::endl;
_CP_LOG << L"[info][pptx] process page(slide) \"" << pageName /*L"" */<< L"\"" << std::endl;
Context.start_page(pageName, pageStyleName, layoutName,masterName);
if (draw_page_attr_.draw_style_name_)
if (attlist_.draw_style_name_)
{
style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(pageStyleName,style_family::DrawingPage,false);
@ -191,19 +187,19 @@ void draw_page::pptx_convert(oox::pptx_conversion_context & Context)
animation_->pptx_convert(Context);
}
/////////////////////////
BOOST_FOREACH(const office_element_ptr& elm, content_)
for (size_t i = 0; i < content_.size(); i++)
{
elm->pptx_convert(Context);
content_[i]->pptx_convert(Context);
}
if (draw_page_attr_.use_footer_name_)//from master_page
if (attlist_.use_footer_name_)//from master_page
{
std::wstring name = L"footer:" + *draw_page_attr_.use_footer_name_;
std::wstring name = L"footer:" + *attlist_.use_footer_name_;
pptx_convert_placeHolder(Context, name, presentation_class::footer);
}
if (draw_page_attr_.use_date_time_name_)//from master_page
if (attlist_.use_date_time_name_)//from master_page
{
std::wstring name = L"datetime:" + *draw_page_attr_.use_date_time_name_;
std::wstring name = L"datetime:" + *attlist_.use_date_time_name_;
pptx_convert_placeHolder(Context, name, presentation_class::date_time);
}
@ -243,6 +239,121 @@ void presentation_date_time_decl::pptx_convert(oox::pptx_conversion_context & Co
{
Context.get_text_context().add_text(text_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t * presentation_notes::ns = L"presentation";
const wchar_t * presentation_notes::name = L"notes";
void presentation_notes::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)
{
CP_CREATE_ELEMENT(content_);
}
void presentation_notes::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
attlist_.add_attributes(Attributes);
}
//void presentation_notes::pptx_convert_placeHolder(oox::pptx_conversion_context & Context, std::wstring styleName, presentation_class::type PresentationClass)
//{
// office_element_ptr elm = Context.root()->odf_context().drawStyles().find_by_style_name(styleName);
// //todooo если это элемент datatime -нужно вытащить формат поля
//
// if (!elm)return;
//
// int index=-1;
//
// const std::wstring masterName = attlist_.master_page_name_.get_value_or(L"");
// style_master_page * master = Context.root()->odf_context().pageLayoutContainer().master_page_by_name(masterName);
//
// //if (master)
// // index = master->find_placeHolderIndex(PresentationClass, Context.last_idx_placeHolder);
//
//
// Context.get_slide_context().start_shape(1);
// Context.get_slide_context().set_placeHolder_type(presentation_class(PresentationClass).get_type_ms());
// Context.get_slide_context().set_placeHolder_idx(index);
//
// Context.get_text_context().start_object();
//
// if (PresentationClass == presentation_class::date_time)
// {
// Context.get_text_context().start_field(oox::datetime, L"");
// }
//
// elm->pptx_convert(Context);
//
// std::wstring text_content_ = Context.get_text_context().end_object();
//
// if (text_content_.length()>0)
// {
// Context.get_slide_context().set_property(_property(L"text-content",text_content_));
// }
// Context.get_slide_context().set_property(_property(L"no_rect",true));
// Context.get_slide_context().end_shape();
//
//}
//
void presentation_notes::pptx_convert(oox::pptx_conversion_context & Context)
{
const std::wstring pageStyleName = attlist_.draw_style_name_.get_value_or(L"");
const std::wstring pageName = attlist_.draw_name_.get_value_or(L"");
const std::wstring layoutName = attlist_.page_layout_name_.get_value_or(L"");
const std::wstring masterName = attlist_.master_page_name_.get_value_or(L"");
_CP_LOG << L"[info][pptx] process note slide" << std::endl;
Context.start_note(pageName, pageStyleName, layoutName, masterName);
if (attlist_.draw_style_name_)
{
style_instance * style_inst = Context.root()->odf_context().styleContainer().style_by_name(pageStyleName,style_family::DrawingPage, false);
if ((style_inst) && (style_inst->content()))
{
const style_drawing_page_properties * properties = style_inst->content()->get_style_drawing_page_properties();
if (properties)
{
oox::_oox_fill fill;
Compute_GraphicFill(properties->content().common_draw_fill_attlist_, office_element_ptr(),
Context.root()->odf_context().drawStyles() ,fill);
Context.get_slide_context().add_background(fill);
////////////////////////////////////////////////
if ((properties->content().presentation_display_footer_) && (*properties->content().presentation_display_footer_))
Context.get_slide_context().set_footer();
if ((properties->content().presentation_display_header_) && (*properties->content().presentation_display_header_))
Context.get_slide_context().set_header();
if ((properties->content().presentation_display_page_number_) && (*properties->content().presentation_display_page_number_))
Context.get_slide_context().set_page_number();
if ((properties->content().presentation_display_date_time_) && (*properties->content().presentation_display_date_time_))
Context.get_slide_context().set_date_time();
}
}
}
/////////////////////////
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->pptx_convert(Context);
}
//if (attlist_.use_footer_name_)//from master_page
//{
// std::wstring name = L"footer:" + *attlist_.use_footer_name_;
// pptx_convert_placeHolder(Context, name, presentation_class::footer);
//}
//if (attlist_.use_date_time_name_)//from master_page
//{
// std::wstring name = L"datetime:" + *attlist_.use_date_time_name_;
// pptx_convert_placeHolder(Context, name, presentation_class::date_time);
//}
Context.end_note();
}
}
}

View File

@ -79,11 +79,10 @@ private:
virtual void add_attributes( const xml::attributes_wc_ptr & Attributes );
virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name);
private:
office_element_ptr_array content_;
office_element_ptr animation_;
office_element_ptr_array content_;
office_element_ptr animation_;
draw_page_attr draw_page_attr_;
draw_page_attr attlist_;
};
CP_REGISTER_OFFICE_ELEMENT2(draw_page);
@ -139,5 +138,28 @@ private:
};
CP_REGISTER_OFFICE_ELEMENT2(presentation_date_time_decl);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//presentation:date-time-decl
class presentation_notes : public office_element_impl<presentation_notes>
{
public:
static const wchar_t * ns;
static const wchar_t * name;
static const xml::NodeType xml_type = xml::typeElement;
static const ElementType type = typePresentationNotes;
CPDOCCORE_DEFINE_VISITABLE();
virtual void pptx_convert(oox::pptx_conversion_context & Context);
private:
virtual void add_attributes( const xml::attributes_wc_ptr & Attributes );
virtual void add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name);
office_element_ptr_array content_;
draw_page_attr attlist_;
};
CP_REGISTER_OFFICE_ELEMENT2(presentation_notes);
}
}

View File

@ -316,6 +316,7 @@ enum ElementType
typeDrawPage,
typePresentationFooterDecl,
typePresentationDateTimeDecl,
typePresentationNotes,
typeAnimPar,
typeAnimSeq,

View File

@ -46,17 +46,17 @@ namespace odf_writer {
void draw_page_attr::serialize(CP_ATTR_NODE)
{
CP_XML_ATTR_OPT(L"draw:id", draw_id_);
CP_XML_ATTR_OPT(L"draw:id", draw_id_);
CP_XML_ATTR_OPT(L"draw:name", draw_name_);
CP_XML_ATTR_OPT(L"draw:style-name", draw_style_name_);
CP_XML_ATTR_OPT(L"draw:name", draw_name_);
CP_XML_ATTR_OPT(L"draw:style-name", draw_style_name_);
CP_XML_ATTR_OPT(L"draw:master-page-name", draw_master_page_name_);
CP_XML_ATTR_OPT(L"presentation:presentation-page-layout-name", page_layout_name_);
CP_XML_ATTR_OPT(L"draw:master-page-name", master_page_name_);
CP_XML_ATTR_OPT(L"presentation:use-date-time-name", use_date_time_name_);
CP_XML_ATTR_OPT(L"presentation:use-footer-name", use_footer_name_);
CP_XML_ATTR_OPT(L"style:page-layout-name", style_page_layout_name_);
CP_XML_ATTR_OPT(L"presentation:presentation-page-layout-name", presentation_page_layout_name_);
CP_XML_ATTR_OPT(L"presentation:use-date-time-name", presentation_use_date_time_name_);
CP_XML_ATTR_OPT(L"presentation:use-footer-name", presentation_use_footer_name_);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
@ -85,7 +85,7 @@ void draw_page::serialize(std::wostream & _Wostream)
{
CP_XML_NODE_SIMPLE()
{
draw_page_attr_.serialize(CP_GET_XML_NODE());
attlist_.serialize(CP_GET_XML_NODE());
for (int i = 0; i < content_.size(); i++)
{
content_[i]->serialize(CP_XML_STREAM());
@ -107,7 +107,7 @@ const wchar_t * presentation_footer_decl::name = L"footer-decl";
// CP_XML_ATTR_OPT(L"presentation:name", presentation_name_);
//}
//////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------
const wchar_t * presentation_date_time_decl::ns = L"presentation";
const wchar_t * presentation_date_time_decl::name = L"date-time-decl";
//
@ -119,5 +119,33 @@ const wchar_t * presentation_date_time_decl::name = L"date-time-decl";
//}
//
//------------------------------------------------------
const wchar_t * presentation_notes::ns = L"presentation";
const wchar_t * presentation_notes::name = L"notes";
void presentation_notes::create_child_element( const std::wstring & Ns, const std::wstring & Name)
{
CP_CREATE_ELEMENT(content_);
}
void presentation_notes::add_child_element( const office_element_ptr & child_element)
{
content_.push_back(child_element);
}
void presentation_notes::serialize(std::wostream & _Wostream)
{
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE_SIMPLE()
{
attlist_.serialize(CP_GET_XML_NODE());
for (int i = 0; i < content_.size(); i++)
{
content_[i]->serialize(CP_XML_STREAM());
}
}
}
}
}
}

View File

@ -54,12 +54,13 @@ public:
_CP_OPT(std::wstring) draw_name_;
_CP_OPT(std::wstring) draw_id_;
_CP_OPT(std::wstring) draw_style_name_;
_CP_OPT(std::wstring) draw_master_page_name_;
_CP_OPT(std::wstring) page_layout_name_;
_CP_OPT(std::wstring) master_page_name_;
_CP_OPT(std::wstring) style_page_layout_name_;
_CP_OPT(std::wstring) use_footer_name_;
_CP_OPT(std::wstring) use_date_time_name_;
_CP_OPT(std::wstring) presentation_use_footer_name_;
_CP_OPT(std::wstring) presentation_use_date_time_name_;
_CP_OPT(std::wstring) presentation_page_layout_name_;
};
class draw_page : public office_element_impl<draw_page>
@ -79,7 +80,7 @@ public:
office_element_ptr_array content_;
office_element_ptr animation_;
draw_page_attr draw_page_attr_;
draw_page_attr attlist_;
};
CP_REGISTER_OFFICE_ELEMENT2(draw_page);
@ -127,6 +128,26 @@ public:
};
CP_REGISTER_OFFICE_ELEMENT2(presentation_date_time_decl);
//---------------------------------------------------------------------
class presentation_notes : public office_element_impl<presentation_notes>
{
public:
static const wchar_t * ns;
static const wchar_t * name;
static const xml::NodeType xml_type = xml::typeElement;
static const ElementType type = typePresentationNotes;
CPDOCCORE_DEFINE_VISITABLE();
virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name);
virtual void add_child_element( const office_element_ptr & child_element);
virtual void serialize(std::wostream & _Wostream);
office_element_ptr_array content_;
draw_page_attr attlist_;
};
CP_REGISTER_OFFICE_ELEMENT2(presentation_notes);
}
}

View File

@ -264,7 +264,7 @@ public:
bool is_footer_;
bool is_header_;
bool is_background_;
_CP_OPT(bool) is_presentation_;
_CP_OPT(int) is_presentation_;
void create_draw_base(int type);
office_element_ptr create_draw_element(int type);
@ -312,12 +312,12 @@ void odf_drawing_context::set_styles_context(odf_style_context* styles_context)
impl_->styles_context_ = styles_context;
}
void odf_drawing_context::set_presentation (bool bMaster)
void odf_drawing_context::set_presentation (int type)
{
impl_->is_presentation_ = bMaster;
impl_->is_presentation_ = type;
}
_CP_OPT(bool) odf_drawing_context::get_presentation ()
_CP_OPT(int) odf_drawing_context::get_presentation ()
{
return impl_->is_presentation_;
}
@ -500,8 +500,8 @@ void odf_drawing_context::end_drawing()
if (impl_->current_drawing_state_.presentation_class_ || impl_->current_drawing_state_.presentation_placeholder_)
{
_CP_OPT(std::wstring) draw_layer;
if (impl_->is_presentation_.get() == true)
{//master
if (impl_->is_presentation_.get() > 0)
{//masters
draw_layer = L"backgroundobjects";
if (!impl_->current_drawing_state_.presentation_class_)
@ -1207,7 +1207,15 @@ void odf_drawing_context::set_placeholder_type (int val)
switch(val)
{
case 0: impl_->current_drawing_state_.presentation_class_ = presentation_class::outline; break;
case 0:
{
if (impl_->is_presentation_ == 2) //notes master
impl_->current_drawing_state_.presentation_class_ = presentation_class::notes;
else if (impl_->is_presentation_ == 3) //handout master
impl_->current_drawing_state_.presentation_class_ = presentation_class::handout;
else
impl_->current_drawing_state_.presentation_class_ = presentation_class::outline;
}break;
case 1: impl_->current_drawing_state_.presentation_class_ = presentation_class::chart; break;
case 2: impl_->current_drawing_state_.presentation_class_ = presentation_class::graphic; break;
case 3: impl_->current_drawing_state_.presentation_class_ = presentation_class::title; break;
@ -1218,7 +1226,7 @@ void odf_drawing_context::set_placeholder_type (int val)
case 8: impl_->current_drawing_state_.presentation_class_ = presentation_class::object; break;
case 9: impl_->current_drawing_state_.presentation_class_ = presentation_class::object; break;
case 10: impl_->current_drawing_state_.presentation_class_ = presentation_class::graphic; break;
case 11: impl_->current_drawing_state_.presentation_class_ = presentation_class::graphic; break;
case 11: impl_->current_drawing_state_.presentation_class_ = presentation_class::page; break;
case 12: impl_->current_drawing_state_.presentation_class_ = presentation_class::page_number;break;
case 13: impl_->current_drawing_state_.presentation_class_ = presentation_class::subtitle; break;
case 14: impl_->current_drawing_state_.presentation_class_ = presentation_class::table; break;

View File

@ -60,8 +60,8 @@ public:
odf_drawing_context (odf_conversion_context *odf_context);
~odf_drawing_context ();
void set_presentation (bool bMaster);
_CP_OPT(bool) get_presentation ();
void set_presentation (int type);
_CP_OPT(int) get_presentation ();
void set_drawings_rect (_CP_OPT(double) x_pt, _CP_OPT(double) y_pt, _CP_OPT(double) width_pt, _CP_OPT(double) height_pt);
void clear ();

View File

@ -584,7 +584,8 @@ void odf_page_layout_context::set_pages_mirrored(bool val)
style_page_layout_properties * odf_page_layout_context::get_properties()
{
if (layout_state_list_.size() < 1) return NULL;
if (layout_state_list_.empty()) return NULL;
style_page_layout_properties * props = layout_state_list_.back().get_properties();
if (props == NULL)
{

View File

@ -84,7 +84,7 @@ void odf_master_state::set_name(std::wstring & name)
if (!style_)return;
style_->style_master_page_attlist_.style_name_ = name;
style_->attlist_.style_name_ = name;
}
void odf_master_state::set_display_name(std::wstring & name)
{
@ -92,7 +92,7 @@ void odf_master_state::set_display_name(std::wstring & name)
if (!style_)return;
style_->style_master_page_attlist_.style_display_name_ = name;
style_->attlist_.style_display_name_ = name;
}
void odf_master_state::set_layout_style_name(std::wstring name)
@ -101,14 +101,14 @@ void odf_master_state::set_layout_style_name(std::wstring name)
if (!style_)return;
style_->style_master_page_attlist_.style_page_layout_name_ = name;
style_->attlist_.style_page_layout_name_ = name;
}
std::wstring odf_master_state::get_name()
{
style_master_page* style_ = dynamic_cast<style_master_page*>(elements_[0].elm.get());
if (!style_)return L"";
return style_->style_master_page_attlist_.style_name_.get_value_or(L"");
return style_->attlist_.style_name_.get_value_or(L"");
}
void odf_master_state::add_footer(office_element_ptr & elm)
{

View File

@ -36,6 +36,7 @@
#include "odp_conversion_context.h"
#include "office_presentation.h"
#include "draw_page.h"
#include "styles.h"
#include "style_table_properties.h"
@ -95,7 +96,7 @@ void odp_conversion_context::start_slide()
create_element(L"draw", L"page", root_presentation_->pages_, this);
slide_context_.start_page(root_presentation_->pages_.back());
drawing_context()->set_presentation(false);
drawing_context()->set_presentation(0);
}
void odp_conversion_context::end_slide()
{
@ -108,7 +109,7 @@ void odp_conversion_context::start_master_slide(std::wstring name)
page_layout_context()->add_master_page(name);
slide_context_.start_page(page_layout_context()->last_master()->get_root());
drawing_context()->set_presentation(true);
drawing_context()->set_presentation(1);
}
void odp_conversion_context::end_master_slide()
{
@ -122,7 +123,7 @@ void odp_conversion_context::start_layout_slide()
slide_context_.start_page(elm);
drawing_context()->set_presentation(true);
drawing_context()->set_presentation(1);
}
void odp_conversion_context::end_layout_slide()
{
@ -147,7 +148,28 @@ void odp_conversion_context::end_drawings()
{
current_slide().drawing_context()->clear();
}
void odp_conversion_context::start_note(bool bMaster)
{
office_element_ptr note_elm;
create_element(L"presentation", L"notes", note_elm, this);
current_slide().drawing_context()->start_drawing();
current_slide().drawing_context()->start_element(note_elm);
slide_context_.start_page(note_elm);
if (bMaster)
{
page_layout_context()->create_layout_page();
odf_writer::presentation_notes* notes = dynamic_cast<odf_writer::presentation_notes*>(note_elm.get());
notes->attlist_.style_page_layout_name_ = page_layout_context()->last_layout()->get_name();
drawing_context()->set_presentation(2);
}
else
drawing_context()->set_presentation(0);
}
void odp_conversion_context::start_comment(int oox_comm_id)
{
office_element_ptr comm_elm;
@ -182,6 +204,15 @@ void odp_conversion_context::end_comment()
current_slide().drawing_context()->end_element();
current_slide().drawing_context()->end_drawing();
}
void odp_conversion_context::end_note()
{
slide_context_.end_page();
slide_context_.remove_page();
current_slide().drawing_context()->end_element();
current_slide().drawing_context()->end_drawing();
}
}
}

View File

@ -77,6 +77,9 @@ public:
void start_comment_content ();
void end_comment_content ();
void start_note(bool bMaster = false);
void end_note();
private:
odp_slide_context slide_context_;

View File

@ -72,12 +72,12 @@ void odp_page_state::set_page_name(std::wstring name)
draw_page* page = dynamic_cast<draw_page*>(page_elm_.get());
if (page)
page->draw_page_attr_.draw_name_ = name;
page->attlist_.draw_name_ = name;
else
{
//style_master_page *master_page = dynamic_cast<style_master_page*>(page_elm_.get());
//if (master_page)
// master_page->style_master_page_attlist_.style_display_name_ = name;
// master_page->attlist_.style_display_name_ = name;
}
}
@ -88,7 +88,7 @@ void odp_page_state::set_layout_page(std::wstring name)
draw_page* page = dynamic_cast<draw_page*>(page_elm_.get());
if (page == NULL)return;
page->draw_page_attr_.page_layout_name_ = name;
page->attlist_.presentation_page_layout_name_ = name;
}
void odp_page_state::set_master_page(std::wstring name)
@ -98,7 +98,7 @@ void odp_page_state::set_master_page(std::wstring name)
draw_page* page = dynamic_cast<draw_page*>(page_elm_.get());
if (page == NULL)return;
page->draw_page_attr_.master_page_name_ = name;
page->attlist_.draw_master_page_name_ = name;
}
void odp_page_state::set_page_style(office_element_ptr & elm)
@ -111,12 +111,18 @@ void odp_page_state::set_page_style(office_element_ptr & elm)
draw_page* page = dynamic_cast<draw_page*>(page_elm_.get());
if (page)
page->draw_page_attr_.draw_style_name_ = office_page_style_->style_name_;
page->attlist_.draw_style_name_ = office_page_style_->style_name_;
else
{
style_master_page *master_page = dynamic_cast<style_master_page*>(page_elm_.get());
if (master_page)
master_page->style_master_page_attlist_.draw_style_name_ = office_page_style_->style_name_;
master_page->attlist_.draw_style_name_ = office_page_style_->style_name_;
else
{
presentation_notes* notes = dynamic_cast<presentation_notes*>(page_elm_.get());
if (notes)
notes->attlist_.draw_style_name_ = office_page_style_->style_name_;
}
}
}
void odp_page_state::add_child_element( const office_element_ptr & child_element)

View File

@ -44,8 +44,9 @@ namespace cpdoccore {
namespace odf_writer {
odp_slide_context::odp_slide_context(odp_conversion_context & Context): context_(Context), table_context_(&Context), comment_context_(&Context)
odp_slide_context::odp_slide_context(odp_conversion_context & Context) : context_(Context), table_context_(&Context), comment_context_(&Context)
{
count_slides_ = 0;
styles_context_ = Context.styles_context();
}
void odp_slide_context::set_styles_context(odf_style_context* styles_context)
@ -67,17 +68,13 @@ void odp_slide_context::start_page(office_element_ptr & elm)
{
page_state_list_.push_back( odp_page_state(&context_, elm) );
std::wstring style_name_new = L"dp" + boost::lexical_cast<std::wstring>(page_state_list_.size());
std::wstring style_name_new = L"dp" + std::to_wstring(++count_slides_);
office_element_ptr & style = styles_context_->add_or_find(style_name_new, style_family::DrawingPage, true);
style->create_child_element(L"style", L"drawing-page-properties");
state().set_page_style(style);
state().drawing_context()->set_styles_context(styles_context_);
//для свойств страницы, а не таблицы - нужно создать master-page c page layout и связать по имени со стилем таблицы
//причем здесь, т.к. с другой стороны это ВСЕ еще свойства листа. то есть совйства листа разделить на свйства страницы и таблицы ..
//todooo
//????
}
void odp_slide_context::end_page()
@ -85,6 +82,11 @@ void odp_slide_context::end_page()
state().drawing_context()->finalize(state().page_elm_);
}
void odp_slide_context::remove_page()
{
page_state_list_.pop_back();
}
odf_table_context* odp_slide_context::table_context()
{
return &table_context_;

View File

@ -53,6 +53,8 @@ public:
void start_page (office_element_ptr & elm);
void end_page ();
void remove_page();
void set_styles_context(odf_style_context* styles_context);
odf_style_context* get_styles_context();
@ -81,6 +83,7 @@ private:
odf_comment_context comment_context_;
std::list<odp_page_state> page_state_list_;
int count_slides_;
friend class odp_conversion_context;

View File

@ -157,8 +157,6 @@ enum ElementType
typeStylePresentationPlaceholder,
typeStyleDrawingPageProperties,
typePresentationNotes,
typeStyleColumns,
typeStyleColumn,
typeStyleColumnSep,
@ -264,6 +262,7 @@ enum ElementType
typeDrawPage,
typePresentationFooterDecl,
typePresentationDateTimeDecl,
typePresentationNotes,
typeAnimPar,
typeAnimSeq,

View File

@ -1270,7 +1270,7 @@ void style_master_page::serialize(std::wostream & strm)
{
CP_XML_NODE_SIMPLE()
{
style_master_page_attlist_.serialize( CP_GET_XML_NODE());
attlist_.serialize( CP_GET_XML_NODE());
if (style_footer_) style_footer_->serialize(CP_XML_STREAM());
if (style_header_) style_header_->serialize(CP_XML_STREAM());

View File

@ -505,7 +505,7 @@ public:
int find_placeHolderIndex(odf_types::presentation_class::type placeHolder,int & last_idx);
style_master_page_attlist style_master_page_attlist_;
style_master_page_attlist attlist_;
office_element_ptr style_header_;
office_element_ptr style_header_left_;

View File

@ -437,8 +437,6 @@ void OoxConverter::convert(PPTX::Logic::Shape *oox_shape)
{
if (oox_shape == NULL) return;
_CP_OPT(bool) bMasterPresentation = odf_context()->drawing_context()->get_presentation();
if (oox_shape->txXfrm.IsInit())
{
odf_context()->drawing_context()->start_group();
@ -1424,9 +1422,9 @@ void OoxConverter::convert(PPTX::Logic::Paragraph *oox_paragraph, PPTX::Logic::T
if (list_local)
{
_CP_OPT(bool) inStyles = odf_context()->drawing_context()->get_presentation();
_CP_OPT(int) inStyles = odf_context()->drawing_context()->get_presentation();
odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles);
odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles > 0);
convert_list_level(oox_paragraph->pPr.GetPointer(), list_level /*- 1*/);
odf_context()->styles_context()->lists_styles().end_style();
@ -1926,9 +1924,9 @@ void OoxConverter::convert(PPTX::Logic::TextListStyle *oox_list_style)
if (!oox_list_style) return;
if (oox_list_style->IsListStyleEmpty()) return;
_CP_OPT(bool) inStyles = odf_context()->drawing_context()->get_presentation();
_CP_OPT(int) inStyles = odf_context()->drawing_context()->get_presentation();
odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles);
odf_context()->styles_context()->lists_styles().start_style(inStyles && *inStyles > 0); // masters
for (int i = 0; i < 9; i++)
{
OoxConverter::convert_list_level(oox_list_style->levels[i].GetPointer(), i);
@ -1947,17 +1945,17 @@ void OoxConverter::convert(PPTX::Logic::TxBody *oox_txBody, PPTX::Logic::ShapeSt
for (size_t i = 0; i < oox_txBody->Paragrs.size(); i++)
{
convert(&oox_txBody->Paragrs[i], oox_txBody->lstStyle.GetPointer());
//внешние настройки для текста
convert(oox_txBody->bodyPr.GetPointer());
if (oox_style)
{
convert(&oox_style->fontRef);
}
}
odf_context()->drawing_context()->set_text( odf_context()->text_context());
//внешние настройки для текста
convert(oox_txBody->bodyPr.GetPointer());
if (oox_style)
{
convert(&oox_style->fontRef);
}
odf_context()->end_text_context();
}
void OoxConverter::convert(PPTX::Logic::ArcTo *oox_geom_path)

View File

@ -35,6 +35,7 @@
#include "../../../ASCOfficePPTXFile/PPTXFormat/Folder.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Presentation.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Slide.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/NotesMaster.h"
#include "../../../ASCOfficePPTXFile/PPTXFormat/Logic/Table/Table.h"
@ -359,7 +360,14 @@ void PptxConverter::convert_slides()
current_clrMap = slide->Layout->clrMapOvr->overrideClrMapping.GetPointer();
current_slide = slide->Layout.operator->();
convert_slide(&slide->Layout->cSld, current_txStyles, true, bShowLayoutMasterSp);
convert_slide(&slide->Layout->cSld, current_txStyles, true, bShowLayoutMasterSp);
if (!presentation->notesMasterIdLst.empty())
{
rId = presentation->notesMasterIdLst[0].rid.get();
smart_ptr<PPTX::NotesMaster> notes_master = ((*presentation)[rId]).smart_dynamic_cast<PPTX::NotesMaster>();
convert(notes_master.operator->());
}
//add note master
odp_context->end_master_slide();
@ -409,9 +417,51 @@ void PptxConverter::convert_slides()
odp_context->end_slide();
}
}
void PptxConverter::convert(PPTX::NotesSlide *oox_note)
void PptxConverter::convert(PPTX::NotesMaster *oox_notes)
{
if (!oox_note) return;
if (!oox_notes) return;
odp_context->start_note(true);
current_slide = dynamic_cast<OOX::IFileContainer*>(oox_notes);
current_clrMap = &oox_notes->clrMap;
//PPTX::Logic::TxStyles* current_txStyles = oox_notes->notesStyle.GetPointer();
if (presentation->notesSz.IsInit())
{
_CP_OPT(odf_types::length) width = odf_types::length(presentation->notesSz->cx / 12700., odf_types::length::pt);
_CP_OPT(odf_types::length) height = odf_types::length(presentation->notesSz->cy / 12700., odf_types::length::pt);
odf_context()->page_layout_context()->set_page_size(width, height);
//if (presentation->notesSz->type.IsInit())
//{
// switch(presentation->notesSz->type->GetBYTECode())
// {
// default:
// break;
// }
// odf_context()->page_layout_context()->set_page_orientation
//}
}
convert_slide(&oox_notes->cSld, NULL, true, true);
odp_context->end_note();
}
void PptxConverter::convert(PPTX::NotesSlide *oox_notes)
{
if (!oox_notes) return;
odp_context->start_note();
current_slide = dynamic_cast<OOX::IFileContainer*>(oox_notes);
if (oox_notes->clrMapOvr.IsInit() && oox_notes->clrMapOvr->overrideClrMapping.IsInit())
current_clrMap = oox_notes->clrMapOvr->overrideClrMapping.GetPointer();
//current_txStyles = oox_notes->Master->txStyles.GetPointer();
convert_slide(&oox_notes->cSld, NULL, true, true);
odp_context->end_note();
}
void PptxConverter::convert(OOX::WritingElement *oox_unknown)
@ -967,8 +1017,6 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
convert(oox_slide->bg.GetPointer());
bool bMaster = *odf_context()->drawing_context()->get_presentation();
for (size_t i = 0 ; i < oox_slide->spTree.SpTreeElems.size(); i++)
{
smart_ptr<PPTX::WrapperWritingElement> pElem = oox_slide->spTree.SpTreeElems[i].GetElem();
@ -987,9 +1035,6 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
{
int ph_type = pShape->nvSpPr.nvPr.ph->type->GetBYTECode();
//if (!bMaster && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12))
// continue;
odf_context()->drawing_context()->set_placeholder_type(ph_type);
}
else

View File

@ -48,6 +48,7 @@ namespace PPTX
{
class TableStyles;
class NotesSlide;
class NotesMaster;
class Presentation;
class Comments;
class Folder;
@ -110,7 +111,8 @@ namespace Oox2Odf
void convert_slide (PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp);
void convert_layout (PPTX::Logic::CSld *oox_slide);
void convert (PPTX::Comments *oox_comments);
void convert (PPTX::NotesSlide *oox_note);
void convert (PPTX::NotesSlide *oox_notes);
void convert (PPTX::NotesMaster *oox_notes);
void convert(PPTX::Logic::Bg *oox_background);
void convert(PPTX::Logic::Timing *oox_timing, PPTX::Logic::Transition *oox_transition);

View File

@ -145,19 +145,21 @@ namespace PPTX
lColorIndex._set(node.GetAttribute(_T("w:followedHyperlink"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("folHlink"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("w:hyperlink"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("hlink"), lColorIndex));
}
lColorIndex._set(node.GetAttribute(_T("accent1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent3"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent3"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent4"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent4"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent5"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent5"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent6"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent6"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("bg1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("bg1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("bg2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("bg2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("tx1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("tx1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("tx2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("tx2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("folHlink")));ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("folHlink"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("hlink"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("hlink"), lColorIndex));
else
{
lColorIndex._set(node.GetAttribute(_T("accent1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent3"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent3"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent4"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent4"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent5"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent5"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("accent6"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("accent6"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("bg1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("bg1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("bg2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("bg2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("tx1"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("tx1"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("tx2"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("tx2"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("folHlink")));ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("folHlink"), lColorIndex));
lColorIndex._set(node.GetAttribute(_T("hlink"))); ColorMap.insert(std::pair<std::wstring,Limit::ColorSchemeIndex>(_T("hlink"), lColorIndex));
}
}
virtual std::wstring toXML() const

View File

@ -182,12 +182,14 @@ namespace PPTX
NSBinPptxRW::CDrawingConverter oDrawingConverter;
NSBinPptxRW::CBinaryFileWriter* pOldWriter = oDrawingConverter.m_pBinaryWriter;
oDrawingConverter.m_pBinaryWriter = pWriter;
oDrawingConverter.m_pBinaryWriter = pWriter;
smart_ptr<OOX::IFileContainer> oldRels = oDrawingConverter.GetRels();
oDrawingConverter.SetRels(pChart.smart_dynamic_cast<OOX::IFileContainer>());
BinXlsxRW::BinaryChartWriter oBinaryChartWriter(*pWriter, &oDrawingConverter);
oBinaryChartWriter.WriteCT_ChartSpace(*pChart);
oDrawingConverter.SetRels(oldRels);
oDrawingConverter.m_pBinaryWriter = pOldWriter;
}
std::wstring ChartRec::toXML() const

View File

@ -0,0 +1,723 @@
#ifndef _XML_OOXMLSIGNER_H_
#define _XML_OOXMLSIGNER_H_
#include "./XmlCanonicalizator.h"
#include "./XmlSignerBase.h"
class COOXMLSigner
{
public:
ICertificate* m_certificate;
std::wstring m_sFolder;
std::wstring m_date;
std::map<std::wstring, std::wstring> m_content_types;
std::vector<std::wstring> m_rels;
std::vector<std::wstring> m_files;
NSStringUtils::CStringBuilderA m_signed_info;
std::wstring m_image_valid;
std::wstring m_image_invalid;
std::wstring m_guid;
public:
class COOXMLRelationship
{
public:
std::wstring rid;
std::wstring type;
std::wstring target;
std::wstring target_mode;
public:
COOXMLRelationship()
{
}
COOXMLRelationship(XmlUtils::CXmlNode& node)
{
rid = node.GetAttribute("Id");
type = node.GetAttribute("Type");
target = node.GetAttribute("Target");
CheckTargetMode();
}
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Relationship Id=\"");
builder.WriteEncodeXmlString(rid);
builder.WriteString(L"\" Type=\"");
builder.WriteEncodeXmlString(type);
builder.WriteString(L"\" Target=\"");
builder.WriteEncodeXmlString(target);
builder.WriteString(L"\" TargetMode=\"");
builder.WriteEncodeXmlString(target_mode);
builder.WriteString(L"\" />");
return builder.GetData();
}
static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j)
{
return i.rid < j.rid;
}
protected:
void CheckTargetMode()
{
if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp"))
target_mode = L"External";
else
target_mode = L"Internal";
}
};
class COOXMLRelationships
{
public:
std::vector<COOXMLRelationship> rels;
public:
COOXMLRelationships()
{
}
COOXMLRelationships(std::wstring& file)
{
XmlUtils::CXmlNode oNode;
if (!oNode.FromXmlFile(file))
return;
XmlUtils::CXmlNodes oNodes;
if (!oNode.GetNodes(L"Relationship", oNodes))
return;
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode oRel;
oNodes.GetAt(i, oRel);
rels.push_back(COOXMLRelationship(oRel));
}
}
std::wstring GetXml()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
// sort by rId
std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare);
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
builder.WriteString(i->GetXml());
builder.WriteString(L"</Relationships>");
return builder.GetData();
}
std::wstring GetTransforms()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">");
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
{
builder.WriteString(L"<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"");
builder.WriteEncodeXmlString(i->rid);
builder.WriteString(L"\" />");
}
builder.WriteString(L"</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
return builder.GetData();
}
void CheckOriginSigs(std::wstring& file)
{
int rId = 0;
std::vector<COOXMLRelationship>::iterator i = rels.begin();
while (i != rels.end())
{
if (0 == i->target.find(L"_xmlsignatures/"))
return;
std::wstring rid = i->rid;
rid = rid.substr(3);
int nTemp = std::stoi(rid);
if (nTemp > rId)
rId = nTemp;
i++;
}
std::string sXmlA;
NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA);
std::string::size_type pos = sXmlA.rfind("</Relationships>");
if (pos == std::string::npos)
return;
rId++;
std::string sRet = sXmlA.substr(0, pos);
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin\" Target=\"_xmlsignatures/origin.sigs\"/>\
</Relationships>");
NSFile::CFileBinary::Remove(file);
NSFile::CFileBinary oFile;
oFile.CreateFileW(file);
oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length());
oFile.CloseFile();
}
};
public:
COOXMLSigner(const std::wstring& sFolder, ICertificate* pContext)
{
m_sFolder = sFolder;
m_certificate = pContext;
m_date = L"2017-04-21T08:30:21Z";
m_signed_info.WriteString("<CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>");
m_signed_info.WriteString("<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>");
}
~COOXMLSigner()
{
}
std::wstring GetReference(const std::wstring& file, const std::wstring& content_type)
{
std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">";
sXml += L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>";
sXml += L"<DigestValue>";
sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file));
sXml += L"</DigestValue>";
sXml += L"</Reference>";
return sXml;
}
std::string GetHashXml(const std::wstring& xml)
{
std::string sXmlSigned = U_TO_UTF8(xml);
sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0);
return m_certificate->GetHash(sXmlSigned);
}
std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true)
{
std::wstring sXml1 = L"<Object xmlns=\"http://www.w3.org/2000/09/xmldsig#\"";
if (id.empty())
sXml1 += L">";
else
sXml1 += (L" Id=\"" + id + L"\">");
sXml1 += xml;
sXml1 += L"</Object>";
std::string sHash = GetHashXml(sXml1);
std::string sRet;
if (isCannon)
sRet = "<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>";
sRet += ("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>" + sHash + "</DigestValue>");
return sRet;
}
std::wstring GetImageBase64(const std::wstring& file)
{
BYTE* pData = NULL;
DWORD dwLen = 0;
if (!NSFile::CFileBinary::ReadAllBytes(file, &pData, dwLen))
return L"";
char* pDataC = NULL;
int nLen = 0;
NSFile::CBase64Converter::Encode(pData, (int)dwLen, pDataC, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::wstring sReturn = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pDataC, (LONG)nLen, FALSE);
RELEASEARRAYOBJECTS(pData);
RELEASEARRAYOBJECTS(pDataC);
return sReturn;
}
std::wstring GetRelsReference(const std::wstring& file)
{
COOXMLRelationships oRels(m_sFolder + file);
if (L"/_rels/.rels" == file)
{
oRels.CheckOriginSigs(m_sFolder + file);
// удалим все лишнее
std::vector<COOXMLRelationship>::iterator i = oRels.rels.begin();
while (i != oRels.rels.end())
{
if (0 == i->target.find(L"docProps/"))
i = oRels.rels.erase(i);
else if (0 == i->target.find(L"_xmlsignatures/"))
i = oRels.rels.erase(i);
else
i++;
}
}
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<Reference URI=\"");
builder.WriteString(file);
builder.WriteString(L"?ContentType=application/vnd.openxmlformats-package.relationships+xml\">");
builder.WriteString(oRels.GetTransforms());
builder.WriteString(L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>");
std::wstring sXml = oRels.GetXml();
std::string sHash = GetHashXml(sXml);
std::wstring sHashW = UTF8_TO_U(sHash);
builder.WriteString(sHashW);
builder.WriteString(L"</DigestValue></Reference>");
return builder.GetData();
}
int GetCountSigns(const std::wstring& file)
{
if (!NSFile::CFileBinary::Exists(file))
{
std::wstring sRels = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature\" Target=\"sig1.xml\"/>\
</Relationships>";
NSFile::CFileBinary::SaveToFile(file, sRels, false);
return 1;
}
XmlUtils::CXmlNode oNode;
oNode.FromXmlFile(file);
XmlUtils::CXmlNodes oNodes;
oNode.GetNodes(L"Relationship", oNodes);
int rId = oNodes.GetCount() + 1;
std::string sXmlA;
NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA);
std::string::size_type pos = sXmlA.rfind("</Relationships>");
if (pos == std::string::npos)
return 1;
std::string sRet = sXmlA.substr(0, pos);
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature\" Target=\"sig" + std::to_string(rId) + ".xml\"/>\
</Relationships>");
NSFile::CFileBinary::Remove(file);
NSFile::CFileBinary oFile;
oFile.CreateFileW(file);
oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length());
oFile.CloseFile();
return rId;
}
void ParseContentTypes()
{
std::wstring file = m_sFolder + L"/[Content_Types].xml";
XmlUtils::CXmlNode oNode;
oNode.FromXmlFile(file);
XmlUtils::CXmlNodes nodesDefaults;
oNode.GetNodes(L"Default", nodesDefaults);
XmlUtils::CXmlNodes nodesOverrides;
oNode.GetNodes(L"Override", nodesOverrides);
int nCount = nodesDefaults.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node;
nodesDefaults.GetAt(i, node);
m_content_types.insert(std::pair<std::wstring, std::wstring>(node.GetAttribute("Extension"), node.GetAttribute("ContentType")));
}
nCount = nodesOverrides.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node;
nodesOverrides.GetAt(i, node);
m_content_types.insert(std::pair<std::wstring, std::wstring>(node.GetAttribute("PartName"), node.GetAttribute("ContentType")));
}
}
void Parse()
{
// 1) Parse Content_Types.xml
ParseContentTypes();
// 2) Parse files in directory
std::vector<std::wstring> files = NSDirectory::GetFiles(m_sFolder, true);
// 3) Check each file
std::wstring sFolder = m_sFolder;
NSStringUtils::string_replace(sFolder, L"\\", L"/");
for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++)
{
std::wstring sCheckFile = *i;
NSStringUtils::string_replace(sCheckFile, L"\\", L"/");
if (0 != sCheckFile.find(sFolder))
continue;
// make cool filename
sCheckFile = sCheckFile.substr(sFolder.length());
// check needed file
if (0 == sCheckFile.find(L"/_xmlsignatures") ||
0 == sCheckFile.find(L"/docProps") ||
0 == sCheckFile.find(L"/[Content_Types].xml"))
continue;
// check rels and add to needed array
std::wstring::size_type posExt = sCheckFile.rfind(L".");
if (std::wstring::npos == posExt)
continue;
std::wstring sExt = sCheckFile.substr(posExt + 1);
if (sExt == L"rels")
m_rels.push_back(sCheckFile);
else
m_files.push_back(sCheckFile);
}
std::sort(m_rels.begin(), m_rels.end());
std::sort(m_files.begin(), m_files.end());
}
void WriteRelsReferences(NSStringUtils::CStringBuilder& builder)
{
for (std::vector<std::wstring>::iterator i = m_rels.begin(); i != m_rels.end(); i++)
{
builder.WriteString(GetRelsReference(*i));
}
}
void WriteFilesReferences(NSStringUtils::CStringBuilder& builder)
{
for (std::vector<std::wstring>::iterator i = m_files.begin(); i != m_files.end(); i++)
{
std::wstring sFile = *i;
std::wstring sContentType = L"application/xml";
std::map<std::wstring, std::wstring>::iterator _find = m_content_types.find(sFile);
if (_find != m_content_types.end())
{
sContentType = _find->second;
}
else
{
std::wstring::size_type posExt = sFile.rfind(L".");
if (std::wstring::npos != posExt)
{
std::wstring sExt = sFile.substr(posExt + 1);
_find = m_content_types.find(sExt);
if (_find != m_content_types.end())
sContentType = _find->second;
}
}
builder.WriteString(GetReference(sFile, sContentType));
}
}
void WriteManifest(NSStringUtils::CStringBuilder& builder)
{
builder.WriteString(L"<Manifest>");
WriteRelsReferences(builder);
WriteFilesReferences(builder);
builder.WriteString(L"</Manifest>");
}
void CorrectContentTypes(int nCountSigsNeeds)
{
std::wstring file = m_sFolder + L"/[Content_Types].xml";
XmlUtils::CXmlNode oNode;
oNode.FromXmlFile(file);
XmlUtils::CXmlNodes nodesDefaults;
oNode.GetNodes(L"Default", nodesDefaults);
XmlUtils::CXmlNodes nodesOverrides;
oNode.GetNodes(L"Override", nodesOverrides);
std::string sAddition = "";
bool bIsSigsExist = false;
int nCount = nodesDefaults.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node;
nodesDefaults.GetAt(i, node);
if ("sigs" == node.GetAttributeA("Extension") &&
"application/vnd.openxmlformats-package.digital-signature-origin" == node.GetAttributeA("ContentType"))
{
bIsSigsExist = true;
break;
}
}
if (!bIsSigsExist)
sAddition += "<Default Extension=\"sigs\" ContentType=\"application/vnd.openxmlformats-package.digital-signature-origin\"/>";
int nCountSigs = 0;
nCount = nodesOverrides.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode node;
nodesOverrides.GetAt(i, node);
if ("application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == node.GetAttributeA("ContentType"))
{
++nCountSigs;
}
}
for (int i = nCountSigs; i < nCountSigsNeeds; ++i)
{
sAddition += "<Override PartName=\"/_xmlsignatures/sig";
sAddition += std::to_string(i + 1);
sAddition += ".xml\" ContentType=\"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml\"/>";
}
std::string sXmlA;
NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA);
std::string::size_type pos = sXmlA.rfind("</Types>");
if (pos == std::string::npos)
return;
std::string sRet = sXmlA.substr(0, pos);
sRet += sAddition;
sRet += "</Types>";
NSFile::CFileBinary::Remove(file);
NSFile::CFileBinary oFile;
oFile.CreateFileW(file);
oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length());
oFile.CloseFile();
}
void SetGuid(const std::wstring& guid)
{
m_guid = guid;
}
void SetImageValid(const std::wstring& file)
{
m_image_valid = GetImageBase64(file);
}
void SetImageInvalid(const std::wstring& file)
{
m_image_invalid = GetImageBase64(file);
}
std::wstring GeneratePackageObject()
{
NSStringUtils::CStringBuilder builder;
WriteManifest(builder);
builder.WriteString(L"<SignatureProperties><SignatureProperty Id=\"idSignatureTime\" Target=\"#idPackageSignature\">");
builder.WriteString(L"<mdssi:SignatureTime xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\">");
builder.WriteString(L"<mdssi:Format>YYYY-MM-DDThh:mm:ssTZD</mdssi:Format>");
builder.WriteString(L"<mdssi:Value>");
builder.WriteString(m_date);
builder.WriteString(L"</mdssi:Value>");
builder.WriteString(L"</mdssi:SignatureTime></SignatureProperty></SignatureProperties>");
std::wstring sXml = builder.GetData();
m_signed_info.WriteString("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idPackageObject\">");
m_signed_info.WriteString(GetReferenceMain(sXml, L"idPackageObject", false));
m_signed_info.WriteString("</Reference>");
return (L"<Object Id=\"idPackageObject\">" + sXml + L"</Object>");
}
std::wstring GenerateOfficeObject()
{
NSStringUtils::CStringBuilder builder;
builder.WriteString(L"<SignatureProperties><SignatureProperty Id=\"idOfficeV1Details\" Target=\"#idPackageSignature\">");
builder.WriteString(L"<SignatureInfoV1 xmlns=\"http://schemas.microsoft.com/office/2006/digsig\">");
builder.WriteString(L"<SetupID>");
builder.WriteString(m_guid);
builder.WriteString(L"</SetupID>");
builder.WriteString(L"<SignatureText></SignatureText>");
builder.WriteString(L"<SignatureImage>");
builder.WriteString(m_image_valid);
builder.WriteString(L"</SignatureImage>");
builder.WriteString(L"<SignatureComments/>\
<WindowsVersion>10.0</WindowsVersion>\
<OfficeVersion>16.0</OfficeVersion>\
<ApplicationVersion>16.0</ApplicationVersion>\
<Monitors>2</Monitors>\
<HorizontalResolution>1680</HorizontalResolution>\
<VerticalResolution>1050</VerticalResolution>\
<ColorDepth>32</ColorDepth>\
<SignatureProviderId>{00000000-0000-0000-0000-000000000000}</SignatureProviderId>\
<SignatureProviderUrl/>\
<SignatureProviderDetails>9</SignatureProviderDetails>\
<SignatureType>2</SignatureType>\
</SignatureInfoV1>\
</SignatureProperty>\
</SignatureProperties>");
m_signed_info.WriteString("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idOfficeObject\">");
m_signed_info.WriteString(GetReferenceMain(builder.GetData(), L"idOfficeObject", false));
m_signed_info.WriteString("</Reference>");
return (L"<Object Id=\"idOfficeObject\">" + builder.GetData() + L"</Object>");
}
std::wstring GenerateImageObject()
{
if (m_image_valid.empty())
return L"";
m_signed_info.WriteString("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idValidSigLnImg\">");
m_signed_info.WriteString(GetReferenceMain(m_image_valid, L"idValidSigLnImg", false));
m_signed_info.WriteString("</Reference>");
m_signed_info.WriteString("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idInvalidSigLnImg\">");
m_signed_info.WriteString(GetReferenceMain(m_image_invalid, L"idInvalidSigLnImg", false));
m_signed_info.WriteString("</Reference>");
return (L"<Object Id=\"idValidSigLnImg\">" + m_image_valid + L"</Object><Object Id=\"idInvalidSigLnImg\">" + m_image_invalid + L"</Object>");
}
std::wstring GenerateSignPropertiesObject()
{
std::wstring sName = m_certificate->GetSignerName();
std::string sKeyA = m_certificate->GetNumber();
std::wstring sKey = UTF8_TO_U(sKeyA);
std::wstring sXml = (L"<xd:SignedSignatureProperties>\
<xd:SigningTime>" + m_date + L"</xd:SigningTime>\
<xd:SigningCertificate>\
<xd:Cert>\
<xd:CertDigest>\
<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\
<DigestValue>MJJT2Y0iMxaPGVXBmOLb9bY60pA=</DigestValue>\
</xd:CertDigest>\
<xd:IssuerSerial>\
<X509IssuerName>CN=" + sName + L"</X509IssuerName>\
<X509SerialNumber>" + sKey + L"</X509SerialNumber>\
</xd:IssuerSerial>\
</xd:Cert>\
</xd:SigningCertificate>\
<xd:SignaturePolicyIdentifier>\
<xd:SignaturePolicyImplied/>\
</xd:SignaturePolicyIdentifier>\
</xd:SignedSignatureProperties>");
std::wstring sSignedXml = L"<xd:SignedProperties xmlns=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Id=\"idSignedProperties\">";
sSignedXml += sXml;
sSignedXml += L"</xd:SignedProperties>";
std::string sXmlTmp = CXmlCanonicalizator::Execute(U_TO_UTF8(sSignedXml), XML_C14N_1_0);
m_signed_info.WriteString("<Reference Type=\"http://uri.etsi.org/01903#SignedProperties\" URI=\"#idSignedProperties\">");
m_signed_info.WriteString("<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
m_signed_info.WriteString("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>");
m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp));
m_signed_info.WriteString("</DigestValue></Reference>");
return (L"<Object><xd:QualifyingProperties xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Target=\"#idPackageSignature\">\
<xd:SignedProperties Id=\"idSignedProperties\">" + sXml + L"</xd:SignedProperties></xd:QualifyingProperties></Object>");
}
int AddSignatureReference()
{
std::wstring sDirectory = m_sFolder + L"/_xmlsignatures";
if (!NSDirectory::Exists(sDirectory))
NSDirectory::CreateDirectory(sDirectory);
if (!NSFile::CFileBinary::Exists(sDirectory + L"/origin.sigs"))
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sDirectory + L"/origin.sigs");
oFile.CloseFile();
}
if (!NSDirectory::Exists(sDirectory + L"/_rels"))
NSDirectory::CreateDirectory(sDirectory + L"/_rels");
int nSignNum = GetCountSigns(sDirectory + L"/_rels/origin.sigs.rels");
CorrectContentTypes(nSignNum);
return nSignNum;
}
void Sign()
{
Parse();
std::string sSignedData;
NSStringUtils::CStringBuilder builderMain;
builderMain.WriteString(GeneratePackageObject());
builderMain.WriteString(GenerateOfficeObject());
builderMain.WriteString(GenerateSignPropertiesObject());
builderMain.WriteString(GenerateImageObject());
std::string sSignedInfoData = m_signed_info.GetData();
std::string sSignedXml = "<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">" + sSignedInfoData + "</SignedInfo>";
sSignedXml = CXmlCanonicalizator::Execute(sSignedXml, XML_C14N_1_0);
sSignedXml = m_certificate->Sign(sSignedXml);
NSStringUtils::CStringBuilder builderResult;
builderResult.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\"?><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\" Id=\"idPackageSignature\"><SignedInfo>");
builderResult.WriteString(UTF8_TO_U(sSignedInfoData));
builderResult.WriteString(L"</SignedInfo>");
builderResult.WriteString(L"<SignatureValue>");
builderResult.WriteString(UTF8_TO_U(sSignedXml));
builderResult.WriteString(L"</SignatureValue>");
builderResult.WriteString(L"<KeyInfo><X509Data><X509Certificate>");
builderResult.WriteString(UTF8_TO_U(m_certificate->GetCertificateBase64()));
builderResult.WriteString(L"</X509Certificate></X509Data></KeyInfo>");
builderResult.Write(builderMain);
builderResult.WriteString(L"</Signature>");
int nSignNum = AddSignatureReference();
NSFile::CFileBinary::SaveToFile(m_sFolder + L"/_xmlsignatures/sig" + std::to_wstring(nSignNum) + L".xml", builderResult.GetData(), false);
}
};
#endif //_XML_OOXMLSIGNER_H_

View File

@ -0,0 +1,84 @@
#ifndef _XML_CANONICALIZATOR_H_
#define _XML_CANONICALIZATOR_H_
#include "../../common/File.h"
#include "../../common/Directory.h"
#include "../../common/StringBuilder.h"
#include "../../xml/include/xmlutils.h"
#include "../../xml/libxml2/include/libxml/c14n.h"
class CXmlCanonicalizator
{
private:
class CXmlBuffer
{
public:
NSStringUtils::CStringBuilderA builder;
public:
CXmlBuffer()
{
}
~CXmlBuffer()
{
}
};
static int buffer_xmlBufferIOWrite(CXmlBuffer* buf, const char* buffer, int len)
{
buf->builder.WriteString(buffer, (size_t)len);
return len;
}
static int buffer_xmlBufferIOClose(CXmlBuffer* buf)
{
return 0;
}
static int buffer_xmlC14NIsVisibleCallback(void * user_data, xmlNodePtr node, xmlNodePtr parent)
{
if (node->type == XML_TEXT_NODE)
{
const char* cur = (char*)node->content;
size_t size = strlen(cur);
for (size_t i = 0; i < size; ++i, ++cur)
{
if (*cur != '\n' && *cur != '\r' && *cur != '\t')
return 1;
}
return 0;
}
return 1;
}
public:
static std::string Execute(const std::string& sXml, int mode)
{
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
CXmlBuffer bufferC14N;
xmlOutputBufferPtr _buffer = xmlOutputBufferCreateIO((xmlOutputWriteCallback)buffer_xmlBufferIOWrite,
(xmlOutputCloseCallback)buffer_xmlBufferIOClose,
&bufferC14N,
NULL);
xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, 0, _buffer);
xmlOutputBufferClose(_buffer);
return bufferC14N.builder.GetData();
}
static std::string Execute(const std::wstring& sXmlFile, int mode)
{
std::string sXml;
NSFile::CFileBinary::ReadAllTextUtf8A(sXmlFile, sXml);
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
return Execute(sXml, mode);
}
};
#endif //_XML_CANONICALIZATOR_H_

View File

@ -0,0 +1,40 @@
#ifndef _XMLSIGNER_BASE_H_
#define _XMLSIGNER_BASE_H_
#include "../../common/File.h"
#include "../../common/BigInteger.h"
#include <string>
#include <vector>
#include <map>
class ICertificate
{
public:
ICertificate()
{
}
virtual ~ICertificate()
{
}
public:
virtual std::string GetNumber() = 0;
virtual std::wstring GetSignerName() = 0;
virtual std::string GetCertificateBase64() = 0;
virtual std::string GetCertificateHash() = 0;
public:
virtual std::string Sign(std::string sXml) = 0;
virtual std::string GetHash(unsigned char* pData, unsigned int nSize) = 0;
virtual std::string GetHash(std::string& sXml) = 0;
virtual std::string GetHash(std::wstring& sXmlFile) = 0;
virtual bool Verify(std::string& sXml, std::string& sXmlSignature) = 0;
public:
virtual bool ShowSelectDialog() = 0;
};
#endif // _XMLSIGNER_BASE_H_

View File

@ -0,0 +1,314 @@
#ifndef _XMLSIGNER_MSCRYPTO_H_
#define _XMLSIGNER_MSCRYPTO_H_
#include "./XmlSignerBase.h"
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <cryptuiapi.h>
class CCertificate_mscrypto : public ICertificate
{
public:
HCERTSTORE m_store;
PCCERT_CONTEXT m_context;
public:
CCertificate_mscrypto() : ICertificate()
{
m_store = NULL;
m_context = NULL;
}
CCertificate_mscrypto(PCCERT_CONTEXT ctx) : ICertificate()
{
m_store = NULL;
m_context = ctx;
}
virtual ~CCertificate_mscrypto()
{
if (m_store != NULL)
{
if (NULL != m_context)
CertFreeCertificateContext(m_context);
CertCloseStore(m_store, 0);
}
}
public:
virtual std::string GetNumber()
{
if (!m_context)
return "";
int nNumberLen = (int)m_context->pCertInfo->SerialNumber.cbData;
BYTE* pNumberData = new BYTE[nNumberLen];
ConvertEndian(m_context->pCertInfo->SerialNumber.pbData, pNumberData, (DWORD)nNumberLen);
CBigInteger oInteger(pNumberData, nNumberLen);
delete[] pNumberData;
return oInteger.ToString();
}
virtual std::wstring GetSignerName()
{
if (!m_context)
return L"";
DWORD dwNameLen = CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
wchar_t* pNameData = new wchar_t[dwNameLen];
CertGetNameStringW(m_context, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pNameData, dwNameLen);
std::wstring sName(pNameData);
RELEASEARRAYOBJECTS(pNameData);
return sName;
}
virtual std::string GetCertificateBase64()
{
if (!m_context)
return "";
char* pData = NULL;
int nDataLen = 0;
NSFile::CBase64Converter::Encode(m_context->pbCertEncoded, (int)m_context->cbCertEncoded, pData, nDataLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sReturn(pData, nDataLen);
RELEASEARRAYOBJECTS(pData);
return sReturn;
}
virtual std::string GetCertificateHash()
{
return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded);
}
public:
virtual std::string Sign(std::string sXml)
{
BOOL bResult = TRUE;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
HCRYPTPROV hCryptProv = NULL;
bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return "";
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return "";
}
bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
DWORD dwSigLen = 0;
BYTE* pbSignature = NULL;
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
pbSignature = new BYTE[dwSigLen];
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
BYTE* pbSignatureMem = new BYTE[dwSigLen];
ConvertEndian(pbSignature, pbSignatureMem, dwSigLen);
char* pBase64 = NULL;
int nBase64Len = 0;
NSFile::CBase64Converter::Encode(pbSignatureMem, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE);
delete[] pbSignature;
delete[] pbSignatureMem;
bResult = CryptDestroyHash(hHash);
std::string sReturn(pBase64, nBase64Len);
delete[] pBase64;
CryptReleaseContext(hCryptProv, 0);
return sReturn;
}
virtual std::string GetHash(unsigned char* pData, unsigned int nSize)
{
BOOL bResult = TRUE;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
DWORD dwSize = (DWORD)nSize;
HCRYPTPROV hCryptProv = NULL;
bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return "";
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return "";
}
bResult = CryptHashData(hHash, pData, dwSize, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
DWORD cbHashSize = 0, dwCount = sizeof(DWORD);
bResult = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &dwCount, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
BYTE* pDataHashRaw = new BYTE[dwCount];
bResult = CryptGetHashParam(hHash, HP_HASHVAL, pDataHashRaw, &cbHashSize, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
char* pBase64_hash = NULL;
int nBase64Len_hash = 0;
NSFile::CBase64Converter::Encode(pDataHashRaw, (int)cbHashSize, pBase64_hash, nBase64Len_hash, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sReturn(pBase64_hash, nBase64Len_hash);
delete [] pBase64_hash;
//delete [] pDataHashRaw;
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return sReturn;
}
virtual std::string GetHash(std::string& sXml)
{
return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length());
}
virtual std::string GetHash(std::wstring& sXmlFile)
{
BYTE* pFileData = NULL;
DWORD dwFileDataLen = 0;
NSFile::CFileBinary::ReadAllBytes(sXmlFile, &pFileData, dwFileDataLen);
if (0 == dwFileDataLen)
return "";
std::string sReturn = GetHash(pFileData, dwFileDataLen);
RELEASEARRAYOBJECTS(pFileData);
return sReturn;
}
virtual bool Verify(std::string& sXml, std::string& sXmlSignature)
{
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hPubKey = NULL;
HCRYPTPROV hCryptProv = NULL;
BOOL bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return FALSE;
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return FALSE;
}
BYTE* pDataHash = NULL;
DWORD dwHashLen = 0;
int nTmp = 0;
NSFile::CBase64Converter::Decode((char*)sXmlSignature.c_str(), (int)sXmlSignature.length(), pDataHash, nTmp);
dwHashLen = (DWORD)nTmp;
BYTE* pDataHashMem = new BYTE[dwHashLen];
ConvertEndian(pDataHash, pDataHashMem, dwHashLen);
RELEASEARRAYOBJECTS(pDataHash);
bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0);
// Get the public key from the certificate
CryptImportPublicKeyInfo(hCryptProv, m_context->dwCertEncodingType, &m_context->pCertInfo->SubjectPublicKeyInfo, &hPubKey);
BOOL bResultRet = CryptVerifySignature(hHash, pDataHashMem, dwHashLen, hPubKey, NULL, 0);
delete[] pDataHashMem;
bResult = CryptDestroyHash(hHash);
CryptDestroyKey(hPubKey);
CryptReleaseContext(hCryptProv, 0);
return bResultRet && bResult;
}
public:
virtual bool ShowSelectDialog()
{
m_store = CertOpenSystemStoreA(NULL, "MY");
if (!m_store)
return false;
m_context = CryptUIDlgSelectCertificateFromStore(m_store, NULL, NULL, NULL, CRYPTUI_SELECT_LOCATION_COLUMN, 0, NULL);
if (!m_context)
{
CertCloseStore(m_store, 0);
m_store = NULL;
return false;
}
return true;
}
private:
void ConvertEndian(const BYTE* src, BYTE* dst, DWORD size)
{
for(BYTE* p = dst + size - 1; p >= dst; ++src, --p)
(*p) = (*src);
}
};
#endif // _XMLSIGNER_MSCRYPTO_H_

File diff suppressed because it is too large Load Diff

View File

@ -333,6 +333,7 @@ namespace NExtractTools
int* m_nFormatTo;
int* m_nCsvTxtEncoding;
int* m_nCsvDelimiter;
std::wstring* m_sCsvDelimiterChar;
bool* m_bPaid;
bool* m_bFromChanges;
bool* m_bDontSaveAdditional;
@ -356,6 +357,7 @@ namespace NExtractTools
m_nFormatTo = NULL;
m_nCsvTxtEncoding = NULL;
m_nCsvDelimiter = NULL;
m_sCsvDelimiterChar = NULL;
m_bPaid = NULL;
m_bFromChanges = NULL;
m_bDontSaveAdditional = NULL;
@ -379,6 +381,7 @@ namespace NExtractTools
RELEASEOBJECT(m_nFormatTo);
RELEASEOBJECT(m_nCsvTxtEncoding);
RELEASEOBJECT(m_nCsvDelimiter);
RELEASEOBJECT(m_sCsvDelimiterChar);
RELEASEOBJECT(m_bPaid);
RELEASEOBJECT(m_bFromChanges);
RELEASEOBJECT(m_bDontSaveAdditional);
@ -456,6 +459,8 @@ namespace NExtractTools
m_nCsvTxtEncoding = new int(XmlUtils::GetInteger(sValue));
else if(_T("m_nCsvDelimiter") == sName)
m_nCsvDelimiter = new int(XmlUtils::GetInteger(sValue));
else if(_T("m_nCsvDelimiterChar") == sName)
m_sCsvDelimiterChar = new std::wstring(sValue);
else if(_T("m_bPaid") == sName)
m_bPaid = new bool(XmlUtils::GetBoolean2(sValue));
else if(_T("m_bFromChanges") == sName)
@ -475,6 +480,10 @@ namespace NExtractTools
else if(_T("m_sPassword") == sName)
m_sPassword = new std::wstring(sValue);
}
else if(_T("m_nCsvDelimiterChar") == sName)
{
m_sCsvDelimiterChar = new std::wstring(L"");
}
}
}
}
@ -492,8 +501,8 @@ namespace NExtractTools
std::wstring getXmlOptions()
{
std::wstring sRes;
int nCsvEncoding = 65001; //utf8
std::string cDelimiter = ",";
int nCsvEncoding = 46;//65001 utf8
std::wstring cDelimiter = L"";
if(NULL != m_nCsvTxtEncoding)
nCsvEncoding = *m_nCsvTxtEncoding;
@ -501,13 +510,17 @@ namespace NExtractTools
{
switch (*m_nCsvDelimiter)
{
case TCSVD_TAB: cDelimiter = "\t"; break;
case TCSVD_SEMICOLON: cDelimiter = ";"; break;
case TCSVD_COLON: cDelimiter = ":"; break;
case TCSVD_COMMA: cDelimiter = ","; break;
case TCSVD_SPACE: cDelimiter = " "; break;
case TCSVD_TAB: cDelimiter = L"\t"; break;
case TCSVD_SEMICOLON: cDelimiter = L";"; break;
case TCSVD_COLON: cDelimiter = L":"; break;
case TCSVD_COMMA: cDelimiter = L","; break;
case TCSVD_SPACE: cDelimiter = L" "; break;
}
}
if(NULL != m_sCsvDelimiterChar)
{
cDelimiter = *m_sCsvDelimiterChar;
}
int nFileType = 1;
if(NULL != m_nFormatFrom && AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == *m_nFormatFrom)
nFileType = 2;
@ -522,7 +535,7 @@ namespace NExtractTools
}
sRes = L"<xmlOptions><fileOptions fileType='" + std::to_wstring(nFileType);
sRes += L"' codePage='" + std::to_wstring(nCsvEncoding);
sRes += L"' delimiter='" + std::wstring(cDelimiter.begin(), cDelimiter.end()) + L"' " + sSaveType;
sRes += L"' delimiter='" + XmlUtils::EncodeXmlString(cDelimiter) + L"' " + sSaveType;
sRes += L"/><TXTOptions><Encoding>" + std::to_wstring(nCsvEncoding) + L"</Encoding></TXTOptions></xmlOptions>";
return sRes;
@ -602,7 +615,7 @@ namespace NExtractTools
eRes = TCD_ERROR;
}
}
else if(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatFrom && (NULL == m_nCsvTxtEncoding || NULL == m_nCsvDelimiter))
else if(AVS_OFFICESTUDIO_FILE_SPREADSHEET_CSV == nFormatFrom && (NULL == m_nCsvTxtEncoding || (NULL == m_nCsvDelimiter && NULL == m_sCsvDelimiterChar)))
{
if(!getDontSaveAdditional())
{

View File

@ -40,10 +40,6 @@
#endif
#include "../../DesktopEditor/common/File.h"
#ifndef CP_UTF8
#define CP_UTF8 65001
#endif
namespace SerializeCommon
{
std::wstring DownloadImage(const std::wstring& strFile)
@ -99,11 +95,11 @@ namespace SerializeCommon
return sSourcePath.substr(0, nIndex + 1) + sTargetExt;
return sSourcePath;
}
void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, WCHAR& wcDelimiter, BYTE& cSaveFileType)
void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& sDelimiter, BYTE& cSaveFileType)
{
result = BinXlsxRW::c_oFileTypes::XLSX;
nCodePage = CP_UTF8;
wcDelimiter = _T(',');
nCodePage = 46;//todo 46 временно CP_UTF8
sDelimiter = _T("");
cSaveFileType = BinXlsxRW::c_oFileTypes::XLSX;
nullable<SimpleTypes::CUnsignedDecimalNumber<>> fileType;
@ -142,9 +138,7 @@ namespace SerializeCommon
cSaveFileType = (BYTE)saveFileType->GetValue();
if (delimiter.IsInit())
{
const std::wstring& sDelimiter = delimiter.get();
if (0 < sDelimiter.length())
wcDelimiter = sDelimiter[0];
sDelimiter = delimiter.get();
}
break;
}

View File

@ -72,7 +72,7 @@ namespace SerializeCommon
aReplies.clear();
}
};
void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, WCHAR& wcDelimiter, BYTE& saveFileType);
void ReadFileType(const std::wstring& sXMLOptions, BYTE& result, UINT& nCodePage, std::wstring& wcDelimiter, BYTE& saveFileType);
}
#endif //SERIALIZER_COMMON

View File

@ -3926,16 +3926,16 @@ namespace BinXlsxRW
// File Type
BYTE fileType;
UINT nCodePage;
WCHAR wcDelimiter;
std::wstring sDelimiter;
BYTE saveFileType;
SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, wcDelimiter, saveFileType);
SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType);
OOX::Spreadsheet::CXlsx *pXlsx = NULL;
switch(fileType)
{
case BinXlsxRW::c_oFileTypes::CSV:
pXlsx = new OOX::Spreadsheet::CXlsx();
CSVReader::ReadFromCsvToXlsx(sInputDir, *pXlsx, nCodePage, wcDelimiter);
CSVReader::ReadFromCsvToXlsx(sInputDir, *pXlsx, nCodePage, sDelimiter);
break;
case BinXlsxRW::c_oFileTypes::XLSX:
default:
@ -3946,8 +3946,8 @@ namespace BinXlsxRW
if (BinXlsxRW::c_oFileTypes::JSON == saveFileType)
{
//todo 46 временно CP_UTF8
CSVWriter::WriteFromXlsxToCsv(sFileDst, *pXlsx, 46, _T(','), true);
//todo 46 временно CP_UTF8
CSVWriter::WriteFromXlsxToCsv(sFileDst, *pXlsx, 46, std::wstring(L","), true);
}
else
{

View File

@ -81,7 +81,7 @@ namespace CSVReader
pCell->setRowCol(nRow, nCol);
oRow.m_arrItems.push_back(pCell);
}
void ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const WCHAR wcDelimiter)
void ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& sDelimiter)
{
// Создадим Workbook
oXlsx.CreateWorkbook();
@ -169,6 +169,20 @@ namespace CSVReader
INT nSize = sFileDataW.length();
const WCHAR *pTemp =sFileDataW.c_str();
WCHAR wcDelimiterLeading = L'\0';
WCHAR wcDelimiterTrailing = L'\0';
int nDelimiterSize = 0;
if (sDelimiter.length() > 0)
{
wcDelimiterLeading = sDelimiter[0];
nDelimiterSize = 1;
if (2 == sizeof(wchar_t) && 0xD800 <= wcDelimiterLeading && wcDelimiterLeading <= 0xDBFF && sDelimiter.length() > 1)
{
wcDelimiterTrailing = sDelimiter[1];
nDelimiterSize = 2;
}
}
const WCHAR wcNewLineN = _T('\n');
const WCHAR wcNewLineR = _T('\r');
const WCHAR wcQuote = _T('"');
@ -188,7 +202,7 @@ namespace CSVReader
for (INT nIndex = 0; nIndex < nSize; ++nIndex)
{
wcCurrent = pTemp[nIndex];
if (wcDelimiter == wcCurrent)
if (wcDelimiterLeading == wcCurrent && (L'\0' == wcDelimiterTrailing || (nIndex + 1 < nSize && wcDelimiterTrailing == pTemp[nIndex + 1])))
{
if (bInQuote)
continue;
@ -197,7 +211,7 @@ namespace CSVReader
AddCell(sCellText, nStartCell, oDeleteChars, *pRow, nIndexRow, nIndexCol++, bIsWrap);
bIsWrap = false;
nStartCell = nIndex + 1;
nStartCell = nIndex + nDelimiterSize;
if (nStartCell == nSize)
{
pWorksheet->m_oSheetData->m_arrItems.push_back(pRow);

View File

@ -40,7 +40,7 @@
namespace CSVReader
{
void AddCell(std::wstring &sText, INT nStartCell, std::stack<INT> &oDeleteChars, OOX::Spreadsheet::CRow &oRow, INT nRow, INT nCol, bool bIsWrap);
void ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const WCHAR wcDelimiter);
void ReadFromCsvToXlsx(const std::wstring &sFileName, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& wcDelimiter);
}
#endif //CSV_READER

View File

@ -3916,10 +3916,10 @@ namespace BinXlsxRW {
std::wstring sDstPathCSV = sDstPath;
BYTE fileType;
UINT nCodePage;
WCHAR wcDelimiter;
std::wstring sDelimiter;
BYTE saveFileType;
SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, wcDelimiter, saveFileType);
SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType);
// Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается.
if (BinXlsxRW::c_oFileTypes::CSV == fileType)
@ -3943,7 +3943,7 @@ namespace BinXlsxRW {
switch(fileType)
{
case BinXlsxRW::c_oFileTypes::CSV:
CSVWriter::WriteFromXlsxToCsv(sDstPathCSV, oXlsx, nCodePage, wcDelimiter, false);
CSVWriter::WriteFromXlsxToCsv(sDstPathCSV, oXlsx, nCodePage, sDelimiter, false);
break;
case BinXlsxRW::c_oFileTypes::XLSX:
default:

View File

@ -64,7 +64,7 @@ namespace CSVWriter
}
}
}
void WriteFile(NSFile::CFileBinary *pFile, WCHAR **pWriteBuffer, INT &nCurrentIndex, std::wstring &sWriteString, UINT &nCodePage, bool bIsEnd)
void WriteFile(NSFile::CFileBinary *pFile, WCHAR **pWriteBuffer, INT &nCurrentIndex, const std::wstring &sWriteString, UINT &nCodePage, bool bIsEnd)
{
if (NULL == pFile || NULL == pWriteBuffer)
return;
@ -84,7 +84,7 @@ namespace CSVWriter
if (nCountChars + nCurrentIndex > c_nSize || bIsEnd)
{
// Буффер заполнился, пишем
if (nCodePage == CP_UTF16)
if (nCodePage == 48 && 2 == sizeof(wchar_t))//todo 48 временно CP_UTF16
{
pFile->WriteFile((BYTE*)*pWriteBuffer, sizeof (WCHAR) * nCurrentIndex);
}
@ -106,23 +106,23 @@ namespace CSVWriter
nCurrentIndex += nCountChars;
}
}
void WriteFromXlsxToCsv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const WCHAR wcDelimiter, bool bJSON)
void WriteFromXlsxToCsv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& sDelimiter, bool bJSON)
{
NSFile::CFileBinary oFile;
oFile.CreateFileW(sFileDst);
// Нужно записать шапку
if (CP_UTF8 == nCodePage)
if (46 == nCodePage)//todo 46 временно CP_UTF8
{
BYTE arUTF8[3] = {0xEF, 0xBB, 0xBF};
oFile.WriteFile(arUTF8, 3);
}
else if (CP_UTF16 == nCodePage)
else if (48 == nCodePage)//todo 48 временно CP_UTF16
{
BYTE arUTF16[2] = {0xFF, 0xFE};
oFile.WriteFile(arUTF16, 2);
}
else if (CP_unicodeFFFE == nCodePage)
else if (49 == nCodePage)//todo 49 временно CP_unicodeFFFE
{
BYTE arBigEndian[2] = {0xFE, 0xFF};
oFile.WriteFile(arBigEndian, 2);
@ -169,9 +169,8 @@ namespace CSVWriter
if (NULL != pWorksheet && pWorksheet->m_oSheetData.IsInit())
{
OOX::Spreadsheet::CSharedStrings *pSharedStrings = oXlsx.GetSharedStrings();
std::wstring sDelimiter = _T(""); sDelimiter += wcDelimiter;
std::wstring sEscape = _T("\"\n");
sEscape += wcDelimiter;
sEscape += sDelimiter;
std::wstring sEndJson = std::wstring(_T("]"));
std::wstring sQuote = _T("\"");
std::wstring sDoubleQuote = _T("\"\"");

View File

@ -32,20 +32,13 @@
#ifndef CSV_WRITER
#define CSV_WRITER
#define CP_UTF16 1200
#define CP_unicodeFFFE 1201
#ifndef CP_UTF8
#define CP_UTF8 65001
#endif
#include "../../DesktopEditor/common/File.h"
#include "../../Common/DocxFormat/Source/XlsxFormat/Xlsx.h"
namespace CSVWriter
{
void WriteFile(NSFile::CFileBinary *pFile, WCHAR **pWriteBuffer, INT &nCurrentIndex, std::wstring &sWriteString, UINT &nCodePage, bool bIsEnd = false);
void WriteFromXlsxToCsv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const WCHAR wcDelimiter, bool bJSON);
void WriteFile(NSFile::CFileBinary *pFile, WCHAR **pWriteBuffer, INT &nCurrentIndex, const std::wstring &sWriteString, UINT &nCodePage, bool bIsEnd = false);
void WriteFromXlsxToCsv(const std::wstring &sFileDst, OOX::Spreadsheet::CXlsx &oXlsx, UINT nCodePage, const std::wstring& wcDelimiter, bool bJSON);
}
#endif //CSV_WRITER