wxWidgets / wxStyledTextCtrl — выделяет все вхождения при двойном нажатии

Я использую wxWidgets 3.0.2 в статической сборке Unicode в Windows 10. Я использую wxStyledTextCtrl, который является возле 1-к-1 картирование сцинтиллы.

Я ищу функциональность, аналогичную Notepad ++, где при двойном щелчке чего-либо в редакторе все вхождения этого элемента выделяются. Трудно найти хорошие примеры, которые действительно демонстрируют стиль. Я просмотрел документацию по wxWidgets, документацию по Scintilla, исходный код Notepad ++ и исходный код Code :: Blocks (последние два используют Scintilla в качестве текстовых редакторов) и до сих пор не особо повезло.

Я пробовал много разных вариантов следующего кода, и он никогда не работал правильно. Либо ничего не выделено, либо весь документ выделен. Я знаю, что что-то упустил, но не могу понять, что.

//textarea is a wxStyledTextCtrl*
textarea->StyleSetBackground(styleHightlightAllSelected, wxColor(80, 255, 80));

wxString selectedText = textarea->GetSelectedText();
int selSize  = selectedText.size();
int selStart = textarea->GetSelectionStart();

int pos    = 0;
int curr   = 0;
int maxPos = textarea->GetLastPosition();
while(pos != -1){
pos = textarea->FindText(curr, maxPos, selectedText);
if(pos == selStart){ //skip the actual highlighted item
curr = pos + selSize;
} else if(pos != -1){
textarea->StartStyling(pos, 0x1F);
textarea->SetStyling(selSize, styleHightlightAllSelected);
curr = pos + selSize;
}
}

Поисковая часть цикла успешно находит выделенный текст; просто стиль, похоже, не закрепился.

Итак, мои вопросы, на которые я не мог найти ответы:

  1. styleHightlightAllSelected является int установить на 100. Когда у меня было это 0, весь документ стал зеленым при двойном щелчке. Я вижу, что стили 32-39 предопределены. Существуют ли другие стили, которые предопределены, но не действительно документированы; то есть 100 нормально?
  2. Нужно ли настраивать весь стиль или я могу просто установить цвет фона, как я делал выше?
  3. Достаточно ли сделать StartStyling() а также SetStyling() когда я нахожу происшествие и покончу с ним, или есть что-то еще?
  4. StartStyling() в wxWidgets есть аргумент-маска, а в Scintilla — нет. Я не могу четко определить, что я должен установить это. Вроде бы 31 (00011111) чтобы сохранить 5 существующих стилей / лексеров? По сути, я не уверен, что установить, если все, что я хочу сделать, это изменить цвет фона каждого вхождения.
  5. Моя программа будет регулярно обрабатывать файлы размером в десятки и более мегабайт, поэтому я должен просто выделять видимые события и корректировать их при необходимости при прокрутке / прыжке? В данный момент он выполняет поиск и (не может) устанавливать стили для каждого вхождения, и это занимает около секунды для файла размером 50 МБ. Я заметил, что в том же файле, загруженном в Notepad ++, это происходит мгновенно, поэтому я предполагаю, что это происходит на видимой основе?

0

Решение

В итоге я спросил об этом на странице проблем github для проекта Notepad ++, и правильный способ сделать это — не использовать стили, а вместо этого использовать индикаторы. Так что мой код выше меняется на это:

int maxPos = textarea->GetLastPosition();

textarea->IndicatorClearRange(0, maxPos);
textarea->IndicatorSetStyle(styleHightlightAllSelected, wxSTC_INDIC_ROUNDBOX);
textarea->IndicatorSetAlpha(styleHightlightAllSelected, 100);
textarea->IndicatorSetUnder(styleHightlightAllSelected, true);
textarea->IndicatorSetForeground(styleHightlightAllSelected, wxColor(0, 255, 0));

wxString selectedText = textarea->GetSelectedText();
int selSize  = selectedText.size();
int selStart = textarea->GetSelectionStart();

int pos    = 0;
int curr   = 0;
vector<int> selectionList;
while((pos = textarea->FindText(curr, maxPos, selectedText)) != -1){
selectionList.push_back(pos);
curr = pos + selSize;
}

textarea->SetIndicatorCurrent(styleHightlightAllSelected);
for(unsigned int i = 0; i < selectionList.size(); i++){
if(selectionList[i] != selStart){
textarea->IndicatorFillRange(selectionList[i], selSize);
}
}

Однако это не учитывает только выделение видимого диапазона и только выделение новых вхождений по мере их прокрутки (теперь я добавлю это позже), поэтому для файлов размером в десятки мегабайт это займет 2-3 секунды. для выделения, чтобы закончить.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]