/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; -*- */ /* AbiWord * Copyright (C) 2003 Francis James Franklin * Copyright (C) 2003 AbiSource, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include #include "ut_exception.h" #include "pd_AbiWord_2.h" PD_AbiWord_2::Element::Element (ElementType et) : m_et(et), m_element(0), m_count(0), m_max(0) { // } PD_AbiWord_2::Element::~Element () { for (UT_uint32 i = 0; i < m_count; i++) delete m_element[i]; if (m_element) free (m_element); } bool PD_AbiWord_2::Element::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; bool okay = true; for (UT_uint32 i = 0; i < m_count; i++) if (!m_element[i]->write (writer, cache, strip)) { okay = false; break; } return okay; } /* responsibility for element deletion passes here */ bool PD_AbiWord_2::Element::ins (UT_uint32 i, Element * element) { if (i > m_count) { if (element) delete element; return false; } if (m_element == 0) { m_element = (Element **) malloc (16 * sizeof (Element *)); if (m_element == 0) { if (element) delete element; return false; } m_max = 16; } if (m_count == m_max) { Element ** more = (Element **) realloc (m_element, (m_max + 16) * sizeof (Element *)); if (more == 0) { if (element) delete element; return false; } m_element = more; m_max += 16; } for (UT_uint j = m_count; j > i; j--) m_element[j] = m_element[j-1]; ++m_count; m_element[i] = element; return true; } /* returns false if element is not a child */ bool PD_AbiWord_2::Element::del (UT_uint32 i, Element * element, bool detach) { if (i >= m_count) return false; if (m_element[i] != element) return false; --m_count; for (j = i; j < m_count; j++) m_element[j] = m_element[j+1]; if (!detach) delete element; return true; } /* returns false if either element is not a child */ bool PD_AbiWord_2::Element::swap (UT_uint32 i, UT_uint32 j) { if ((i >= m_count) || (j >= m_count)) return false; if (i == j) return true; // huh Element * tmp = m_element[i]; m_element[i] = m_element[j]; m_element[j] = tmp; return true; } /* returns false if element is not a child */ bool PD_AbiWord_2::Element::index (UT_uint32 & i, Element * element) { bool match = false; for (UT_uint32 j = 0; j < m_count; j++) if (m_element[j] == element) { i = j; match = true; break; } return match; } PD_AbiWord_2::Stack::Stack () : m_element(0), m_count(0), m_max(0) { // } PD_AbiWord_2::Stack::~Stack () { for (UT_uint32 i = 0; i < m_count; i++) delete m_element[i]; if (m_element) free (m_element); } bool PD_AbiWord_2::Stack::push (Element * element) { if (m_element == 0) { m_element = (Element **) malloc (16 * sizeof (Element *)); if (m_element == 0) return false; m_max = 16; } if (m_count == m_max) { Element ** more = (Element **) realloc (m_element, (m_max + 16) * sizeof (Element *)); if (more == 0) return false; m_element = more; m_max += 16; } m_element[m_count++] = element; return true; } void PD_AbiWord_2::Stack::pop () { if (m_count) --m_count; } /* if any elements of type et are in the stack, pop until one is reached; * otherwise don't pop at all */ bool PD_AbiWord_2::Stack::popTo (ElementType et) { bool bPopped = false; UT_uint32 count = m_count; while (count) { Element * el = m_element[--count]; if (el->type () == et) { m_count = count + 1; bPopped = true; break; } } return bPopped; } /* if any elements of type et1 or et2 are in the stack, pop until one or other is reached; * otherwise don't pop at all */ bool PD_AbiWord_2::Stack::popTo (ElementType et1, ElementType et2) { bool bPopped = false; UT_uint32 count = m_count; while (count) { Element * el = m_element[--count]; if ((el->type () == et1) || (el->type () == et2)) { m_count = count + 1; bPopped = true; break; } } return bPopped; } void PD_AbiWord_2::Stack::clear () { m_count = 0; } PD_AbiWord_2::El_M::El_M (const char * key, const char * value) : Element(et_m), m_key(key), m_value(value) { // } bool PD_AbiWord_2::El_M::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" in key and value cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_MetaData::El_MetaData () : Element(et_metadata) { // } bool PD_AbiWord_2::El_MetaData::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count ()== 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_M * PD_AbiWord_2::El_MetaData::insert (const char * key, const char * value) { El_M * M = 0; UT_TRY { M = new El_M(key,value); } UT_CATCH(...) { M = 0; } if (M) { if (!Element::ins (count (), M)) M = 0; } return M; } PD_AbiWord_2::El_M * PD_AbiWord_2::El_MetaData::lookup_key (const char * key) { // TODO } PD_AbiWord_2::El_R::El_R (const char * old_id, const char * new_id, const char * reviewer) : Element(et_r), m_old_id(old_id), m_new_id(new_id), m_reviewer(reviewer) { // } bool PD_AbiWord_2::El_R::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in reviewer cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Revisions::El_Revisions () : Element(et_revisions) { // } bool PD_AbiWord_2::El_Revisions::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count () == 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_R * PD_AbiWord_2::El_Revisions::insert (const char * old_id, const char * new_id, const char * reviewer) { El_R * R = 0; UT_TRY { R = new El_R(old_id,new_id,reviewer); } UT_CATCH(...) { R = 0; } if (R) { if (!Element::ins (count (), R)) R = 0; } return R; } PD_AbiWord_2::El_R * PD_AbiWord_2::El_Revisions::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::El_R * PD_AbiWord_2::El_Revisions::lookup_new_id (const char * new_id) { // TODO } PD_AbiWord_2::El_S::El_S (const char * name, const char * type, const char * style, const char * based_on, const char * followed_by) : Element(et_s), m_name(name), m_type(type), m_style(style), m_based_on(based_on), m_followed_by(followed_by) { // } bool PD_AbiWord_2::El_S::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Styles::El_Styles () : Element(et_styles) { // } bool PD_AbiWord_2::El_Styles::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count () == 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_S * PD_AbiWord_2::El_Styles::insert (const char * name, const char * type, const char * style, const char * based_on, const char * followed_by) { El_S * S = 0; UT_TRY { S = new El_S(name,type,style,based_on,followed_by); } UT_CATCH(...) { S = 0; } if (S) { if (!Element::ins (count (), S)) S = 0; } return S; } PD_AbiWord_2::El_S * PD_AbiWord_2::El_Styles::lookup_name (const char * name) { // TODO } PD_AbiWord_2::El_IW::El_IW (const char * word) : Element(et_iw), m_word(word) { // } bool PD_AbiWord_2::El_IW::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" in word cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_IgnoredWords::El_IgnoredWords () : Element(et_ignoredwords) { // } bool PD_AbiWord_2::El_IgnoredWords::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count () == 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_IW * PD_AbiWord_2::El_IgnoredWords::insert (const char * word) { El_IW * IW = 0; UT_TRY { IW = new El_IW(word); } UT_CATCH(...) { IW = 0; } if (IW) { if (!Element::ins (count (), IW)) IW = 0; } return IW; } PD_AbiWord_2::El_IW * PD_AbiWord_2::El_IgnoredWords::lookup_word (const char * word) { // TODO } PD_AbiWord_2::El_L::El_L (const char * old_id, const char * new_id, const char * old_parent_id, const char * type, const char * start_value, const char * list_decimal, const char * list_delim) : Element(et_l), m_old_id(old_id), m_new_id(new_id), m_old_parent_id(old_parent_id), m_new_parent_id("none"), // warning: this needs to be determined m_type(type), m_start_value(start_value), m_list_decimal(list_decimal), m_list_delim(list_delim) { // } bool PD_AbiWord_2::El_L::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in list_decimal & list_delim ?? cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Lists::El_Lists () : Element(et_lists) { // } bool PD_AbiWord_2::El_Lists::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count () == 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_L * PD_AbiWord_2::El_Lists::insert (const char * old_id, const char * new_id, const char * old_parent_id, const char * type, const char * start_value, const char * list_decimal, const char * list_delim) { El_L * L = 0; UT_TRY { L = new El_L(old_id,new_id,old_parent_id,type,start_value,list_decimal,list_delim); } UT_CATCH(...) { L = 0; } if (L) { if (!Element::ins (count (), L)) L = 0; } return L; } PD_AbiWord_2::El_L * PD_AbiWord_2::El_Lists::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::El_L * PD_AbiWord_2::El_Lists::lookup_new_id (const char * new_id) { // TODO } /* determine new_parent_id for each child */ bool PD_AbiWord_2::El_Lists::sync () { // TODO } PD_AbiWord_2::El_PageSize::El_PageSize (const char * page_type, const char * page_scale, const char * width, const char * height, const char * orientation, const char * units) : Element(et_pagesize), m_page_type(page_type), m_page_scale(page_scale), m_width(width), m_height(height), m_orientation(orientation), m_units(units) { // } bool PD_AbiWord_2::El_PageSize::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" ... ?? cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Br::El_Br () : Element(et_br) { // } bool PD_AbiWord_2::El_Br::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; cache = "
"; return writer->A2_write (cache); } PD_AbiWord_2::El_CBr::El_CBr () : Element(et_cbr) { // } bool PD_AbiWord_2::El_CBr::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_PBr::El_PBr () : Element(et_pbr) { // } bool PD_AbiWord_2::El_PBr::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_BookMark::El_BookMark (const char * old_id, const char * new_id) : Element(et_bookmark), m_old_id(old_id), m_new_id(new_id) { // } bool PD_AbiWord_2::El_BookMark::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_Image::El_Image (const char * old_href, const char * new_href, const char * style) : Element(et_image), m_old_href(old_href), m_new_href("none"), // warning: this needs to be determined m_style(style) { // } bool PD_AbiWord_2::El_Image::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_Field::El_Field (const char * style_class, const char * style, const char * type) : Element(et_field), m_style_class(style_class), m_style(style), m_type(type) { // } bool PD_AbiWord_2::El_Field::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_CDATA::El_CDATA (const UT_UTF8String & cdata) : Element(et_CDATA), m_cdata(cdata) { // } bool PD_AbiWord_2::El_CDATA::write (Writer * writer, UT_UTF8String & /* cache */, bool /* strip */) { if (!writer) return false; return writer->A2_write (m_cdata); } PD_AbiWord_2::El_Span::El_Span (const char * style_class, const char * style) : Element(et_span), m_style_class(style_class), m_style(style) { // } bool PD_AbiWord_2::El_Span::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count () == 0) return true; // TODO: check for <>&" in style ?? cache = ""; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_NoteAnchor::El_NoteAnchor (const char * style_class, const char * style) : Element(et_noteanchor), m_style_class(style_class), m_style(style) { // } bool PD_AbiWord_2::El_NoteAnchor::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = ""; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_NoteLink::El_NoteLink (const char * old_href, const char * style_class, const char * style, const char * type) : Element(et_notelink), m_old_href(old_href), m_new_href("none"), // warning: this needs to be determined m_style_class(style_class), m_style(style), m_type(type) { // } bool PD_AbiWord_2::El_NoteLink::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = ""; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_A::El_A (const char * old_href) : Element(et_a), m_old_href(old_href), m_new_href("none") // warning: this needs to be determined { // } bool PD_AbiWord_2::El_A::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? // TODO: should we be encoding URLs here? cache = ""; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = ""; return writer->A2_write (cache); } PD_AbiWord_2::El_P::El_P (const char * style_class, const char * style, const char * old_list_id, const char * level) : Element(et_p), m_style_class(style_class), m_style(style), m_old_list_id(old_list_id), m_new_list_id("none"), // warning: this needs to be determined m_level(level) { // } bool PD_AbiWord_2::El_P::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "

"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "

\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Cell * PD_AbiWord_2::El_Cell::cell (const char * style, UT_uint32 rowspan, UT_uint32 colspan) { if (rowspan == 0) return 0; if (colspan == 0) return 0; El_Cell * Cell = 0; UT_TRY { Cell = new El_Cell(style,rowspan,colspan); } UT_CATCH(...) { Cell = 0; } return Cell; } PD_AbiWord_2::El_Cell::El_Cell (const char * style, UT_uint32 rowspan, UT_uint32 colspan) : Element(et_cell), m_style(style), m_rowspan(""), m_colspan("") { UT_UTF8String_sprintf (m_rowspan, "%lu", static_cast(rowspan)); UT_UTF8String_sprintf (m_colspan, "%lu", static_cast(colspan)); } bool PD_AbiWord_2::El_Cell::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_VCell::El_VCell () : Element(et_vcell), m_virtual(false) { // } bool PD_AbiWord_2::El_VCell::write (Writer * writer, UT_UTF8String & /* cache */, bool /* strip */) { if (!writer) return false; return true; } PD_AbiWord_2::El_Col::El_Col (const char * style) : Element(et_col), m_style(style) { // } bool PD_AbiWord_2::El_Col::write (Writer * writer, UT_UTF8String & cache, bool /* strip */) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Row * PD_AbiWord_2::El_Row::row (const char * style, UT_uint32 col_count) { if (col_count == 0) return 0; El_Row * Row = 0; UT_TRY { Row = new Row(style); } UT_CATCH(...) { Row = 0; } if (Row == 0) return 0; bool bAllVCells = true; for (UT_uint32 i = 0; i < col_count; i++) { El_VCell * VCell = 0; UT_TRY { VCell = new VCell; } UT_CATCH(...) { VCell = 0; } if (VCell == 0) { bAllVCells = false; break; } if (!Row->ins (Row->count (), VCell)) { bAllVCells = false; break; } } if (!bAllVCells) { delete Row; Row = 0; } return Row; } PD_AbiWord_2::El_Row::El_Row (const char * style) : Element(et_row), m_style(style) { // } bool PD_AbiWord_2::El_Row::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } bool PD_AbiWord_2::El_Row::set (UT_uint32 i, El_Cell * Cell) { if (Cell == 0) return false; UT_uint32 j = count (); if (i >= j) return false; if (!ins (j, Cell)) return false; Element * el = (*this)[i]; swap (i, j); return del (j, el); } PD_AbiWord_2::El_Table * PD_AbiWord_2::El_Table::table (const char * new_id, const char * style, UT_uint32 row_count, UT_uint32 col_count) { if (row_count == 0) return 0; if (col_count == 0) return 0; El_Table * Table = 0; UT_TRY { Table = new Table(new_id,style,row_count,col_count); } UT_CATCH(...) { Table = 0; } if (Table == 0) return 0; for (UT_uint32 i = 0; i < row_count; i++) if (!Table->add_row ("")) { delete Table; Table = 0; break; } return Table; } PD_AbiWord_2::El_Table::El_Table (const char * new_id, const char * style, UT_uint32 row_count, UT_uint32 col_count) : Element(et_table), m_new_id(new_id), m_style(style), m_rows(""), m_cols(""), m_row_count(row_count), m_col_count(col_count), m_auto(false), m_auto_row(0), m_auto_col(0) { UT_UTF8String_sprintf (m_rows, "%lu", static_cast(m_row_count)); UT_UTF8String_sprintf (m_cols, "%lu", static_cast(m_col_count)); } bool PD_AbiWord_2::El_Table::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "
\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Row * PD_AbiWord_2::El_Table::add_row (const char * style) { El_Row * Row = El_Row::row (style, m_col_count); if (Row == 0) return 0; if (!ins (count (), Row)) return 0; UT_UTF8String_sprintf (m_rows, "%lu", static_cast(++m_row_count)); return Row; } bool PD_AbiWord_2::El_Table::auto_end () { if (!m_auto) return false; // huh? m_auto = false; bool okay = true; for (UT_uint32 j = 0; j < m_row_count; j++) { El_Row * Row = row (j); for (UT_uint32 i = 0; i < m_col_count; i++) { Element * el = (*Row)[i]; if (el->type == et_vcell) { El_VCell * VCell = static_cast(el); if (VCell->m_virtual == false) { El_Cell * Cell = El_Cell::cell ("", 1, 1); if (Cell == 0) okay = false; else if (!Row->set (i, Cell)) okay = false; } } } } return okay; } PD_AbiWord_2::El_Row * PD_AbiWord_2::El_Table::auto_row (const char * style) { if (!m_auto) { m_auto = true; m_auto_row = 0; } else { if (m_auto_row == m_row_count) return 0; ++m_auto_row; } if (m_auto_row == m_row_count) { m_auto_col = 0; return add_row (style); } El_Row * Row = row (m_auto_row); Row->m_style = style; /* skip past cells which are hidden [Q: what happens if all cells are hidden?] */ m_auto_col = m_col_count; for (UT_uint32 i = 0; i < m_col_count; i++) { Element * el = (*Row)[i]; if (el->type () == et_vcell) { El_VCell * VCell = static_cast(el); if (VCell->m_virtual == false) { m_auto_col = i; break; } } } return Row; } PD_AbiWord_2::El_Cell * PD_AbiWord_2::El_Table::auto_cell (const char * style, UT_uint32 rowspan, UT_uint32 colspan) { if ((rowspan == 0) || (colspan == 0)) return 0; if (!m_auto) return 0; if (m_auto_col + colspan > m_col_count) return 0; // can't increase number of columns while (m_auto_row + rowspan > m_row_count) if (!add_row ("")) break; if (m_auto_row + rowspan > m_row_count) return 0; // table isn't large enough UT_uint32 i; UT_uint32 j; bool bCellFits = true; for (j = 0; j < rowspan; j++) { El_Row * Row = row (m_auto_row + j); for (i = 0; i < colspan; i++) { Element * el = (*Row)[m_auto_col+i]; if (el->type == et_vcell) { El_VCell * VCell = static_cast(el); if (VCell->m_virtual == false) continue; } bCellFits = false; break; } if (!bCellFits) break; } if (!bCellFits) return 0; /* mark virtual cells as being proper virtual, i.e., occluded, cells */ for (j = 0; j < rowspan; j++) { El_Row * Row = row (m_auto_row + j); for (i = 0; i < colspan; i++) { El_VCell * VCell = static_cast((*Row)[m_auto_col+i]); VCell->m_virtual = true; } } /* finally, exchange a real cell for the virtual cell */ El_Cell * Cell = El_Cell::cell (style, rowspan, colspan); if (Cell == 0) return 0; El_Row * Row = row (m_auto_row); bool okay = Row->set (m_auto_col, Cell); if (okay) { /* skip past cells which are hidden */ j = m_auto_col + colspan; m_auto_col = m_col_count; for (i = j; i < m_col_count; i++) { Element * el = (*Row)[i]; if (el->type () == et_vcell) { El_VCell * VCell = static_cast(el); if (VCell->m_virtual == false) { m_auto_col = i; break; } } } } return okay ? Cell : 0; } PD_AbiWord_2::El_Section::El_Section (const char * old_id, const char * new_id, const char * type, const char * style, const char * old_header_id, const char * old_footer_id, const char * columns, const char * column_gap) : Element(et_section), m_old_id(old_id), m_new_id(new_id), m_type(type), m_style(style), m_old_header_id(old_header_id), m_new_header_id("none"), // warning: this needs to be determined m_old_footer_id(old_footer_id), m_new_footer_id("none"), // warning: this needs to be determined m_columns(columns), m_column_gap(column_gap) { // } bool PD_AbiWord_2::El_Section::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "
\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "
\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_EndNote::El_EndNote (const char * old_id, const char * new_id) : Element(et_endnote), m_old_id(old_id), m_new_id(new_id), m_note_anchor("","") { // } bool PD_AbiWord_2::El_EndNote::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = "\n"; if (!writer->A2_write (cache)) return false; if (!m_note_anchor.write (writer, cache, strip)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_EndNotes::El_EndNotes () : Element(et_endnotes) { // } bool PD_AbiWord_2::El_EndNotes::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count ()== 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_EndNote * PD_AbiWord_2::El_EndNotes::insert (const char * old_id, const char * new_id) { El_EndNote * EndNote = 0; UT_TRY { EndNote = new El_EndNote(old_id,new_id); } UT_CATCH(...) { EndNote = 0; } if (EndNote) { if (!Element::ins (count (), EndNote)) EndNote = 0; } return EndNote; } PD_AbiWord_2::El_EndNote * PD_AbiWord_2::El_EndNotes::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::El_EndNote * PD_AbiWord_2::El_EndNotes::lookup_new_id (const char * new_id) { // TODO } PD_AbiWord_2::El_FootNote::El_FootNote (const char * old_id, const char * new_id) : Element(et_footnote), m_old_id(old_id), m_new_id(new_id), m_note_anchor("","") { // } bool PD_AbiWord_2::El_FootNote::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = "\n"; if (!writer->A2_write (cache)) return false; if (!m_note_anchor.write (writer, cache, strip)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_FootNotes::El_FootNotes () : Element(et_footnotes) { // } bool PD_AbiWord_2::El_FootNotes::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count ()== 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_FootNote * PD_AbiWord_2::El_FootNotes::insert (const char * old_id, const char * new_id) { El_FootNote * FootNote = 0; UT_TRY { FootNote = new El_FootNote(old_id,new_id); } UT_CATCH(...) { FootNote = 0; } if (FootNote) { if (!Element::ins (count (), FootNote)) FootNote = 0; } return FootNote; } PD_AbiWord_2::El_FootNote * PD_AbiWord_2::El_FootNotes::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::El_FootNote * PD_AbiWord_2::El_FootNotes::lookup_new_id (const char * new_id) { // TODO } PD_AbiWord_2::El_D::El_D (const char * old_id, const char * new_id, const char * type) : Element(et_d), m_old_id(old_id), m_new_id(new_id), m_type(type), m_data(0) { // } bool PD_AbiWord_2::El_D::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; // TODO: check for <>&" in ... ?? cache = "\n"; if (!writer->A2_write (cache)) return false; // TODO: m_data cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_Data::El_Data () : Element(et_data) { // } bool PD_AbiWord_2::El_Data::write (Writer * writer, UT_UTF8String & cache, bool strip) { if (!writer) return false; if (count ()== 0) return true; cache = "\n"; if (!writer->A2_write (cache)) return false; if (!Element::write (writer, cache, strip)) return false; cache = "\n"; return writer->A2_write (cache); } PD_AbiWord_2::El_D * PD_AbiWord_2::El_Data::insert (const char * old_id, const char * new_id, const char * type) { El_D * D = 0; UT_TRY { D = new El_D(old_id,new_id,type); } UT_CATCH(...) { D = 0; } if (D) { if (!Element::ins (count (), D)) D = 0; } return D; } PD_AbiWord_2::El_D * PD_AbiWord_2::El_Data::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::El_D * PD_AbiWord_2::El_Data::lookup_new_id (const char * new_id) { // TODO } PD_AbiWord_2::El_AbiWord::El_AbiWord (const char * fileformat, const char * template, const char * styles, const char * version, const char * style) : Element(et_abiword), m_fileformat(fileformat), m_template(template), m_styles(styles), m_version(version), m_style(style) { // } /* These are optional sections, children of El_AbiWord, occuring in a specific order. * If necessary, these methods create the section and insert it into the correct place. */ PD_AbiWord_2::El_MetaData * PD_AbiWord_2::El_AbiWord::getMetaData () { if (count ()) { Element * el = (*this)[0]; if (el->type () == et_metadata) { return static_cast(el); } } El_MetaData * MetaData = 0; UT_TRY { MetaData = new El_MetaData; } UT_CATCH(...) { MetaData = 0; } if (MetaData) { if (!Element::ins (0, MetaData)) MetaData = 0; // erk! } return MetaData; } PD_AbiWord_2::El_Revisions * PD_AbiWord_2::El_AbiWord::getRevisions () { UT_uint32 index = count (); UT_uint32 children = count (); El_Revisions * Revisions = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: break; case et_revisions: Revisions = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (Revisions) return Revisions; El_Revisions * Revisions = 0; UT_TRY { Revisions = new El_Revisions; } UT_CATCH(...) { Revisions = 0; } if (Revisions) { if (!Element::ins (index, Revisions)) Revisions = 0; // erk! } return Revisions; } PD_AbiWord_2::El_Styles * PD_AbiWord_2::El_AbiWord::getStyles () { UT_uint32 index = count (); UT_uint32 children = count (); El_Styles * Styles = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: break; case et_styles: Styles = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (Styles) return Styles; El_Styles * Styles = 0; UT_TRY { Styles = new El_Styles; } UT_CATCH(...) { Styles = 0; } if (Styles) { if (!Element::ins (index, Styles)) Styles = 0; // erk! } return Styles; } PD_AbiWord_2::El_IgnoredWords * PD_AbiWord_2::El_AbiWord::getIgnoredWords () { UT_uint32 index = count (); UT_uint32 children = count (); El_IgnoredWords * IgnoredWords = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: break; case et_ignoredwords: IgnoredWords = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (IgnoredWords) return IgnoredWords; El_IgnoredWords * IgnoredWords = 0; UT_TRY { IgnoredWords = new El_IgnoredWords; } UT_CATCH(...) { IgnoredWords = 0; } if (IgnoredWords) { if (!Element::ins (index, IgnoredWords)) IgnoredWords = 0; // erk! } return IgnoredWords; } PD_AbiWord_2::El_Lists * PD_AbiWord_2::El_AbiWord::getLists () { UT_uint32 index = count (); UT_uint32 children = count (); El_Lists * Lists = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: break; case et_lists: Lists = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (Lists) return Lists; El_Lists * Lists = 0; UT_TRY { Lists = new El_Lists; } UT_CATCH(...) { Lists = 0; } if (Lists) { if (!Element::ins (index, Lists)) Lists = 0; // erk! } return Lists; } PD_AbiWord_2::El_FootNotes * PD_AbiWord_2::El_AbiWord::getFootNotes () { UT_uint32 index = count (); UT_uint32 children = count (); El_FootNotes * FootNotes = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: case et_pagesize: case et_section: break; case et_footnotes: FootNotes = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (FootNotes) return FootNotes; El_FootNotes * FootNotes = 0; UT_TRY { FootNotes = new El_FootNotes; } UT_CATCH(...) { FootNotes = 0; } if (FootNotes) { if (!Element::ins (index, FootNotes)) FootNotes = 0; // erk! } return FootNotes; } PD_AbiWord_2::El_EndNotes * PD_AbiWord_2::El_AbiWord::getEndNotes () { UT_uint32 index = count (); UT_uint32 children = count (); El_EndNotes * EndNotes = 0; bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: case et_pagesize: case et_section: case et_footnotes: break; case et_endnotes: EndNotes = static_cast(el); have_index = true; break; default: index = i; have_index = true; break; } if (have_index) break; } if (EndNotes) return EndNotes; El_EndNotes * EndNotes = 0; UT_TRY { EndNotes = new El_EndNotes; } UT_CATCH(...) { EndNotes = 0; } if (EndNotes) { if (!Element::ins (index, EndNotes)) EndNotes = 0; // erk! } return EndNotes; } PD_AbiWord_2::El_Data * PD_AbiWord_2::El_AbiWord::getData () { if (count ()) { Element * el = (*this)[count()-1]; if (el->type () == et_metadata) { return static_cast(el); } } El_Data * Data = 0; UT_TRY { Data = new El_Data; } UT_CATCH(...) { Data = 0; } if (Data) { if (!Element::ins (count (), Data)) Data = 0; // erk! } return Data; } /* responsibility for element deletion passes here */ bool PD_AbiWord_2::El_AbiWord::append (EL_PageSize * PageSize) { if (PageSize == 0) return false; UT_uint32 index = count (); UT_uint32 children = count (); bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: case et_pagesize: break; default: index = i; have_index = true; break; } if (have_index) break; } return Element::ins (index, PageSize); } /* returns false if either element is not a child, or if child element-types differ */ bool PD_AbiWord_2::El_AbiWord::swap (UT_uint32 i, UT_uint32 j) { if ((i < count ()) && (j < count ())) if ((*this)[i]->type () == (*this)[j]->type ()) return Element::swap (i, j); return false; } bool PD_AbiWord_2::El_AbiWord::append (EL_Section * Section) { if (Section == 0) return false; UT_uint32 index = count (); UT_uint32 children = count (); bool have_index = false; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: case et_pagesize: case et_section: break; default: index = i; have_index = true; break; } if (have_index) break; } return Element::ins (index, Section); } /* responsibility for element deletion passes here */ bool PD_AbiWord_2::El_AbiWord::ins (UT_uint32 index, EL_PageSize * PageSize) { if (PageSize == 0) return false; if (i > count ()) { delete PageSize; return false; } UT_uint32 minindex = 0; UT_uint32 maxindex = count (); UT_uint32 children = count (); for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: minindex = i + 1; break; case et_pagesize: break; default: if (maxindex > i) maxindex = i; break; } } if ((index < min_index) || (index > max_index)) { delete PageSize; return false; } return Element::ins (index, PageSize); } bool PD_AbiWord_2::El_AbiWord::ins (UT_uint32 i, EL_Section * Section) { if (Section == 0) return false; if (i > count ()) { delete Section; return false; } UT_uint32 minindex = 0; UT_uint32 maxindex = count (); UT_uint32 children = count (); for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; switch (el->type ()) { case et_metadata: case et_revisions: case et_styles: case et_ignoredwords: case et_lists: case et_pagesize: minindex = i + 1; break; case et_section: break; default: if (maxindex > i) maxindex = i; break; } } if ((index < min_index) || (index > max_index)) { delete Section; return false; } return Element::ins (index, Section); } PD_AbiWord_2::EL_PageSize * PD_AbiWord_2::El_AbiWord::insert (const char * page_type, const char * page_scale, const char * width, const char * height, const char * orientation, const char * units) { El_PageSize * PageSize = 0; UT_TRY { PageSize = new El_PageSize(page_type,page_scale,width,height,orientation,units); } UT_CATCH(...) { PageSize = 0; } if (PageSize) { if (!append (PageSize)) PageSize = 0; } return PageSize; } PD_AbiWord_2::EL_PageSize * PD_AbiWord_2::El_AbiWord::lookup_page_type (const char * page_type) { // TODO } PD_AbiWord_2::EL_Section * PD_AbiWord_2::El_AbiWord::insert (const char * old_id, const char * new_id, const char * type, const char * style, const char * header_id, const char * footer_id, const char * columns, const char * column_gap) { El_Section * Section = 0; UT_TRY { Section = new El_Section(old_id,new_id,type,style,header_id,footer_id,columns,column_gap); } UT_CATCH(...) { Section = 0; } if (Section) { if (!append (Section)) Section = 0; } return Section; } PD_AbiWord_2::EL_Section * PD_AbiWord_2::El_AbiWord::lookup_old_id (const char * old_id) { // TODO } PD_AbiWord_2::EL_Section * PD_AbiWord_2::El_AbiWord::lookup_new_id (const char * new_id) { // TODO } bool PD_AbiWord_2::El_AbiWord::write (Writer * writer, UT_UTF8String & cache, bool include_meta_data, bool embed_object_data, bool strip) { if (!writer) return false; // TODO: check for <>&" in style ?? cache = "\n"; if (!writer->A2_write (cache)) return false; UT_uint32 children = count (); bool okay = true; for (UT_uint32 i = 0; i < children; i++) { Element * el = (*this)[i]; if (!include_meta_data && (el->type () == et_metadata)) continue; if (!embed_object_data && (el->type () == et_data )) continue; if (!el->write (writer, cache, strip)) { okay = false; break; } } if (!okay) return false; cache = "\n"; return writer->A2_write (cache); }