Commit d4502d84 authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

(1.2.0.48): ASCOfficeOdfFileW

шаблонные формулы (shared )

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@56420 954022d7-b5bf-4e40-9824-e11837661b57
parent 9951602b
......@@ -24,6 +24,7 @@ public:
static std::wstring replace_cells_range_formater2(boost::wsmatch const & what);
static std::wstring replace_arguments(boost::wsmatch const & what);
static std::wstring convert_part_formula(boost::wsmatch const & what);
static std::wstring convert_scobci(boost::wsmatch const & what);
std::wstring replace_arguments1(std::wstring & workstr);
void replace_named_ref(std::wstring & expr);
......@@ -113,42 +114,45 @@ public:
// [$'Sheet2 A'.$B2] -> 'Sheet2 A'!$B2
void oox2odf_converter::Impl::replace_cells_range(std::wstring& expr)
{
std::vector<std::wstring> split1;
std::vector<std::wstring> split2;
//std::vector<std::wstring> split1;
//std::vector<std::wstring> split2;
boost::algorithm::split(split1,expr,boost::algorithm::is_any_of(L"!"), boost::algorithm::token_compress_on);
//boost::algorithm::split(split1,expr,boost::algorithm::is_any_of(L"!"), boost::algorithm::token_compress_on);
std::wstring sheet, cells_range, cell1,cell2;
if (split1.size() > 1)
{
sheet = split1[0];
cells_range = split1[1]; //+ ???
}else
cells_range = split1[0];
//std::wstring sheet, cells_range, cell1,cell2;
//if (split1.size() > 1)
//{
// sheet = split1[0];
// cells_range = split1[1]; //+ ???
//}else
// cells_range = split1[0];
boost::algorithm::split(split2,cells_range,boost::algorithm::is_any_of(L":"), boost::algorithm::token_compress_on);
//boost::algorithm::split(split2,cells_range,boost::algorithm::is_any_of(L":"), boost::algorithm::token_compress_on);
cell1 = split2[0];
if (split2.size() > 1)
{
cell2 = split2[1];
}
//cell1 = split2[0];
//if (split2.size() > 1)
//{
// cell2 = split2[1];
//}
if (!sheet.empty() || !cell1.empty())
{
std::wstring s = std::wstring(L"[") + sheet + (sheet.empty() ? L"" : L".") +
cell1 +
(cell2.empty() ? L"" : (L":" + sheet + (sheet.empty() ? L"" : L".") + cell2) ) + std::wstring(L"]");
//if (!sheet.empty() || !cell1.empty())
//{
// std::wstring s = /*std::wstring(L"[") */+ sheet + (sheet.empty() ? L"" : L".") +
// cell1 +
// (cell2.empty() ? L"" : (L":" + sheet + (sheet.empty() ? L"" : L".") + cell2) )/* + std::wstring(L"]")*/;
expr = s;
}
// expr = s;
//}
return;
//return;
boost::wregex re(L"([:$!])+");
boost::wregex re1(L"(\\$?\\w+?)?\\!?([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
boost::wregex re1(L"(\\$?\\w+\\!)?([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
//boost::wregex re1(L"(\\$?(\\w*?\\s*?['\"]*)?)?\\!?([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
//boost::wregex re2(L"([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
// $ Sheet2 ! $ A1 : $ B5
// $ Sheet2 ! $ A1 : $ B5
//
boost::wsmatch result;
bool b = boost::regex_search(expr, result, re);
......@@ -180,7 +184,7 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater1(boost::wsmat
if (sz>3)
{
std::wstring sheet1 = what[1].matched ? what[1].str() : L"";
//boost::algorithm::replace_all(sheet1, L"$", L"");
boost::algorithm::replace_all(sheet1, L"!", L"");
std::wstring c1 = what[2].str();
std::wstring c2 = what[3].str();
......@@ -445,6 +449,32 @@ std::wstring oox2odf_converter::Impl::replace_arguments1(std::wstring & workstr
return out ;
}
std::wstring oox2odf_converter::Impl::convert_scobci(boost::wsmatch const & what)
{
if (what[1].matched)
{
std::wstring inner = what[1].str();
boost::algorithm::replace_all(inner, L"(", L"SCOBCAIN");
boost::algorithm::replace_all(inner, L")", L"SCOBCAOUT");
boost::algorithm::replace_all(inner, L" ", L"PROBEL");
boost::algorithm::replace_all(inner, L"'", L"APOSTROF");
return inner;
}
else if (what[2].matched)
{
std::wstring inner = what[2].str();
boost::algorithm::replace_all(inner, L"(", L"SCOBCAIN");
boost::algorithm::replace_all(inner, L")", L"SCOBCAOUT");
boost::algorithm::replace_all(inner, L" ", L"PROBEL");
boost::algorithm::replace_all(inner, L"\"", L"KAVYCHKA");
return inner;
}
else if (what[3].matched)
return what[3].str();
}
std::wstring oox2odf_converter::Impl::replace_arguments(boost::wsmatch const & what)
{
std::wstring out;
......@@ -499,38 +529,28 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring & expr)
if (is_forbidden1(expr))
return L"NULLFORMULA";
std::wstring workstr = expr, out;
std::wstring workstr = expr;
//std::wstring res = boost::regex_replace(
// workstr,
// boost::wregex(L"(?:([\"']?.*[\"']?))"),//(\".*?\")|('.*?')|
// &oox2odf_converter::Impl::convert_part_formula,
// boost::match_all | boost::format_all);
std::wstring res1 = boost::regex_replace(
workstr,
boost::wregex(L"('.*?')"),
&oox2odf_converter::Impl::convert_scobci,boost::match_default | boost::format_all);
//std::list<std::wstring> result;
//bool b = boost::regex_split(std::back_inserter(result),workstr, boost::wregex(L"(\".*?\")|('.*?')"));
//
//result.push_back(workstr);// .. - boost.regex_split
//for (std::list<std::wstring>::iterator iter=result.begin(); iter!=result.end(); ++iter)
//{
// workstr = *iter;
//int res1 = workstr.find(L"\'");
//int res2 = workstr.find(L"\"");
//if (res1 >=0 || res2 >=0)out += workstr;
//else
//{
std::wstring res = boost::regex_replace(
workstr,
boost::wregex(L"(?:(?=[()])(.*?)(?=[)]))|(\".*?\")|('.*?')"),
&oox2odf_converter::Impl::replace_arguments,
boost::match_default | boost::format_all);
out += res;
////}
//}
std::wstring res = boost::regex_replace(
res1,
boost::wregex(L"(?:(?=[()])(.*?)(?=[)]))"),
&oox2odf_converter::Impl::replace_arguments,boost::match_default | boost::format_all);
boost::algorithm::replace_all(res, L"SCOBCAIN", L"(");
boost::algorithm::replace_all(res, L"SCOBCAOUT", L")");
boost::algorithm::replace_all(res, L"PROBEL", L" ");
boost::algorithm::replace_all(res, L"APOSTROF", L"'");
boost::algorithm::replace_all(res, L"KAVYCHKA", L"\"");
return std::wstring(L"of:=") + out;
return std::wstring(L"of:=") + res;
}
std::wstring oox2odf_converter::Impl::convert_part_formula(boost::wsmatch const & what)
......
......@@ -16,65 +16,7 @@ namespace odf {
namespace utils
{
size_t getColAddressInv(const std::wstring & a_)
{
std::wstring a = a_;
::boost::algorithm::to_upper(a);
static const size_t r = (L'Z' - L'A' + 1);
size_t mul = 1;
bool f = true;
size_t res = 0;
BOOST_REVERSE_FOREACH(const wchar_t c, a)
{
size_t v = c - L'A';
if (f)
f = false;
else
v += 1;
res += v * mul;
mul *= r;
}
return res;
}
size_t getRowAdderssInv(const std::wstring & a_)
{
int sz = a_.length();
if (a_.length()>0)
{
return boost::lexical_cast<size_t>(a_)-1;
}
else
return 0;
}
void splitCellAddress(const std::wstring & a_, std::wstring & col, std::wstring & row)
{
std::wstring a = a_;
std::reverse(a.begin(), a.end());
::boost::algorithm::replace_all(a, L"$", L"");
//::boost::algorithm::replace_all(a, L"'", L"");
::boost::algorithm::to_upper(a);
BOOST_FOREACH(wchar_t c, a)
{
if (c >= L'0' && c <= L'9')
row +=c;
else
col += c;
}
std::reverse(col.begin(), col.end());
std::reverse(row.begin(), row.end());
}
void parsing_ref (const std::wstring & ref, int & col,int & row)
{
std::wstring strCol, strRow;
splitCellAddress(ref,strCol,strRow);
col = getColAddressInv(strCol)+1;
row = getRowAdderssInv(strRow)+1;
}
void calculate_size_font_symbols(_font_metrix & metrix)
{
double appr_px = 0;//(int)_gdi_graphics_::calculate_size_symbol_asc(metrix.font_name,metrix.font_size,metrix.italic,metrix.bold);
......
......@@ -16,12 +16,15 @@
#include "style_paragraph_properties.h"
#include "style_graphic_properties.h"
namespace cpdoccore {
namespace odf {
//////////////////////////////////////////// .. utils ???
namespace utils
int ods_table_state::current_table_column_ = 0;
int ods_table_state::current_table_row_ = 0;
int ods_table_state::tmp_value_ =0;
namespace utils//////////////////////////////////////////// .. utils ???
{
std::wstring convert_date(std::wstring & oox_date)
{
......@@ -550,6 +553,108 @@ void ods_table_state::set_cell_formula(std::wstring & formula)
cell->table_table_cell_attlist_.table_formula_ = odfFormula;
}
std::wstring ods_table_state::replace_cell_row(boost::wsmatch const & what)
{
if (what[1].matched)
{
std::wstring base_str = boost::lexical_cast<std::wstring>(tmp_value_);
std::wstring replace_str = boost::lexical_cast<std::wstring>(current_table_row_);
std::wstring out = what[1].str();
boost::replace_all(out,base_str,replace_str);
return out;
}
else if (what[2].matched)
return what[2].str();
else if (what[3].matched)
return what[3].str();
else
return L"";
}
std::wstring ods_table_state::replace_cell_column(boost::wsmatch const & what)
{
if (what[1].matched)
{
std::wstring base_str = utils::getColAddress(tmp_value_-1);
std::wstring replace_str = utils::getColAddress(current_table_column_-1);
std::wstring out = what[1].str();
boost::replace_all(out,base_str,replace_str);
return out;
}
else if (what[2].matched)
return what[2].str();
else if (what[3].matched)
return what[3].str();
else
return L"";
}
void ods_table_state::add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, int ind)
{
if (ind < 0)return;
std::wstring odf_formula;
if (formula.size() > 0)
{
odf_formula = formulas_converter.convert_formula(formula);
int moving_type = 0;
std::vector<std::wstring> distance;
boost::algorithm::split(distance, ref,boost::algorithm::is_any_of(L":"), boost::algorithm::token_compress_on);
if (distance.size() >1)
{
int col1, row1, col2, row2;
utils::parsing_ref(distance[0],col1,row1);
utils::parsing_ref(distance[1],col2,row2);
if (row2-row1 >0)moving_type = 2;
if (col2-col1 >0)moving_type = 1;
}
ods_shared_formula_state state = {ind, odf_formula,ref, current_table_column_,current_table_row_, moving_type};
shared_formulas_.push_back(state);
}
else
{
for (long i=0; i<shared_formulas_.size() ;i++)
{
if (shared_formulas_[i].index = ind)
{
odf_formula = shared_formulas_[i].formula;
table_table_cell* cell = dynamic_cast<table_table_cell*>(cells_.back().elm.get());
if (cell == NULL)return;
// ref !!!
if (shared_formulas_[i].moving_type == 1)
{
tmp_value_ = shared_formulas_[i].base_column;
const std::wstring res = boost::regex_replace(
odf_formula,
boost::wregex(L"([a-zA-Z]{1,3}[0-9]{1,3})|(?:'.*?')|(?:\".*?\")"),
&ods_table_state::replace_cell_column,
boost::match_default | boost::format_all);
odf_formula = res;
}
if (shared_formulas_[i].moving_type == 2)
{
tmp_value_ = shared_formulas_[i].base_row;
const std::wstring res = boost::regex_replace(
odf_formula,
boost::wregex(L"([a-zA-Z]{1,3}[0-9]{1,3})|(?:'.*?')|(?:\".*?\")"),
&ods_table_state::replace_cell_row,
boost::match_default | boost::format_all);
odf_formula = res;
}
cell->table_table_cell_attlist_.table_formula_ = odf_formula;
}
}
}
}
void ods_table_state::add_child_element(office_element_ptr & child_element)
{
......
......@@ -2,14 +2,10 @@
#include <string>
#include <vector>
//
//#include "ods_row_spanned.h"
//#include "ods_merge_cells.h"
//#include "ods_table_metrics.h"
//#include "ods_comments_context.h"
#include "odf_drawing_context.h"
#include <boost/regex.hpp>
#include "odf_drawing_context.h"
#include "office_elements.h"
#include "office_elements_create.h"
......@@ -36,6 +32,82 @@ class table_table;
class style;
class color;
namespace utils {
static std::wstring getColAddress(size_t col)
{
static const size_t r = (L'Z' - L'A' + 1);
std::wstring res;
size_t r0 = col / r;
if (r0 > 0)
{
const std::wstring rest = getColAddress(col - r*r0);
const std::wstring res = getColAddress(r0-1) + rest;
return res;
}
else
return std::wstring(1, (wchar_t)(L'A' + col));
}
static size_t getColAddressInv(const std::wstring & a_)
{
std::wstring a = a_;
::boost::algorithm::to_upper(a);
static const size_t r = (L'Z' - L'A' + 1);
size_t mul = 1;
bool f = true;
size_t res = 0;
BOOST_REVERSE_FOREACH(const wchar_t c, a)
{
size_t v = c - L'A';
if (f)
f = false;
else
v += 1;
res += v * mul;
mul *= r;
}
return res;
}
static size_t getRowAdderssInv(const std::wstring & a_)
{
int sz = a_.length();
if (a_.length()>0)
{
return boost::lexical_cast<size_t>(a_)-1;
}
else
return 0;
}
static void splitCellAddress(const std::wstring & a_, std::wstring & col, std::wstring & row)
{
std::wstring a = a_;
std::reverse(a.begin(), a.end());
::boost::algorithm::replace_all(a, L"$", L"");
//::boost::algorithm::replace_all(a, L"'", L"");
::boost::algorithm::to_upper(a);
BOOST_FOREACH(wchar_t c, a)
{
if (c >= L'0' && c <= L'9')
row +=c;
else
col += c;
}
std::reverse(col.begin(), col.end());
std::reverse(row.begin(), row.end());
}
static void parsing_ref (const std::wstring & ref, int & col,int & row)
{
std::wstring strCol, strRow;
splitCellAddress(ref,strCol,strRow);
col = getColAddressInv(strCol)+1;
row = getRowAdderssInv(strRow)+1;
}
};
struct ods_element_state
{
office_element_ptr elm;
......@@ -74,6 +146,18 @@ struct ods_comment_state
office_element_ptr elm;
//style graphic
};
struct ods_shared_formula_state
{
int index;
std::wstring formula;
std::wstring ref;
int base_column;
int base_row;
int moving_type; //1 - col, 2 - row
};
class ods_table_state
{
public:
......@@ -109,9 +193,14 @@ public:
void set_cell_value(std::wstring & value);
void set_cell_text(odf_text_context *text_context, bool cash_value = false);
void set_cell_formula(std::wstring &formula);
void add_or_find_cell_shared_formula(std::wstring & formula, std::wstring ref, int ind);
static std::wstring replace_cell_row(boost::wsmatch const & what);
static std::wstring replace_cell_column(boost::wsmatch const & what);
void add_child_element(office_element_ptr & child_element);
///////////////////////////////
void add_hyperlink(std::wstring & ref,int col, int row, std::wstring & link);
void add_definded_expression(office_element_ptr & elm);
......@@ -156,8 +245,10 @@ private:
std::wstring row_default_cell_style_name_;
int current_table_column_;
int current_table_row_;
static int current_table_column_;
static int current_table_row_;
static int tmp_value_;
std::vector<ods_element_state> columns_;
std::vector<ods_element_state> rows_;
......@@ -169,6 +260,8 @@ private:
std::vector<ods_hyperlink_state> hyperlinks_;
std::vector<ods_comment_state> comments_;
std::vector<ods_shared_formula_state> shared_formulas_;
odf_drawing_context drawing_context_;
friend class ods_table_context;
......
......@@ -497,7 +497,39 @@ void XlsxConverter::convert(OOX::Spreadsheet::CFormula *oox_formula)
{
if (oox_formula == NULL)return;
ods_context->current_table().set_cell_formula(string2std_string(oox_formula->m_sText));
std::wstring formula = string2std_string(oox_formula->m_sText);
std::wstring ref;
int ind = -1;
if (oox_formula->m_oSi.IsInit()) ind = oox_formula->m_oSi->GetValue();
if (oox_formula->m_oRef.IsInit()) ref = string2std_string(oox_formula->m_oRef.get2());
if (oox_formula->m_oT.IsInit())
{
if (oox_formula->m_oT->GetValue() == SimpleTypes::Spreadsheet::cellformulatypeShared)
{
ods_context->current_table().add_or_find_cell_shared_formula(formula,ref, ind);
}
else if (oox_formula->m_oT->GetValue() == SimpleTypes::Spreadsheet::cellformulatypeArray)
{
}
else if (oox_formula->m_oT->GetValue() == SimpleTypes::Spreadsheet::cellformulatypeDataTable)
{
}
}
if (formula.length() > 0)ods_context->current_table().set_cell_formula(formula);
//nullable<SimpleTypes::COnOff<>> m_oAca;
//nullable<SimpleTypes::COnOff<>> m_oBx;
//nullable<SimpleTypes::COnOff<>> m_oCa;
//nullable<SimpleTypes::COnOff<>> m_oDel1;
//nullable<SimpleTypes::COnOff<>> m_oDel2;
//nullable<SimpleTypes::COnOff<>> m_oDt2D;
//nullable<SimpleTypes::COnOff<>> m_oDtr;
//nullable<CString> m_oR1;
//nullable<CString> m_oR2;
}
void XlsxConverter::convert(OOX::Spreadsheet::CCol *oox_column)
{
......
......@@ -2,6 +2,6 @@
//1
//2
//0
//48
#define INTVER 1,2,0,48
#define STRVER "1,2,0,48\0"
//49
#define INTVER 1,2,0,49
#define STRVER "1,2,0,49\0"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment