diff --git a/ChangeLog b/ChangeLog index 6e9981ad..ea0511b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2017-09-19 Markus Gans + * FString has now got its own streaming functionality for + inbound and outbound type conversion + 2017-09-19 Markus Gans * The command line help text is now available in all applications diff --git a/README.md b/README.md index d51259b5..c27f92ae 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ The Final Cut ============= -The Final Cut is a class library and widget toolkit with full mouse support for creating a [text-based user interface](https://en.wikipedia.org/wiki/Text-based_user_interface). The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple windows on the screen. -The C++ class design was inspired by the Qt framework. It provides common controls like dialog windows, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on. +The Final Cut is a C++ class library and widget toolkit with full mouse support for creating a [text-based user interface](https://en.wikipedia.org/wiki/Text-based_user_interface). The library supports the programmer to develop an application for the text console. It allows the simultaneous handling of multiple text windows on the screen. +The C++ class design was inspired by the Qt framework. It provides common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on. ![](doc/fileopen-dialog.png) diff --git a/doc/readme.txt b/doc/readme.txt index 066405be..66ffe493 100644 --- a/doc/readme.txt +++ b/doc/readme.txt @@ -2,12 +2,12 @@ The Final Cut ---------------------------------------------------------------------- -The Final Cut is a class library and widget toolkit with full mouse +The Final Cut is a C++ class library and widget toolkit with full mouse support for creating a text-based user interface. The library supports the programmer to develop an application for the text console. It allows -the simultaneous handling of multiple windows on the screen. +the simultaneous handling of multiple text windows on the screen. The C++ class design was inspired by the Qt framework. It provides -common controls like dialog windows, push buttons, check boxes, +common controls like dialog boxes, push buttons, check boxes, radio buttons, input lines, list boxes, status bars and so on. diff --git a/examples/listbox.cpp b/examples/listbox.cpp index 00a747bc..286a975f 100644 --- a/examples/listbox.cpp +++ b/examples/listbox.cpp @@ -26,7 +26,7 @@ void doubleToItem (FListBoxItem& item, FWidget::data_ptr container, int index) double_list_ptr dbllist = static_cast(container); std::list::iterator iter = dbllist->begin(); std::advance (iter, index); - item.setText (FString().setNumber(*iter)); + item.setText (FString() << *iter); item.setData (FWidget::data_ptr(&(*iter))); } diff --git a/examples/string-operations.cpp b/examples/string-operations.cpp index 8cee6a4d..f5fe0ba6 100644 --- a/examples/string-operations.cpp +++ b/examples/string-operations.cpp @@ -32,13 +32,118 @@ int main (int, char**) // Test: input stream (operator >>) FString in; - std::cout << " Input: "; std::cin >> in; + std::cout << " Input: "; + std::cin >> in; std::cout << " instream >> " << in << std::endl; // Test: output stream (operator <<) const FString& out = L"A test string for 0 \x20ac"; std::cout << " outstream << " << out << std::endl; + // Test: Streaming into a FString (operator <<)... + + // ...from FStrings + FString streamer1; + streamer1 << FString("FStr") << FString("ing"); + std::cout << " stream in: " << streamer1 << std::endl; + + // ...from c++ wide string + FString streamer2; + streamer2 << std::wstring(L"std::wstring"); + std::cout << " stream in: " << streamer2 << std::endl; + + // ...from wide string + FString streamer3; + streamer3 << const_cast(L"wchar_t*"); + std::cout << " stream in: " << streamer3 << std::endl; + + // ...from c++ string + FString streamer4; + streamer4 << std::string("std::string"); + std::cout << " stream in: " << streamer4 << std::endl; + + // ...from c-string + FString streamer5; + streamer5 << const_cast("char*"); + std::cout << " stream in: " << streamer5 << std::endl; + + // ...from wide character + FString streamer6; + streamer6 << wchar_t(L'w'); + std::cout << " stream in: " << streamer6 << std::endl; + + // ...from character + FString streamer7; + streamer7 << char('c'); + std::cout << " stream in: " << streamer7 << std::endl; + + // ...from interger + FString streamer8; + streamer8 << int(-12345); + std::cout << " stream in: " << streamer8 << std::endl; + + // ...from unsigned interger + FString streamer9; + streamer9 << uInt(54321); + std::cout << " stream in: " << streamer9 << std::endl; + + // ...from long double + FString streamer10; + streamer10 << lDouble(0.333333333333333333L); + std::cout << " stream in: " << streamer10 << std::endl; + + // ...from double + FString streamer11; + streamer11 << double(0.11111111111); + std::cout << " stream in: " << streamer11 << std::endl; + + // ...from float + FString streamer12; + streamer12 << float(0.22222222); + std::cout << " stream in: " << streamer12 << std::endl; + + // Test: Streaming from a FString (operator >>)... + + // ...to FStrings + FString stream_fstring; + FString("FString") >> stream_fstring; + std::cout << "stream out: " << stream_fstring << std::endl; + + // ...to c++ wide string + std::wstring stream_wstring; + FString("std::wstring") >> stream_wstring; + std::wcout << "stream out: " << stream_wstring << std::endl; + + // ...to wide character + wchar_t stream_wchar_t = 0; + FString("w") >> stream_wchar_t; + std::wcout << "stream out: " << stream_wchar_t << std::endl; + + // ...to character + char stream_char; + FString('c') >> stream_char; + std::cout << "stream out: " << stream_char << std::endl; + + // ...to interger + int stream_int; + FString("-321") >> stream_int; + std::cout << "stream out: " << stream_int << std::endl; + + // ...to unsigned interger + uInt stream_uint; + FString("123") >> stream_uint; + std::cout << "stream out: " << stream_uint << std::endl; + + // ...to double + double stream_double; + FString("0.123456e+2") >> stream_double; + std::cout << "stream out: " << stream_double << std::endl; + + // ...to float + float stream_float; + FString("0.123e-3") >> stream_float; + std::cout << "stream out: " << stream_float << std::endl; + // Test: c-string output printf (" c_str: \"%s\"\n", out.c_str()); diff --git a/examples/ui.cpp b/examples/ui.cpp index fa2a903a..59ada30e 100644 --- a/examples/ui.cpp +++ b/examples/ui.cpp @@ -511,7 +511,7 @@ MyDialog::MyDialog (FWidget* parent) myList->setMultiSelection(); for (int z = 1; z < 100; z++) - myList->insert (FString().setNumber(z) + L" placeholder"); + myList->insert (FString() << z << L" placeholder"); // Text labels FLabel* headline = new FLabel (this); @@ -693,12 +693,13 @@ void MyDialog::cb_terminfo (FWidget*, data_ptr) int x = getColumnNumber(); int y = getLineNumber(); FMessageBox info1 ( "Environment" - , " Type: " + FString(getTermType()) + "\n" - " Name: " + FString(getTermName()) + "\n" - " Mode: " + FString(getEncoding()) + "\n" - " Size: " + FString().setNumber(x) + wchar_t(fc::Times) - + FString().setNumber(y) + "\n" - "Colors: " + FString().setNumber(getMaxColor()) + , FString() + << " Type: " << getTermType() << "\n" + << " Name: " << getTermName() << "\n" + << " Mode: " << getEncoding() << "\n" + << " Size: " << x << wchar_t(fc::Times) + << y << "\n" + << "Colors: " << getMaxColor() , FMessageBox::Ok, 0, 0, this ); info1.setHeadline("Terminal:"); info1.exec(); diff --git a/include/final/fstring.h b/include/final/fstring.h index cc029f69..4e9d7958 100644 --- a/include/final/fstring.h +++ b/include/final/fstring.h @@ -88,6 +88,32 @@ class FString const FString operator + (const wchar_t); const FString operator + (const char); + FString& operator << (const FString&); + FString& operator << (const wchar_t); + FString& operator << (const char); + FString& operator << (const sInt16); + FString& operator << (const uInt16); + FString& operator << (const int); + FString& operator << (const uInt); + FString& operator << (const long); + FString& operator << (const uLong); + FString& operator << (const float); + FString& operator << (const double); + FString& operator << (const lDouble); + + const FString& operator >> (FString&); + const FString& operator >> (std::wstring&); + const FString& operator >> (wchar_t&); + const FString& operator >> (char&); + const FString& operator >> (sInt16&); + const FString& operator >> (uInt16&); + const FString& operator >> (int&); + const FString& operator >> (uInt&); + const FString& operator >> (long&); + const FString& operator >> (uLong&); + const FString& operator >> (double&); + const FString& operator >> (float&); + wchar_t& operator [] (int); wchar_t& operator [] (uInt); const FString& operator () (); @@ -138,11 +164,6 @@ class FString operator const char* () const { return c_str(); } // Non-member operators - friend std::ostream& operator << (std::ostream& outstr, const FString& s); - friend std::istream& operator >> (std::istream& instr, FString& s); - friend std::wostream& operator << (std::wostream& outstr, const FString& s); - friend std::wistream& operator >> (std::wistream& instr, FString& s); - friend const FString operator + (const FString&, const FString&); friend const FString operator + (const FString&, const wchar_t); friend const FString operator + (const std::wstring&, const FString&); @@ -154,6 +175,11 @@ class FString friend const FString operator + (const wchar_t, const std::wstring&); friend const FString operator + (const FString&, const char); + friend std::ostream& operator << (std::ostream& outstr, const FString& s); + friend std::istream& operator >> (std::istream& instr, FString& s); + friend std::wostream& operator << (std::wostream& outstr, const FString& s); + friend std::wistream& operator >> (std::wistream& instr, FString& s); + // inquiries bool isNull() const; bool isEmpty() const; @@ -221,9 +247,9 @@ class FString FString& setNumber (uInt); FString& setNumber (long); FString& setNumber (uLong); - FString& setNumber (float, int = 8); - FString& setNumber (double, int = 11); - FString& setNumber (lDouble, int = 11); + FString& setNumber (float, int = FLT_DIG); + FString& setNumber (double, int = DBL_DIG); + FString& setNumber (lDouble, int = LDBL_DIG); FString& setFormatedNumber (sInt16, char = nl_langinfo(THOUSEP)[0]); FString& setFormatedNumber (uInt16, char = nl_langinfo(THOUSEP)[0]); diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 3a60e666..41f23b79 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -298,7 +298,7 @@ void FListBox::insert ( long item , bool s , data_ptr d ) { - insert (FString().setNumber(item), b, s, d); + insert (FString() << item, b, s, d); } //---------------------------------------------------------------------- diff --git a/src/fmessagebox.cpp b/src/fmessagebox.cpp index 952cb6ca..a65a5adb 100644 --- a/src/fmessagebox.cpp +++ b/src/fmessagebox.cpp @@ -205,7 +205,7 @@ int FMessageBox::info ( FWidget* parent try { mbox = new FMessageBox ( caption - , FString().setNumber(num) + , FString() << num , button0, button1, button2 , parent ); } diff --git a/src/fstring.cpp b/src/fstring.cpp index cbd053f6..9f4b049f 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -458,6 +458,186 @@ const FString FString::operator + (const char c) return tmp; } +//---------------------------------------------------------------------- +FString& FString::operator << (const FString& s) +{ + _insert (length, s.length, s.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const wchar_t c) +{ + FString s = FString(c); + _insert (length, s.length, s.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const char c) +{ + FString s = FString(c); + _insert (length, s.length, s.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const sInt16 num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const uInt16 num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const int num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const uInt num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const long num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const uLong num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const float num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const double num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +FString& FString::operator << (const lDouble num) +{ + FString numstr = FString().setNumber(num); + _insert (length, numstr.length, numstr.string); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (FString& s) +{ + s._insert (s.length, length, string); + _assign(s.string); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (std::wstring& s) +{ + s += std::wstring(string); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (wchar_t& c) +{ + c = ( length > 0 ) ? string[0] : L'\0'; + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (char& c) +{ + c = ( length > 0 ) ? char(string[0] & 0xff) : '\0'; + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (sInt16& num) +{ + num = toShort(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (uInt16& num) +{ + num = toUShort(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (int& num) +{ + num = toInt(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (uInt& num) +{ + num = toUInt(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (long& num) +{ + num = toLong(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (uLong& num) +{ + num = toULong(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (double& num) +{ + num = toDouble(); + return *this; +} + +//---------------------------------------------------------------------- +const FString& FString::operator >> (float& num) +{ + num = toFloat(); + return *this; +} + //---------------------------------------------------------------------- wchar_t& FString::operator [] (int pos) { @@ -1076,27 +1256,33 @@ FString& FString::setNumber (uLong num) //---------------------------------------------------------------------- FString& FString::setNumber (lDouble num, int precision) { - register wchar_t *s; + register wchar_t* s; wchar_t format[20]; // = "%.Lg" s = &format[0]; *s++ = L'%'; *s++ = L'.'; + // The precision can not have more than 2 digits if ( precision > 99 ) precision = 99; if ( precision >= 10 ) { + // The precision value is 2 digits long *s++ = precision / 10 + L'0'; *s++ = precision % 10 + L'0'; } else + { + // The precision value has only 1 digit *s++ = precision + L'0'; + } *s++ = L'L'; *s++ = L'g'; - *s = L'\0'; + *s = L'\0'; + return sprintf(format, num); } @@ -2534,51 +2720,6 @@ inline wchar_t* FString::extractToken ( wchar_t** rest // FString non-member operators -//---------------------------------------------------------------------- -std::ostream& operator << (std::ostream& outstr, const FString& s) -{ - if ( s.length ) - outstr << s.wc_to_c_str( s.string ); - - return outstr; -} - -//---------------------------------------------------------------------- -std::istream& operator >> (std::istream& instr, FString& s) -{ - const wchar_t* wc_str; - char buf[FString::INPBUFFER + 1]; - - instr.getline (buf, FString::INPBUFFER); - wc_str = s.c_to_wc_str(buf); - - if ( wc_str ) - { - s._assign (wc_str); - delete[] wc_str; - } - - return instr; -} - -//---------------------------------------------------------------------- -std::wostream& operator << (std::wostream& outstr, const FString& s) -{ - if ( s.length ) - outstr << s.string; - - return outstr; -} - -//---------------------------------------------------------------------- -std::wistream& operator >> (std::wistream& instr, FString& s) -{ - wchar_t buf[FString::INPBUFFER + 1]; - instr.getline (buf, FString::INPBUFFER); - s._assign (buf); - return instr; -} - //---------------------------------------------------------------------- const FString operator + (const FString& s1, const FString& s2) { @@ -2671,3 +2812,48 @@ const FString operator + (const FString& s, const char c) tmp1._insert (s.length, 1, tmp2); return tmp1; } + +//---------------------------------------------------------------------- +std::ostream& operator << (std::ostream& outstr, const FString& s) +{ + if ( s.length ) + outstr << s.wc_to_c_str( s.string ); + + return outstr; +} + +//---------------------------------------------------------------------- +std::istream& operator >> (std::istream& instr, FString& s) +{ + const wchar_t* wc_str; + char buf[FString::INPBUFFER + 1]; + + instr.getline (buf, FString::INPBUFFER); + wc_str = s.c_to_wc_str(buf); + + if ( wc_str ) + { + s._assign (wc_str); + delete[] wc_str; + } + + return instr; +} + +//---------------------------------------------------------------------- +std::wostream& operator << (std::wostream& outstr, const FString& s) +{ + if ( s.length ) + outstr << s.string; + + return outstr; +} + +//---------------------------------------------------------------------- +std::wistream& operator >> (std::wistream& instr, FString& s) +{ + wchar_t buf[FString::INPBUFFER + 1]; + instr.getline (buf, FString::INPBUFFER); + s._assign (buf); + return instr; +}