1/*
2 * Copyright 2013, Stephan A��mus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6#include "TextSpan.h"
7
8
9TextSpan::TextSpan()
10	:
11	fText(),
12	fCharCount(0),
13	fStyle(),
14	fCursor((BMessage*)NULL),
15	fClickMessage()
16{
17}
18
19
20TextSpan::TextSpan(const BString& text, const CharacterStyle& style)
21	:
22	fText(text),
23	fCharCount(text.CountChars()),
24	fStyle(style),
25	fCursor((BMessage*)NULL),
26	fClickMessage()
27{
28}
29
30
31TextSpan::TextSpan(const TextSpan& other)
32	:
33	fText(other.fText),
34	fCharCount(other.fCharCount),
35	fStyle(other.fStyle),
36	fCursor(other.fCursor),
37	fClickMessage(other.fClickMessage)
38{
39}
40
41
42TextSpan&
43TextSpan::operator=(const TextSpan& other)
44{
45	fText = other.fText;
46	fCharCount = other.fCharCount;
47	fStyle = other.fStyle;
48	fCursor = other.fCursor;
49	fClickMessage = other.fClickMessage;
50
51	return *this;
52}
53
54
55bool
56TextSpan::operator==(const TextSpan& other) const
57{
58	return fCharCount == other.fCharCount
59		&& fStyle == other.fStyle
60		&& fText == other.fText
61		&& fCursor == other.fCursor
62		&& fClickMessage.what == other.fClickMessage.what
63		&& fClickMessage.HasSameData(other.fClickMessage);
64}
65
66
67bool
68TextSpan::operator!=(const TextSpan& other) const
69{
70	return !(*this == other);
71}
72
73
74void
75TextSpan::SetText(const BString& text)
76{
77	fText = text;
78	fCharCount = fText.CountChars();
79}
80
81
82void
83TextSpan::SetStyle(const CharacterStyle& style)
84{
85	fStyle = style;
86}
87
88
89void
90TextSpan::SetCursor(const BCursor& cursor)
91{
92	fCursor = cursor;
93}
94
95
96void
97TextSpan::SetClickMessage(BMessage* message)
98{
99	fClickMessage = *message;
100}
101
102
103bool
104TextSpan::Append(const BString& text)
105{
106	return Insert(fCharCount, text);
107}
108
109
110bool
111TextSpan::Insert(int32 offset, const BString& text)
112{
113	_TruncateInsert(offset);
114
115	fText.InsertChars(text, offset);
116
117	int32 charCount = fText.CountChars();
118	bool success = charCount > fCharCount;
119	fCharCount = charCount;
120
121	return success;
122}
123
124
125bool
126TextSpan::Remove(int32 start, int32 count)
127{
128	_TruncateRemove(start, count);
129
130	if (count > 0) {
131		fText.RemoveChars(start, count);
132
133		int32 charCount = fText.CountChars();
134		bool success = charCount < fCharCount;
135		fCharCount = charCount;
136
137		return success;
138	}
139	return true;
140}
141
142
143TextSpan
144TextSpan::SubSpan(int32 start, int32 count) const
145{
146	_TruncateRemove(start, count);
147
148	BString subString;
149	if (count > 0)
150		fText.CopyCharsInto(subString, start, count);
151
152	return TextSpan(subString, fStyle);
153}
154
155
156// #pragma mark - private
157
158
159void
160TextSpan::_TruncateInsert(int32& start) const
161{
162	if (start < 0)
163		start = 0;
164
165	if (start >= fCharCount)
166		start = fCharCount;
167}
168
169
170void
171TextSpan::_TruncateRemove(int32& start, int32& count) const
172{
173	if (count < 0) {
174		count = 0;
175		return;
176	}
177
178	if (start < 0) {
179		count += start;
180		start = 0;
181	}
182
183	if (start < fCharCount) {
184		if (start + count > fCharCount)
185			count = fCharCount - start;
186	} else {
187		count = 0;
188	}
189}
190