wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице Topic is solved

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

Всем привет.
Спрашивал в англоязычном сегменте, но никто не знает.
Метод wxStyledTextCtrl::Remove не до конца удаляет необходимый текст не кириллице.

Code: Select all

//текст который ищем, берём из обычного wxTextCtrl
wxString valDel = m_textCtrlDelText2->GetValue();
int valDelLen = valDel.Len();

//здесь начинаем работать с wxStyledTextCtrl
// Устанавливаем юникод
m_styledTextCtrl->SetCodePage(wxSTC_CP_UTF8); 

int docLength = m_styledTextCtrl->GetLastPosition(); //Длина документа

//Ищем в документе нужный текст
int valPos = m_styledTextCtrl->FindText(0, docLength, valDel, wxSTC_FIND_MATCHCASE); 

//Удаляем найденный текст
m_styledTextCtrl->Remove(valPos, valPos+valDelLen); 
С литиницей никаких проблем нет, а вот с кириллицей начинаются проблемы.
Если текст состоит например из 4-х букв (например "руб.") то удаляется только две буквы.
Т.е. после вызова m_styledTextCtrl->Remove(valPos, valPos+valDelLen); слово "руб." превращается
в "б.", т.е. удалились только первые две буквы "ру".
С латиницей такой проблемы нет.
wxTextCtrl в многострочном режиме, прекрасно справляется, глюк только с wxStyledText.
Понятно, что проблема повидимому с Юникодом.
Ни на форуме, ни в рассылке wx-users ничего подобного не нашёл.
Чё за хрень? Второй день не могу побороть.

ОС: Xubutnu 20.04
wx: 3.0.4 и 3.1.4
Kvaz1r
Super wx Problem Solver
Super wx Problem Solver
Posts: 357
Joined: Tue Jun 07, 2016 1:07 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Kvaz1r »

Привет. Если в англоязычном разделе никто не знает, то тут тем более не подскажут.
Если предоставите минимальный воспроизводимый пример, то попробую протестировать под виндой.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

Kvaz1r wrote: Tue Sep 07, 2021 9:12 pm Привет. Если в англоязычном разделе никто не знает, то тут тем более не подскажут.
Если предоставите минимальный воспроизводимый пример, то попробую протестировать под виндой.
Минимальный воспроизводимый пример, который можно скопировать и скомпилировать.

Code: Select all

#include <wx/app.h>
#include <wx/frame.h>
#include <wx/button.h>
#include <wx/stc/stc.h>

#define wxID_BUTTON_1 1000

class MyFrame : public wxFrame
{
    wxButton *m_button1;
    wxStyledTextCtrl *m_styledTextCtrl;
    wxString m_stVal;

public:
    MyFrame(wxWindow *parent, int id = wxID_ANY, wxString title = wxT("wxStyledTextCtrl Bug"), wxPoint pos = wxPoint(200,200), wxSize siz = wxSize(600,400) ) : wxFrame(parent, id, title, pos, siz)
    {
        m_button1 = new wxButton( this, wxID_BUTTON_1, wxT("Button1"), wxPoint(10,10), wxSize(80,35), 0 );
        this->Bind( wxEVT_BUTTON, &MyFrame::OnButton1Click, this, wxID_BUTTON_1 );

        m_stVal = "Здравствуй большой мир!"; //Текст в wxStyledTextCtrl в котором будем искать нужное слово

        m_styledTextCtrl = new wxStyledTextCtrl( this, wxID_ANY, wxPoint(0,60), wxSize(580,300), 0, wxEmptyString );
        m_styledTextCtrl->SetCodePage(wxSTC_CP_UTF8); //Устанавливаем кодировку Юникод (UTF-8)
        m_styledTextCtrl->SetValue(m_stVal);

    }

    virtual void OnButton1Click( wxCommandEvent& event )
    {
        wxString findText = "большой"; //Искомое слово, которое нужно удалить в wxStyledTextCtrl

        int findValLen = findText.Len(); //Длина искомого слова

        int docLength = m_styledTextCtrl->GetTextLength(); //Длина всего документа загруженного в wxStyledTextCtrl

        int valPos = m_styledTextCtrl->FindText(0, docLength, findText, wxSTC_FIND_MATCHCASE); //Ищем нужное слово в wxStyledTextCtrl

        m_styledTextCtrl->Remove(valPos, valPos+findValLen); //Удаляем найденное слово в wxStyledTextCtrl

    }

