Займемся ее реализацией.
void LexerZ::styleText(int start, int end)
{
//editor() - функция из родительского класса.
//Возвращает указатель на QsciScintilla
if (!editor())
return;
//получить исходник
//выделим кусок памяти
// +1 - под \0
char * chars = new char[end - start + 1];
//заполним кусок обратившись сцинтилле
editor()->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE,
start, end, chars);
//преобразуем в строку
QString source(chars);
delete [] chars;
//Оптимизация - кэшируем уже ранее отрисованную строку
if (source == cache)
return;
else
cache = source;
//Не работаем с пустой строкой
if (source.isEmpty())
return;
//вызываем функцию отрисовки комментария
//передаем исходную строку, начало и конец
commentStyling(source, start, end);
}
* This source code was highlighted with Source Code Highlighter.
В комментариях описано, что мы делаем в этой функции. Здесь мы получаем строку, которую требуется отрисовать (это может быть не только текущая строка, а в том числе и соседние строки, сцинтилла в этом плане довольно умна).
Дальше вызываем функцию commentStyling(source, start, end);
Ее реализация приведена ниже:
bool LexerZ::commentStyling(const QString & line, int start, int end)
{
//Если в строке вообще нет символов комментария, то ничего не делать
if (!line.contains("**"))
return false;
//Определяем сколько раз встречаются комменты (они могут быть в середине строки, или же line - это может быть на самом деле несколько строк)
int count = line.count("**");
int style = Comment;
int idxStart = 0;
int idxEnd = idxStart;
//Обрабатываем каждый символ комментария
for (int i = 0; i < count; i++)
{
idxStart = line.indexOf("**", idxStart);
if (idxStart == -1)
break;
int pos = line.indexOf("\r", idxStart);
if (pos != -1)
{
idxEnd = pos;
}
else
{
idxEnd = idxStart + line.mid(idxStart).size();
}
//Здесь мы сообщаем, что начинаем новый стиль
//с позиции start + idxStart
startStyling(start + idxStart);
int len = idxEnd - idxStart;
//А здесь мы сообщаем, что начиная от текущей позиции, определенной startStyling,
//дальше последуют len символов стиля style == Comment
setStyling(len, style);
//Заканчиваем отрисовку стиля
startStyling(start + idxEnd);
idxStart = idxEnd;
}
return true;
}
* This source code was highlighted with Source Code Highlighter.
Итак, здесь нужно уяснить основной прицип. Сначала мы сообщаем сцинтилле, что с позиции
start + idxStart начнется новый стиль. idxStart это собственно индекс, которого начинается комментарий в текущей строке line.
Дальше мы вычисляем сколько символов занимает коммент. Он может длиться до конца строки, определяемого символом \r. Длина коммента хранится в переменной len.
Затем сообщаем сцинтилле, что len символов это коммент : setStyling(len, style);
Получив такое указание, сцинтилла начнет дергать виртуальные функции, которые мы определяли в предыдущем посте, с параметром style. Вот почему я говорил ранее, что название констант и их числовое значение особого смысла не имеют. Мы их сами определяли.
И, наконец, сцинтилле надо сообщить, что стиль закончился startStyling(start + idxEnd);
На этом я закрываю цикл статей о QScintilla.
Если вспомню вдруг что интересное - выложу.
Комментариев нет:
Отправить комментарий