From 1cd1e521c3dc7bf13209fc2840dc6077dd4f7543 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sat, 9 Sep 2017 22:03:17 +0200 Subject: [PATCH] Wrong UTF-8 string length fixed when attaching to FString --- ChangeLog | 3 ++ src/ffiledialog.cpp | 12 ++++---- src/flistview.cpp | 29 ++++++++++++------ src/fmenubar.cpp | 30 +++++++++--------- src/fonts/bdf2c.sh | 8 ++--- src/fonts/font2c.sh | 6 ++-- src/fstring.cpp | 2 +- src/fterm.cpp | 16 +++++----- src/fvterm.cpp | 2 +- src/fwindow.cpp | 2 +- test/string-operations.cpp | 62 +++++++++++++++++++------------------- test/windows.cpp | 4 +-- 12 files changed, 94 insertions(+), 82 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab9bee17..6a5096e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2017-09-09 Markus Gans + * Wrong UTF-8 string length fixed when attaching to FString + 2017-09-07 Markus Gans * Type definition exported into a separate header file diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index c7b56994..8a245f44 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -735,8 +735,8 @@ int FFileDialog::changeDir (const FString& dirname) //---------------------------------------------------------------------- void FFileDialog::printPath (const FString& txt) { - FString path = txt; - uInt max_width = uInt(filebrowser->getWidth()) - 4; + const FString& path = txt; + const uInt max_width = uInt(filebrowser->getWidth()) - 4; if ( path.getLength() > max_width ) filebrowser->setText(".." + path.right(max_width - 2)); @@ -773,7 +773,7 @@ void FFileDialog::cb_processActivate (FWidget*, data_ptr) if ( ! dir_entries.empty() ) { std::vector::const_iterator iter, end; - FString input = filename->getText().trim(); + const FString& input = filename->getText().trim(); iter = dir_entries.begin(); end = dir_entries.end(); @@ -800,12 +800,12 @@ void FFileDialog::cb_processActivate (FWidget*, data_ptr) //---------------------------------------------------------------------- void FFileDialog::cb_processRowChanged (FWidget*, data_ptr) { - int n = filebrowser->currentItem(); + const int n = filebrowser->currentItem(); if ( n == 0 ) return; - FString name = dir_entries[uLong(n - 1)].name; + const FString& name = dir_entries[uLong(n - 1)].name; if ( dir_entries[uLong(n - 1)].type == DT_DIR ) filename->setText( name + '/' ); @@ -818,7 +818,7 @@ void FFileDialog::cb_processRowChanged (FWidget*, data_ptr) //---------------------------------------------------------------------- void FFileDialog::cb_processClicked (FWidget*, data_ptr) { - uLong n = uLong(filebrowser->currentItem() - 1); + const uLong n = uLong(filebrowser->currentItem() - 1); if ( dir_entries[n].type == DT_DIR ) changeDir(dir_entries[n].name); diff --git a/src/flistview.cpp b/src/flistview.cpp index 973b5c33..2219d08c 100644 --- a/src/flistview.cpp +++ b/src/flistview.cpp @@ -156,9 +156,9 @@ void FListViewItem::setText (int column, const FString& text) //---------------------------------------------------------------------- void FListViewItem::insert (FListViewItem* child) { - // Add a FListViewItem as child element - if ( ! child || ! hasChildren() ) - return; + // Add a FListViewItem as child element + if ( ! child || ! hasChildren() ) + return; addChild (child); expandable = true; @@ -190,8 +190,8 @@ int FListViewItem::getVisibleLines() if ( ! isExpand() || ! hasChildren() ) { - visible_lines = 1; - return visible_lines; + visible_lines = 1; + return visible_lines; } FObjectList children = this->getChildren(); @@ -354,7 +354,6 @@ void FListView::insert (FListViewItem* item) { int width = (*iter).width; bool fixed_width = (*iter).fixed_width; - FString text = (*iter).name; if ( ! fixed_width ) { @@ -1129,7 +1128,7 @@ void FListView::drawColumnLabels() while ( iter != header.end() ) { - FString text = (*iter).name; + const FString& text = (*iter).name; int width = (*iter).width; int column_width; @@ -1158,8 +1157,8 @@ void FListView::drawColumnLabels() if ( txt_length + tailing_space < uInt(column_width) ) { setColor(); - FString line ( uInt(column_width) - tailing_space - txt_length - , wchar_t(fc::BoxDrawingsHorizontal) ); + const FString line ( uInt(column_width) - tailing_space - txt_length + , wchar_t(fc::BoxDrawingsHorizontal) ); headerline << line; // horizontal line } } @@ -1254,6 +1253,11 @@ void FListView::drawList() // print the entry FString line = " "; + if ( tree_view /*&& (*iter)->expandable*/ ) + { + line += "► "; + } + // print columns if ( ! (*iter)->column_value.empty() ) { @@ -1261,7 +1265,8 @@ void FListView::drawList() { static const int leading_space = 1; static const int ellipsis_length = 2; - FString text = (*iter)->column_value[i]; + + const FString& text = (*iter)->column_value[i]; int width = header[i].width; uInt txt_length = text.getLength(); // Increment the value of i for the column position @@ -1270,23 +1275,27 @@ void FListView::drawList() fc::text_alignment align = getColumnAlignment(int(i)); uInt align_offset = getAlignOffset (align, txt_length, uInt(width)); + // Insert alignment spaces if ( align_offset > 0 ) line += FString(align_offset, ' '); if ( align_offset + txt_length <= uInt(width) ) { + // Insert text and tailing space line += text.left(width); line += FString ( leading_space + width - int(align_offset + txt_length), ' '); } else if ( align == fc::alignRight ) { + // Ellipse right align text line += FString (".."); line += text.right(width - ellipsis_length); line += ' '; } else { + // Ellipse left align text and center text line += text.left(width - ellipsis_length); line += FString (".. "); } diff --git a/src/fmenubar.cpp b/src/fmenubar.cpp index 8fd89f2b..29d33884 100644 --- a/src/fmenubar.cpp +++ b/src/fmenubar.cpp @@ -682,25 +682,25 @@ bool FMenuBar::hotkeyMenu (FKeyEvent*& ev) if ( (*iter)->hasMenu() ) { - FMenuItem* first_item; - FMenu* menu = (*iter)->getMenu(); - (*iter)->setSelected(); - setSelectedItem(*iter); - (*iter)->setFocus(); - (*iter)->openMenu(); - menu->selectFirstItem(); - first_item = menu->getSelectedItem(); + FMenuItem* first_item; + FMenu* menu = (*iter)->getMenu(); + (*iter)->setSelected(); + setSelectedItem(*iter); + (*iter)->setFocus(); + (*iter)->openMenu(); + menu->selectFirstItem(); + first_item = menu->getSelectedItem(); - if ( first_item ) - first_item->setFocus(); + if ( first_item ) + first_item->setFocus(); - menu->redraw(); + menu->redraw(); - if ( getStatusBar() ) - getStatusBar()->drawMessage(); + if ( getStatusBar() ) + getStatusBar()->drawMessage(); - redraw(); - drop_down = true; + redraw(); + drop_down = true; } else { diff --git a/src/fonts/bdf2c.sh b/src/fonts/bdf2c.sh index f983cc3b..9e39bfb2 100755 --- a/src/fonts/bdf2c.sh +++ b/src/fonts/bdf2c.sh @@ -5,10 +5,10 @@ HEIGHT=16 FONTFILE="8x16graph.bdf" ( - echo -e "// newfont.h\n" + echo -e "// newfont.h\\n" echo -e "#ifndef FNEWFONT_H" - echo -e "#define FNEWFONT_H\n" - echo -e "\nstatic unsigned char __8x16graph[] =\n{" + echo -e "#define FNEWFONT_H\\n" + echo -e "\\nstatic unsigned char __8x16graph[] =\\n{" grep -A${HEIGHT} ^BITMAP "$FONTFILE" \ | tr '\n' ',' \ @@ -26,6 +26,6 @@ FONTFILE="8x16graph.bdf" done echo -e "};" - echo -e "\n#endif // FNEWFONT_H" + echo -e "\\n#endif // FNEWFONT_H" ) > newfont.h diff --git a/src/fonts/font2c.sh b/src/fonts/font2c.sh index 49e37d01..1a38d074 100755 --- a/src/fonts/font2c.sh +++ b/src/fonts/font2c.sh @@ -5,9 +5,9 @@ HEIGHT=16 FONTFILE="8x16std" ( - echo -e "// vgafont.h\n" + echo -e "// vgafont.h\\n" echo -e "#ifndef FVGAFONT_H" - echo -e "#define FVGAFONT_H\n" + echo -e "#define FVGAFONT_H\\n" xxd -g 1 -i -c $HEIGHT $FONTFILE \ | sed -e 's/ {$/\n{/' \ @@ -24,5 +24,5 @@ FONTFILE="8x16std" fi done - echo -e "\n#endif // FVGAFONT_H" + echo -e "\\n#endif // FVGAFONT_H" ) > vgafont.h diff --git a/src/fstring.cpp b/src/fstring.cpp index 9068d99b..40e8acd1 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -354,7 +354,7 @@ const FString& FString::operator += (const char* s) if ( wc_string ) { - _insert (length, uInt(std::strlen(s)), wc_string); + _insert (length, uInt(std::wcslen(wc_string)), wc_string); delete[] wc_string; } diff --git a/src/fterm.cpp b/src/fterm.cpp index f5c6d0bd..ff7be6cf 100644 --- a/src/fterm.cpp +++ b/src/fterm.cpp @@ -451,13 +451,13 @@ int FTerm::parseKeyString ( char buffer[] // SGR mouse tracking if ( buffer[1] == '[' && buffer[2] == '<' && buf_len >= 9 && (buffer[buf_len - 1] == 'M' || buffer[buf_len - 1] == 'm') ) - return fc::Fkey_extended_mouse; + return fc::Fkey_extended_mouse; // urxvt mouse tracking if ( buffer[1] == '[' && buffer[2] >= '1' && buffer[2] <= '9' && buffer[3] >= '0' && buffer[3] <= '9' && buf_len >= 9 && buffer[buf_len - 1] == 'M' ) - return fc::Fkey_urxvt_mouse; + return fc::Fkey_urxvt_mouse; // look for termcap keys for (int i = 0; Fkey[i].tname[0] != 0; i++) @@ -655,7 +655,7 @@ bool FTerm::setNewFont() pc_charset_console = true; Encoding = fc::PC; - if ( xterm_terminal && utf8_console ) + if ( xterm_terminal && utf8_console ) Fputchar = &FTerm::putchar_UTF8; else Fputchar = &FTerm::putchar_ASCII; @@ -1271,7 +1271,7 @@ void FTerm::resetXTermDefaults() //---------------------------------------------------------------------- void FTerm::saveColorMap() { - // ioctl (0, GIO_CMAP, &color_map); + //ioctl (0, GIO_CMAP, &color_map); } //---------------------------------------------------------------------- @@ -1688,7 +1688,7 @@ void FTerm::initLinuxConsoleCharMap() || charEncode(c2, fc::PC) == charEncode(c2, fc::ASCII) || charEncode(c3, fc::PC) == charEncode(c3, fc::ASCII) ) { - no_shadow_character = true; + no_shadow_character = true; } c4 = fc::RightHalfBlock; @@ -1697,7 +1697,7 @@ void FTerm::initLinuxConsoleCharMap() if ( charEncode(c4, fc::PC) == charEncode(c4, fc::ASCII) || charEncode(c5, fc::PC) == charEncode(c5, fc::ASCII) ) { - no_half_block_character = true; + no_half_block_character = true; } } #endif @@ -2661,7 +2661,7 @@ char* FTerm::parseAnswerbackMsg (char*& current_termtype) return 0; } - if ( *answer_back == FString("PuTTY") ) + if ( *answer_back == "PuTTY" ) { putty_terminal = true; @@ -2726,7 +2726,7 @@ char* FTerm::parseSecDA (char*& current_termtype) if ( num_components >= 2 ) { - FString* sec_da_components = &sec_da_split[0]; + const FString* sec_da_components = &sec_da_split[0]; if ( ! sec_da_components[0].isEmpty() ) { diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 21ff90ed..c6ce5198 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -2509,7 +2509,7 @@ void FVTerm::updateTerminalLine (uInt y) print_char->attr.bit.printed = true; // skip character with no changes - if ( print_char->attr.bit.no_changes ) + if ( print_char->attr.bit.no_changes ) { uInt count = 1; diff --git a/src/fwindow.cpp b/src/fwindow.cpp index e028d52c..b6d08754 100644 --- a/src/fwindow.cpp +++ b/src/fwindow.cpp @@ -727,7 +727,7 @@ void FWindow::switchToPrevWindow() break; } } - while ( iter != begin ); + while ( iter != begin ); } } diff --git a/test/string-operations.cpp b/test/string-operations.cpp index fc3a6588..dca7d116 100644 --- a/test/string-operations.cpp +++ b/test/string-operations.cpp @@ -34,91 +34,91 @@ int main (int, char**) std::cout << " instream >> " << in << std::endl; // Test: output stream (operator <<) - FString out = L"A test string for 0 \x20ac"; + const FString& out = L"A test string for 0 \x20ac"; std::cout << " outstream << " << out << std::endl; // Test: c-string output printf (" c_str: \"%s\"\n", out.c_str()); // Test: copy a c++ string - FString cpp_str( std::string("c++ String") ); + const FString& cpp_str( std::string("c++ String") ); std::cout << " cpp_str: \"" << cpp_str << "\"" << std::endl; // Test: copy a character - FString ch('c'); + const FString& ch('c'); std::cout << " char: '" << ch << "'" << std::endl; // Test: copy a wide character - FString wch(L'w'); + const FString& wch(L'w'); std::cout << " wchar_t: '" << wch << "'" << std::endl; // Test: utf-8 string - FString len = "длина́"; + const FString& len = "длина́"; std::cout << " length: \"" << len << "\" has " << len.getLength() << " characters" << std::endl; // Test: convert uppercase letter to lowercase - FString lower = FString(L"InPut").toLower(); + const FString& lower = FString(L"InPut").toLower(); std::wcout << L" toLower: " << lower << std::endl; // Test: convert lowercase letter to uppercase - FString upper = FString("inPut").toUpper(); + const FString& upper = FString("inPut").toUpper(); std::cout << " toUpper: " << upper << std::endl; // Test: concatenate two FStrings (operator +) - FString add1 = FString("FString + ") + FString("FString"); + const FString& add1 = FString("FString + ") + FString("FString"); std::cout << " add: " << add1 << std::endl; // Test: concatenate a FString and a c++ wide string (operator +) - FString add2 = FString("FString + ") + std::wstring(L"std::wstring"); + const FString& add2 = FString("FString + ") + std::wstring(L"std::wstring"); std::cout << " add: " << add2 << std::endl; // Test: concatenate a FString and a wide string (operator +) - FString add3 = FString("FString + ") + const_cast(L"wchar_t*"); + const FString& add3 = FString("FString + ") + const_cast(L"wchar_t*"); std::cout << " add: " << add3 << std::endl; // Test: concatenate a FString and a c++ string (operator +) - FString add4 = FString("FString + ") + std::string("std::string"); + const FString& add4 = FString("FString + ") + std::string("std::string"); std::cout << " add: " << add4 << std::endl; // Test: concatenate a FString and a c-string (operator +) - FString add5 = FString("FString + ") + const_cast("char*"); + const FString& add5 = FString("FString + ") + const_cast("char*"); std::cout << " add: " << add5 << std::endl; // Test: concatenate a FString and a wide character (operator +) - FString add6 = FString("FString + ") + wchar_t(L'w'); + const FString& add6 = FString("FString + ") + wchar_t(L'w'); std::cout << " add: " << add6 << std::endl; // Test: concatenate a FString and a character (operator +) - FString add7 = FString("FString + ") + char('c'); + const FString& add7 = FString("FString + ") + char('c'); std::cout << " add: " << add7 << std::endl; // Test: concatenate a character and a FString (operator +) - FString add8 = 'c' + FString(" + FString"); + const FString& add8 = 'c' + FString(" + FString"); std::cout << " add: " << add8 << std::endl; // Test: concatenate a wide character and a FString (operator +) - FString add9 = L'w' + FString(" + FString"); + const FString& add9 = L'w' + FString(" + FString"); std::cout << " add: " << add9 << std::endl; // Test: concatenate a c-string and a FString (operator +) - FString add10 = const_cast("char*") + FString(" + FString"); + const FString& add10 = const_cast("char*") + FString(" + FString"); std::cout << " add: " << add10 << std::endl; // Test: concatenate a c++ string and a FString (operator +) - FString add11 = std::string("std::string") + FString(" + FString"); + const FString& add11 = std::string("std::string") + FString(" + FString"); std::cout << " add: " << add11 << std::endl; // Test: concatenate a wide string and a FString (operator +) - FString add12 = const_cast(L"wchar_t*") + FString(" + FString"); + const FString& add12 = const_cast(L"wchar_t*") + FString(" + FString"); std::cout << " add: " << add12 << std::endl; // Test: concatenate a c++ wide string and a FString (operator +) - FString add13 = std::wstring(L"std::wstring") + FString(" + FString"); + const FString& add13 = std::wstring(L"std::wstring") + FString(" + FString"); std::cout << " add: " << add13 << std::endl; // Test: compare operators ==, <=, <, >=, >, != - FString cmp = "compare"; + const FString& cmp = "compare"; if ( cmp == FString("compare") ) std::cout << " cmp: == Ok" << std::endl; @@ -172,7 +172,7 @@ int main (int, char**) // Test: convert a string to a unsigned long interger try { - uLong ulong_num = FString("123456789").toULong(); + const uLong ulong_num = FString("123456789").toULong(); std::cout << " toULong: " << ulong_num << std::endl; } catch (const std::invalid_argument& ex) @@ -187,7 +187,7 @@ int main (int, char**) // Test: convert a string to a signed long interger try { - long long_num = FString("-9876543210").toLong(); + const long long_num = FString("-9876543210").toLong(); std::cout << " toLong: " << long_num << std::endl; } catch (const std::invalid_argument& ex) @@ -204,7 +204,7 @@ int main (int, char**) try { - double double_num = FString("2.7182818284590452353").toDouble(); + const double double_num = FString("2.7182818284590452353").toDouble(); std::ios_base::fmtflags save_flags = std::cout.flags(); std::cout << " toDouble: " << std::setprecision(11) << double_num << std::endl; @@ -249,7 +249,7 @@ int main (int, char**) << fnum2 << " (signed)" << std::endl; // Test: remove whitespace from the end of a string - FString trim_str = " A string \t"; + const FString& trim_str = " A string \t"; std::wcout << " rtrim: \"" << trim_str.rtrim() << "\"" << std::endl; @@ -262,7 +262,7 @@ int main (int, char**) << trim_str.trim() << "\"" << std::endl; // Test: 11 characters from the left of the string - FString alphabet = "a b c d e f g h i j k l m n o p q r s t u v w x y z"; + const FString& alphabet = "a b c d e f g h i j k l m n o p q r s t u v w x y z"; std::cout << " left: \"" << alphabet.left(11) << "\"" << std::endl; @@ -304,7 +304,7 @@ int main (int, char**) } // Test: character access with std::iterator - FString stringIterator = "iterator"; + const FString& stringIterator = "iterator"; FString::iterator iter; iter = stringIterator.begin(); std::cout << " " << stringIterator << ": "; @@ -353,22 +353,22 @@ int main (int, char**) // Test: find and replace a substring FString source_str = "computer and software"; - FString replace_str = source_str.replace("computer", "hard-"); + const FString& replace_str = source_str.replace("computer", "hard-"); std::cout << " replace: " << replace_str << std::endl; // Test: convert tabs to spaces - FString tab_str = "1234\t5678"; + const FString& tab_str = "1234\t5678"; std::cout << " tab: " << tab_str.expandTabs() << std::endl; // Test: backspaces remove characters in the string - FString bs_str = "t\b\bTesT\bt"; + const FString& bs_str = "t\b\bTesT\bt"; std::cout << "backspace: " << bs_str.removeBackspaces() << std::endl; // Test: delete characters remove characters in the string - FString del_str = "apple \177\177\177pietree"; + const FString& del_str = "apple \177\177\177pietree"; std::cout << " delete: " << del_str.removeDel() << std::endl; } diff --git a/test/windows.cpp b/test/windows.cpp index ff77f751..566dcf50 100644 --- a/test/windows.cpp +++ b/test/windows.cpp @@ -75,13 +75,13 @@ smallWindow::smallWindow (FWidget* parent) right_arrow->ignorePadding(); right_arrow->setGeometry (getWidth() - 1, 2, 1, 1); - FString top_left_label_text = "menu"; + const FString& top_left_label_text = "menu"; top_left_label = new FLabel (top_left_label_text, this); top_left_label->setForegroundColor (wc.label_inactive_fg); top_left_label->setEmphasis(); top_left_label->setGeometry (1, 1, 6, 1); - FString top_right_label_text = "zoom"; + const FString& top_right_label_text = "zoom"; top_right_label = new FLabel (top_right_label_text, this); top_right_label->setAlignment (fc::alignRight); top_right_label->setForegroundColor (wc.label_inactive_fg);