    ~MyFrame(){}
};

class MyApp : public wxApp
{
    wxLocale m_local;
public:
    virtual bool OnInit()
    {
        m_local.Init(wxLANGUAGE_RUSSIAN);
        MyFrame* frame = new MyFrame(0L);

        frame->Show(true);

        return true;

    }

};

wxIMPLEMENT_APP(MyApp);


Kvaz1r
Super wx Problem Solver
Super wx Problem Solver
Posts: 357
Joined: Tue Jun 07, 2016 1:07 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Kvaz1r »

Не уверен что это баг - в Юникоде (UTF8) одна буква может занимать несколько байт, а позиции могут отмерять как раз по байтам.
Я думаю, что в том числе для этого придумали крайний аргумент, используйте его и таких проблем не будет:

Code: Select all

        int to;
        int valPos = m_styledTextCtrl->FindText(0, docLength, findText, wxSTC_FIND_MATCHCASE, &to); //Ищем нужное слово в wxStyledTextCtrl
        m_styledTextCtrl->Remove(valPos, to); //Удаляем найденное слово в wxStyledTextCtrl
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

Kvaz1r wrote: Wed Sep 08, 2021 5:06 pm Не уверен что это баг - в Юникоде (UTF8) одна буква может занимать несколько байт, а позиции могут отмерять как раз по байтам.
Я думаю, что в том числе для этого придумали крайний аргумент, используйте его и таких проблем не будет:

Code: Select all

        int to;
        int valPos = m_styledTextCtrl->FindText(0, docLength, findText, wxSTC_FIND_MATCHCASE, &to); //Ищем нужное слово в wxStyledTextCtrl
        m_styledTextCtrl->Remove(valPos, to); //Удаляем найденное слово в wxStyledTextCtrl
Это какой-то заговор против метода int wxStyledTextCtrl::FindText :)))
В англоязычной ветке New Pagodi тоже советует метод FindText с 5-тью аргументами
viewtopic.php?f=1&t=48565&sid=b3c9f2f8d ... c1#p207985

в поиске по форуму я тоже кругом вижу метод с 5-тью аргументами.

Но когда пытаюсь скомпилировать, то получаю ошибку:
error: no matching function for call to ‘wxStyledTextCtrl::FindText(int, int&, wxString&, int, int*)’

Потому, что согласно документации, у этого метода 4-аргумента
https://docs.wxwidgets.org/3.0/classwx_ ... 2cbff84341

Не обижайте метод Find он хороший :))
Kvaz1r
Super wx Problem Solver
Super wx Problem Solver
Posts: 357
Joined: Tue Jun 07, 2016 1:07 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Kvaz1r »

Serge_N wrote: Wed Sep 08, 2021 7:34 pm Потому, что согласно документации, у этого метода 4-аргумента
https://docs.wxwidgets.org/3.0/classwx_ ... 2cbff84341

Не обижайте метод Find он хороший :))
Обновитесь, этот аргумент был добавлен в 3.1.1:
findEnd (Optional) This parameter can optionally be used to receive the end position (starting from zero) of the found text. This is primarily needed when searching using regular expressions. This parameter is available since wxWidgets 3.1.1.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

Kvaz1r wrote: Wed Sep 08, 2021 7:54 pm
Serge_N wrote: Wed Sep 08, 2021 7:34 pm Потому, что согласно документации, у этого метода 4-аргумента
https://docs.wxwidgets.org/3.0/classwx_ ... 2cbff84341

Не обижайте метод Find он хороший :))
Обновитесь, этот аргумент был добавлен в 3.1.1:
findEnd (Optional) This parameter can optionally be used to receive the end position (starting from zero) of the found text. This is primarily needed when searching using regular expressions. This parameter is available since wxWidgets 3.1.1.
Спасибо. Как раз разобрался. Хотел стандартную библиотеку из реп убунты, теперь придётся самосборную линковать статически.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by ONEEYEMAN »

