From 112deadd169988ec02a7e2fc04805a0189947ad1 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 10 Dec 2015 00:24:31 +0800 Subject: [PATCH] elimiate nana::string for listbox --- include/nana/deploy.hpp | 25 ++- include/nana/gui/widgets/listbox.hpp | 65 ++++--- include/nana/system/dataexch.hpp | 22 ++- source/deploy.cpp | 58 ++++++- source/gui/programming_interface.cpp | 4 +- source/gui/widgets/categorize.cpp | 4 +- source/gui/widgets/combox.cpp | 4 +- source/gui/widgets/listbox.cpp | 250 +++++++++++++++++---------- source/gui/widgets/spinbox.cpp | 2 +- source/gui/widgets/textbox.cpp | 6 +- source/gui/widgets/widget.cpp | 6 +- source/system/dataexch.cpp | 140 +++++++++------ 12 files changed, 384 insertions(+), 202 deletions(-) diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 55f0441a..3d1fe4d0 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -102,6 +102,12 @@ namespace nana const std::wstring& to_wstring(const std::wstring& wstr); std::wstring&& to_wstring(std::wstring&& wstr); +#if defined(NANA_WINDOWS) + std::string to_osmbstr(const std::string& text_utf8); +#else + std::string to_osmbstr(std::string text_utf8) +#endif + namespace detail { @@ -113,16 +119,19 @@ namespace nana } #if defined(NANA_WINDOWS) - const detail::native_string_type to_native_string(const std::string&); - const detail::native_string_type& to_native_string(const std::wstring&); - detail::native_string_type to_native_string(int); - detail::native_string_type to_native_string(double); + const detail::native_string_type to_nstring(const std::string&); + const detail::native_string_type& to_nstring(const std::wstring&); + detail::native_string_type to_nstring(std::string&&); + detail::native_string_type&& to_nstring(std::wstring&&); #else //POSIX - const detail::native_string_type& to_native_string(const std::string&); - const detail::native_string_type to_native_string(const std::wstring&); - detail::native_string_type to_native_string(int); - detail::native_string_type to_native_string(double); + const detail::native_string_type& to_nstring(const std::string&); + const detail::native_string_type to_nstring(const std::wstring&); + detail::native_string_type&& to_nstring(std::string&&); + detail::native_string_type to_nstring(std::wstring&&); #endif + detail::native_string_type to_nstring(int); + detail::native_string_type to_nstring(double); + detail::native_string_type to_nstring(std::size_t); } #ifndef NANA_UNICODE diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 0a16a112..2b25d47b 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -31,6 +31,7 @@ namespace nana namespace listbox { using size_type = std::size_t; + using native_string_type = ::nana::detail::native_string_type; /// usefull for both absolute and display (sorted) positions struct index_pair @@ -81,7 +82,7 @@ namespace nana using selection = std::vector; - using inline_notifier_interface = detail::inline_widget_notifier_interface; + using inline_notifier_interface = detail::inline_widget_notifier_interface; struct cell { @@ -94,17 +95,17 @@ namespace nana format(const ::nana::color& bgcolor, const ::nana::color& fgcolor); }; - using format_ptr = std::unique_ptr < format > ; + using format_ptr = ::std::unique_ptr; - ::nana::string text; - format_ptr custom_format; + ::std::string text; + format_ptr custom_format; cell() = default; cell(const cell&); cell(cell&&); - cell(nana::string); - cell(nana::string, const format&); - cell(nana::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); + cell(::std::string); + cell(::std::string, const format&); + cell(::std::string, const ::nana::color& bgcolor, const ::nana::color& fgcolor); cell& operator=(const cell&); cell& operator=(cell&&); @@ -126,9 +127,9 @@ namespace nana oresolver& operator<<(double); oresolver& operator<<(long double); - oresolver& operator<<(const char*); + oresolver& operator<<(const char* text_utf8); oresolver& operator<<(const wchar_t*); - oresolver& operator<<(const std::string&); + oresolver& operator<<(const std::string& text_utf8); oresolver& operator<<(const std::wstring&); oresolver& operator<<(std::wstring&&); oresolver& operator<<(cell); @@ -157,7 +158,7 @@ namespace nana iresolver& operator>>(double&); iresolver& operator>>(long double&); - iresolver& operator>>(std::string&); + iresolver& operator>>(std::string& utf8_cast); iresolver& operator>>(std::wstring&); iresolver& operator>>(cell&); iresolver& operator>>(std::nullptr_t); @@ -241,8 +242,9 @@ namespace nana size_type columns() const; item_proxy& text(size_type col, cell); - item_proxy& text(size_type col, nana::string); - nana::string text(size_type col) const; + item_proxy& text(size_type col, std::string); + item_proxy& text(size_type col, std::wstring); + std::string text(size_type col) const; void icon(const nana::paint::image&); @@ -300,9 +302,10 @@ namespace nana } /// Behavior of Iterator's value_type - bool operator==(const nana::string& s) const; bool operator==(const char * s) const; bool operator==(const wchar_t * s) const; + bool operator==(const ::std::string& s) const; + bool operator==(const ::std::wstring& s) const; /// Behavior of Iterator item_proxy & operator=(const item_proxy&); @@ -375,18 +378,20 @@ namespace nana } /// Appends one item at the end of this category with the specifies text in the column fields - void append(std::initializer_list); + void append(std::initializer_list texts_utf8); + void append(std::initializer_list texts); size_type columns() const; - cat_proxy& text(nana::string); - nana::string text() const; + cat_proxy& text(std::string); + cat_proxy& text(std::wstring); + std::string text() const; cat_proxy & select(bool); bool selected() const; /// Behavior of a container - void push_back(nana::string); + void push_back(std::string text_utf8); item_proxy begin() const; item_proxy end() const; @@ -449,8 +454,8 @@ namespace nana struct export_options { - nana::string sep = nana::string {L"\t"}, - endl= nana::string {L"\n"}; + std::string sep = ::std::string {"\t"}, + endl= ::std::string {"\n"}; bool only_selected_items{true}, only_checked_items {false}, only_visible_columns{true}; @@ -510,16 +515,16 @@ By \a clicking on one header the list get \a reordered, first up, and then down and antisymmetry(comp(a, b) != comp(b, a) returns true) A simple example. - bool sort_compare( const nana::string& s1, nana::any*, - const nana::string& s2, nana::any*, bool reverse) + bool sort_compare( const std::string& s1, nana::any*, + const std::string& s2, nana::any*, bool reverse) { return (reverse ? s1 > s2 : s1 < s2); } listbox.set_sort_compare(0, sort_compare); The listbox supports attaching a customer's object for each item, therefore the items can be sorted by comparing these customer's object. - bool sort_compare( const nana::string&, nana::any* o1, - const nana::string&, nana::any* o2, bool reverse) + bool sort_compare( const std::string&, nana::any* o1, + const std::string&, nana::any* o2, bool reverse) { if(o1 && o2) //some items may not attach a customer object. { @@ -565,15 +570,19 @@ By \a clicking on one header the list get \a reordered, first up, and then down void scroll(bool to_bottom, const index_pair& pos); /// Appends a new column with a header text and the specified width at the end, and return it position - size_type append_header(nana::string header_text, unsigned width = 120); + size_type append_header(std::string text_utf8, unsigned width = 120); + size_type append_header(std::wstring text, unsigned width = 120); listbox& header_width(size_type position, unsigned pixels); unsigned header_width(size_type position) const; unsigned auto_width(size_type position, unsigned max=3000); - cat_proxy append(nana::string); ///< Appends a new category at the end - void append(std::initializer_list); ///< Appends categories at the end + cat_proxy append(std::string); ///< Appends a new category to the end + cat_proxy append(std::wstring); ///< Appends a new category to the end + void append(std::initializer_list); ///< Appends categories to the end + void append(std::initializer_list); ///< Appends categories to the end + cat_proxy insert(cat_proxy, ::std::string); cat_proxy insert(cat_proxy, ::std::wstring); cat_proxy at(size_type pos) const; @@ -639,8 +648,8 @@ By \a clicking on one header the list get \a reordered, first up, and then down void sortable(bool enable); ///Sets a strict weak ordering comparer for a column - void set_sort_compare(size_type col, std::function strick_ordering); + void set_sort_compare(size_type col, std::function strick_ordering); /// sort() and ivalidate any existing reference from display position to absolute item, that is: after sort() display offset point to different items void sort_col(size_type col, bool reverse = false); diff --git a/include/nana/system/dataexch.hpp b/include/nana/system/dataexch.hpp index ecfe9b22..575a79c3 100644 --- a/include/nana/system/dataexch.hpp +++ b/include/nana/system/dataexch.hpp @@ -1,6 +1,6 @@ /* * Data Exchanger Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -21,22 +21,26 @@ namespace paint{ } namespace system{ - /// a data exchange mechanism through Windows Clipboard, X11 Selection. + + /// a data exchange mechanism through Windows Clipboard, X11 Selection. class dataexch { public: - struct format + enum class format { - enum{ text, unicode, pixmap, end}; + text, pixmap }; - void set(const nana::char_t* text); - void set(const nana::string& text); + void set(const std::string & text_utf8); + void set(const std::wstring& text); + bool set(const nana::paint::graphics& g); - void get(nana::string& str); + + void get(std::string& text_utf8); + void get(std::wstring& text); private: - bool _m_set(unsigned type, const void* buf, std::size_t size); - void* _m_get(unsigned type, size_t& size); + bool _m_set(format, const void* buf, std::size_t size); + void* _m_get(format, size_t& size); }; }//end namespace system diff --git a/source/deploy.cpp b/source/deploy.cpp index 020ed92a..980ad5e9 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -508,42 +508,84 @@ namespace nana } #if defined(NANA_WINDOWS) - const detail::native_string_type to_native_string(const std::string& text) + std::string to_osmbstr(const std::string& text_utf8) + { + return ::nana::charset(text_utf8, ::nana::unicode::utf8); + } +#else + std::string to_osmbstr(std::string text_utf8) + { + return text_utf8; + } +#endif + +#if defined(NANA_WINDOWS) + const detail::native_string_type to_nstring(const std::string& text) { return ::nana::charset(text, ::nana::unicode::utf8); } - const detail::native_string_type& to_native_string(const std::wstring& text) + const detail::native_string_type& to_nstring(const std::wstring& text) { return text; } - detail::native_string_type to_native_string(int n) + detail::native_string_type to_nstring(std::string&& text) + { + return ::nana::charset(text, ::nana::unicode::utf8); + } + + detail::native_string_type&& to_nstring(std::wstring&& text) + { + return std::move(text); + } + + detail::native_string_type to_nstring(int n) { return std::to_wstring(n); } - detail::native_string_type to_native_string(double d) + detail::native_string_type to_nstring(double d) + { + return std::to_wstring(d); + } + + detail::native_string_type to_nstring(std::size_t d) { return std::to_wstring(d); } #else //POSIX - const detail::native_string_type& to_native_string(const std::string& text) + const detail::native_string_type& to_nstring(const std::string& text) { return text; } - const detail::native_string_type to_native_string(const std::wstring& text) + const detail::native_string_type to_nstring(const std::wstring& text) { return ::nana::charset(text).to_bytes(::nana::unicode::utf8); } - detail::native_string_type to_native_string(int n) + detail::native_string_type&& to_nstring(std::string&& text) + { + return std::move(text); + } + + detail::native_string_type to_nstring(std::wstring&& text) + { + return ::nana::charset(text).to_bytes(::nana::unicode::utf8); + } + + detail::native_string_type to_nstring(int n) { return std::to_string(n); } - detail::native_string_type to_native_string(double d) + detail::native_string_type to_nstring(double d) + { + return std::to_string(d); + } + + detail::native_string_type to_nstring(std::size_t d) { return std::to_string(d); } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 6f76bcbc..0888ab41 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -823,7 +823,7 @@ namespace API auto const iwd = reinterpret_cast(wd); internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) - iwd->widget_notifier->caption(to_native_string(title_utf8)); + iwd->widget_notifier->caption(to_nstring(title_utf8)); } void window_caption(window wd, const std::wstring& title) @@ -831,7 +831,7 @@ namespace API auto const iwd = reinterpret_cast(wd); internal_scope_guard lock; if (restrict::wd_manager().available(iwd)) - iwd->widget_notifier->caption(to_native_string(title)); + iwd->widget_notifier->caption(to_nstring(title)); } std::string window_caption(window wd) diff --git a/source/gui/widgets/categorize.cpp b/source/gui/widgets/categorize.cpp index 87075b69..eb68d29e 100644 --- a/source/gui/widgets/categorize.cpp +++ b/source/gui/widgets/categorize.cpp @@ -543,7 +543,7 @@ namespace nana { if(node) { - API::dev::window_caption(window_handle(), to_native_string(tree().path())); + API::dev::window_caption(window_handle(), to_nstring(tree().path())); if(evt_holder_.selected) evt_holder_.selected(node->value.second.value); } @@ -807,7 +807,7 @@ namespace nana { throw_not_utf8(str); scheme_->tree().insert(str, value); - API::dev::window_caption(scheme_->window_handle(), to_native_string(scheme_->tree().path())); + API::dev::window_caption(scheme_->window_handle(), to_nstring(scheme_->tree().path())); scheme_->draw(); } diff --git a/source/gui/widgets/combox.cpp b/source/gui/widgets/combox.cpp index ad1fa88c..18592de0 100644 --- a/source/gui/widgets/combox.cpp +++ b/source/gui/widgets/combox.cpp @@ -987,7 +987,7 @@ namespace nana internal_scope_guard lock; auto editor = _m_impl().editor(); if (editor) - return to_native_string(editor->text()); + return to_nstring(editor->text()); return native_string_type(); } @@ -997,7 +997,7 @@ namespace nana auto editor = _m_impl().editor(); if (editor) - editor->text(to_native_string(str)); + editor->text(to_nstring(str)); API::refresh_window(*this); } diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 6bad9fed..a433a759 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -52,16 +52,16 @@ namespace nana { } - cell::cell(nana::string text) + cell::cell(std::string text) : text(std::move(text)) {} - cell::cell(nana::string text, const format& fmt) + cell::cell(std::string text, const format& fmt) : text(std::move(text)), custom_format(new format{ fmt }) //make_unique {} - cell::cell(nana::string text, const ::nana::color& bgcolor, const ::nana::color& fgcolor) + cell::cell(std::string text, const ::nana::color& bgcolor, const ::nana::color& fgcolor) : text(std::move(text)), custom_format{ new format{ bgcolor, fgcolor } } //make_unique {} @@ -90,101 +90,101 @@ namespace nana //definition of iresolver/oresolver oresolver& oresolver::operator<<(bool n) { - cells_.emplace_back(n ? L"true" : L"false"); + cells_.emplace_back(n ? "true" : "false"); return *this; } oresolver& oresolver::operator<<(short n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(unsigned short n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(int n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(unsigned int n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(long n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(unsigned long n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(long long n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(unsigned long long n) { - cells_.emplace_back(std::to_wstring(n)); + cells_.emplace_back(std::to_string(n)); return *this; } oresolver& oresolver::operator<<(float f) { - cells_.emplace_back(std::to_wstring(f)); + cells_.emplace_back(std::to_string(f)); return *this; } oresolver& oresolver::operator<<(double f) { - cells_.emplace_back(std::to_wstring(f)); + cells_.emplace_back(std::to_string(f)); return *this; } oresolver& oresolver::operator<<(long double f) { - cells_.emplace_back(std::to_wstring(f)); + cells_.emplace_back(std::to_string(f)); return *this; } oresolver& oresolver::operator<<(const char* text) { - cells_.emplace_back(std::wstring(charset(text))); + cells_.emplace_back(text); return *this; } oresolver& oresolver::operator<<(const wchar_t* text) { - cells_.emplace_back(text); + cells_.emplace_back(utf8_cast(text)); return *this; } oresolver& oresolver::operator<<(const std::string& text) { - cells_.emplace_back(std::wstring(charset(text))); + cells_.emplace_back(text); return *this; } oresolver& oresolver::operator<<(const std::wstring& text) { - cells_.emplace_back(text); + cells_.emplace_back(utf8_cast(text)); return *this; } oresolver& oresolver::operator<<(std::wstring&& text) { - cells_.emplace_back(std::move(text)); + cells_.emplace_back(utf8_cast(text)); return *this; } @@ -291,14 +291,14 @@ namespace nana iresolver& iresolver::operator>>(std::string& text) { if (pos_ < cells_.size()) - text = charset(cells_[pos_++].text); + text = cells_[pos_++].text; return *this; } iresolver& iresolver::operator>>(std::wstring& text) { if (pos_ < cells_.size()) - text = cells_[pos_++].text; + text = utf8_cast(cells_[pos_++].text); return *this; } @@ -328,14 +328,14 @@ namespace nana struct column_t { - nana::string text; ///< "text" header of the column number "index" with weigth "pixels" + native_string_type text; ///< "text" header of the column number "index" with weigth "pixels" unsigned pixels; bool visible{true}; size_type index; - std::function weak_ordering; + std::function weak_ordering; column_t() = default; - column_t(nana::string&& txt, unsigned px, size_type pos) + column_t(native_string_type&& txt, unsigned px, size_type pos) : text(std::move(txt)), pixels(px), index(pos) {} }; @@ -353,9 +353,9 @@ namespace nana return idx; } - nana::string to_string(const export_options& exp_opt) const + std::string to_string(const export_options& exp_opt) const { - nana::string head_str; + std::string head_str; bool first{true}; for( size_type idx{}; idx fetch_comp(std::size_t pos) const + std::function fetch_comp(std::size_t pos) const { try { @@ -405,7 +405,7 @@ namespace nana return{}; } - size_type create(nana::string&& text, unsigned pixels) + size_type create(native_string_type&& text, unsigned pixels) { cont_.emplace_back(std::move(text), pixels, static_cast(cont_.size())); return cont_.back().index; @@ -604,13 +604,13 @@ namespace nana flags.selected = flags.checked = false; } - item_t(nana::string&& s) + item_t(std::string&& s) { flags.selected = flags.checked = false; cells.emplace_back(std::move(s)); } - item_t(nana::string&& s, const nana::color& bg, const nana::color& fg) + item_t(std::string&& s, const nana::color& bg, const nana::color& fg) : bgcolor(bg), fgcolor(fg) { @@ -632,9 +632,9 @@ namespace nana return *this; } - nana::string to_string(const export_options& exp_opt) const + std::string to_string(const export_options& exp_opt) const { - nana::string item_str; + std::string item_str; bool ignore_first = true; for (size_type idx{}; idx < exp_opt.columns_order.size(); ++idx) @@ -657,7 +657,7 @@ namespace nana { using container = std::deque; - ::nana::string text; + native_string_type text; std::vector sorted; container items; bool expand{true}; @@ -670,7 +670,7 @@ namespace nana category_t() = default; - category_t(nana::string str) + category_t(native_string_type str) :text(std::move(str)) {} @@ -689,8 +689,8 @@ namespace nana public: using container = std::list; - std::function(std::size_t) > fetch_ordering_comparer; + std::function(std::size_t) > fetch_ordering_comparer; es_lister() { @@ -727,7 +727,8 @@ namespace nana } return nullptr; } - nana::string to_string(const export_options& exp_opt) const; + + std::string to_string(const export_options& exp_opt) const; /// each sort() ivalidate any existing reference from display position to absolute item, that is after sort() display offset point to different items void sort() @@ -749,11 +750,11 @@ namespace nana auto & my = cat.items[y]; if (mx.cells.size() <= sorted_index_ || my.cells.size() <= sorted_index_) { - nana::string a; + std::string a; if (mx.cells.size() > sorted_index_) a = mx.cells[sorted_index_].text; - nana::string b; + std::string b; if (my.cells.size() > sorted_index_) b = my.cells[sorted_index_].text; @@ -774,11 +775,11 @@ namespace nana if (item_x.cells.size() <= sorted_index_ || item_y.cells.size() <= sorted_index_) { - nana::string a; + std::string a; if (item_x.cells.size() > sorted_index_) a = item_x.cells[sorted_index_].text; - nana::string b; + std::string b; if (item_y.cells.size() > sorted_index_) b = item_y.cells[sorted_index_].text; @@ -856,7 +857,7 @@ namespace nana void scroll(const index_pair& pos, bool to_bottom); ///Append a new category with a specified name and return a pointer to it. - category_t* create_cat(nana::string&& text) + category_t* create_cat(native_string_type&& text) { list_.emplace_back(std::move(text)); return &list_.back(); @@ -880,13 +881,13 @@ namespace nana return &list_.back(); } /// add a new cat created at "pos" and return a ref to it - category_t* create_cat(std::size_t pos, nana::string&& text) + category_t* create_cat(std::size_t pos, native_string_type&& text) { return &(*list_.emplace(this->get(pos), std::move(text))); } /// Insert before item in absolute "pos" a new item with "text" in column 0, and place it in last display position of this cat - bool insert(const index_pair& pos, nana::string&& text) + bool insert(const index_pair& pos, std::string&& text) { auto & catobj = *get(pos.cat); @@ -1094,7 +1095,7 @@ namespace nana } } - void text(category_t* cat, size_type pos, size_type col, nana::string&& str, size_type columns) + void text(category_t* cat, size_type pos, size_type col, std::string&& str, size_type columns) { if ((col < columns) && (pos < cat->items.size())) { @@ -1876,7 +1877,7 @@ namespace nana inline_indicator * indicator; index_pair item_pos; //The item index of the inline widget std::size_t column_pos; - ::nana::string text; + ::std::string text; //text in UTF-8 encoded }; std::map>> inline_table, inline_buffered_table; @@ -1888,7 +1889,7 @@ namespace nana lister.fetch_ordering_comparer = std::bind(&es_header::fetch_comp, &header, std::placeholders::_1); } - nana::string to_string(const export_options& exp_opt) const + std::string to_string(const export_options& exp_opt) const { return header.to_string(exp_opt) + exp_opt.endl + lister.to_string(exp_opt) ; } @@ -2359,7 +2360,7 @@ namespace nana }; class inline_indicator - : public ::nana::detail::inline_widget_indicator + : public ::nana::detail::inline_widget_indicator { public: using parts = essence_t::parts; @@ -2589,16 +2590,16 @@ namespace nana } } - nana::string es_lister::to_string(const export_options& exp_opt) const + std::string es_lister::to_string(const export_options& exp_opt) const { - nana::string list_str; + std::string list_str; bool first{true}; for(auto & cat: cat_container()) { if(first) first=false; else - list_str += (cat.text + exp_opt.endl); + list_str += (utf8_cast(cat.text) + exp_opt.endl); for (auto i : cat.sorted) { @@ -2978,7 +2979,7 @@ namespace nana graph->string({ x + 20, y + txtoff }, categ.text, txt_color); - ::nana::string str = L'(' + std::to_wstring(categ.items.size()) + L')'; + native_string_type str = L'(' + to_nstring(categ.items.size()) + L')'; auto text_s = graph->text_extent_size(categ.text).width; auto extend_text_w = text_s + graph->text_extent_size(str).width; @@ -3812,14 +3813,21 @@ namespace nana return *this; } - item_proxy& item_proxy::text(size_type col, nana::string str) + item_proxy& item_proxy::text(size_type col, std::string str) { ess_->lister.text(cat_, pos_.item, col, std::move(str), columns()); ess_->update(); return *this; } - nana::string item_proxy::text(size_type col) const + item_proxy& item_proxy::text(size_type col, std::wstring str) + { + ess_->lister.text(cat_, pos_.item, col, utf8_cast(str), columns()); + ess_->update(); + return *this; + } + + std::string item_proxy::text(size_type col) const { return ess_->lister.get_cells(cat_, pos_.item).at(col).text; } @@ -3839,20 +3847,24 @@ namespace nana //Behavior of Iterator's value_type - bool item_proxy::operator==(const nana::string& s) const - { - return (ess_->lister.get_cells(cat_, pos_.item).at(0).text == s); - } - bool item_proxy::operator==(const char * s) const { - return (ess_->lister.get_cells(cat_, pos_.item).at(0).text == nana::string(nana::charset(s))); - + return this->operator==(std::string(s)); } bool item_proxy::operator==(const wchar_t * s) const { - return (ess_->lister.get_cells(cat_, pos_.item).at(0).text == nana::string(nana::charset(s))); + return this->operator==(std::wstring(s)); + } + + bool item_proxy::operator==(const std::string& s) const + { + return (ess_->lister.get_cells(cat_, pos_.item).at(0).text == s); + } + + bool item_proxy::operator==(const std::wstring& s) const + { + return (ess_->lister.get_cells(cat_, pos_.item).at(0).text == utf8_cast(s)); } item_proxy & item_proxy::operator=(const item_proxy& rhs) @@ -3973,10 +3985,10 @@ namespace nana } } - void cat_proxy::append(std::initializer_list arg) + void cat_proxy::append(std::initializer_list arg) { const auto items = columns(); - push_back(nana::string{}); + push_back(std::string{}); item_proxy ip{ ess_, index_pair(pos_, size() - 1) }; size_type pos = 0; for (auto & txt : arg) @@ -3987,6 +3999,20 @@ namespace nana } } + void cat_proxy::append(std::initializer_list arg) + { + const auto items = columns(); + push_back(std::string{}); + item_proxy ip{ ess_, index_pair(pos_, size() - 1) }; + size_type pos = 0; + for (auto & txt : arg) + { + ip.text(pos++, utf8_cast(txt)); + if (pos >= items) + break; + } + } + cat_proxy & cat_proxy::select(bool sel) { for (item_proxy &it : *this ) @@ -4009,24 +4035,37 @@ namespace nana return ess_->header.cont().size(); } - cat_proxy& cat_proxy::text(nana::string s) + cat_proxy& cat_proxy::text(std::string s) { + auto text = to_nstring(s); internal_scope_guard lock; - if (s != cat_->text) + if (text != cat_->text) { - cat_->text.swap(s); + cat_->text.swap(text); ess_->update(); } return *this; } - nana::string cat_proxy::text() const + cat_proxy& cat_proxy::text(std::wstring s) { + auto text = to_nstring(s); internal_scope_guard lock; - return cat_->text; + if (text != cat_->text) + { + cat_->text.swap(text); + ess_->update(); + } + return *this; } - void cat_proxy::push_back(nana::string s) + std::string cat_proxy::text() const + { + internal_scope_guard lock; + return utf8_cast(cat_->text); + } + + void cat_proxy::push_back(std::string s) { internal_scope_guard lock; @@ -4303,14 +4342,24 @@ namespace nana ess.update(); } - listbox::size_type listbox::append_header(nana::string text, unsigned width) + listbox::size_type listbox::append_header(std::string s, unsigned width) { + internal_scope_guard lock; auto & ess = _m_ess(); - auto pos = ess.header.create(std::move(text), width); + auto pos = ess.header.create(to_nstring(std::move(s)), width); ess.update(); return pos; } + listbox::size_type listbox::append_header(std::wstring s, unsigned width) + { + internal_scope_guard lock; + auto & ess = _m_ess(); + auto pos = ess.header.create(to_nstring(std::move(s)), width); + ess.update(); + return pos; + } + listbox& listbox::header_width(size_type pos, unsigned pixels) { auto & ess = _m_ess(); @@ -4331,31 +4380,58 @@ namespace nana return _m_ess().header.item_width(pos); } - listbox::cat_proxy listbox::append(nana::string s) + listbox::cat_proxy listbox::append(std::string s) { internal_scope_guard lock; auto & ess = _m_ess(); - auto new_cat_ptr = ess.lister.create_cat(std::move(s)); + auto new_cat_ptr = ess.lister.create_cat(to_nstring(std::move(s))); ess.update(); return cat_proxy{ &ess, new_cat_ptr }; } - void listbox::append(std::initializer_list args) + listbox::cat_proxy listbox::append(std::wstring s) + { + internal_scope_guard lock; + auto & ess = _m_ess(); + auto new_cat_ptr = ess.lister.create_cat(to_nstring(std::move(s))); + ess.update(); + return cat_proxy{ &ess, new_cat_ptr }; + } + + void listbox::append(std::initializer_list args) { internal_scope_guard lock; auto & ess = _m_ess(); for (auto & arg : args) - ess.lister.create_cat(nana::string{ arg }); + ess.lister.create_cat(native_string_type(to_nstring(arg))); ess.update(); } + void listbox::append(std::initializer_list args) + { + internal_scope_guard lock; + auto & ess = _m_ess(); + + for (auto & arg : args) + ess.lister.create_cat(native_string_type(to_nstring(arg))); + ess.update(); + } + + auto listbox::insert(cat_proxy cat, std::string str) -> cat_proxy + { + internal_scope_guard lock; + auto & ess = _m_ess(); + auto new_cat_ptr = ess.lister.create_cat(cat.position(), to_nstring(std::move(str))); + return cat_proxy{ &ess, new_cat_ptr }; + } + auto listbox::insert(cat_proxy cat, std::wstring str) -> cat_proxy { internal_scope_guard lock; auto & ess = _m_ess(); - auto new_cat_ptr = ess.lister.create_cat(cat.position(), std::move(str)); + auto new_cat_ptr = ess.lister.create_cat(cat.position(), to_nstring(std::move(str))); return cat_proxy{ &ess, new_cat_ptr }; } @@ -4386,17 +4462,12 @@ namespace nana } void listbox::insert(const index_pair& pos, std::string text) - { - insert(pos, utf8_cast(text)); - } - - void listbox::insert(const index_pair& pos, std::wstring text) { internal_scope_guard lock; auto & ess = _m_ess(); if (ess.lister.insert(pos, std::move(text))) { - if (! empty()) + if (!empty()) { auto & item = ess.lister.at(pos); item.bgcolor = bgcolor(); @@ -4406,6 +4477,11 @@ namespace nana } } + void listbox::insert(const index_pair& pos, std::wstring text) + { + insert(pos, utf8_cast(text)); + } + void listbox::checkable(bool chkable) { auto & ess = _m_ess(); @@ -4524,7 +4600,7 @@ namespace nana _m_ess().header.sortable(enable); } - void listbox::set_sort_compare(size_type col, std::function strick_ordering) + void listbox::set_sort_compare(size_type col, std::function strick_ordering) { _m_ess().header.column(col).weak_ordering = std::move(strick_ordering); } @@ -4638,7 +4714,7 @@ namespace nana } else { - cat = ess.lister.create_cat(nana::string{}); + cat = ess.lister.create_cat(native_string_type{}); cat->key_ptr = ptr; } ess.update(); diff --git a/source/gui/widgets/spinbox.cpp b/source/gui/widgets/spinbox.cpp index bd1c15fc..f2ed5c3d 100644 --- a/source/gui/widgets/spinbox.cpp +++ b/source/gui/widgets/spinbox.cpp @@ -682,7 +682,7 @@ namespace nana internal_scope_guard lock; auto editor = get_drawer_trigger().impl()->editor(); if (editor) - return to_native_string(editor->text()); + return to_nstring(editor->text()); return native_string_type(); } diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 26e588b7..71a7b794 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -511,13 +511,13 @@ namespace drawerbase { textbox& textbox::from(int n) { - _m_caption(to_native_string(n)); + _m_caption(to_nstring(n)); return *this; } textbox& textbox::from(double d) { - _m_caption(to_native_string(d)); + _m_caption(to_nstring(d)); return *this; } @@ -600,7 +600,7 @@ namespace drawerbase { internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); if (editor) - return to_native_string(editor->text()); + return to_nstring(editor->text()); return native_string_type(); } diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index a98bc289..7b7725b4 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -76,14 +76,14 @@ namespace nana widget& widget::caption(std::string utf8) { ::nana::throw_not_utf8(utf8); - native_string_type str = to_native_string(utf8); + native_string_type str = to_nstring(utf8); _m_caption(std::move(str)); return *this; } widget& widget::caption(std::wstring text) { - native_string_type str = to_native_string(text); + native_string_type str = to_nstring(text); _m_caption(std::move(str)); return *this; } @@ -92,7 +92,7 @@ namespace nana { if (handle()) { - native_string_type str = to_native_string(eval()); + native_string_type str = to_nstring(eval()); _m_caption(std::move(str)); internationalization_parts::set_eval(handle(), std::move(eval)); } diff --git a/source/system/dataexch.cpp b/source/system/dataexch.cpp index 1158bb26..1c4b34ee 100644 --- a/source/system/dataexch.cpp +++ b/source/system/dataexch.cpp @@ -27,14 +27,25 @@ namespace nana{ namespace system{ //class dataexch - void dataexch::set(const nana::char_t* text) + void dataexch::set(const std::string& text) { - _m_set(std::is_same::value ? format::text : format::unicode, text, (nana::strlen(text) + 1) * sizeof(nana::char_t)); +#ifdef NANA_WINDOWS + std::wstring wstr = ::nana::charset(text, nana::unicode::utf8); + _m_set(format::text, wstr.c_str(), (wstr.length() + 1) * sizeof(wchar_t)); +#else + _m_set(format::text, text, std::strlen(text) + 1); +#endif } - void dataexch::set(const nana::string& text) + + void dataexch::set(const std::wstring& text) { - _m_set(std::is_same::value ? format::text : format::unicode, text.c_str(), (text.length() + 1) * sizeof(nana::char_t)); +#ifdef NANA_WINDOWS + _m_set(format::text, text.c_str(), (text.length() + 1) * sizeof(wchar_t)); +#else + std::string str = utf8_cast(text); + _m_set(format::text, str.c_str(), str.size() + 1); +#endif } bool dataexch::set(const nana::paint::graphics& g) @@ -101,36 +112,74 @@ namespace nana{ namespace system{ #endif } - void dataexch::get(nana::string& str) + + void dataexch::get(std::string& text_utf8) { std::size_t size; - void* res = _m_get(std::is_same::value ? format::text : format::unicode, size); - if(res) + auto res = _m_get(format::text, size); + if (res) { -#if defined(NANA_X11) && defined(NANA_UNICODE) - nana::detail::charset_conv conv("UTF-32", "UTF-8"); - const std::string & utf32str = conv.charset(reinterpret_cast(res), size); - const nana::char_t * utf32ptr = reinterpret_cast(utf32str.c_str()); - str.append(utf32ptr + 1, utf32ptr + utf32str.size() / sizeof(nana::char_t)); -#else - str.reserve(size / sizeof(nana::char_t)); - str.append(reinterpret_cast(res), reinterpret_cast(res) + size / sizeof(nana::char_t)); -#endif - auto pos = str.find_last_not_of(nana::char_t(0)); - if(pos != str.npos) - str.erase(pos + 1); +#if defined(NANA_WINDOWS) + size /= sizeof(wchar_t); + std::wstring wstr; + wstr.reserve(size); + wstr.append(reinterpret_cast(res), reinterpret_cast(res) + size); -#if defined(NANA_X11) + auto pos = wstr.find_last_not_of(L'\0'); + if (pos != wstr.npos) + wstr.erase(pos + 1); + + text_utf8 = utf8_cast(wstr); +#else + text_utf8.reserve(size); + text_utf8.append(reinterpret_cast(res), reinterpret_cast(res) + size); + + auto pos = text_utf8.find_last_not_of('\0'); + if (pos != text_utf8.npos) + text_utf8.erase(pos + 1); ::XFree(res); +#endif + } + } + + void dataexch::get(std::wstring& str) + { + std::size_t size; + auto res = _m_get(format::text, size); + if(res) + { +#if defined(NANA_WINDOWS) + str.clear(); + + size /= sizeof(wchar_t); + + str.reserve(size); + str.append(reinterpret_cast(res), reinterpret_cast(res) + size); + + auto pos = str.find_last_not_of(L'\0'); + if (pos != str.npos) + str.erase(pos + 1); +#else + std::string text_utf8; + text_utf8.reserve(size); + text_utf8.append(reinterpret_cast(res), reinterpret_cast(res) + size); + + auto pos = text_utf8.find_last_not_of('\0'); + if (pos != text_utf8.npos) + text_utf8.erase(pos + 1); + ::XFree(res); + + str = utf8_cast(text_utf8); #endif } } //private: - bool dataexch::_m_set(unsigned type, const void* buf, std::size_t size) + bool dataexch::_m_set(format fmt, const void* buf, std::size_t size) { bool res = false; + #if defined(NANA_WINDOWS) - if(type < format::end && ::OpenClipboard(::GetFocus())) + if(::OpenClipboard(::GetFocus())) { if(::EmptyClipboard()) { @@ -140,14 +189,14 @@ namespace nana{ namespace system{ memcpy(addr, buf, size); ::GlobalUnlock(g); - switch(type) + unsigned data_format; + switch(fmt) { - case format::text: type = CF_TEXT; break; - case format::unicode: type = CF_UNICODETEXT; break; - case format::pixmap: type = CF_BITMAP; break; + case format::text: data_format = CF_UNICODETEXT; break; + case format::pixmap: data_format = CF_BITMAP; break; } - HANDLE h = ::SetClipboardData(type, g); - res = (h != NULL); + + res = (nullptr != ::SetClipboardData(data_format, g)); } ::CloseClipboard(); } @@ -165,38 +214,32 @@ namespace nana{ namespace system{ Atom atom_type; switch(type) { - case format::text: atom_type = XA_STRING; break; - case format::unicode: atom_type = spec.atombase().utf8_string; break; + case format::text: atom_type = spec.atombase().utf8_string; break; default: return false; } - #if defined(NANA_UNICODE) - //The internal clipboard stores UTF8_STRING, the parameter string should be converted from utf32 to utf8. - nana::detail::charset_conv conv("UTF-8", "UTF-32"); - std::string utf8str = conv.charset(reinterpret_cast(buf), size); - buf = utf8str.c_str(); - size = utf8str.size(); - #endif - spec.write_selection(owner, atom_type, buf, size); + + spec.write_selection(owner, spec.atombase().utf8_string, buf, size); return true; } #endif return res; } - void* dataexch::_m_get(unsigned type, size_t& size) + void* dataexch::_m_get(format fmt, size_t& size) { - void* res = 0; + size = 0; + void* res = nullptr; #if defined(NANA_WINDOWS) - if(type < format::end && ::OpenClipboard(::GetFocus())) + if(::OpenClipboard(::GetFocus())) { - switch(type) + unsigned data_format; + switch(fmt) { - case format::text: type = CF_TEXT; break; - case format::unicode: type = CF_UNICODETEXT; break; - case format::pixmap: type = CF_BITMAP; break; + case format::text: data_format = CF_UNICODETEXT; break; + case format::pixmap: data_format = CF_BITMAP; break; } - HANDLE handle = ::GetClipboardData(type); + HANDLE handle = ::GetClipboardData(data_format); if(handle) { res = reinterpret_cast(::GlobalLock(handle)); @@ -224,10 +267,9 @@ namespace nana{ namespace system{ switch(type) { - case format::text: atom = XA_STRING; break; - case format::unicode: atom = spec.atombase().utf8_string; break; + case format::text: atom = spec.atombase().utf8_string; break; default: - return 0; + return nullptr; } res = spec.request_selection(requester, atom, size); }