Compare commits

..

6 Commits

Author SHA1 Message Date
52777e36cb refactoring 2017-11-21 12:49:32 +03:00
7b7e9f3e6e . 2017-11-20 16:21:58 +03:00
d39fa156e7 fix build 2017-11-20 15:47:40 +03:00
48bf40919c fix... 2017-11-17 19:33:38 +03:00
fd53a987be fix bug #36272 2017-11-17 19:02:51 +03:00
b4d298542a fix bug #36251 2017-11-17 15:58:19 +03:00
9 changed files with 2076 additions and 35 deletions

View File

@ -582,7 +582,7 @@ namespace DocFileFormat
// The style id is used for a reverse reference.
// It can happen that the reference points to the wrong style.
if (styleIndex != ListData::ISTD_NIL)
if (styleIndex != ListData::ISTD_NIL && styleIndex < m_document->Styles->Styles->size())
{
m_pXmlWriter->WriteNodeBegin( L"w:pStyle", TRUE );
m_pXmlWriter->WriteAttribute( L"w:val", FormatUtils::XmlEncode(StyleSheetMapping::MakeStyleId(m_document->Styles->Styles->at(styleIndex))));

View File

@ -356,6 +356,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\Common\DocxFormat\Source\Base\unicode_util.cpp"
>
</File>
<File
RelativePath="..\..\UnicodeConverter\UnicodeConverter.cpp"
>

View File

@ -899,34 +899,254 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
{
std::wostream & strm = Context.current_sheet().sheetData();
const int sharedStringId = content_.xlsx_convert(Context, NULL);
const common_value_and_type_attlist & attr = attlist_.common_value_and_type_attlist_;
office_value_type::type odf_value_type = office_value_type::Custom;
oox::XlsxCellType::type t_val = oox::XlsxCellType::s;
std::wstring formula = attlist_.table_formula_.get_value_or(L"");
std::wstring number_val;
_CP_OPT(bool) bool_val;
_CP_OPT(std::wstring) str_val;
std::wstring num_format;
size_t xfId_last_set = 0;
int empty_cell_count = 0;
bool skip_next_cell = false;
bool is_style_visible = true;
bool is_data_visible = false;
// вычислить стиль для ячейки
std::wstring cellStyleName = attlist_.table_style_name_.get_value_or(L"");
std::wstring columnStyleName = Context.get_table_context().default_column_cell_style();
std::wstring rowStyleName = Context.get_table_context().default_row_cell_style();
if (attlist_.table_number_columns_repeated_ > 1)
columnStyleName.clear(); // могут быть разные стили колонок Book 24.ods
odf_read_context & odfContext = Context.root()->odf_context();
style_instance *defaultCellStyle=NULL, *defaultColumnCellStyle = NULL, *defaultRowCellStyle =NULL, *cellStyle = NULL;
try
{
defaultCellStyle = odfContext.styleContainer().style_default_by_type(style_family::TableCell);
defaultColumnCellStyle = odfContext.styleContainer().style_by_name(columnStyleName, style_family::TableCell, false);
defaultRowCellStyle = odfContext.styleContainer().style_by_name(rowStyleName, style_family::TableCell, false);
cellStyle = odfContext.styleContainer().style_by_name(cellStyleName, style_family::TableCell, false);
}
catch(...)
{
_CP_LOG << L"[error]: style wrong\n";
}
std::wstring data_style = CalcCellDataStyle(Context, columnStyleName, rowStyleName, cellStyleName);
// стили не наследуются
std::vector<const style_instance *> instances;
instances.push_back(defaultCellStyle);
if (defaultColumnCellStyle)
instances.push_back(defaultColumnCellStyle);
if (defaultRowCellStyle)
{
if (instances.size() > 1)
instances[1] = defaultRowCellStyle;
else
instances.push_back(defaultRowCellStyle);
}
if (cellStyle)
{
if (instances.size() > 1)
instances[1] = cellStyle;
else
instances.push_back(cellStyle);
}
text_format_properties_content textFormatProperties = calc_text_properties_content (instances);
paragraph_format_properties parFormatProperties = calc_paragraph_properties_content (instances);
style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties (instances);
if (attr.office_value_type_)
odf_value_type = attr.office_value_type_->get_type();
if ((odf_value_type == office_value_type::Float) ||
(odf_value_type == office_value_type::Custom && attr.office_value_))
{
t_val = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if (odf_value_type == office_value_type::Percentage)
{
t_val = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if (odf_value_type == office_value_type::Currency)
{
t_val = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if ((odf_value_type == office_value_type::Date) ||
(odf_value_type == office_value_type::Custom && attr.office_date_value_))
{
t_val = oox::XlsxCellType::n;
if (attr.office_date_value_)
{
int y, m, d;
if (oox::parseDate(attr.office_date_value_.get(), y, m, d))
{
number_val = boost::lexical_cast<std::wstring>(oox::convertDate(y, m, d));
}
}
}
else if ((odf_value_type == office_value_type::Time) ||
(odf_value_type == office_value_type::Custom && attr.office_time_value_))
{
t_val = oox::XlsxCellType::n;
if (attr.office_time_value_)
{
const std::wstring tv = attr.office_time_value_.get();
int h,m;
double s;
if (oox::parseTime(tv, h, m, s))
{
number_val = boost::lexical_cast<std::wstring>(oox::convertTime(h, m, s));
}
}
}
else if ((odf_value_type == office_value_type::Boolean) ||
(odf_value_type == office_value_type::Custom && attr.office_boolean_value_))
{
t_val = oox::XlsxCellType::b;
if (attr.office_boolean_value_) bool_val = oox::parseBoolVal(attr.office_boolean_value_.get());
}
else if ((odf_value_type == office_value_type::String) ||
(odf_value_type == office_value_type::Custom && attr.office_string_value_))
{
t_val = oox::XlsxCellType::str;
if (attr.office_string_value_) str_val = attr.office_string_value_.get();
}
if (!data_style.empty())
{
office_element_ptr elm = odfContext.numberStyles().find_by_style_name(data_style);
number_style_base *num_style = dynamic_cast<number_style_base*>(elm.get());
if (num_style)
{
Context.get_num_format_context().start_complex_format();
num_style->oox_convert(Context.get_num_format_context());
Context.get_num_format_context().end_complex_format();
num_format = Context.get_num_format_context().get_last_format();
}
}
oox::xlsx_cell_format cellFormat;
cellFormat.set_cell_type(t_val);
cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type));
is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false;
if ( content_.elements_.size() > 0 ||
!formula.empty() ||
( t_val == oox::XlsxCellType::n && !number_val.empty()) ||
( t_val == oox::XlsxCellType::b && bool_val) ||
(( t_val == oox::XlsxCellType::str || oox::XlsxCellType::inlineStr) && str_val)) is_data_visible = true;
if (attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false;
int cell_repeated_max = Context.current_table_column() + attlist_.table_number_columns_repeated_ + 1;
if (cell_repeated_max >= 1024 && cellStyleName.empty() && last_cell_ && !is_data_visible)
{//Book 24.ods
return;
}
if (is_style_visible)
{
xfId_last_set = Context.get_style_manager().xfId(&textFormatProperties, &parFormatProperties, &cellFormatProperties, &cellFormat, num_format, false, is_style_visible);
}
for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r)
{
Context.start_table_covered_cell();
const int xfId = Context.get_current_cell_style_id();
Context.start_table_covered_cell ();
if (is_style_visible)
Context.set_current_cell_style_id(xfId_last_set);
const int sharedStringId = content_.xlsx_convert(Context, &textFormatProperties);
if (t_val == oox::XlsxCellType::str && sharedStringId >=0)
t_val = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
if (skip_next_cell)break;
CP_XML_WRITER(strm)
// пустые ячейки пропускаем.
if ( is_data_visible || ((cellStyle || defaultColumnCellStyle) && is_style_visible))
{
CP_XML_NODE(L"c")
CP_XML_WRITER(strm)
{
CP_XML_ATTR(L"r", Context.current_cell_address());
if (xfId >= 0)
{
CP_XML_ATTR(L"s", xfId);
}
CP_XML_NODE(L"c")
{
CP_XML_ATTR(L"r", oox::getCellAddress(Context.current_table_column(), Context.current_table_row()));
CP_XML_ATTR(L"t", oox::cellType2Str(t_val));
CP_XML_ATTR(L"s", xfId_last_set);
if (sharedStringId >=0)
{
CP_XML_NODE(L"v")
if (!formula.empty())
{
CP_XML_CONTENT(sharedStringId);
const std::wstring xlsxFormula = formulas_converter.convert(formula);
if (!xlsxFormula.empty())
{
CP_XML_NODE(L"f")
{
CP_XML_CONTENT(xlsxFormula);
}
}
}
}
} // c
if (sharedStringId >= 0 && t_val == oox::XlsxCellType::s)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(sharedStringId); }
}
else if ((t_val == oox::XlsxCellType::str || t_val == oox::XlsxCellType::inlineStr) && str_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(str_val.get()); }
}
else if (t_val == oox::XlsxCellType::n && !number_val.empty())
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(number_val);}
}
else if (t_val == oox::XlsxCellType::b && bool_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT((int)(bool_val.get())); }
}
}
if ( is_data_visible || (cellStyle && is_style_visible && !last_cell_))
{
Context.non_empty_row();
empty_cell_count = 0 ;
}
else
{
empty_cell_count++;
//Уведомление_оручении.ods - 13 повторов пустых с cellStyle=NULL - нужные !!!
if (empty_cell_count > 19 && last_cell_&& (attlist_.table_number_columns_repeated_> 299 || cellStyle == NULL))
{//пишем простыню только если задан стиль тока для этих ячеек
skip_next_cell = true;
}
}
}
}
else
{
if (last_cell_) // Vehicle log book.ods (row = 24 and more)
skip_next_cell = true;
}
Context.end_table_covered_cell();