Dobrogo vremeni sutok,
Pod *nix, NIKOGDA ne ispolzujte staticheskuju linkovku.

Dinamicheskaja - prosche i udobnee, a glavnoe - de-facto standart pod *nix.

Slishkom monogo nugno proverjat dlja togo chtoby rabotat so static library under *nix".

Spasibo.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

ONEEYEMAN wrote: Mon Sep 13, 2021 6:50 pm Dobrogo vremeni sutok,
Pod *nix, NIKOGDA ne ispolzujte staticheskuju linkovku.

Dinamicheskaja - prosche i udobnee, a glavnoe - de-facto standart pod *nix.

Slishkom monogo nugno proverjat dlja togo chtoby rabotat so static library under *nix".

Spasibo.
Ну вроде нормально работает, иначе тогда использовать соборку выше 3.1.1 не получится. В репозиториях убунты 20.04 есть только сборка 3.0.4.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by ONEEYEMAN »

Dobrogo vremeni sutok,
A zachem nugna staticheskaja sborka v *nix?

Eto g kakaja golovnaja bol - perekompilirovat vse prilogenie tolko dlja togo chtoby upgradenut kakuju-to odnu maljusenkuju biblioteku i pri etom ubit kluchu vremeni.
A samoe glavnoe - chto esli licensija pomenjaetsja u etoj biblioteki? Kak naprinmer u Qt - tolko v obratnuju storonu.

Poetomu staticheskaja linkovka "is frown upon in a *nuix world".

Spasibo.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

ONEEYEMAN wrote: Mon Sep 13, 2021 7:49 pm Dobrogo vremeni sutok,
A zachem nugna staticheskaja sborka v *nix?

Eto g kakaja golovnaja bol - perekompilirovat vse prilogenie tolko dlja togo chtoby upgradenut kakuju-to odnu maljusenkuju biblioteku i pri etom ubit kluchu vremeni.
A samoe glavnoe - chto esli licensija pomenjaetsja u etoj biblioteki? Kak naprinmer u Qt - tolko v obratnuju storonu.

Poetomu staticheskaja linkovka "is frown upon in a *nuix world".

Spasibo.
Да, но если версия библиотеки отличается от версии в репозиториях, то не имеет значения как она собрана, статически или динамически, она может одинаково создать проблемы совместимости.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by ONEEYEMAN »

Dobrogo vremeni sutok,
Net, ne moget.
Tak rabotaet dinamicheskij linker v *nix'e.

Spoasibo.
User avatar
cutecode
Super wx Problem Solver
Super wx Problem Solver
Posts: 425
Joined: Fri Dec 09, 2016 7:28 am
Contact:

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by cutecode »

я правда Remove не использовал, но зато у меня в кирилице FindText() ищет только если регистры букв совпадают, и это уже давно.
Уже несколько версий wx сменил, одно и тоже.

и code::blocks, тоже с.ка ищет только если регистры совпадают в Кирилице
wx 3.1.6 win/mac/linux

regards,
Alexander Saprykin
https://v2.dental-soft.ru
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7458
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by ONEEYEMAN »

Доброго времени суток,
А как работает native Scintilla?

Спасибо.
Serge_N
Knows some wx things
Knows some wx things
Posts: 40
Joined: Thu Apr 13, 2017 1:34 pm

Re: wxStyledTextCtrl::Remove - Не до конца удаляет текст на кириллице

Post by Serge_N »

cutecode wrote: Sat Sep 18, 2021 2:36 pm я правда Remove не использовал, но зато у меня в кирилице FindText() ищет только если регистры букв совпадают, и это уже давно.
Уже несколько версий wx сменил, одно и тоже.

и code::blocks, тоже с.ка ищет только если регистры совпадают в Кирилице
По всей видимости это нормальное поведение. Функция ищет то, что ей передали для поиска. Если нужно найти в другом регистре, то можно штатными средствами wxString изменить регистр и передать в FindText() изменённую строку. Если регистр зараннее не известен, то можно в условии if передать несколько вариантов для поиска раделённых ll (или).
Post Reply