Merge branch 'qPCR4vir-hotfix-1.3' into hotfix-1.3

This commit is contained in:
Jinhao 2016-04-12 22:22:15 +08:00
commit 82ef2c075d
13 changed files with 527 additions and 158 deletions

View File

@ -46,7 +46,31 @@ namespace nana
class charset_encoding_interface;
}
/// An intelligent charset class for character code conversion.
/*!\class charset
\brief An intelligent charset class for character code conversion.
Example:
1. A UTF-8 string from the socket.
int len = ::recv(sd, buf, buflen, 0);
textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8));
2. Send the string in text to the socket as UTF-8.
std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8);
::send(sd, utf8str.c_str(), utf8str.size(), 0);
3, Convert a string to the specified multi-byte character code.
// Convert to a multibytes string through default system language.
std::string mbstr = nana::charset(a_wstring);
// If the default system language is English and convert
// a Chinese unicode string to multibytes string through GB2312
std::setlocale(LC_CTYPE, "zh_CN.GB2312");
//set::setlocale(LC_CTYPE, ".936"); call it in Windows
std::string mbstr = nana::charset(a_wstring_with_chinese);
*/
class charset
{
public:
@ -74,27 +98,3 @@ namespace nana
}//end namespace nana
#endif
/*!\class charset
Example
1. A UTF-8 string from the socket.
int len = ::recv(sd, buf, buflen, 0);
textbox.caption(nana::charset(std::string(buf, len), nana::unicode::utf8));
2. Send the string in text to the socket as UTF-8.
std::string utf8str = nana::charset(textbox.caption()).to_bytes(nana::unicode::utf8);
::send(sd, utf8str.c_str(), utf8str.size(), 0);
3, Convert a string to the specified multi-byte character code.
//Convert to a multibytes string through default system language.
std::string mbstr = nana::charset(a_wstring);
//If the default system language is English and convert
//a Chinese unicode string to multibytes string through GB2312
std::setlocale(LC_CTYPE, "zh_CN.GB2312");
//set::setlocale(LC_CTYPE, ".936"); call it in Windows
std::string mbstr = nana::charset(a_wstring_with_chinese);
*/

View File

@ -114,12 +114,29 @@ namespace std
namespace nana
{
/// move to *.h ??
struct utf8_Error : std::runtime_error
{
static bool use_throw; ///< def { true }; use carefully - it is a global variable !! \todo initialize from a #define ?
using std::runtime_error::runtime_error;
void emit();
};
/// Checks whether a specified text is utf8 encoding
bool is_utf8(const char* str, unsigned len);
void throw_not_utf8(const std::string& text);
void throw_not_utf8(const char*, unsigned len);
void throw_not_utf8(const char*);
/// this text needed change, it needed review ??
bool review_utf8(const std::string& text);
/// this text needed change, it needed review ??
bool review_utf8(std::string& text);
const std::string& to_utf8(const std::string&);
std::string to_utf8(const std::wstring&);

View File

@ -1,15 +1,15 @@
/*
/**
* Selector of Platform Specification
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/detail/platform_spec_selector.hpp
* @file nana/detail/platform_spec_selector.hpp
*
* Selects the proper platform_spec header file for the current platform
* @brief Selects the proper platform_spec header file for the current platform
*/
#include <nana/config.hpp>

View File

@ -1,4 +1,4 @@
/*
/**
* A Basic Window Widget Definition
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,7 +7,8 @@
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/gui/detail/basic_window.hpp
* @file nana/gui/detail/basic_window.hpp
* @brief A Basic Window Widget Definition
*/
#ifndef NANA_GUI_DETAIL_BASIC_WINDOW_HPP
@ -58,20 +59,18 @@ namespace detail
::nana::rectangle effective_range_;
};//end class caret_descriptor
//tab_type
//@brief: Define some constant about tab category, these flags can be combine with operator |
/// Define some constant about tab category, these flags can be combine with operator |
struct tab_type
{
enum t
{
none, //process by nana
tabstop, //move to the next tabstop window
eating, //process by current window
none, ///< process by nana
tabstop, ///< move to the next tabstop window
eating, ///< process by current window
};
};
//struct basic_window
//@brief: a window data structure descriptor
/// a window data structure descriptor
struct basic_window
: public events_holder
{
@ -88,8 +87,7 @@ namespace detail
bool rendered;
};
//basic_window
//@brief: constructor for the root window
/// constructor for the root window
basic_window(basic_window* owner, std::unique_ptr<widget_notifier_interface>&&, category::root_tag**);
template<typename Category>
@ -106,8 +104,7 @@ namespace detail
~basic_window();
//bind_native_window
//@brief: bind a native window and baisc_window
/// bind a native window and baisc_window
void bind_native_window(native_window_type, unsigned width, unsigned height, unsigned extra_width, unsigned extra_height, paint::graphics&);
void frame_window(native_window_type);
@ -116,13 +113,13 @@ namespace detail
bool visible_parents() const;
bool displayed() const;
bool belong_to_lazy() const;
const basic_window * child_caret() const; //Returns a child which owns a caret
const basic_window * child_caret() const; ///< Returns the child which owns the caret
bool is_draw_through() const; ///< Determines whether it is a draw-through window.
basic_window * seek_non_lite_widget_ancestor() const;
public:
//Override event_holder
/// Override event_holder
bool set_events(const std::shared_ptr<general_events>&) override;
general_events * get_events() const override;
private:
@ -132,7 +129,7 @@ namespace detail
#if defined(NANA_LINUX) || defined(NANA_MACOS)
point pos_native;
#endif
point pos_root; //coordinate for root window
point pos_root; ///< coordinates of the root window
point pos_owner;
size dimension;
::nana::size min_track_size;
@ -147,9 +144,9 @@ namespace detail
basic_window *owner;
native_string_type title;
::nana::detail::drawer drawer; //Self Drawer with owen graphics
basic_window* root_widget; //A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
paint::graphics* root_graph; //Refer to the root buffer graphics
::nana::detail::drawer drawer; ///< Self Drawer with owen graphics
basic_window* root_widget; ///< A pointer refers to the root basic window, if the window is a root, the pointer refers to itself.
paint::graphics* root_graph; ///< Refer to the root buffer graphics
cursor predef_cursor;
std::unique_ptr<widget_notifier_interface> widget_notifier;
@ -157,20 +154,20 @@ namespace detail
{
bool enabled :1;
bool dbl_click :1;
bool captured :1; //if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
bool captured :1; ///< if mouse button is down, it always receive mouse move even the mouse is out of its rectangle
bool modal :1;
bool take_active:1; //If take_active is false, other.active_window still keeps the focus.
bool take_active:1; ///< If take_active is false, other.active_window still keeps the focus.
bool refreshing :1;
bool destroying :1;
bool dropable :1; //Whether the window has make mouse_drop event.
bool fullscreen :1; //When the window is maximizing whether it fit for fullscreen.
bool dropable :1; ///< Whether the window has make mouse_drop event.
bool fullscreen :1; ///< When the window is maximizing whether it fit for fullscreen.
bool borderless :1;
bool make_bground_declared : 1; //explicitly make bground for bground effects
bool ignore_menubar_focus : 1; //A flag indicates whether the menubar sets the focus.
bool ignore_mouse_focus : 1; //A flag indicates whether the widget accepts focus when clicking on it
bool space_click_enabled : 1; //A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key.
bool make_bground_declared : 1; ///< explicitly make bground for bground effects
bool ignore_menubar_focus : 1; ///< A flag indicates whether the menubar sets the focus.
bool ignore_mouse_focus : 1; ///< A flag indicates whether the widget accepts focus when clicking on it
bool space_click_enabled : 1; ///< A flag indicates whether enable mouse_down/click/mouse_up when pressing and releasing whitespace key.
unsigned Reserved :18;
unsigned char tab; //indicate a window that can receive the keyboard TAB
unsigned char tab; ///< indicate a window that can receive the keyboard TAB
mouse_action action;
}flags;
@ -199,7 +196,7 @@ namespace detail
struct attr_root_tag
{
container frames; //initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame
container frames; ///< initialization is null, it will be created while creating a frame widget. Refer to WindowManager::create_frame
container tabstop;
std::vector<edge_nimbus_action> effects_edge_nimbus;
basic_window* focus{nullptr};
@ -211,13 +208,13 @@ namespace detail
cursor state_cursor{nana::cursor::arrow};
basic_window* state_cursor_window{ nullptr };
std::function<void()> draw_through; // A draw through renderer for root widgets.
std::function<void()> draw_through; ///< A draw through renderer for root widgets.
};
const category::flags category;
basic_window *active_window; //if flags.take_active is false, the active_window still keeps the focus,
//if the active_window is null, the parent of this window keeps focus.
paint::graphics glass_buffer; //if effect.bground is avaiable. Refer to window_layout::make_bground.
basic_window *active_window; ///< if flags.take_active is false, the active_window still keeps the focus,
///< if the active_window is null, the parent of this window keeps focus.
paint::graphics glass_buffer; ///< if effect.bground is avaiable. Refer to window_layout::make_bground.
update_state upd_state;
union
@ -230,8 +227,8 @@ namespace detail
~other_tag();
}other;
native_window_type root; //root Window handle
unsigned thread_id; //the identifier of the thread that created the window.
native_window_type root; ///< root Window handle
unsigned thread_id; ///< the identifier of the thread that created the window.
unsigned index;
container children;
};

View File

@ -538,7 +538,7 @@ namespace nana
struct arg_click : public event_arg
{
::nana::window window_handle; ///< A handle to the event window
const arg_mouse* mouse_args; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise.
const arg_mouse* mouse_args{}; ///< If it is not null, it refers to the mouse arguments for click event emitted by mouse, nullptr otherwise.
};
/// provides some fundamental events that every widget owns.

View File

@ -297,7 +297,18 @@ namespace nana
throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value");
return *p;
}
template<typename T>
T & value()
{
auto * pany = _m_value();
if (nullptr == pany)
throw std::runtime_error("listbox::item_proxy.value<T>() is empty");
T * p = any_cast<T>(_m_value(false));
if (nullptr == p)
throw std::runtime_error("listbox::item_proxy.value<T>() invalid type of value");
return *p;
}
template<typename T>
item_proxy & value(T&& t)
{
@ -506,7 +517,7 @@ namespace nana
basic_event<arg_listbox> checked;
basic_event<arg_listbox> selected;
/// An event occurs when a listbox category is double clicking.
/// An event that occurs when a listbox category is double clicking.
basic_event<arg_category> category_dbl_click;
};
@ -518,26 +529,40 @@ namespace nana
color_proxy header_floated{ static_cast<color_rgb>(0xBABBBC)};
color_proxy item_selected{ static_cast<color_rgb>(0xD5EFFC) };
unsigned max_header_width{3000}, /// \todo how to implement some geometrical parameters ??
ext_w = 5;
/// \todo how to implement some geometrical parameters ??
unsigned max_header_width{ 3000 }; ///< during auto width don't alow more than this
unsigned min_header_width{ 20 }; ///< non counting suspension_width
unsigned suspension_width{ 0 }; ///< the trigger will set this to the width if ("...")
unsigned ext_w { 5 }; ///< ??
unsigned header_height { 20 }; ///< header height header_size
unsigned text_height { 0 }; ///< the trigger will set this to the height of the text font
unsigned item_height_ex { 6 }; ///< 6? item_height = text_height + item_height_ex
unsigned item_height { 0 }; ///< the trigger will set this TO item_height = text_height + item_height_ex
unsigned header_mouse_spliter_area_before{ 2 };
unsigned header_mouse_spliter_area_after { 3 };
};
}
}//end namespace drawerbase
/*! \class listbox
\brief A rectangle containing a list of strings from which the user can select. This widget contain a list of \a categories, with in turn contain a list of \a items.
A category is a text with can be \a selected, \a checked and \a expanded to show the items.
An item is formed by \a column-fields, each corresponding to one of the \a headers.
An item can be \a selected and \a checked.
\brief A rectangle containing a list of strings from which the user can select.
This widget contain a list of \a categories, with in turn contain a list of \a items.
A \a category is a text with can be \a selected, \a checked and \a expanded to show the \a items.
An \a item is formed by \a column-fields, each corresponding to one of the \a headers.
An \a item can be \a selected and \a checked.
The user can \a drag the header to \a resize it or to \a reorganize it.
By \a clicking on one header the list get \a reordered, first up, and then down alternatively.
1. The resolver is used to resolute an object of the specified type for a listbox item.
3. nana::listbox creates the category 0 by default. The member functions without the categ parameter operate the items that belong to category 0.
1. The resolver is used to resolute an object of the specified type into (or back from) a listbox item.
3. nana::listbox creates the category 0 by default.
This is an special category, becouse it is invisible, while the associated items are visible.
The optional, user-created categories begin at index 1 and are visibles.
The member functions without the categ parameter operate the items that belong to category 0.
4. A sort compare is used for sorting the items. It is a strict weak ordering comparer that must meet the requirement:
Irreflexivity (comp(x, x) returns false)
and
antisymmetry(comp(a, b) != comp(b, a) returns true)
Antisymmetry(comp(a, b) != comp(b, a) returns true)
A simple example.
bool sort_compare( const std::string& s1, nana::any*,
const std::string& s2, nana::any*, bool reverse)
@ -552,10 +577,10 @@ By \a clicking on one header the list get \a reordered, first up, and then down
{
if(o1 && o2) //some items may not attach a customer object.
{
int * i1 = o1->get<int>();
int * i2 = o2->get<int>();
int * i1 = any_cast<int>(*o1);
int * i2 = any_cast<int>(*o2);
return (i1 && i2 && (reverse ? *i1 > *i2 : *i1 < *i2));
;//some types may not be int.
// ^ some types may not be int.
}
return false;
}
@ -699,7 +724,7 @@ By \a clicking on one header the list get \a reordered, first up, and then down
size_type size_categ() const; ///<Get the number of categories
size_type size_item() const; ///<The number of items in the default category
size_type size_item(size_type cat) const; ///<The number of items in category "cat"
size_type size_item(size_type cat) const; ///<The number of items in category "cat"
void enable_single(bool for_selection, bool category_limited);
void disable_single(bool for_selection);

View File

@ -114,7 +114,7 @@ namespace nana
};
}//end namespace slider
}//end namespace drawerbase
/// A slider widget wich the user can drag for tracking
/// A slider widget wich the user can drag for tracking \todo add scheme ?
class slider
: public widget_object<category::widget_tag, drawerbase::slider::trigger, drawerbase::slider::slider_events>
{

View File

@ -1,4 +1,4 @@
/*
/**
* A Character Encoding Set Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
@ -7,9 +7,9 @@
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* @file: nana/charset.cpp
* @brief: A conversion between unicode characters and multi bytes characters
* @contributions:
* @file nana/charset.cpp
* @brief A conversion between unicode characters and multi bytes characters
* @contributions
* UTF16 4-byte decoding issue by Renke Yan.
* Pr0curo(pr#98)
*/
@ -20,6 +20,7 @@
#include <cwchar>
#include <clocale>
#include <cstring> //Added by Pr0curo(pr#98)
#include <memory>
//GCC 4.7.0 does not implement the <codecvt> and codecvt_utfx classes
#ifndef STD_CODECVT_NOT_SUPPORTED
@ -34,6 +35,7 @@ namespace nana
{
namespace utf
{
/// return a pointer to the code unit of the character at pos
const char* char_ptr(const char* text, unsigned pos)
{
auto ustr = reinterpret_cast<const unsigned char*>(text);
@ -48,10 +50,10 @@ namespace nana
continue;
}
if (uch < 0xC0)
if (uch < 0xC0) // use police ?
return nullptr;
if ((uch < 0xE0) && (ustr + 1 < end))
if ((uch < 0xE0) && (ustr + 1 < end)) //? *(ustr + 1) < 0xE0
ustr += 2;
else if (uch < 0xF0 && (ustr + 2 <= end))
ustr += 3;
@ -64,6 +66,7 @@ namespace nana
return reinterpret_cast<const char*>(ustr);
}
/// return a pointer to the code unit of the character at pos - reuse ^ ?
const char* char_ptr(const std::string& text_utf8, unsigned pos)
{
auto ustr = reinterpret_cast<const unsigned char*>(text_utf8.c_str());
@ -94,6 +97,7 @@ namespace nana
return reinterpret_cast<const char*>(ustr);
}
/// return a code point (max 16 bits?) and the len in code units of the character at pos
wchar_t char_at(const char* text_utf8, unsigned pos, unsigned * len)
{
if (!text_utf8)
@ -112,10 +116,10 @@ namespace nana
if (len)
*len = 1;
return *text_utf8;
return *text_utf8; // uch ?
}
if (uch < 0xC0)
if (uch < 0xC0) // use police or ??
{
if (len)
*len = 0;
@ -151,6 +155,7 @@ namespace nana
return 0;
}
/// return a code point (max 16 bits?) and the len in code units of the character at pos
wchar_t char_at(const ::std::string& text_utf8, unsigned pos, unsigned * len)
{
const char* ptr;
@ -210,22 +215,23 @@ namespace nana
}
namespace detail
{
{
/// candidate to be more general??
class locale_initializer
{
public:
static void init()
{
static bool initialized = false;
if(false == initialized)
{
initialized = true;
//Only set the C library locale
std::setlocale(LC_CTYPE, "");
}
if (initialized) return;
initialized = true;
//Only set the C library locale
std::setlocale(LC_CTYPE, "");
}
};
/// convert wchar C string from ? ANSI code page CP_ACP (windows) or LC_CTYPE c locale (-nix) into utf8 std::string
bool wc2mb(std::string& mbstr, const wchar_t * s)
{
if(nullptr == s || *s == 0)
@ -258,7 +264,8 @@ namespace nana
#endif
return true;
}
/// convert a char C-string from The system default Windows ANSI code page CP_ACP or from LC_CTYPE c locale (-nix) into utf16 std::wstring
bool mb2wc(std::wstring& wcstr, const char* s)
{
if(nullptr == s || *s == 0)
@ -291,6 +298,7 @@ namespace nana
return true;
}
/// convert a char C string from The system default Windows ANSI code page CP_ACP or LC_CTYPE c locale (-nix) into utf16 std::string
bool mb2wc(std::string& wcstr, const char* s)
{
if(nullptr == s || *s == 0)
@ -304,6 +312,7 @@ namespace nana
{
wcstr.resize((chars - 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, s, -1, reinterpret_cast<wchar_t*>(&wcstr[0]), chars - 1);
// ^ the trick !
}
#else
locale_initializer::init();
@ -338,6 +347,87 @@ namespace nana
virtual std::wstring&& wstr_move() = 0;
};
/// playing with the idea - we need a mechanisme to set a user selected police - Testing an abtract interphase
struct encoding_error_police
{
virtual unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) = 0;
virtual ~encoding_error_police() = default;
};
/// the current nana default: it is safe - you may want to keep it ! use the other at your risk: mainly for debugging
struct utf8_error_police : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
current_code_unit = end;
return 0;
}
};
///
struct utf8_error_police_def_char : public encoding_error_police
{
static unsigned long def_error_mark ;
unsigned long error_mark{ def_error_mark };
utf8_error_police_def_char() = default;
utf8_error_police_def_char( unsigned long mark): error_mark{mark}{}
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
++current_code_unit; //check (p != end) ?
return error_mark;
}
};
unsigned long utf8_error_police_def_char::def_error_mark{ '*' };
///
struct utf8_error_police_throw : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
//utf8_Error::use_throw = true;
utf8_Error(std::string("The text is not encoded in UTF8: ") +
reinterpret_cast<const char*>( current_code_unit) ).emit();;
current_code_unit = end;
return 0;
}
};
struct utf8_error_police_latin : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
return *(current_code_unit++) ;
}
};
/// buggie?
struct utf8_error_police_system : public encoding_error_police
{
unsigned long next_code_point(const unsigned char*& current_code_unit, const unsigned char* end) override
{
std::wstring wc;
mb2wc(wc, reinterpret_cast<const char*>(current_code_unit));
current_code_unit++;
//wchar_t *p = &wc[0];
return wc[0]; // use utf16char but what endian?
}
};
// auto def_encoding_error_police = std::make_unique<utf8_error_police>(); // the nana default
// auto def_encoding_error_police = std::make_unique<utf8_error_police_latin>();
// auto def_encoding_error_police = std::make_unique<utf8_error_police_throw>();
// auto def_encoding_error_police = std::make_unique<utf8_error_police_def_char>('X');
auto def_encoding_error_police = std::make_unique<utf8_error_police_system>();
#ifndef STD_CODECVT_NOT_SUPPORTED
class charset_string
: public charset_encoding_interface
@ -578,37 +668,42 @@ namespace nana
std::string data_for_move_;
};
#else
/// return the first code point and move the pointer to next character, springing to the end by errors
unsigned long utf8char(const unsigned char*& p, const unsigned char* end)
{
if(p != end)
{
if(*p < 0x80)
if(*p < 0x80) // ASCII char 0-127 or 0-0x80
{
return *(p++);
}
unsigned ch = *p;
unsigned long code;
if(ch < 0xC0)
if(ch < 0xC0) // error? - move to end. Posible ANSI or ISO code-page
{
p = end;
return 0;
//return *(p++); // temp: assume equal
//p = end;
//return 0;
return def_encoding_error_police->next_code_point(p, end);
}
else if(ch < 0xE0 && (p + 1 <= end))
else if(ch < 0xE0 && (p + 1 <= end)) // two byte chararcter
{
code = ((ch & 0x1F) << 6) | (p[1] & 0x3F);
p += 2;
}
else if(ch < 0xF0 && (p + 2 <= end))
else if(ch < 0xF0 && (p + 2 <= end)) // 3 byte character
{
code = ((((ch & 0xF) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F);
p += 3;
}
else if(ch < 0x1F && (p + 3 <= end))
else if(ch < 0x1F && (p + 3 <= end)) // 4 byte character
{
code = ((((((ch & 0x7) << 6) | (p[1] & 0x3F)) << 6) | (p[2] & 0x3F)) << 6) | (p[3] & 0x3F);
p += 4;
}
else
else // error, go to end
{
p = end;
return 0;
@ -1068,10 +1163,10 @@ namespace nana
switch(encoding)
{
case unicode::utf8:
return utf32_to_utf8(wcstr);
case unicode::utf16:
return utf32_to_utf16(wcstr);
return utf16_to_utf8(wcstr);
case unicode::utf32:
return utf16_to_utf32(wcstr);
case unicode::utf16:
return wcstr;
}
}

View File

@ -479,6 +479,8 @@ namespace std
}
//#endif // STD_put_time_NOT_SUPPORTED
#include <iostream>
namespace nana
{
bool is_utf8(const char* str, unsigned len)
@ -511,25 +513,71 @@ namespace nana
return true;
}
void utf8_Error::emit()
{
if (use_throw)
throw utf8_Error(*this);
std::cerr << what();
}
//bool utf8_Error::use_throw{true};
bool utf8_Error::use_throw{ false };
void throw_not_utf8(const std::string& text)
{
if (!is_utf8(text.c_str(), text.length()))
throw std::invalid_argument("The text is not encoded in UTF8");
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
}
void throw_not_utf8(const char* text, unsigned len)
{
if (!is_utf8(text, len))
throw std::invalid_argument("The text is not encoded in UTF8");
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + std::string(text, len) ).emit();
//throw std::invalid_argument("The text is not encoded in UTF8");
}
void throw_not_utf8(const char* text)
{
if (!is_utf8(text, std::strlen(text)))
throw std::invalid_argument("The text is not encoded in UTF8");
return utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
//throw std::invalid_argument("The text is not encoded in UTF8");
}
std::string recode_to_utf8(std::string no_utf8)
{
return nana::charset(std::move(no_utf8)).to_bytes(nana::unicode::utf8);
}
/// this text needed change, it needed review ??
bool review_utf8(const std::string& text)
{
if (!is_utf8(text.c_str(), text.length()))
{
utf8_Error(std::string("\nThe const text is not encoded in UTF8: ") + text).emit();
return true; /// it needed change, it needed review !!
}
else
return false;
}
/// this text needed change, it needed review ??
bool review_utf8(std::string& text)
{
if (!is_utf8(text.c_str(), text.length()))
{
utf8_Error(std::string("\nThe text is not encoded in UTF8: ") + text).emit();
text=recode_to_utf8(text);
return true; /// it needed change, it needed review !!
}
else
return false;
}
const std::string& to_utf8(const std::string& str)
{
return str;

View File

@ -1,7 +1,7 @@
/*
/**
* Platform Specification Implementation
* Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com)
* Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com)
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
@ -9,7 +9,7 @@
*
* @file: nana/detail/platform_spec.cpp
*
* This file provides basis class and data structrue that required by nana
* @brief basis classes and data structrues required by nana
*/
#include <nana/detail/platform_spec_selector.hpp>
@ -19,9 +19,172 @@
#include <shellapi.h>
#include <stdexcept>
#if defined(_MSC_VER)
#include <VersionHelpers.h>
#endif // _MSVC
///////////////////////////////////////////////////////////////////////////////////////////////////////
/******************************************************************
* *
* VersionHelpers.h -- This module defines helper functions to *
* promote version check with proper *
* comparisons. *
* *
* Copyright (c) Microsoft Corp. All rights reserved. *
* *
******************************************************************/
#include <specstrings.h> // for _In_, etc.
#if !defined(__midl) && !defined(SORTPP_PASS)
#if (NTDDI_VERSION >= NTDDI_WINXP)
#ifdef __cplusplus
#define VERSIONHELPERAPI inline bool
#else // __cplusplus
#define VERSIONHELPERAPI FORCEINLINE BOOL
#endif // __cplusplus
VERSIONHELPERAPI
IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
VERSIONHELPERAPI
IsWindowsXPOrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0);
}
VERSIONHELPERAPI
IsWindowsXPSP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 1);
}
VERSIONHELPERAPI
IsWindowsXPSP2OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 2);
}
VERSIONHELPERAPI
IsWindowsXPSP3OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 3);
}
VERSIONHELPERAPI
IsWindowsVistaOrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
}
VERSIONHELPERAPI
IsWindowsVistaSP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 1);
}
VERSIONHELPERAPI
IsWindowsVistaSP2OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 2);
}
VERSIONHELPERAPI
IsWindows7OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
}
VERSIONHELPERAPI
IsWindows7SP1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
}
#ifndef _WIN32_WINNT_WIN8 // (0x0602)
#define _WIN32_WINNT_WIN8 (0x0602)
#endif // _WIN32_WINNT_WIN8(0x0602)
VERSIONHELPERAPI
IsWindows8OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
}
#ifndef _WIN32_WINNT_WINBLUE // (0x0602)
#define _WIN32_WINNT_WINBLUE (0x0602)
#endif // _WIN32_WINNT_WINBLUE (0x0602)
VERSIONHELPERAPI
IsWindows8Point1OrGreater()
{
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), LOBYTE(_WIN32_WINNT_WINBLUE), 0);
}
VERSIONHELPERAPI
IsWindowsServer()
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0, 0, VER_NT_WORKSTATION };
DWORDLONG const dwlConditionMask = VerSetConditionMask(0, VER_PRODUCT_TYPE, VER_EQUAL);
return !VerifyVersionInfoW(&osvi, VER_PRODUCT_TYPE, dwlConditionMask);
}
#endif // NTDDI_VERSION
#endif // defined(__midl)
////////////////////////////////////////////////////////////////////////////////////////////////////
//#if defined(_MSC_VER)
////#include <VersionHelpers.h>
//bool IsWindowsVistaOrGreater() { return false; }
//bool //VERSIONHELPERAPI
//IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
//{
// OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 };
// DWORDLONG const dwlConditionMask = VerSetConditionMask(
// VerSetConditionMask(
// VerSetConditionMask(
// 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
// VER_MINORVERSION, VER_GREATER_EQUAL),
// VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
//
// osvi.dwMajorVersion = wMajorVersion;
// osvi.dwMinorVersion = wMinorVersion;
// osvi.wServicePackMajor = wServicePackMajor;
//
// return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
//}
//
//
//
//#endif // _MSVC
namespace nana
{

View File

@ -95,9 +95,9 @@ namespace nana
}
//read_visual_rectangle
//@brief: Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
// the visual rectangle is a rectangular block that a window should be displayed on screen.
// The result is a rectangle that is a visible area for its ancesters.
///@brief Reads the visual rectangle of a window, the visual rectangle's reference frame is to root widget,
/// the visual rectangle is a rectangular block that a window should be displayed on screen.
/// The result is a rectangle that is a visible area for its ancesters.
bool window_layout::read_visual_rectangle(core_window_t* wd, nana::rectangle& visual)
{
if (! wd->displayed()) return false;

View File

@ -355,13 +355,15 @@ namespace nana
msgbox::msgbox(const std::string& title)
: wd_(nullptr), title_(title), button_(ok), icon_(icon_none)
{
throw_not_utf8(title_);
// throw_not_utf8(title_);
review_utf8(title_);
}
msgbox::msgbox(window wd, const std::string& title, button_t b)
: wd_(wd), title_(title), button_(b), icon_(icon_none)
{
throw_not_utf8(title_);
// throw_not_utf8(title_);
review_utf8(title_);
}
msgbox& msgbox::icon(icon_t ic)

View File

@ -329,7 +329,7 @@ namespace nana
struct column_t
{
native_string_type text; ///< "text" header of the column number "index" with weigth "pixels"
unsigned pixels;
unsigned pixels; ///< width
bool visible{true};
size_type index;
std::function<bool(const std::string&, nana::any*, const std::string&, nana::any*, bool reverse)> weak_ordering;
@ -338,6 +338,7 @@ namespace nana
column_t(native_string_type&& txt, unsigned px, size_type pos)
: text(std::move(txt)), pixels(px), index(pos)
{}
/// \todo introduce default cell format
};
using container = std::vector<column_t> ;
@ -410,7 +411,7 @@ namespace nana
return cont_.back().index;
}
void item_width(size_type pos, unsigned width)
void item_width(size_type pos, unsigned width) ///< set the column width
{
column(pos).pixels = width;
}
@ -427,7 +428,7 @@ namespace nana
return 0;
}
unsigned pixels() const
unsigned pixels() const ///< the visible width of the whole header
{
unsigned pixels = 0;
for(auto & m : cont_)
@ -470,12 +471,13 @@ namespace nana
{
if(x < static_cast<int>(col.pixels))
return col.index;
x -= col.pixels;
if (col.visible)
x -= col.pixels;
}
return npos;
}
/// return the left position of the column originaly at index "pos" .
/// return the left position and width (in variable *pixels) of the column originaly at index "pos" .
int item_pos(size_type pos, unsigned * pixels) const
{
int left = 0;
@ -493,7 +495,8 @@ namespace nana
}
return left;
}
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
/// return the original index of the visible col currently before(in front of) or after the col originaly at index "index"
size_type neighbor(size_type index, bool front) const
{
size_type n = npos;
@ -509,11 +512,12 @@ namespace nana
break;
}
else if(i->visible)
n = i->index;
n = i->index;
}
return npos;
}
/// return the original index of the currently first visible col
/// return the original index of the currently first visible col
size_type begin() const
{
for(const auto & m : cont_)
@ -532,7 +536,8 @@ namespace nana
}
return npos;
}
/// move the col originaly at index to the position currently in front (or after) the col originaly at index "to" invalidating some current index
/// move the col originaly at "index" to the position currently in front (or after) the col originaly at index "to" invalidating some current index
void move(size_type index, size_type to, bool front) throw()
{
if ((index == to) || (index >= cont_.size()) || (to >= cont_.size()))
@ -879,7 +884,8 @@ namespace nana
list_.back().key_ptr = ptr;
return &list_.back();
}
/// add a new cat created at "pos" and return a ref to it
/// add a new cat created at "pos" and return a ref to it
category_t* create_cat(std::size_t pos, native_string_type&& text)
{
return &(*list_.emplace(this->get(pos), std::move(text)));
@ -1828,9 +1834,7 @@ namespace nana
};//end class es_lister
//struct essence_t
//@brief: this struct gives many data for listbox,
// the state of the struct does not effect on member funcions, therefore all data members are public.
/// created and live by the trigger, holds data for listbox: the state of the struct does not effect on member funcions, therefore all data members are public.
struct essence_t
{
enum class item_state{normal, highlighted, pressed, grabbed, floated};
@ -1859,7 +1863,7 @@ namespace nana
struct scroll_part
{
static const unsigned scale = 16;
static const unsigned scale = 16; // ?
int offset_x;
index_pair offset_y_abs, offset_y_dpl; //cat stands for category, item stands for item. "item == npos" means that is a category.
// need to be abs??? to see the same item after sort() ??
@ -1942,8 +1946,8 @@ namespace nana
//number_of_lister_item
//@brief: Returns the number of items that are contained in pixels
//@param,with_rest: Means whether including extra one item that is not completely contained in reset pixels.
/// @brief Returns the number of items that are contained in pixels
/// @param with_rest: Means whether including extra one item that is not completely contained in reset pixels.
size_type number_of_lister_items(bool with_rest) const
{
unsigned lister_s = graph->height() - 2 - header_visible_px() - (scroll.h.empty() ? 0 : scroll.scale);
@ -1983,8 +1987,9 @@ namespace nana
void trace_item_abs( index_pair abs_pos )
{
if(abs_pos.item == npos && abs_pos.cat == scroll.offset_y_abs.cat
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
if( abs_pos.item == npos
&& abs_pos.cat == scroll.offset_y_abs.cat
&& scroll.offset_y_abs.item == npos ) // if item==off y and is a cat
return;
trace_item_dpl( lister.relative_pair(abs_pos)) ; // ??? scroll_y_dpl_refresh() ;
@ -2072,10 +2077,10 @@ namespace nana
bool v = (lister.the_number_of_expanded() > screen_number);
if(v == true && h == false)
h = (header_s > (sz.width - 2 - scroll.scale));
h = ( (header_s + 2 + scroll.scale ) > sz.width); // 2?
unsigned width = sz.width - 2 - (v ? scroll.scale : 0);
unsigned height = sz.height - 2 - (h ? scroll.scale : 0);
unsigned width = sz.width - 2 - (v ? scroll.scale : 0); // -? 2?
unsigned height = sz.height - 2 - (h ? scroll.scale : 0); // -? 2?
//event hander for scrollbars
auto evt_fn = [this](const arg_scroll& arg)
@ -2168,7 +2173,8 @@ namespace nana
return (seq.size() ? (header.item_pos(seq[0], nullptr) - scroll.offset_x + r.x) : 0);
}
std::pair<parts, size_t> where(int x, int y){
std::pair<parts, size_t> where(int x, int y)
{
std::pair<parts, size_t> new_where;
if(2 < x && x < static_cast<int>(graph->width()) - 2 && 1 < y && y < static_cast<int>(graph->height()) - 1)
@ -2644,6 +2650,7 @@ namespace nana
item_spliter_ = npos;
}
/// return true an set member item_spliter_ if x is in the spliter area after that header item (column)
bool mouse_spliter(const nana::rectangle& r, int x)
{
if(essence_->ptr_state == item_state::highlighted)
@ -2658,7 +2665,7 @@ namespace nana
item_spliter_ = hd.index; // original index
return true;
}
x -= hd.pixels;
x -= hd.pixels;
}
}
}
@ -2672,7 +2679,7 @@ namespace nana
if(is_grab)
{
ref_xpos_ = pos.x;
if(item_spliter_ != npos)
if(item_spliter_ != npos) // resize header item, not move it
orig_item_width_ = essence_->header.column(item_spliter_).pixels;
}
else if(grab_terminal_.index != npos && grab_terminal_.index != essence_->pointer_where.second)
@ -2680,21 +2687,21 @@ namespace nana
}
//grab_move
//@brief: draw when an item is grabbing.
//@return: 0 = no graphics changed, 1 = just update, 2 = refresh
/// @brief draw when an item is grabbing.
/// @return 0 = no graphics changed, 1 = just update, 2 = refresh
int grab_move(const nana::rectangle& rect, const nana::point& pos)
{
if(item_spliter_ == npos)
{
draw(rect);
_m_make_float(rect, pos);
{ // move header item, not resize it
draw(rect); // first draw the entery header as it was
_m_make_float(rect, pos); // now draw one floating header item
//Draw the target strip
grab_terminal_.index = _m_target_strip(pos.x, rect, essence_->pointer_where.second, grab_terminal_.place_front);
return 1;
}
else
{
{ // resize header item, not move it
const auto& item = essence_->header.column(item_spliter_);
//Resize the item specified by item_spliter_.
auto new_w = orig_item_width_ - (ref_xpos_ - pos.x);
@ -3003,9 +3010,19 @@ namespace nana
}
}
//Draws an item
//@param content_r the rectangle of list content
void _m_draw_item(const category_t& cat, const index_pair& item_pos, const int x, const int y, const int txtoff, unsigned width, const nana::rectangle& content_r, const std::vector<size_type>& seqs, nana::color bgcolor, nana::color fgcolor, item_state state) const
/// Draws an item
void _m_draw_item(const category_t& cat,
const index_pair& item_pos,
const int x,
const int y,
const int txtoff,
unsigned width,
const nana::rectangle& content_r, ///< the rectangle where the full list content have to be drawn
const std::vector<size_type>& seqs,
nana::color bgcolor,
nana::color fgcolor,
item_state state
) const
{
auto & item = cat.items[item_pos.item];
@ -3022,7 +3039,7 @@ namespace nana
if (item.flags.selected)
bgcolor = bgcolor.blend(colors::black, 0.98); // or "selected"
else
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7);
bgcolor = bgcolor.blend(essence_->scheme_ptr->item_selected, 0.7); /// \todo create a parametre for amount of blend
}
unsigned show_w = width - essence_->scroll.offset_x;
@ -3148,6 +3165,7 @@ namespace nana
{
auto cell_txtcolor = fgcolor;
auto & m_cell = item.cells[column_pos];
review_utf8(m_cell.text);
nana::size ts = graph->text_extent_size(m_cell.text); // precalcule text geometry
if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) // adapt to costum format if need
@ -3338,18 +3356,18 @@ namespace nana
if(essence_->ptr_state == item_state::pressed)
{
if(essence_->pointer_where.first == parts::header)
{
{ // moving a pressed header : grab it (or split-resize?)
essence_->ptr_state = item_state::grabbed;
nana::point pos = arg.pos;
essence_->widget_to_header(pos);
drawer_header_->grab(pos, true);
API::capture_window(essence_->lister.wd_ptr()->handle(), true);
update = 2;
update = 2; //0 = nothing, 1 = update, 2 = refresh
}
}
if(essence_->ptr_state == item_state::grabbed)
{
{ // moving a grabbed header
nana::point pos = arg.pos;
essence_->widget_to_header(pos);
@ -3701,6 +3719,7 @@ namespace nana
//end class trigger
//class item_proxy
item_proxy::item_proxy(essence_t * ess)
: ess_(ess)
{}
@ -3973,6 +3992,7 @@ namespace nana
//end class item_proxy
//class cat_proxy
//the member cat_ is used for fast accessing to the category
cat_proxy::cat_proxy(essence_t * ess, size_type pos)
: ess_(ess),
@ -4303,6 +4323,7 @@ namespace nana
//Implementation of arg_category
//Contributed by leobackes(pr#97)
arg_category::arg_category ( const nana::drawerbase::listbox::cat_proxy& cat ) noexcept
: category(cat), block_change_(false)
{
@ -4320,6 +4341,7 @@ namespace nana
//class listbox
listbox::listbox(window wd, bool visible)
{
create(wd, rectangle(), visible);