Задача: есть wxTextCtrl, пользователь должен уметь загружать в него свои текстовые файлы для просмотра и редактирования, своего рода notepad. Файлы у пользователя могут быть в ANSI, utf-8 и в одном из двух юникодов.
Есть wxTextCtrl::LoadFile() - думаю зашибись, повезло. Тестирую, юникод\утф-8 грузит, ANSI грузит только если там одни английские символы, если есть русские обламывается. Нахожу? что проблема в дебрях библиотеки, в попытке грузить файл как wxFFile::ReadAll(wxString * str, wxMBConv& conv = wxConvUTF8)
Спрашиваю в wx-dev@, вот ответ
TN> Is this a bug? If no, is there a any way to load ANSI files in unicode
TN> build?
Yes, use wxCSConv(wxFONTENCODING_CP1251) instead of default wxConvAuto
which only handles UTF-x encodings in 2.8 (in the trunk it falls back to
the system default encoding if the input doesn't seem to be in UTF-8, but
not in 2.8).
Баг это или нет, я так и не понял. Но понял что wxTextCtrl::LoadFile() использовать нельзя, так как кодировку там задать нет возможности. Пришлось использовать напрямую wxFFile, с шаманством. Вот функция для загрузки файла
bool BegUtils::ReadFileToString(const wxString & FileName, wxString & Data)
{
wxFFile file(FileName);
if (!file.IsOpened() ) return false;
// пытаемся читать файл подразумевая что он юникодный
if (!file.ReadAll(&Data)) return false;
if (Data.IsEmpty() && file.Length()>0)
{ // Если строка пустая и длина у файла есть - то он наверняка был анси, читаем как анси
file.Seek(0);
if (!file.ReadAll(&Data, *wxConvCurrent)) return false;
}
return true;
}
Вроде как работает, правда будут проблемы при загрузки пустых юникодных файлов - на экране будет мусор (BOM), можно конечно проверять загруженную строку на равенство одному из них, но я забил.
Подозреваю что это довольно кривой метод, поэтому если кто знает как решить задачу "правильно", с удовольствием послушаю.
5 комментариев:
Николай, что-то у меня в Опере в этой записи некоторое строки отображаются некорректно, в частности строка "Баг это или нет, я так и не понял. Но понял что wxTextCtrl::Load" здесь и заканчивается. В Firefox отображается корректно.
Может быть, там тэг где-нибудь незакрытый?
Да, похоже что WLW не идеал:( вроде подправил. Так нормально?
Ага, сейчас, вроде, все нормально.
Спасибо.
а что скажешь про такое извращение ? )))
это если файл внутри виртуальной файловой системы ...
wxString MainFrame::OpenFileToString(wxString location)
{
wxFileSystem fs;
wxFSFile *fsfile = fs.OpenFile(location);
wxInputStream *stream = fsfile->GetStream();
wxTextInputStream text ( *stream);
wxString result;
while (!stream->Eof())
{
result += wxString(text.ReadLine() + wxT("\n"));
}
return result;
}
А чего говорить, вроде нормально все, извращением не пахнет:)
Я правда с виртуальной фс не работал, да и с потокоми не очень.
Отправить комментарий