Commit 4c12ba9c authored by ElenaSubbotina's avatar ElenaSubbotina

OdfFormatReader - fix bugs...

parent eae048a8
......@@ -260,12 +260,22 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f)
{
impl_->conditionalFormattings_.back().rules.back().formula_type = L"expression";
val = f.substr(11, f.size() - 12);
if (0 == (pos = val.find(L"\""))) //Raport_7A.ods или выкинуть ограждающие кавычки с формулы?
{
impl_->conditionalFormattings_.back().rules.back().text = val;
val.clear();
}
impl_->conditionalFormattings_.back().rules.back().formula = converter.convert(val);
}
else if (0 <= (pos = f.find(L"is-between(")))
{
impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val);
}
else if (0 <= (pos = f.find(L"is-time(")))
{
impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val);
}
else
{
......@@ -273,46 +283,50 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f)
if (0 <= (pos = f.find(L"!empty")))
{
val = converter.convert_named_expr( f );
}
else if (0 <= (pos = f.find(L"empty")))
{
val = converter.convert_named_expr( f );
}
else if (0 <= (pos = f.find(L"bottom")))
{
val = converter.convert_named_expr( f );
}
else if (0 <= (pos = f.find(L"top")))
{
impl_->conditionalFormattings_.back().rules.back().formula_type = L"top10";
val = converter.convert_named_expr( f );
}
else if (0 <= (pos = f.find(L"!=")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"notEqual";
val = f.substr(2);
val = converter.convert_named_expr( f.substr(2) );
}
else if (0 <= (pos = f.find(L"<=")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"lessThanOrEqual";
val = f.substr(2);
val = converter.convert_named_expr( f.substr(2) );
}
else if (0 <= (pos = f.find(L">=")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"greaterThanOrEqual";
val = f.substr(2);
val = converter.convert_named_expr( f.substr(2) );
}
else if (0 <= (pos = f.find(L"=")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"equal";
val = f.substr(1);
val = converter.convert_named_expr( f.substr(1) );
}
else if (0 <= (pos = f.find(L"<")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"lessThan";
val = f.substr(1);
val = converter.convert_named_expr( f.substr(1) );
}
else if (0 <= (pos = f.find(L">")))
{
impl_->conditionalFormattings_.back().rules.back().operator_ = L"greaterThan";
val = f.substr(1);
val = converter.convert_named_expr( f.substr(1) );
}
else if (0 <= (pos = f.find(L"contains-text")))
{
......@@ -327,17 +341,20 @@ void xlsx_conditionalFormatting_context::set_formula(std::wstring f)
if (0 <= (pos = val.find(L",")))
{
impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr(val.substr(pos + 1));
impl_->conditionalFormattings_.back().rules.back().formula2 = converter.convert_named_expr( val.substr(pos + 1) );
val = val.substr(0, pos);
}
val = converter.convert_named_expr( val );
}
else
{
val = f;
val = converter.convert( f );
}
if (!val.empty())
impl_->conditionalFormattings_.back().rules.back().formula = val;
}
impl_->conditionalFormattings_.back().rules.back().formula = converter.convert_named_expr(val);
}
void xlsx_conditionalFormatting_context::set_dataBar(_CP_OPT(int) min, _CP_OPT(int) max)
{
......
......@@ -471,6 +471,9 @@ void xlsx_drawing_context::process_position_properties(drawing_object_descriptio
x = obj.anchor_x_ - cx;
y = obj.anchor_y_ - cy;
if (x < 0) x = 0;
if (y < 0) y = 0; // calcul dun MS.ods
to = pos_anchor;
from = table_metrics.calc(x, y);
......
......@@ -40,15 +40,15 @@ namespace oox
struct region
{
region(size_t sCell, double sPos, size_t c, double l) : start_cell(sCell),
region(int sCell, double sPos, int c, double l) : start_cell(sCell),
start_pos(sPos),
count(c),
length(l)
{}
size_t start_cell;
int start_cell;
double start_pos;
size_t count;
int count;
double length;
};
......@@ -59,17 +59,19 @@ public:
{}
public:
void add(size_t count, double length_pt)
void add(int count, double length_pt)
{
region_.push_back(region(next_cell_, next_pos_, count, length_pt));
next_cell_ += count;
next_pos_ += count * length_pt;
}
double search(size_t cell)
double search(int cell)
{
double length_pt =0;
BOOST_FOREACH(region const & r, region_)
for (int i = 0; i < region_.size(); i++)
{
region & r = region_[i];
if (cell <= r.start_cell + r.count)
{
length_pt += (cell-r.start_cell)*r.length;
......@@ -87,34 +89,57 @@ public:
{
offset =0;
}
length_pt+= offset * region_.back().length;
length_pt += offset * region_.back().length;
}
}
return length_pt;
}
std::pair<size_t, double> search(size_t offset, double pos)
std::pair<int, double> search(int offset, double pos)
{
double skip_length =0;
BOOST_FOREACH(region const & r, region_)
if (pos < 0)//cs102.ods
{
int c_skip = 0, i = 0;
for (i = 0; i < region_.size(); i++)
{
if (region_[i].count + c_skip > offset)
break;
c_skip += region_[i].count;
}
for (; i >= 0 && pos < 0; i--)
{
pos += region_[i].length * region_[i].count;
offset--;
}
if (offset < 0) offset = 0;
if (pos < 0) pos = 0;
}
for (int i = 0; i < region_.size(); i++)
{
region & r = region_[i];
if (r.start_cell + r.count <= offset)
{
skip_length = r.start_pos +r.count*r.length;
skip_length = r.start_pos + r.count*r.length;
continue;
}
if (pos+skip_length >= r.start_pos && pos+skip_length < (r.start_pos + r.count * r.length))
if (pos + skip_length >= r.start_pos && pos + skip_length < (r.start_pos + r.count * r.length))
{
skip_length += (offset-r.start_cell) * r.length;
const double diff = pos+skip_length - r.start_pos;
const size_t cell = diff / r.length ;
skip_length += (offset - r.start_cell) * r.length;
const double diff = pos + skip_length - r.start_pos;
int cell = diff / r.length ;
double offset_cell = diff - cell * r.length;
if (offset_cell < 0)
{
offset_cell =0;
}
return std::pair<size_t, double>(r.start_cell + cell , offset_cell);
return std::pair<int, double>(r.start_cell + cell, offset_cell);
}
}
......@@ -122,38 +147,47 @@ public:
{
if (region_.back().start_cell + region_.back().count < offset)
{
skip_length+= (offset-region_.back().start_cell-region_.back().count/*-1*/) * region_.back().length;
skip_length += (offset - region_.back().start_cell - region_.back().count /*- 1*/) * region_.back().length;
}
region const & last_r = region_[region_.size() - 1];
const size_t last_cell = last_r.start_cell + last_r.count;
const double last_pos = last_r.start_pos + last_r.count * last_r.length;
double diff = pos+skip_length-last_r.start_pos-(last_r.count * last_r.length);
const size_t cell = diff / last_r.length;
double offset_cell = diff - cell * last_r.length;
region const & last_r = region_[region_.size() - 1];
const int last_cell = last_r.start_cell + last_r.count;
const double last_pos = last_r.start_pos + last_r.count * last_r.length;
double diff = pos + skip_length - last_r.start_pos - (last_r.count * last_r.length);
if (diff < 0)
diff = 0;
const int cell = diff / last_r.length;
double offset_cell = diff - cell * last_r.length;
if (offset_cell < 0)
{
offset_cell =0;
offset_cell = 0;
}
return std::pair<size_t, double>(last_cell + cell , offset_cell);
return std::pair<int, double>(last_cell + cell , offset_cell);
}
else
return std::pair<size_t, double>(offset, pos);
return std::pair<int, double>(offset, pos);
}
std::pair<size_t, double> search(double pos)
std::pair<int, double> search(double pos)
{
BOOST_FOREACH(region const & r, region_)
for (int i = 0; i < region_.size(); i++)
{
region & r = region_[i];
if (pos >= r.start_pos && pos < (r.start_pos + r.count * r.length))
{
const double diff = pos - r.start_pos;
const size_t cell = diff / r.length;
double offset = diff - cell * r.length;
const double diff = pos - r.start_pos;
const int cell = diff / r.length;
double offset = diff - cell * r.length;
if (offset < 0)
{
offset =0;
}
return std::pair<size_t, double>(r.start_cell + cell, offset);
return std::pair<int, double>(r.start_cell + cell, offset);
}
}
......@@ -162,20 +196,21 @@ public:
region const & last_r = region_[region_.size() - 1];
const size_t last_cell = last_r.start_cell + last_r.count;
const double last_pos = last_r.start_pos + last_r.count * last_r.length;
const double diff = pos - last_pos;
const size_t cell = diff / last_r.length;
double offset = diff - cell * last_r.length;
const double diff = pos - last_pos;
const int cell = diff / last_r.length;
double offset = diff - cell * last_r.length;
if (offset < 0)
{
offset =0;
}
return std::pair<size_t, double>(last_cell + cell, offset);
return std::pair<int, double>(last_cell + cell, offset);
}
else
return std::pair<size_t, double>(0, pos);
return std::pair<int, double>(0, pos);
}
private:
size_t next_cell_;
int next_cell_;
double next_pos_;
std::vector<region> region_;
};
......@@ -185,48 +220,48 @@ class xlsx_table_metrics::Impl
public:
xlsx_table_position calc(double x_pt, double y_pt)
{
const std::pair<size_t, double> c = cols_.search(x_pt);
const std::pair<size_t, double> r = rows_.search(y_pt);
const std::pair<int, double> c = cols_.search (x_pt);
const std::pair<int, double> r = rows_.search (y_pt);
xlsx_table_position res = {c.first, c.second, r.first, r.second};
return res;
}
xlsx_table_position calc(size_t offset_col,size_t offset_row,double x_pt, double y_pt)
xlsx_table_position calc(int offset_col, int offset_row, double x_pt, double y_pt)
{
std::pair<size_t, double> c ;
std::pair<size_t, double> r ;
std::pair<int, double> c ;
std::pair<int, double> r ;
c = cols_.search(offset_col,x_pt);
c = cols_.search(offset_col, x_pt);
r = rows_.search(offset_row,y_pt);
r = rows_.search(offset_row, y_pt);
xlsx_table_position res = {c.first, c.second, r.first, r.second};
return res;
}
xlsx_table_position calc(size_t last_col,size_t last_row)
xlsx_table_position calc(int last_col,int last_row)
{
std::pair<size_t, double> c = cols_.search(last_col,0);
std::pair<size_t, double> r = rows_.search(last_row,0);
std::pair<int, double> c = cols_.search (last_col, 0);
std::pair<int, double> r = rows_.search (last_row, 0);
xlsx_table_position res = {c.first, c.second, r.first, r.second};
return res;
}
void update_pt(size_t offset_col,size_t offset_row,double &x_pt, double &y_pt)
void update_pt(int offset_col,int offset_row,double &x_pt, double &y_pt)
{
x_pt += cols_.search(offset_col);
y_pt += rows_.search(offset_row);
x_pt += cols_.search (offset_col);
y_pt += rows_.search (offset_row);
}
void add_cols(size_t count, double widht_pt)
void add_cols(int count, double widht_pt)
{
return cols_.add(count, widht_pt);
}
void add_rows(size_t count, double height_pt)
void add_rows(int count, double height_pt)
{
return rows_.add(count, height_pt);
}
......@@ -247,30 +282,30 @@ xlsx_table_metrics::~xlsx_table_metrics()
xlsx_table_position xlsx_table_metrics::calc(double x_pt, double y_pt)
{
return impl_->calc(x_pt, y_pt);
return impl_->calc (x_pt, y_pt);
}
xlsx_table_position xlsx_table_metrics::calc(size_t offset_col,size_t offset_row,double x_pt, double y_pt)
xlsx_table_position xlsx_table_metrics::calc(int offset_col,int offset_row,double x_pt, double y_pt)
{
return impl_->calc(offset_col,offset_row,x_pt, y_pt);
return impl_->calc(offset_col, offset_row, x_pt, y_pt);
}
xlsx_table_position xlsx_table_metrics::calc(size_t last_col,size_t last_row)
xlsx_table_position xlsx_table_metrics::calc(int last_col,int last_row)
{
return impl_->calc(last_col,last_row);
return impl_->calc (last_col, last_row);
}
void xlsx_table_metrics::update_pt(size_t offset_col,size_t offset_row,double &x_pt, double &y_pt)
void xlsx_table_metrics::update_pt(int offset_col,int offset_row,double &x_pt, double &y_pt)
{
return impl_->update_pt(offset_col,offset_row,x_pt, y_pt);
return impl_->update_pt (offset_col, offset_row, x_pt, y_pt);
}
void xlsx_table_metrics::add_cols(size_t count, double width_pt)
void xlsx_table_metrics::add_cols(int count, double width_pt)
{
return impl_->add_cols(count, width_pt);
return impl_->add_cols (count, width_pt);
}
void xlsx_table_metrics::add_rows(size_t count, double height_pt)
void xlsx_table_metrics::add_rows(int count, double height_pt)
{
return impl_->add_rows(count, height_pt);
return impl_->add_rows (count, height_pt);
}
}
......
......@@ -44,18 +44,18 @@ namespace oox
class xlsx_table_metrics
{
public:
xlsx_table_metrics();
~xlsx_table_metrics();
xlsx_table_metrics ();
~xlsx_table_metrics ();
public:
xlsx_table_position calc(double x_pt, double y_pt);
xlsx_table_position calc(size_t offset_col,size_t offset_row,double x_pt, double y_pt);
xlsx_table_position calc(size_t last_col,size_t last_row);
xlsx_table_position calc (double x_pt, double y_pt);
xlsx_table_position calc (int offset_col, int offset_row, double x_pt, double y_pt);
xlsx_table_position calc (int last_col, int last_row);
void update_pt(size_t offset_col,size_t offset_row,double &x_pt, double &y_pt);
void update_pt (int offset_col, int offset_row, double &x_pt, double &y_pt);
void add_cols(size_t count, double widht_pt);
void add_rows(size_t count, double height_pt);
void add_cols (int count, double widht_pt);
void add_rows (int count, double height_pt);
private:
class Impl;
......
......@@ -191,8 +191,8 @@ std::wstring xlsx_table_state::default_row_cell_style() const
std::wstring xlsx_table_state::default_column_cell_style() const
{
if (current_table_column_ < column_default_cell_style_name_.size())
return column_default_cell_style_name_.at(current_table_column_);
if (current_table_column_ + 1 < column_default_cell_style_name_.size())
return column_default_cell_style_name_.at(current_table_column_ + 1);
else
{
//непонятная хрень!! - неправильно сформирован ods???
......
......@@ -179,7 +179,7 @@ void xlsx_conversion_context::end_document()
{
CP_XML_NODE(L"sheet")
{
CP_XML_ATTR(L"name", sheet->name());
CP_XML_ATTR(L"name", sheet->name()); // office 2010 ! ограничение на длину имени !!!
CP_XML_ATTR(L"sheetId", count);
CP_XML_ATTR(L"state", L"visible");
CP_XML_ATTR(L"r:id", id);
......
......@@ -80,7 +80,7 @@ void table_table_row::xlsx_convert(oox::xlsx_conversion_context & Context)
///обработка чтилей для роу -
size_t Default_Cell_style_in_row_ = 0;
const std::wstring rowStyleName = table_table_row_attlist_.table_style_name_.get_value_or(L"");
const std::wstring rowStyleName = table_table_row_attlist_.table_style_name_.get_value_or(L"");
const std::wstring defaultCellStyleName = table_table_row_attlist_.table_default_cell_style_name_.get_value_or( L"");
style_instance * instStyle_CellDefault =
......@@ -604,45 +604,49 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
{
std::wostream & strm = Context.current_sheet().sheetData();
const std::wstring formula = table_table_cell_attlist_.table_formula_.get_value_or(L"");
const std::wstring styleName = table_table_cell_attlist_.table_style_name_.get_value_or(L"");
const common_value_and_type_attlist & attr = table_table_cell_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 number_val = L"";
std::wstring formula = table_table_cell_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 = L"";
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 = table_table_cell_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();
// вычислить стиль для ячейки
odf_read_context & odfContext = Context.root()->odf_context();
if (table_table_cell_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(Context.get_table_context().default_column_cell_style(), style_family::TableCell,false);
defaultRowCellStyle = odfContext.styleContainer().style_by_name(Context.get_table_context().default_row_cell_style(), style_family::TableCell,false);
cellStyle = odfContext.styleContainer().style_by_name(styleName, style_family::TableCell, false);
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,
Context.get_table_context().default_column_cell_style(),
Context.get_table_context().default_row_cell_style(),
styleName);
std::wstring data_style = CalcCellDataStyle(Context, columnStyleName, rowStyleName, cellStyleName);
// стили не наследуются
std::vector<const style_instance *> instances;
......@@ -733,8 +737,8 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
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());
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)
{
......@@ -751,10 +755,8 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
cellFormat.set_cell_type(t_val);
cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type));
is_style_visible = (styleName.length() > 0 || defaultColumnCellStyle) ? true : false;
xfId_last_set= Context.get_style_manager().xfId(&textFormatProperties, &parFormatProperties, &cellFormatProperties, &cellFormat, num_format, false, is_style_visible);
is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false;
if ( table_table_cell_content_.elements_.size() > 0 ||
!formula.empty() ||
( t_val == oox::XlsxCellType::n && !number_val.empty()) ||
......@@ -762,12 +764,26 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
(( t_val == oox::XlsxCellType::str || oox::XlsxCellType::inlineStr) && str_val)) is_data_visible = true;
if (table_table_cell_attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false;
int cell_repeated_max = Context.current_table_column() + table_table_cell_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 < table_table_cell_attlist_.table_number_columns_repeated_; ++r)
{
Context.start_table_cell ( formula, table_table_cell_attlist_extra_.table_number_columns_spanned_ - 1 ,
table_table_cell_attlist_extra_.table_number_rows_spanned_ - 1 );
Context.set_current_cell_style_id(xfId_last_set);
if (is_style_visible)
Context.set_current_cell_style_id(xfId_last_set);
const int sharedStringId = table_table_cell_content_.xlsx_convert(Context, &textFormatProperties);
......
......@@ -7,7 +7,7 @@
QT -= core
QT -= gui
VERSION = 2.0.2.410
VERSION = 2.0.2.411
DEFINES += INTVER=$$VERSION
TARGET = x2t
......
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