Continued refactoring.
[tagua/yd.git] / src / hline.cpp
blobbd2836989a08835efc104c871c323adcb69e314b
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include "hline.h"
13 #include "common.h"
14 #include <iostream>
16 class TrivialExecutor : public HLineExecutor {
17 public:
18 virtual ~TrivialExecutor() {
19 std::cout << std::endl;
22 virtual void writeChunk(const QString& text) {
23 std::cout << text << "|";
26 virtual void setFormat(const QTextCharFormat&) { }
29 void HLine::Format::applyTo(QTextCharFormat& fmt) const {
30 if (m_bold.first) {
31 fmt.setFontWeight(m_bold.second ? QFont::Bold : QFont::Normal);
33 if (m_italic.first) {
34 fmt.setFontItalic(m_italic.second);
36 if (m_color.first)
37 fmt.setForeground(m_color.second);
40 HLine::HLine(const QString& text, const QTextCharFormat& baseFormat)
41 : m_text(text) {
42 m_regions.push_back(Region(text.length(), baseFormat));
45 HLine::HLine(const HLine& other)
46 : m_regions(other.m_regions)
47 , m_text(other.m_text) { }
49 uint HLine::findRegion(int index) const {
50 if (index >= m_text.length()) return m_regions.size();
51 uint r = 0;
52 while (index >= m_regions[r].end())
53 r++;
54 Q_ASSERT(r < m_regions.size());
55 return r;
58 int HLine::begin(uint r) const {
59 if (r == 0) return 0;
60 else return m_regions[r - 1].end();
63 uint HLine::splitRegion(int index) {
64 if (index >= m_text.length()) return m_regions.size();
65 int r = findRegion(index);
66 if (begin(r) != index) {
67 m_regions.insert(
68 m_regions.begin() + r + 1,
69 m_regions[r]);
70 m_regions[r].setEnd(index);
71 return r + 1;
73 else return r;
76 const QTextCharFormat& HLine::getFormat(int index) const {
77 return m_regions[findRegion(index)].format();
80 void HLine::setFormat(int begin, int end, const Format& format) {
81 Q_ASSERT(begin < m_text.length());
82 Q_ASSERT(end <= m_text.length());
84 if (begin >= end) return;
85 int r1 = splitRegion(begin);
86 int r2 = splitRegion(end);
88 for (int r = r1; r < r2; r++) {
89 QTextCharFormat fmt = m_regions[r].format();
90 format.applyTo(fmt);
91 m_regions[r].setFormat(fmt);
95 void HLine::setBold(int begin, int end, bool value) {
96 Format format;
97 format.m_bold = std::make_pair(true, value);
98 setFormat(begin, end, format);
101 void HLine::setItalic(int begin, int end, bool value) {
102 Format format;
103 format.m_italic = std::make_pair(true, value);
104 setFormat(begin, end, format);
107 void HLine::setColor(int begin, int end, const QColor& color) {
108 Format format;
109 format.m_color = std::make_pair(true, color);
110 setFormat(begin, end, format);
113 QString HLine::mid(int begin, int end) const {
114 return m_text.mid(begin, end - begin);
117 HLine* HLine::extract(int begin, int end) const {
118 HLine* res = new HLine(*this);
119 int r1 = res->splitRegion(begin);
120 int r2 = res->splitRegion(end);
122 // adjust text
123 res->m_text = mid(begin, end);
125 // remove superflous regions
126 res->m_regions.erase(
127 res->m_regions.begin() + r2,
128 res->m_regions.end());
129 res->m_regions.erase(
130 res->m_regions.begin(),
131 res->m_regions.begin() + r1);
133 // adjust regions
134 for (uint i = 0; i < res->m_regions.size(); i++) {
135 res->m_regions[i].setEnd(res->m_regions[i].end() - begin);
138 return res;
141 HLine* HLine::append(const HLine& other, int begin, int end) const {
142 HLine* res = new HLine(*this);
144 int old_r = res->m_regions.size();
145 int old_length = res->m_text.length();
147 // append text
148 res->m_text += other.mid(begin, end);
150 // add regions
151 int r1 = other.findRegion(begin);
152 int r2 = other.findRegion(end);
153 std::copy(other.m_regions.begin() + r1,
154 other.m_regions.begin() + r2,
155 std::back_insert_iterator<std::vector<Region> >(res->m_regions));
157 // adjust regions
158 for (uint i = old_r; i < res->m_regions.size(); i++) {
159 int new_end = old_length + res->m_regions[i].end() - begin;
160 res->m_regions[i].setEnd(new_end);
163 return res;
166 void HLine::dump() const {
167 TrivialExecutor executor;
168 run(executor);
171 void HLine::run(HLineExecutor& executor) const {
172 int begin = 0;
173 for (uint i = 0; i < m_regions.size(); i++) {
174 int end = m_regions[i].end();
175 executor.setFormat(m_regions[i].format());
176 executor.writeChunk(mid(begin, end));
177 begin = end;