summaryrefslogtreecommitdiffstatshomepage
path: root/DocumentBuffer.cpp
blob: 6d68d5355feac9556ee667d777d131703fdae6d0 (plain) (blame)
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;
}