1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#include "DocumentBuffer.h"
#include <QVariant>
#include <QDataStream>
#include <QDebug>
void DocumentBuffer::insertCharacterAt(QChar character, int row, int col)
{
// Make sure lists are allocated properly
for (int i = m_document.size(); i <= row; ++i)
m_document.append(QList<QLinkedList<QChar> >());
for (int i = m_document[row].size(); i <= col; ++i)
m_document[row].append(QLinkedList<QChar>());
// We clear the list if we're writing on top of a newline, since newlines are not ink
if (!m_document[row][col].isEmpty() && m_document[row][col].last() == QLatin1Char('\n'))
m_document[row][col].clear();
m_document[row][col].append(character);
}
QPair<int,int> DocumentBuffer::setText(const QString &string, int width)
{
int row = 0;
int col = 0;
foreach (const QChar &character, string) {
if (character == QLatin1Char('\n')) {
col = 0;
++row;
} else {
insertCharacterAt(character, row, col++);
if (col == width) {
col = 0;
++row;
}
}
}
return qMakePair(row, col);
}
QChar DocumentBuffer::topCharacterAt(int row, int col) const
{
return m_document[row][col].last();
}
QString DocumentBuffer::topLineAt(int row) const
{
const QList<QLinkedList<QChar> > &line = m_document.at(row);
const int size = line.size();
QString str(size, Qt::Uninitialized);
for (int i = 0; i < size; ++i)
str[i] = line[i].last();
return str;
}
QString DocumentBuffer::topDocument() const
{
QString str;
for (int i = 0; i < m_document.size(); ++i)
str += topLineAt(i);
return str;
}
const QLinkedList<QChar>& DocumentBuffer::charactersAt(int row, int col) const
{
return m_document[row][col];
}
const QList<QLinkedList<QChar > >& DocumentBuffer::lineAt(int row) const
{
return m_document[row];
}
const QList<QList<QLinkedList<QChar> > >& DocumentBuffer::document() const
{
return m_document;
}
int DocumentBuffer::lineSize(int row) const
{
const int size = m_document.value(row).size();
const QLinkedList<QChar> &list = m_document.value(row).value(size - 1);
if (!list.isEmpty() && list.last() == QLatin1Char('\n'))
return size - 1;
return size;
}
int DocumentBuffer::linesCount() const
{
return m_document.size();
}
QVariant DocumentBuffer::toVariant() const
{
QByteArray out;
QDataStream stream(&out, QIODevice::ReadWrite);
stream << m_document.size();
foreach (const QList<QLinkedList<QChar> > &line, m_document) {
stream << line.size();
foreach (const QLinkedList<QChar> &letters, line) {
stream << letters.size();
foreach (const QChar &letter, letters)
stream << letter;
}
}
return QVariant(out);
}
DocumentBuffer* DocumentBuffer::fromVariant(const QVariant &variant)
{
DocumentBuffer *document = new DocumentBuffer;
QDataStream stream(variant.toByteArray());
int linesCount;
stream >> linesCount;
for (int i = 0; i < linesCount; ++i) {
QList<QLinkedList<QChar> > line;
int colsCount;
stream >> colsCount;
for (int j = 0; j < colsCount; ++j) {
QLinkedList<QChar> letters;
int lettersCount;
stream >> lettersCount;
for (int k = 0; k < lettersCount; ++k) {
QChar letter;
stream >> letter;
letters.append(letter);
}
line.append(letters);
}
document->m_document.append(line);
}
return document;
}
|