MyGUI: MyGUI_TextIterator.cpp Source File

MyGUI 3.4.2

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files
- Examples

- File List
- Globals

MyGUI_TextIterator.cpp
Go to the documentation of this file.
1/*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7#include "MyGUI_Precompiled.h"
8#include "MyGUI_TextIterator.h"
9
10namespace MyGUI
11{
12
13 TextIterator::TextIterator() :
14 mPosition(0),
15 mSize(ITEM_NONE),
16 mFirst(true),
17 mHistory(nullptr)
18 {
19 }
20
21 TextIterator::TextIterator(const UString& _text, VectorChangeInfo* _history) :
22 mText(_text.asUTF32()),
23 mCurrent(mText.begin()),
24 mEnd(mText.end()),
25 mSave(mEnd),
26 mPosition(0),
27 mSize(ITEM_NONE),
28 mFirst(true),
29 mHistory(_history)
30 {
31 }
32
33 bool TextIterator::moveNext()
34 {
35 if (mCurrent == mEnd) return false;
36 else if (mFirst)
37 {
38 mFirst = false;
39 return true;
40 }
41
42 // jump to next character, skipping tags (#)
43 for (UString::utf32string::iterator iter = mCurrent; iter != mEnd; ++iter)
44 {
45
46 if ((*iter) == L'#')
47 {
48
49 // следующий символ
50 ++ iter;
51 if (iter == mEnd)
52 {
53 mCurrent = mEnd;
54 return false;
55 }
56
57 // две решетки подряд
58 if ((*iter) == L'#')
59 {
60
61 // следующий символ
62 mPosition ++;
63 ++iter;
64 if (iter == mEnd)
65 {
66 mCurrent = mEnd;
67 return false;
68 }
69
70 // указатель на следующий символ
71 mCurrent = iter;
72 return true;
73 }
74
75 // остальные 5 символов цвета
76 for (size_t pos = 0; pos < 5; pos++)
77 {
78 // следующий символ
79 ++ iter;
80 if (iter == mEnd)
81 {
82 mCurrent = mEnd;
83 return false;
84 }
85 }
86
87 }
88 else
89 {
90
91 // обыкновенный символ
92 mPosition ++;
93 ++iter;
94 if (iter == mEnd)
95 {
96 mCurrent = mEnd;
97 return false;
98 }
99
100 // указатель на следующий символ
101 mCurrent = iter;
102 return true;
103 }
104 }
105
106 return false;
107 }
108
109 // возвращает цвет
110 bool TextIterator::getTagColour(UString& _colour) const
111 {
112 if (mCurrent == mEnd) return false;
113
114 UString::utf32string::iterator iter = mCurrent;
115
116 // нам нужен последний цвет
117 bool ret = false;
118 while (getTagColour(_colour, iter))
119 {
120 ret = true;
121 }
122
123 return ret;
124 }
125
126 bool TextIterator::setTagColour(const Colour& _colour)
127 {
128 if (mCurrent == mEnd) return false;
129 clearTagColour();
130 if (mCurrent == mEnd) return false;
131
132 const size_t SIZE = 16;
133 wchar_t buff[SIZE];
134
135#ifdef __MINGW32__
136 swprintf(buff, L"#%.2X%.2X%.2X\0", (int)(_colour.red * 255), (int)(_colour.green * 255), (int)(_colour.blue * 255));
137#else
138 swprintf(buff, SIZE, L"#%.2X%.2X%.2X\0", (int)(_colour.red * 255), (int)(_colour.green * 255), (int)(_colour.blue * 255));
139#endif
140 UString tmpStr = UString(buff);
141 insert(mCurrent, tmpStr.asUTF32());
142
143 return true;
144 }
145
146 bool TextIterator::setTagColour(const UString::utf32string& _colour)
147 {
148 if (mCurrent == mEnd) return false;
149 clearTagColour();
150 if (mCurrent == mEnd) return false;
151
152 // check if it looks like a colour tag
153 if ( (_colour.size() != 7) || (_colour.find(L'#', 1) != MyGUI::UString::npos) ) return false;
154
155 insert(mCurrent, _colour);
156
157 return true;
158 }
159
160 bool TextIterator::setTagColour(const UString& _colour)
161 {
162 return setTagColour(_colour.asUTF32());
163 }
164
165 // возвращает размер строки
166 size_t TextIterator::getSize() const
167 {
168 if (mSize != ITEM_NONE) return mSize;
169 mSize = mPosition;
170
171 for (UString::utf32string::const_iterator iter = mCurrent; iter != mEnd; ++iter)
172 {
173
174 if ((*iter) == L'#')
175 {
176 // следующий символ
177 ++ iter;
178 if (iter == mEnd) break;
179
180 // тэг цвета
181 if ((*iter) != L'#')
182 {
183 // остальные 5 символов цвета
184 for (size_t pos = 0; pos < 5; pos++)
185 {
186 ++ iter;
187 if (iter == mEnd)
188 {
189 --iter;
190 break;
191 }
192 }
193 continue;
194 }
195 }
196
197 // обыкновенный символ
198 mSize ++;
199 }
200
201 return mSize;
202 }
203
204 // возвращает текст без тегов
205 UString TextIterator::getOnlyText(const UString& _text)
206 {
207 UString::utf32string ret;
208 UString::utf32string text(_text.asUTF32());
209 ret.reserve(text.size());
210
211 UString::utf32string::const_iterator end = text.end();
212 for (UString::utf32string::const_iterator iter = text.begin(); iter != end; ++iter)
213 {
214
215 if ((*iter) == L'#')
216 {
217 // следующий символ
218 ++ iter;
219 if (iter == end) break;
220
221 // тэг цвета
222 if ((*iter) != L'#')
223 {
224 // остальные 5 символов цвета
225 for (size_t pos = 0; pos < 5; pos++)
226 {
227 ++ iter;
228 if (iter == end)
229 {
230 --iter;
231 break;
232 }
233 }
234 continue;
235 }
236 }
237
238 // обыкновенный символ
239 ret.push_back(*iter);
240 }
241
242 return UString(ret);
243 }
244
245 // возвращает цвет
246 bool TextIterator::getTagColour(UString& _colour, UString::utf32string::iterator& _iter) const
247 {
248 if ( (_iter == mEnd) || ((*_iter) != L'#') ) return false;
249
250 // следующий символ
251 ++_iter;
252 if ( (_iter == mEnd) || ((*_iter) == L'#') ) return false;
253
254 // берем цвет
255 wchar_t buff[16] = L"#FFFFFF\0";
256 buff[1] = (wchar_t)(*_iter);
257 for (size_t pos = 2; pos < 7; pos++)
258 {
259 ++_iter;
260 if ( _iter == mEnd ) return false;
261 buff[pos] = (wchar_t)(*_iter);
262 }
263
264 // ставим на следующий тег или символ
265 ++_iter;
266
267 // возвращаем цвет
268 _colour = buff;
269 return true;
270 }
271
272 void TextIterator::clearNewLine(UString& _text)
273 {
274 for (UString::iterator iter = _text.begin(); iter != _text.end(); iter.moveNext())
275 {
276 auto character = iter.getCharacter();
277 if (character == FontCodeType::NEL ||
278 character == FontCodeType::CR ||
279 character == FontCodeType::LF )
280 {
281 (*iter) = FontCodeType::Space;
282 }
283 }
284 }
285
286 bool TextIterator::saveStartPoint()
287 {
288 if (mCurrent == mEnd) return false;
289 mSave = mCurrent;
290 return true;
291 }
292
293 UString TextIterator::getFromStart() const
294 {
295 if (mSave == mEnd) return L"";
296 size_t start = mSave - mText.begin();
297 return UString(mText.substr(start, mCurrent - mText.begin() - start));
298 }
299
300 bool TextIterator::eraseFromStart()
301 {
302 if (mSave == mEnd) return false;
303 mCurrent = erase(mSave, mCurrent);
304 mSave = mEnd = mText.end();
305 return true;
306 }
307
308 void TextIterator::insertText(const UString& _insert, bool _multiLine)
309 {
310 UString text = _insert;
311
312 normaliseNewLine(text);
313
314 if (!_multiLine)
315 clearNewLine(text);
316
317 insert(mCurrent, text.asUTF32());
318 }
319
320 void TextIterator::setText(const UString& _text, bool _multiLine)
321 {
322 // сначала все очищаем
323 clear();
324
325 // а теперь вставляем
326 UString text = _text;
327
328 // нормализуем
329 normaliseNewLine(text);
330
331 if (!_multiLine)
332 clearNewLine(text);
333
334 insert(mCurrent, text.asUTF32());
335 }
336
337 UString TextIterator::getTextCharInfo(Char _char)
338 {
339 if (_char == L'#') return L"##";
340 wchar_t buff[16] = L"_\0";
341 buff[0] = (wchar_t)_char;
342 return buff;
343 }
344
345 UString TextIterator::convertTagColour(const Colour& _colour)
346 {
347 const size_t SIZE = 16;
348 wchar_t buff[SIZE];
349//FIXME
350#ifdef __MINGW32__
351 swprintf(buff, L"#%.2X%.2X%.2X\0", (int)(_colour.red * 255), (int)(_colour.green * 255), (int)(_colour.blue * 255));
352#else
353 swprintf(buff, SIZE, L"#%.2X%.2X%.2X\0", (int)(_colour.red * 255), (int)(_colour.green * 255), (int)(_colour.blue * 255));
354#endif
355 return buff;
356 }
357
358 UString TextIterator::toTagsString(const UString& _text)
359 {
360 // преобразуем в строку с тегами
361 UString text(_text);
362 for (UString::iterator iter = text.begin(); iter != text.end(); iter.moveNext())
363 {
364 // потом переделать через TextIterator чтобы отвязать понятие тег от эдита
365 if (L'#' == (*iter)) iter = text.insert(iter.moveNext(), L'#');
366 }
367 return text;
368 }
369
370 void TextIterator::insert(UString::utf32string::iterator& _start, const UString::utf32string& _insert)
371 {
372 // сбрасываем размер
373 mSize = ITEM_NONE;
374 // записываем в историю
375 if (mHistory) mHistory->push_back(TextCommandInfo(_insert, _start - mText.begin(), TextCommandInfo::COMMAND_INSERT));
376 // запоминаем позицию итератора
377 size_t pos = _start - mText.begin();
378 size_t pos_save = (mSave == mEnd) ? ITEM_NONE : _start - mText.begin();
379 // непосредственно вставляем
380 mText.insert(_start, _insert.begin(), _insert.end());
381 // возвращаем итераторы
382 _start = mText.begin() + pos;
383 mEnd = mText.end();
384 (pos_save == ITEM_NONE) ? mSave = mEnd : mSave = mText.begin() + pos_save;
385 }
386
387 UString::utf32string::iterator TextIterator::erase(UString::utf32string::iterator _start, UString::utf32string::iterator _end)
388 {
389 // сбрасываем размер
390 mSize = ITEM_NONE;
391 // сохраняем в историю
392 size_t start = _start - mText.begin();
393 if (mHistory) mHistory->push_back(TextCommandInfo(mText.substr(start, _end - _start), start, TextCommandInfo::COMMAND_ERASE));
394 // возвращаем итератор
395 return mText.erase(_start, _end);
396 }
397
398 void TextIterator::clear()
399 {
400 if (mText.empty()) return;
401
402 // записываем в историю
403 if (mHistory) mHistory->push_back(TextCommandInfo(mText, 0, TextCommandInfo::COMMAND_ERASE));
404
405 // все сбрасываем
406 mText.clear();
407 mCurrent = mText.begin();
408 mEnd = mSave = mText.end();
409 mSize = ITEM_NONE;
410 }
411
412 void TextIterator::cutMaxLength(size_t _max)
413 {
414 if ( (mSize != ITEM_NONE) && (mSize <= _max) ) return;
415 if (mPosition > _max)
416 {
417 // придется считать сначала
418 mSize = mPosition = 0;
419 mCurrent = mText.begin();
420 mEnd = mSave = mText.end();
421 }
422
423 mSize = mPosition;
424
425 for (UString::utf32string::iterator iter = mCurrent; iter != mEnd; ++iter)
426 {
427
428 if ((*iter) == L'#')
429 {
430 // следующий символ
431 ++ iter;
432 if (iter == mEnd) break;
433
434 // тэг цвета
435 if ((*iter) != L'#')
436 {
437 // остальные 5 символов цвета
438 for (size_t pos = 0; pos < 5; pos++)
439 {
440 ++ iter;
441 if (iter == mEnd)
442 {
443 -- iter;
444 break;
445 }
446 }
447 continue;
448 }
449 }
450
451 // проверяем и обрезаем
452 if (mSize == _max)
453 {
454 mPosition = mSize; // сохраняем
455 mCurrent = erase(iter, mEnd);
456 mSave = mEnd = mText.end();
457 mSize = mPosition; // восстанавливаем
458 return;
459 }
460
461 // увеличиваем
462 mSize ++;
463 }
464 }
465
466 void TextIterator::cutMaxLengthFromBeginning(size_t _max)
467 {
468 // узнаем размер без тегов
469 size_t size = getSize();
470 if (size <= _max) return;
471
472 // разница
473 size_t diff = size - _max;
474
475 // последний цвет
476 UString::utf32string::iterator iter_colour = mEnd;
477
478 // теперь пройдем от начала и узнаем реальную позицию разницы
479 UString::utf32string::iterator iter = mText.begin();
480 for (; iter != mEnd; ++iter)
481 {
482 if ((*iter) == L'#')
483 {
484 UString::utf32string::iterator save = iter;
485
486 // следующий символ
487 ++ iter;
488 if (iter == mEnd) break;
489
490 // тэг цвета
491 if ((*iter) != L'#')
492 {
493 // остальные 5 символов цвета
494 for (size_t pos = 0; pos < 5; pos++)
495 {
496 ++ iter;
497 if (iter == mEnd)
498 {
499 -- iter;
500 break;
501 }
502 }
503 // сохраняем цвет
504 iter_colour = save;
505 }
506 continue;
507 }
508 // обычный символ был
509 if (diff == 0) break;
510 -- diff;
511 }
512
513 UString::utf32string colour;
514 // если бы цвет, то вставляем назад
515 if (iter_colour != mEnd)
516 {
517 colour.append(iter_colour, iter_colour + size_t(7));
518 }
519
520 mCurrent = erase(mText.begin(), iter);
521 mEnd = mText.end();
522 mSave = mText.end(); //FIXME
523 mPosition = 0;
524 mSize = _max;
525
526 if ( ! colour.empty() ) setTagColour(colour);
527
528 }
529
530 void TextIterator::clearTagColour()
531 {
532 if (mCurrent == mEnd) return;
533
534 UString::utf32string::iterator iter = mCurrent;
535 UString colour;
536 // нам нужен последний цвет
537 while (getTagColour(colour, iter))
538 {
539 // обязательно обновляем итераторы
540 iter = mCurrent = erase(mCurrent, iter);
541 mEnd = mText.end();
542 }
543 }
544
545 size_t TextIterator::getPosition() const
546 {
547 return mPosition;
548 }
549
550 UString TextIterator::getText() const
551 {
552 return UString(mText);
553 }
554
555 void TextIterator::clearText()
556 {
557 clear();
558 }
559
560 UString TextIterator::getTextNewLine()
561 {
562 return L"\n";
563 }
564
565 void TextIterator::normaliseNewLine(UString& _text)
566 {
567 for (size_t index = 0; index < _text.size(); ++index)
568 {
569 Char character = _text[index];
570 if ((character == FontCodeType::CR) &&
571 ((index + 1) < _text.size()) &&
572 (_text[index + 1] == FontCodeType::LF))
573 {
574 _text.erase(index, 1);
575 }
576 }
577 }
578
579} // namespace MyGUI
MyGUI_Precompiled.h
MyGUI_TextIterator.h
MyGUI::TextIterator::eraseFromStart
bool eraseFromStart()
Definition MyGUI_TextIterator.cpp:300
MyGUI::TextIterator::getOnlyText
static UString getOnlyText(const UString &_text)
Definition MyGUI_TextIterator.cpp:205
MyGUI::TextIterator::clearTagColour
void clearTagColour()
Definition MyGUI_TextIterator.cpp:530
MyGUI::TextIterator::clearNewLine
void clearNewLine(UString &_text)
Definition MyGUI_TextIterator.cpp:272
MyGUI::TextIterator::getText
UString getText() const
Definition MyGUI_TextIterator.cpp:550
MyGUI::TextIterator::getTextNewLine
static UString getTextNewLine()
Definition MyGUI_TextIterator.cpp:560
MyGUI::TextIterator::getTextCharInfo
static UString getTextCharInfo(Char _char)
Definition MyGUI_TextIterator.cpp:337
MyGUI::TextIterator::cutMaxLength
void cutMaxLength(size_t _max)
Definition MyGUI_TextIterator.cpp:412
MyGUI::TextIterator::setTagColour
bool setTagColour(const Colour &_colour)
Definition MyGUI_TextIterator.cpp:126
MyGUI::TextIterator::moveNext
bool moveNext()
Definition MyGUI_TextIterator.cpp:33
MyGUI::TextIterator::getFromStart
UString getFromStart() const
Definition MyGUI_TextIterator.cpp:293
MyGUI::TextIterator::convertTagColour
static UString convertTagColour(const Colour &_colour)
Definition MyGUI_TextIterator.cpp:345
MyGUI::TextIterator::clearText
void clearText()
Definition MyGUI_TextIterator.cpp:555
MyGUI::TextIterator::saveStartPoint
bool saveStartPoint()
Definition MyGUI_TextIterator.cpp:286
MyGUI::TextIterator::toTagsString
static UString toTagsString(const UString &_text)
Definition MyGUI_TextIterator.cpp:358
MyGUI::TextIterator::cutMaxLengthFromBeginning
void cutMaxLengthFromBeginning(size_t _max)
Definition MyGUI_TextIterator.cpp:466
MyGUI::TextIterator::setText
void setText(const UString &_text, bool _multiLine)
Definition MyGUI_TextIterator.cpp:320
MyGUI::TextIterator::getPosition
size_t getPosition() const
Definition MyGUI_TextIterator.cpp:545
MyGUI::TextIterator::getSize
size_t getSize() const
Definition MyGUI_TextIterator.cpp:166
MyGUI::TextIterator::insertText
void insertText(const UString &_insert, bool _multiLine)
Definition MyGUI_TextIterator.cpp:308
MyGUI::TextIterator::getTagColour
bool getTagColour(UString &_colour) const
Definition MyGUI_TextIterator.cpp:110
MyGUI::UString::_fwd_iterator
forward iterator for UString
Definition MyGUI_UString.h:224
MyGUI::UString::_fwd_iterator::moveNext
_fwd_iterator & moveNext()
advances to the next Unicode character, honoring surrogate pairs in the UTF-16 stream
Definition MyGUI_UString.cpp:192
MyGUI::UString
A UTF-16 string with implicit conversion to/from std::string and std::wstring.
Definition MyGUI_UString.h:145
MyGUI::UString::insert
iterator insert(iterator i, const code_point &ch)
inserts ch before the code point denoted by i
Definition MyGUI_UString.cpp:1062
MyGUI::UString::size
size_type size() const
Returns the number of code points in the current string.
Definition MyGUI_UString.cpp:592
MyGUI::UString::asUTF32
const utf32string & asUTF32() const
returns the current string in UTF-32 form within a utf32string
Definition MyGUI_UString.cpp:715
MyGUI::UString::utf32string
std::basic_string< unicode_char > utf32string
string type used for returning UTF-32 formatted data
Definition MyGUI_UString.h:178
MyGUI::UString::erase
iterator erase(iterator loc)
removes the code point pointed to by loc, returning an iterator to the next character
Definition MyGUI_UString.cpp:1175
MyGUI::UString::end
iterator end()
returns an iterator just past the end of the string
Definition MyGUI_UString.cpp:809
MyGUI::UString::npos
static const size_type npos
the usual constant representing: not found, no limit, etc
Definition MyGUI_UString.h:164
MyGUI::UString::begin
iterator begin()
returns an iterator to the first element of the string
Definition MyGUI_UString.cpp:793
MyGUI::FontCodeType::CR
@ CR
Definition MyGUI_FontData.h:23
MyGUI::FontCodeType::NEL
@ NEL
Definition MyGUI_FontData.h:25
MyGUI::FontCodeType::Space
@ Space
Definition MyGUI_FontData.h:24
MyGUI::FontCodeType::LF
@ LF
Definition MyGUI_FontData.h:22
MyGUI
Definition MyGUI_ActionController.h:15
MyGUI::VectorChangeInfo
std::vector< TextCommandInfo > VectorChangeInfo
Definition MyGUI_TextChangeHistory.h:58
MyGUI::Char
unsigned int Char
Definition MyGUI_Types.h:50
MyGUI::ITEM_NONE
const size_t ITEM_NONE
Definition MyGUI_Macros.h:18
MyGUI::Colour
Definition MyGUI_Colour.h:17
MyGUI::Colour::green
float green
Definition MyGUI_Colour.h:51
MyGUI::Colour::blue
float blue
Definition MyGUI_Colour.h:52
MyGUI::Colour::red
float red
Definition MyGUI_Colour.h:50
MyGUI::TextCommandInfo
Definition MyGUI_TextChangeHistory.h:20
MyGUI::TextCommandInfo::COMMAND_INSERT
@ COMMAND_INSERT
Definition MyGUI_TextChangeHistory.h:24
MyGUI::TextCommandInfo::COMMAND_ERASE
@ COMMAND_ERASE
Definition MyGUI_TextChangeHistory.h:25