View File

@ -2057,11 +2057,12 @@ void DocxConverter::convert(OOX::Logic::CRunProperty *oox_run_pr, odf_writer::st
convert(oox_run_pr->m_oColor.GetPointer(),text_properties->content_.fo_color_);
}
text_properties->content_.style_text_underline_type_= odf_types::line_type(odf_types::line_type::None);
//text_properties->content_.style_text_underline_type_= odf_types::line_type(odf_types::line_type::None); //нельзя..если будет выше наследуемого то подчеркивания не будет
if (oox_run_pr->m_oU.IsInit())
{
text_properties->content_.style_text_underline_style_ = odf_types::line_style(odf_types::line_style::Solid);
text_properties->content_.style_text_underline_type_ = odf_types::line_type(odf_types::line_type::Single);
text_properties->content_.style_text_underline_width_ = odf_types::line_width(odf_types::line_width::Auto);
_CP_OPT(odf_types::color) color;
convert(oox_run_pr->m_oU->m_oColor.GetPointer(), oox_run_pr->m_oU->m_oThemeColor.GetPointer(),
@ -3187,9 +3188,9 @@ void DocxConverter::convert_table_style(OOX::CStyle *oox_style)
{
if (oox_style == NULL)return;
std::wstring oox_name = oox_style->m_sStyleId.IsInit() ? *oox_style->m_sStyleId : L"";
std::wstring oox_name_id = oox_style->m_sStyleId.IsInit() ? *oox_style->m_sStyleId : L"";
odt_context->styles_context()->table_styles().start_style(oox_name);
odt_context->styles_context()->table_styles().start_style(oox_name_id);
//общие
if (oox_style->m_oTblPr.IsInit())
@ -3303,17 +3304,21 @@ void DocxConverter::convert(OOX::CStyle *oox_style)
return;
}
std::wstring oox_name = oox_style->m_sStyleId.IsInit() ? *oox_style->m_sStyleId : L"";
odt_context->styles_context()->create_style(oox_name, family, false, true, -1);
std::wstring oox_name_id = oox_style->m_sStyleId.IsInit() ? *oox_style->m_sStyleId : L"";
odt_context->styles_context()->create_style(oox_name_id, family, false, true, -1);
std::wstring style_name;
if (oox_style->m_oName.IsInit() && oox_style->m_oName->m_sVal.IsInit())
odt_context->styles_context()->last_state()->set_display_name(*oox_style->m_oName->m_sVal);
{
style_name = *oox_style->m_oName->m_sVal;
odt_context->styles_context()->last_state()->set_display_name(style_name);
}
odf_writer::style_text_properties* text_properties = NULL;
if (oox_style->m_oRunPr.IsInit())
{
odf_writer::style_text_properties* text_properties = odt_context->styles_context()->last_state()->get_text_properties();
text_properties = odt_context->styles_context()->last_state()->get_text_properties();
if (oox_style->m_oDefault.IsInit() && oox_style->m_oDefault->ToBool())
{
@ -3330,14 +3335,14 @@ void DocxConverter::convert(OOX::CStyle *oox_style)
}
if (oox_style->m_oParPr.IsInit())
{
odf_writer::style_paragraph_properties * paragraph_properties = odt_context->styles_context()->last_state()->get_paragraph_properties();
odf_writer::style_paragraph_properties *paragraph_properties = odt_context->styles_context()->last_state()->get_paragraph_properties();
if (oox_style->m_oDefault.IsInit() && oox_style->m_oDefault->ToBool())
{
//основан на дефолтовом - накатить
odf_writer::odf_style_state_ptr def_style_state;
if (odt_context->styles_context()->find_odf_default_style_state(odf_types::style_family::Paragraph, def_style_state) && def_style_state)
{
odf_writer::style_paragraph_properties * props = def_style_state->get_paragraph_properties();
odf_writer::style_paragraph_properties *props = def_style_state->get_paragraph_properties();
paragraph_properties->apply_from(props);
}
}
@ -3367,9 +3372,19 @@ void DocxConverter::convert(OOX::CStyle *oox_style)
if (oox_style->m_oBasedOn.IsInit() && oox_style->m_oBasedOn->m_sVal.IsInit())
odt_context->styles_context()->last_state()->set_parent_style_name(*oox_style->m_oBasedOn->m_sVal);
//nullable<ComplexTypes::Word::COnOff2<SimpleTypes::onoffTrue>> m_oQFormat;
//nullable<ComplexTypes::Word::std::wstring_> m_oAliases;
//nullable<ComplexTypes::Word::COnOff2<SimpleTypes::onoffTrue>> m_oQFormat;
//nullable<ComplexTypes::Word::std::wstring_> m_oAliases;
//-------------------------------------------------------------------------------------------------------------------------
if (style_name == L"Hyperlink")
{
odt_context->styles_context()->create_style(L"Internet_20_link", family, false, true, -1);
//odt_context->styles_context()->last_state()->set_parent_style_name(oox_name_id);
odt_context->styles_context()->last_state()->set_display_name(L"Internet link");
odf_writer::style_text_properties* hyperlink_text_props = odt_context->styles_context()->last_state()->get_text_properties();
hyperlink_text_props->apply_from(text_properties);
}
}
void DocxConverter::convert(OOX::Logic::CCommentRangeStart* oox_comm_start)

View File

@ -2318,9 +2318,9 @@ namespace NSEditorApi
public:
CAscMenuEvent(int nType = -1)
: m_nType(nType)
, m_pData(NULL)
{
m_nType = nType;
m_pData = NULL;
}
virtual ~CAscMenuEvent()
{

View File

@ -18,10 +18,13 @@ public:
public:
int GetValid();
std::string GetGuid();
std::string GetDate();
ICertificate* GetCertificate();
std::string GetImageValidBase64();
std::string GetImageInvalidBase64();
std::wstring GetFile();
public:
void Check();
@ -41,6 +44,8 @@ public:
int GetSignatureCount();
COOXMLSignature* GetSignature(const int& index);
void RemoveSignature(const std::string& sGuid);
private:
COOXMLVerifier_private* m_internal;
};

View File

@ -432,7 +432,12 @@ Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-sign
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);
std::wstring sGUID = m_guid;
if (0 == sGUID.find(L"/_xmlsignatures"))
sGUID = L"";
builder.WriteString(sGUID);
builder.WriteString(L"</SetupID>");
builder.WriteString(L"<SignatureText></SignatureText>");
builder.WriteString(L"<SignatureImage>");

View File

@ -14,6 +14,9 @@ public:
std::wstring m_sFolder;
std::wstring m_sFile;
std::string m_sDate;
XmlUtils::CXmlNode m_node; // signature file
class CXmlStackNamespaces
@ -144,6 +147,10 @@ public:
{
return m_guid;
}
std::string GetDate()
{
return m_sDate;
}
ICertificate* GetCertificate()
{
return m_cert;
@ -157,6 +164,11 @@ public:
return m_sImageInvalidBase64;
}
std::wstring GetFile()
{
return m_sFile;
}
public:
void Check()
{
@ -178,6 +190,19 @@ public:
std::wstring sSetupID = FindFirstChild(firstChild, L"SetupID").GetText();
m_guid = U_TO_UTF8(sSetupID);
if (m_guid.empty())
{
std::wstring sFile = m_sFile;
NSStringUtils::string_replace(sFile, L"\\", L"/");
std::wstring::size_type posSign = sFile.find(L"/_xmlsignatures");
if (std::wstring::npos != posSign)
{
sFile = sFile.substr(posSign);
}
m_guid = U_TO_UTF8(sFile);
}
// 2) Images
XmlUtils::CXmlNode nodeImageValid = GetObjectById("idValidSigLnImg");
if (nodeImageValid.IsValid())
@ -194,6 +219,13 @@ public:
return;
}
XmlUtils::CXmlNode nodeSignProperties = GetObjectSignedProperties();
XmlUtils::CXmlNode nodeSignedSignatureProperties = nodeSignProperties.ReadNodeNoNS(L"SignedSignatureProperties");
XmlUtils::CXmlNode nodeST = nodeSignedSignatureProperties.ReadNodeNoNS(L"SigningTime");
std::wstring sDateW = nodeST.GetText();
if (!sDateW.empty())
m_sDate = U_TO_UTF8(sDateW);
XmlUtils::CXmlNodes nodesManifestRefs = nodeManifect.ReadNode(L"Manifest").GetNodes(L"Reference");
int nRefsCount = nodesManifestRefs.GetCount();
for (int i = 0; i < nRefsCount; i++)
@ -272,6 +304,25 @@ public:
return ret;
}
XmlUtils::CXmlNode GetObjectSignedProperties()
{
XmlUtils::CXmlNodes oNodes = m_node.GetNodes(L"Object");
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; i++)
{
XmlUtils::CXmlNode tmp;
oNodes.GetAt(i, tmp);
XmlUtils::CXmlNode nodeQ = tmp.ReadNodeNoNS(L"QualifyingProperties");
if (nodeQ.IsValid())
{
return nodeQ.ReadNodeNoNS(L"SignedProperties");
}
}
XmlUtils::CXmlNode ret;
return ret;
}
XmlUtils::CXmlNode FindFirstChild(XmlUtils::CXmlNode& node, const std::wstring& sName)
{
if (node.GetName() == sName)
@ -456,6 +507,10 @@ std::string COOXMLSignature::GetGuid()
{
return m_internal->GetGuid();
}
std::string COOXMLSignature::GetDate()
{
return m_internal->GetDate();
}
ICertificate* COOXMLSignature::GetCertificate()
{
@ -482,6 +537,7 @@ class COOXMLVerifier_private
public:
std::wstring m_sFolder;
std::vector<COOXMLSignature*> m_arSignatures;
std::vector<std::wstring> m_arSignaturesFiles;
public:
COOXMLVerifier_private(const std::wstring& sFolder)
@ -515,11 +571,13 @@ public:
continue;
COOXMLSignature* pSignature = new COOXMLSignature();
pSignature->m_internal->m_sFile = sFile;
pSignature->m_internal->m_node = nodeSig;
pSignature->m_internal->m_sFolder = m_sFolder;
pSignature->Check();
m_arSignatures.push_back(pSignature);
m_arSignaturesFiles.push_back(sFile);
}
}
~COOXMLVerifier_private()
@ -531,6 +589,107 @@ public:
}
m_arSignatures.clear();
}
void RemoveSignature(const std::string& sGuid)
{
int nCountSignatures = m_arSignatures.size();
if (0 == nCountSignatures)
return;
bool bIsRemoveAll = sGuid.empty();
std::wstring sFile;
if (!bIsRemoveAll)
{
for (int i = 0; i < nCountSignatures; ++i)
{
COOXMLSignature* pSignature = m_arSignatures.at(i);
if (pSignature->GetGuid() == sGuid)
{
sFile = m_arSignaturesFiles.at(i);
m_arSignatures.erase(m_arSignatures.begin() + i);
delete pSignature;
}
}
bIsRemoveAll = m_arSignatures.empty();
}
if (!sFile.empty())
NSFile::CFileBinary::Remove(sFile);
if (!bIsRemoveAll && sFile.empty())
return;
XmlUtils::CXmlNode oContentTypes;
if (!oContentTypes.FromXmlFile(m_sFolder + L"/[Content_Types].xml"))
return;
std::wstring sXml = L"<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
XmlUtils::CXmlNodes oNodes;
if (oContentTypes.GetNodes(L"*", oNodes))
{
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode oNode;
oNodes.GetAt(i, oNode);
if (bIsRemoveAll)
{
if (L"Default" == oNode.GetName() && L"sigs" == oNode.GetAttribute(L"Extension"))
continue;
if (L"Override" == oNode.GetName() && L"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == oNode.GetAttribute(L"ContentType"))
continue;
sXml += oNode.GetXml();
}
else
{
std::wstring sFileFound = sFile.substr(m_sFolder.length());
if (L"Override" == oNode.GetName() &&
L"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == oNode.GetAttribute(L"ContentType") &&
sFileFound == oNode.GetAttribute(L"PartName"))
continue;
sXml += oNode.GetXml();
}
}
}
sXml += L"</Types>";
NSFile::CFileBinary::SaveToFile(m_sFolder + L"/[Content_Types].xml", sXml);
if (bIsRemoveAll)
{
NSDirectory::DeleteDirectory(m_sFolder + L"/_xmlsignatures");
XmlUtils::CXmlNode oRels;
if (!oRels.FromXmlFile(m_sFolder + L"/_rels/.rels"))
return;
sXml = L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
XmlUtils::CXmlNodes oNodes;
if (oRels.GetNodes(L"*", oNodes))
{
int nCount = oNodes.GetCount();
for (int i = 0; i < nCount; ++i)
{
XmlUtils::CXmlNode oNode;
oNodes.GetAt(i, oNode);
if (L"Relationship" == oNode.GetName() &&
L"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin" == oNode.GetAttribute(L"Type"))
continue;
sXml += oNode.GetXml();
}
}
sXml += L"</Relationships>";
NSFile::CFileBinary::SaveToFile(m_sFolder + L"/_rels/.rels", sXml);
}
}
};
COOXMLVerifier::COOXMLVerifier(const std::wstring& sFolder)
@ -554,3 +713,11 @@ COOXMLSignature* COOXMLVerifier::GetSignature(const int& index)
return NULL;
return m_internal->m_arSignatures[index];
}
void COOXMLVerifier::RemoveSignature(const std::string& sGuid)
{
std::wstring sFolder = m_internal->m_sFolder;
m_internal->RemoveSignature(sGuid);
RELEASEOBJECT(m_internal);
m_internal = new COOXMLVerifier_private(sFolder);
}