void Block::insertAtPos(int pos, const QString &text, const TextStyle &style, bool only_latin) { m_changed = true; m_only_latin = m_only_latin && only_latin; m_text_line.insert(pos,text); bool found = false; for (int i = 0; i < m_style_list.size(); i++) { TextStyleLine ¤t_style = m_style_list[i]; if (found) { current_style.start_index += text.size(); current_style.end_index += text.size(); current_style.index_dirty = true; if (current_style.start_index >= m_text_line.size()) { current_style.releaseTextSegment(m_screen); m_style_list.remove(i); i--; } else if (current_style.end_index >= m_text_line.size()) { current_style.end_index = m_text_line.size()-1; } } else if (pos >= current_style.start_index && pos <= current_style.end_index) { found = true; if (current_style.start_index == pos) { current_style.start_index += text.size(); current_style.end_index += text.size(); current_style.index_dirty = true; m_style_list.insert(i, TextStyleLine(style, pos, pos+ text.size() - 1)); i++; } else if (current_style.end_index == pos) { current_style.end_index--; current_style.text_dirty = true; m_style_list.insert(i+1, TextStyleLine(style, pos, pos+ text.size() - 1)); i++; } else { int old_end = current_style.end_index; current_style.end_index = pos -1; current_style.text_dirty = true; m_style_list.insert(i+1, TextStyleLine(style, pos, pos + text.size() - 1)); if (pos + text.size() < m_text_line.size()) { int segment_end = std::min(m_text_line.size() -1, old_end + text.size()); m_style_list.insert(i+2, TextStyleLine(current_style, pos + text.size(), segment_end)); i+=2; } else { i++; } } } } }
void Line::clearToEndOfLine(int index) { m_changed = true; QString empty(m_text_line.size() - index, QChar(' ')); m_text_line.replace(index, m_text_line.size()-index,empty); bool found = false; for (int i = 0; i < m_style_list.size(); i++) { const TextStyleLine current_style = m_style_list.at(i); if (found) { if (current_style.text_segment) releaseTextSegment(current_style.text_segment); m_style_list.remove(i); i--; } else { if (index <= current_style.end_index) { found = true; if (current_style.start_index == index) { if (current_style.text_segment) releaseTextSegment(current_style.text_segment); m_style_list.remove(i); i--; } else { m_style_list[i].changed = true; } } } } if (m_style_list.size() && m_style_list.last().isCompatible(m_screen->defaultTextStyle())) { m_style_list.last().end_index = m_text_line.size() -1; } else { m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(),index, m_text_line.size() -1)); } }
void Block::deleteCharacters(int from, int to) { m_changed = true; int removed = 0; const int size = (to + 1) - from; bool found = false; int last_index = -1; for (int i = 0; i < m_style_list.size(); i++) { TextStyleLine ¤t_style = m_style_list[i]; last_index = i; if (found) { current_style.start_index -= removed; current_style.end_index -= removed; current_style.index_dirty = true; if (removed != size) { int current_style_size = current_style.end_index + 1 - current_style.start_index; if (current_style_size <= size - removed) { removed += current_style.end_index + 1 - current_style.start_index; current_style.releaseTextSegment(m_screen); m_style_list.remove(i); i--; } else { current_style.end_index -= size - removed; removed = size; } } } else { if (current_style.start_index <= from && current_style.end_index >= from) { found = true; int left_in_style = (current_style.end_index + 1) - from; int subtract = std::min(left_in_style, size); current_style.end_index -= subtract; current_style.text_dirty = true; removed = subtract; if (current_style.end_index < current_style.start_index) { current_style.releaseTextSegment(m_screen); m_style_list.remove(i); i--; } } } } if (last_index >= 0) { TextStyleLine &last_modified = m_style_list[last_index]; TextStyle defaultStyle = m_screen->defaultTextStyle(); if (last_modified.isCompatible(defaultStyle)) { last_modified.end_index += size; last_modified.text_dirty = true; } else { m_style_list.insert(last_index + 1, TextStyleLine(defaultStyle, last_modified.end_index + 1, last_modified.end_index + size)); } } m_text_line.remove(from, size); }
void Block::moveLinesFromBlock(Block *block, int start_line, int count) { Q_ASSERT(block); Q_ASSERT(block->lineCount() >= start_line + count); int start_char = block->width() * start_line; int end_char = (block->width() * (start_line + count)) - 1; for (int i = 0; i < block->m_style_list.size(); i++) { TextStyleLine ¤t_style = block->m_style_list[i]; if (current_style.start_index >= start_char && current_style.end_index <= end_char) { current_style.start_index += (-start_char + m_text_line.size()); current_style.end_index += (-start_char + m_text_line.size()); current_style.releaseTextSegment(m_screen); m_style_list.append(TextStyleLine(current_style, current_style.start_index, current_style.end_index)); block->m_style_list.remove(i); i--; } else if (current_style.start_index > end_char) { current_style.start_index -= (end_char + 1) - start_char; current_style.end_index -= (end_char + 1) - start_char; current_style.index_dirty = true; current_style.text_dirty = true; } } m_text_line.append(block->m_text_line.mid(start_char, (end_char + 1) - start_char)); block->m_text_line.remove(start_char, (end_char + 1) - start_char); m_changed = true; block->m_changed = true; }
Block *Block::takeLine(int line) { if (line >= lineCount()) return nullptr; m_changed = true; Block *to_return = new Block(m_screen); int start_index = line * m_width; int end_index = start_index + (m_width - 1); for (int i = 0; i < m_style_list.size(); i++) { ensureStyleAlignWithLines(i); TextStyleLine ¤t_style = m_style_list[i]; if (current_style.start_index >= start_index && current_style.end_index <= end_index) { current_style.releaseTextSegment(m_screen); current_style.start_index -= start_index; current_style.end_index -= start_index; current_style.index_dirty = true; to_return->m_style_list.append(TextStyleLine(current_style, current_style.start_index, current_style.end_index)); m_style_list.remove(i); i--; } else if (current_style.start_index > end_index) { current_style.start_index -= (end_index + 1) - start_index; current_style.end_index -= (end_index + 1) - start_index; current_style.index_dirty = true; current_style.text_dirty = true; } } to_return->m_text_line = m_text_line.mid(start_index, m_width); m_text_line.remove(start_index, m_width); return to_return; }
void Block::ensureStyleAlignWithLines(int i) { int start_line = m_style_list[i].start_index / m_width; int end_line = m_style_list[i].end_index / m_width; if (start_line != end_line) { int remainder_start_line = ((m_width * (start_line + 1))-1) - m_style_list[i].start_index; int next_line_end_index = m_style_list[i].end_index; m_style_list[i].end_index = m_style_list[i].start_index + remainder_start_line; m_style_list.insert(i + 1, TextStyleLine(m_style_list[i], m_style_list[i].end_index + 1, next_line_end_index)); } }
void Line::clear() { m_text_line.fill(QChar(' ')); for (int i = 0; i < m_style_list.size(); i++) { if (m_style_list.at(i).text_segment) releaseTextSegment(m_style_list.at(i).text_segment); } m_style_list.clear(); m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(),0,m_text_line.size() -1)); m_changed = true; }
void Line::insertAtPos(int pos, const QString &text, const TextStyle &style) { Q_ASSERT(pos + text.size() <= m_text_line.size()); m_changed = true; m_text_line.replace(pos,text.size(),text); bool found = false; for (int i = 0;i < m_style_list.size(); i++) { const TextStyleLine current_style = m_style_list.at(i); if (found) { if (current_style.end_index <= pos + text.size()) { if (current_style.text_segment) releaseTextSegment(current_style.text_segment); m_style_list.remove(i); i--; } else if (current_style.start_index <= pos + text.size()) { m_style_list[i].start_index = pos + text.size(); m_style_list[i].changed = true; } else { break; } } else if (pos <= current_style.end_index) { found = true; if (pos + text.size() <= current_style.end_index) { if (current_style.isCompatible(style)) { m_style_list[i].changed = true; } else { if (current_style.start_index == pos && current_style.end_index == pos + text.size()) { m_style_list[i].setStyle(style); } else if (current_style.start_index == pos) { m_style_list[i].start_index = pos + text.size(); m_style_list.insert(i, TextStyleLine(style,pos, pos+text.size()-1)); } else if (current_style.end_index == pos + text.size()) { m_style_list[i].end_index = pos -1; m_style_list.insert(i+1, TextStyleLine(style,pos, pos+text.size() - 1)); } else { m_style_list[i].end_index = pos -1; m_style_list.insert(i+1, TextStyleLine(style,pos, pos+text.size() -1 )); m_style_list.insert(i+2, TextStyleLine(current_style,pos + text.size(), current_style.end_index)); } } break; } else { if (current_style.isCompatible(style)) { m_style_list[i].end_index = pos + text.size() - 1; m_style_list[i].changed = true; } else { if (current_style.start_index == pos) { m_style_list[i].end_index = pos + text.size() - 1; m_style_list[i].changed = true; m_style_list[i].style = style.style; m_style_list[i].foreground = style.foreground; m_style_list[i].background = style.background; } else { m_style_list[i].end_index = pos - 1; m_style_list[i].changed = true; m_style_list.insert(i+1, TextStyleLine(style, pos, pos + text.size() -1)); i++; } } } } } }
void Block::replaceAtPos(int pos, const QString &text, const TextStyle &style, bool only_latin) { m_changed = true; m_only_latin = m_only_latin && only_latin; if (pos >= m_text_line.size()) { if (pos > m_text_line.size()) { int old_size = m_text_line.size(); QString filling(pos - m_text_line.size(), QChar(' ')); m_text_line.append(filling); m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(), old_size, old_size + filling.size() -1)); } m_text_line.append(text); m_style_list.append(TextStyleLine(style, pos, pos + text.size()-1)); return; } else if (pos + text.size() > m_text_line.size()) { m_style_list.append(TextStyleLine(m_screen->defaultTextStyle(), pos + text.size() - m_text_line.size(), pos + text.size() -1)); } m_text_line.replace(pos,text.size(),text); bool found = false; for (int i = 0; i < m_style_list.size(); i++) { TextStyleLine ¤t_style = m_style_list[i]; if (found) { if (current_style.end_index <= pos + text.size() - 1) { current_style.releaseTextSegment(m_screen); m_style_list.remove(i); i--; } else if (current_style.start_index <= pos + text.size()) { current_style.start_index = pos + text.size(); current_style.style_dirty = true; current_style.text_dirty = true; current_style.index_dirty = true; } else { break; } } else if (pos >= current_style.start_index && pos <= current_style.end_index) { found = true; if (pos + text.size() -1 <= current_style.end_index) { if (current_style.isCompatible(style)) { current_style.text_dirty = true; } else { if (current_style.start_index == pos && current_style.end_index == pos + text.size() - 1) { current_style.setStyle(style); current_style.text_dirty = true; current_style.style_dirty = true; } else if (current_style.start_index == pos) { current_style.start_index = pos + text.size(); current_style.text_dirty = true; m_style_list.insert(i, TextStyleLine(style,pos, pos+text.size() -1)); } else if (current_style.end_index == pos + text.size() - 1) { current_style.end_index = pos - 1; current_style.text_dirty = true; m_style_list.insert(i+1, TextStyleLine(style,pos, pos + text.size() - 1)); } else { int old_end = current_style.end_index; current_style.end_index = pos - 1; current_style.text_dirty = true; m_style_list.insert(i+1, TextStyleLine(style,pos, pos + text.size() - 1)); if (pos + text.size() < m_text_line.size()) { m_style_list.insert(i+2, TextStyleLine(current_style,pos + text.size(), old_end)); } } } break; } else { if (current_style.isCompatible(style)) { current_style.end_index = pos + text.size() - 1; current_style.text_dirty = true; } else { if (current_style.start_index == pos) { if (i > 0 && m_style_list.at(i-1).isCompatible(style)) { TextStyleLine &previous_style = m_style_list[i -1]; previous_style.end_index+= text.size(); previous_style.text_dirty = true; current_style.releaseTextSegment(m_screen); m_style_list.remove(i); i--; } else { current_style.end_index = pos + text.size() - 1; current_style.style = style.style; current_style.forground = style.forground; current_style.background = style.background; current_style.text_dirty = true; current_style.style_dirty = true; current_style.index_dirty = true; } } else { current_style.end_index = pos - 1; current_style.text_dirty = true; m_style_list.insert(i+1, TextStyleLine(style, pos, pos + text.size() -1)); i++; } } } } } }