MyGUI 3.2.0

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

- File List
- Globals

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