xref: /haiku/src/apps/haikudepot/textview/TextSpan.cpp (revision e92b4d3a272f31ee71cf9d561fcf965bfd8375b8)
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 
9 TextSpan::TextSpan()
10 	:
11 	fText(),
12 	fCharCount(0),
13 	fStyle(),
14 	fCursor((BMessage*)NULL),
15 	fClickMessage()
16 {
17 }
18 
19 
20 TextSpan::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 
31 TextSpan::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 
42 TextSpan&
43 TextSpan::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 
55 bool
56 TextSpan::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 
67 bool
68 TextSpan::operator!=(const TextSpan& other) const
69 {
70 	return !(*this == other);
71 }
72 
73 
74 void
75 TextSpan::SetText(const BString& text)
76 {
77 	fText = text;
78 	fCharCount = fText.CountChars();
79 }
80 
81 
82 void
83 TextSpan::SetStyle(const CharacterStyle& style)
84 {
85 	fStyle = style;
86 }
87 
88 
89 void
90 TextSpan::SetCursor(const BCursor& cursor)
91 {
92 	fCursor = cursor;
93 }
94 
95 
96 void
97 TextSpan::SetClickMessage(BMessage* message)
98 {
99 	fClickMessage = *message;
100 }
101 
102 
103 bool
104 TextSpan::Append(const BString& text)
105 {
106 	return Insert(fCharCount, text);
107 }
108 
109 
110 bool
111 TextSpan::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 
125 bool
126 TextSpan::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 
143 TextSpan
144 TextSpan::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 
159 void
160 TextSpan::_TruncateInsert(int32& start) const
161 {
162 	if (start < 0)
163 		start = 0;
164 
165 	if (start >= fCharCount)
166 		start = fCharCount;
167 }
168 
169 
170 void
171 TextSpan::_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