📄 html.cpp
字号:
// Error will be posted later } ERR_POST("Bad attribute: " << attributeName << "=\"" << value << "\""); return 1;}void CHTML_tc::DoSetAttribute(const string& name, const string& value, bool optional){ if (name == "rowspan" || name == "colspan") { // Changing cell size ResetTableCache(); } CParent::DoSetAttribute(name, value, optional);}void CHTML_tc::ResetTableCache(void){ if ( m_Parent ) { m_Parent->ResetTableCache(); }}void CHTML_tc_Cache::SetUsed(){ if ( IsUsed() ) { NCBI_THROW(CHTMLException, eTableCellUse, "overlapped table cells"); } m_Used = true;}void CHTML_tc_Cache::SetCellNode(CHTML_tc* cellNode){ SetUsed(); m_Node = cellNode;}staticCHTML_table::TIndex x_NextSize(CHTML_table::TIndex size, CHTML_table::TIndex limit){ do { if ( size == 0 ) size = 2; else size *= 2; } while ( size < limit ); return size;}CHTML_tc_Cache& CHTML_tr_Cache::GetCellCache(TIndex col){ TIndex count = GetCellCount(); if ( col >= count ) { TIndex newCount = col + 1; TIndex size = m_CellsSize; if ( newCount > size ) { TIndex newSize = x_NextSize(size, newCount); CHTML_tc_Cache* newCells = new CHTML_tc_Cache[newSize]; for ( TIndex i = 0; i < count; ++i ) newCells[i] = m_Cells[i]; delete[] m_Cells; m_Cells = newCells; m_CellsSize = newSize; } m_CellCount = newCount; } return m_Cells[col];}void CHTML_tr_Cache::SetUsedCells(TIndex colBegin, TIndex colEnd){ for ( TIndex col = colBegin; col < colEnd; ++col ) { GetCellCache(col).SetUsed(); }}void CHTML_tr_Cache::AppendCell(CHTML_tr* rowNode, TIndex col, CHTML_tc* cellNode, TIndex colSpan){ _ASSERT(m_FilledCellCount <= col); for ( TIndex i = m_FilledCellCount; i < col; ++i ) { CHTML_tc_Cache& cellCache = GetCellCache(i); if ( !cellCache.IsUsed() ) { CHTML_tc* cell; cell = new CHTML_td; rowNode->AppendCell(cell); cellCache.SetCellNode(cell); } } CHTML_tc_Cache& cellCache = GetCellCache(col); _ASSERT(!cellCache.IsUsed()); _ASSERT(x_GetSpan(cellNode, "colspan") == colSpan); rowNode->AppendCell(cellNode); cellCache.SetCellNode(cellNode); if ( colSpan != 1 ) { SetUsedCells(col + 1, col + colSpan); } m_FilledCellCount = col + colSpan;}void CHTML_tr_Cache::SetUsedCells(CHTML_tc* cellNode, TIndex colBegin, TIndex colEnd){ GetCellCache(colBegin).SetCellNode(cellNode); SetUsedCells(colBegin + 1, colEnd); m_FilledCellCount = colEnd;}CHTML_table_Cache::~CHTML_table_Cache(void){ for ( TIndex i = 0; i < GetRowCount(); ++i ) { delete m_Rows[i]; } delete[] m_Rows;}CHTML_tr_Cache& CHTML_table_Cache::GetRowCache(TIndex row){ TIndex count = GetRowCount(); if ( row >= count ) { TIndex newCount = row + 1; TIndex size = m_RowsSize; if ( newCount > size ) { TIndex newSize = x_NextSize(size, newCount); CHTML_tr_Cache** newRows = new CHTML_tr_Cache*[newSize]; for ( TIndex i = 0; i < count; ++i ) newRows[i] = m_Rows[i]; delete[] m_Rows; m_Rows = newRows; m_RowsSize = newSize; } for ( TIndex i = count; i < newCount; ++i ) m_Rows[i] = new CHTML_tr_Cache; m_RowCount = newCount; } return *m_Rows[row];}void CHTML_table_Cache::InitRow(TIndex row, CHTML_tr* rowNode){ CHTML_tr_Cache& rowCache = GetRowCache(row); m_Rows[row]->SetRowNode(rowNode); m_FilledRowCount = row + 1; // Scan all children (which should be <TH> or <TD> tags) if ( rowNode->HaveChildren() ) { // Beginning with column 0 TIndex col = 0; for ( CNCBINode::TChildren::iterator iCol = rowNode->ChildBegin(), iColEnd = rowNode->ChildEnd(); iCol != iColEnd; ++iCol ) { CHTML_tc* cellNode = dynamic_cast<CHTML_tc*>(rowNode->Node(iCol)); if ( !cellNode ) { continue; } // Skip all used cells while ( rowCache.GetCellCache(col).IsUsed() ) { ++col; } // Determine current cell size TIndex rowSpan = x_GetSpan(cellNode, "rowspan"); TIndex colSpan = x_GetSpan(cellNode, "colspan"); // End of new cell in columns rowCache.SetUsedCells(cellNode, col, col + colSpan); if ( rowSpan > 1 ) { SetUsedCells(row + 1, row + rowSpan, col, col + colSpan); } // Skip this cell's columns col += colSpan; } }}CHTML_table_Cache::CHTML_table_Cache(CHTML_table* table) : m_Node(table), m_RowCount(0), m_RowsSize(0), m_Rows(0), m_FilledRowCount(0){ // Scan all children (which should be <TR> tags) if ( table->HaveChildren() ) { // Beginning with row 0 TIndex row = 0; for ( CNCBINode::TChildren::iterator iRow = table->ChildBegin(), iRowEnd = table->ChildEnd(); iRow != iRowEnd; ++iRow ) { CHTML_tr* rowNode = dynamic_cast<CHTML_tr*>(table->Node(iRow)); if ( !rowNode ) { continue; } InitRow(row, rowNode); ++row; } }}CHTML_tr* CHTML_table_Cache::GetRowNode(TIndex row){ GetRowCache(row); while ( row >= m_FilledRowCount ) { CHTML_tr* rowNode = new CHTML_tr; m_Node->AppendRow(rowNode); m_Rows[m_FilledRowCount++]->SetRowNode(rowNode); } return m_Rows[row]->GetRowNode();}void CHTML_table_Cache::SetUsedCells(TIndex rowBegin, TIndex rowEnd, TIndex colBegin, TIndex colEnd){ for ( TIndex row = rowBegin; row < rowEnd; ++row ) { GetRowCache(row).SetUsedCells(colBegin, colEnd); }}CHTML_tc* CHTML_table_Cache::GetCellNode(TIndex row, TIndex col, CHTML_table::ECellType type){ CHTML_tr_Cache& rowCache = GetRowCache(row); if ( col < rowCache.GetCellCount() ) { CHTML_tc_Cache& cellCache = rowCache.GetCellCache(col); if ( cellCache.IsNode() ) { CHTML_tc* cell = cellCache.GetCellNode(); switch ( type ) { case CHTML_table::eHeaderCell: if ( !dynamic_cast<CHTML_th*>(cell) ) NCBI_THROW(CHTMLException, eTableCellType, "wrong cell type: TH expected"); break; case CHTML_table::eDataCell: if ( !dynamic_cast<CHTML_td*>(cell) ) NCBI_THROW(CHTMLException, eTableCellType, "wrong cell type: TD expected"); break; default: break; } return cell; } if ( cellCache.IsUsed() ) NCBI_THROW(CHTMLException, eTableCellUse, "invalid use of big table cell"); } CHTML_tc* cell; if ( type == CHTML_table::eHeaderCell ) { cell = new CHTML_th; } else { cell = new CHTML_td; } rowCache.AppendCell(GetRowNode(row), col, cell, 1); return cell;}CHTML_tc* CHTML_table_Cache::GetCellNode(TIndex row, TIndex col, CHTML_table::ECellType type, TIndex rowSpan, TIndex colSpan){ CHTML_tr_Cache& rowCache = GetRowCache(row); if ( col < rowCache.GetCellCount() ) { CHTML_tc_Cache& cellCache = rowCache.GetCellCache(col); if ( cellCache.IsNode() ) { CHTML_tc* cell = cellCache.GetCellNode(); switch ( type ) { case CHTML_table::eHeaderCell: if ( !dynamic_cast<CHTML_th*>(cell) ) NCBI_THROW(CHTMLException, eTableCellType, "wrong cell type: TH expected"); break; case CHTML_table::eDataCell: if ( !dynamic_cast<CHTML_td*>(cell) ) NCBI_THROW(CHTMLException, eTableCellType, "wrong cell type: TD expected"); break; default: break; } if ( x_GetSpan(cell, "rowspan") != rowSpan || x_GetSpan(cell, "colspan") != colSpan ) NCBI_THROW(CHTMLException, eTableCellUse, "cannot change table cell size"); return cell; } if ( cellCache.IsUsed() ) NCBI_THROW(CHTMLException, eTableCellUse, "invalid use of big table cell"); } CHTML_tc* cell; if ( type == CHTML_table::eHeaderCell ) { cell = new CHTML_th; } else { cell = new CHTML_td; } if ( colSpan != 1 ) { cell->SetColSpan(colSpan); } if ( rowSpan != 1 ) { cell->SetRowSpan(rowSpan); } rowCache.AppendCell(GetRowNode(row), col, cell, colSpan); if ( rowSpan != 1 ) { SetUsedCells(row + 1, row + rowSpan, col, col + colSpan); } return cell;}CHTML_table::CHTML_table(void) : CParent("table"), m_CurrentRow(0), m_CurrentCol(TIndex(-1)), m_ColSepL(kEmptyStr), m_ColSepM(" "), m_ColSepR(kEmptyStr), m_RowSepChar('-'), m_IsRowSep(eSkipRowSep){ return;}CHTML_table::~CHTML_table(void){ return;}CHTML_table* CHTML_table::SetCellSpacing(int spacing){ SetAttribute("cellspacing", spacing); return this;}CHTML_table* CHTML_table::SetCellPadding(int padding){ SetAttribute("cellpadding", padding); return this;}void CHTML_table::ResetTableCache(void){ m_Cache.reset(0);}CHTML_table_Cache& CHTML_table::GetCache(void) const{ CHTML_table_Cache* cache = m_Cache.get(); if ( !cache ) { m_Cache.reset(cache = new CHTML_table_Cache(const_cast<CHTML_table*>(this))); } return *cache;}void CHTML_table::DoAppendChild(CNCBINode* node){ CHTML_tr* row = dynamic_cast<CHTML_tr*>(node); if ( row ) { // Adding new row _ASSERT(!row->m_Parent); ResetTableCache(); row->m_Parent = this; } CParent::DoAppendChild(node);}void CHTML_table::AppendRow(CHTML_tr* row){ _ASSERT(!row->m_Parent); row->m_Parent = this; CParent::DoAppendChild(row);}CHTML_tr* CHTML_table::Row(TIndex row){ return GetCache().GetRowNode(row);}CHTML_tc* CHTML_table::Cell(TIndex row, TIndex col, ECellType type){ return GetCache().GetCellNode(m_CurrentRow = row, m_CurrentCol = col, type);}CHTML_tc* CHTML_table::Cell(TIndex row, TIndex col, ECellType type, TIndex rowSpan, TIndex colSpan){ return GetCache().GetCellNode(m_CurrentRow = row, m_CurrentCol = col, type, rowSpan, colSpan);}void CHTML_table::CheckTable(void) const{ GetCache();}CHTML_table::TIndex CHTML_table::CalculateNumberOfColumns(void) const{ CHTML_table_Cache& cache = GetCache(); TIndex columns = 0; for ( TIndex i = 0; i < cache.GetRowCount(); ++i ) { columns = max(columns, cache.GetRowCache(i).GetCellCount()); } return columns;}CHTML_table::TIndex CHTML_table::CalculateNumberOfRows(void) const{ return GetCache().GetRowCount();}CNcbiOstream& CHTML_table::PrintBegin(CNcbiOstream& out, TMode mode){ if ( mode == ePlainText ) { out << CHTMLHelper::GetNL(); CHECK_STREAM_WRITE(out); if ( m_IsRowSep == ePrintRowSep ) { SIZE_TYPE seplen = 0; // Find length of first non-empty row NON_CONST_ITERATE ( TChildren, i, Children() ) { if ( (seplen = dynamic_cast<CHTML_tr*>(&**i)->GetTextLength(mode)) >0) { break; } } if ( !seplen ) { seplen = 1; } out << string(seplen, m_RowSepChar) << CHTMLHelper::GetNL(); CHECK_STREAM_WRITE(out); } } return CParent::PrintBegin(out, mode);}void CHTML_table::SetPlainSeparators(const string& col_left, const string& col_middle, const string& col_right, const char row_sep_char, ERowPlainSep is_row_sep){ m_ColSepL = col_left; m_ColSepM = col_middle; m_ColSepR = col_right; m_RowSepChar = row_sep_char; m_IsRowSep = is_row_sep;}// <form> tag.CHTML_form::CHTML_form(void) : CParent("form"){ return;}CHTML_form::CHTML_form(const string& url, EMethod method) : CParent("form"){ Init(url, method);}CHTML_form::CHTML_form(const string& url, CNCBINode* node, EMethod method) : CParent("form", node){ Init(url, method);}CHTML_form::~CHTML_form(void){ return;}void CHTML_form::Init(const string& url, EMethod method){ SetOptionalAttribute("action", url); switch ( method ) { case eGet: SetAttribute("method", "GET"); break; case ePost: SetAttribute("enctype", "application/x-www-form-urlencoded"); SetAttribute("method", "POST"); break; case ePostData: SetAttribute("enctype", "multipart/form-data"); SetAttribute("method", "POST"); break; }}void CHTML_form::AddHidden(const string& name, const string& value){ AppendChild(new CHTML_hidden(name, value));}void CHTML_form::AddHidden(const string& name, int value){ AppendChild(new CHTML_hidden(name, value));}// <legend> tag.CHTML_legend::CHTML_legend(const string& legend) : CParent("legend", legend){ return;}CHTML_legend::CHTML_legend(CHTMLNode* legend) : CParent("legend", legend){ return;}CHTML_legend::~CHTML_legend(void){ return;}// <fieldset> tag.CHTML_fieldset::CHTML_fieldset(void) : CParent("fieldset"){ return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -