Merge branch 'qPCR4vir-test_error' into develop
This commit is contained in:
@@ -46,8 +46,6 @@ before_install:
|
||||
- cd ..
|
||||
- git clone --depth=1 --branch=hotfix https://github.com/qPCR4vir/nana-demo.git nana-demo
|
||||
- export PATH="$HOME/bin:$PATH"
|
||||
|
||||
#- mkdir ~/bin #it seemd that a bin already exists from 20170901
|
||||
- wget --no-check-certificate --no-clobber -O /tmp/tools/cmake https://cmake.org/files/v3.12/cmake-3.12.0-rc3-Linux-x86_64.sh || true
|
||||
- chmod -R +x /tmp/tools
|
||||
|
||||
@@ -65,7 +63,7 @@ before_script :
|
||||
- cd demo-build
|
||||
|
||||
script:
|
||||
- cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=ON -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON
|
||||
- cmake -G"Unix Makefiles" ../nana-demo -DCMAKE_INSTALL_PREFIX=.. -DNANA_CMAKE_ENABLE_JPEG=ON -DNANA_CMAKE_FIND_BOOST_FILESYSTEM=OFF -DNANA_CMAKE_AUTOMATIC_GUI_TESTING=ON
|
||||
- make install
|
||||
# todo: separate resources from sources (a directory for images)
|
||||
- ls
|
||||
|
||||
@@ -17,6 +17,9 @@ if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # AN
|
||||
target_compile_options(nana PRIVATE -Wall
|
||||
PUBLIC -g )
|
||||
|
||||
# todo: set in target property of nana
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -mtune=native -DNDEBUG")
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON) # todo - test this
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(nana PRIVATE Threads::Threads)
|
||||
|
||||
@@ -30,6 +30,8 @@ if (NANA_CMAKE_VERBOSE_PREPROCESSOR)
|
||||
|
||||
cmake_print_variables(CMAKE_BUILD_TYPE)
|
||||
cmake_print_variables(CMAKE_CONFIGURATION_TYPES)
|
||||
cmake_print_variables(CMAKE_CXX_FLAGS_RELEASE)
|
||||
|
||||
message ( "CMAKE_CXX_COMPILER_ID = " ${CMAKE_CXX_COMPILER_ID})
|
||||
message ( "COMPILER_IS_CLANG = " ${COMPILER_IS_CLANG})
|
||||
message ( "CMAKE_COMPILER_IS_GNUCXX = " ${CMAKE_COMPILER_IS_GNUCXX})
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -116,6 +117,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -132,6 +134,7 @@
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -150,6 +153,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -252,6 +256,7 @@
|
||||
<ClInclude Include="..\..\include\nana\gui.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\animation.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\basis.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\dragdrop.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\dragger.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\drawing.hpp" />
|
||||
<ClInclude Include="..\..\include\nana\gui\effects.hpp" />
|
||||
|
||||
@@ -474,6 +474,9 @@
|
||||
<ClInclude Include="..\..\include\nana\verbose_preprocessor.hpp">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\nana\gui\dragdrop.hpp">
|
||||
<Filter>Include\gui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\include\nana\pop_ignore_diagnostic">
|
||||
|
||||
@@ -40,7 +40,16 @@ namespace nana
|
||||
simple_dragdrop(simple_dragdrop&&) = delete;
|
||||
simple_dragdrop& operator=(simple_dragdrop&&) = delete;
|
||||
public:
|
||||
simple_dragdrop(window source);
|
||||
explicit simple_dragdrop(window source);
|
||||
simple_dragdrop(window drag_origin,
|
||||
std::function<bool()> when,
|
||||
window drop_target,
|
||||
std::function<void()> how)
|
||||
: simple_dragdrop{drag_origin}
|
||||
{
|
||||
condition(when);
|
||||
make_drop(drop_target, how);
|
||||
}
|
||||
~simple_dragdrop();
|
||||
|
||||
/// Condition checker
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
/**
|
||||
* An Implementation of Place for Layout
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 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/gui/place.cpp
|
||||
* @file nana/gui/place.cpp
|
||||
*
|
||||
* @contributions:
|
||||
* min/max and splitter bar initial weight by Ariel Vina-Rodriguez.
|
||||
* @contributions
|
||||
* error, width/height, min/max and splitter bar initial weight by Ariel Vina-Rodriguez.
|
||||
*/
|
||||
|
||||
#ifndef NANA_GUI_PLACE_HPP
|
||||
@@ -79,6 +79,7 @@ namespace nana
|
||||
{
|
||||
struct implement;
|
||||
|
||||
|
||||
class field_interface
|
||||
{
|
||||
field_interface(const field_interface&) = delete;
|
||||
@@ -103,6 +104,19 @@ namespace nana
|
||||
virtual void _m_add_agent(const detail::place_agent&) = 0;
|
||||
};
|
||||
public:
|
||||
class error :public std::invalid_argument
|
||||
{
|
||||
public:
|
||||
error( const std::string& what,
|
||||
const place& plc,
|
||||
std::string field = "unknown",
|
||||
std::string::size_type pos = std::string::npos);
|
||||
std::string base_what;
|
||||
std::string owner_caption; ///< truncate caption (title) of the "placed" widget
|
||||
std::string div_text; ///< involved div_text
|
||||
std::string field; ///< posible field where the error ocurred.
|
||||
std::string::size_type pos; ///< posible position in the div_text where the error ocurred. npos if unknown
|
||||
};
|
||||
/// reference to a field manipulator which refers to a field object created by place
|
||||
using field_reference = field_interface &;
|
||||
|
||||
@@ -119,9 +133,13 @@ namespace nana
|
||||
|
||||
void splitter_renderer(std::function<void(window, paint::graphics&, mouse_action)> fn);
|
||||
|
||||
void div(std::string div_text); ///< Divides the attached widget into fields.
|
||||
void div(std::string div_text); ///< Divides the attached widget into fields. May throw placa::error
|
||||
const std::string& div() const noexcept; ///< Returns div-text that depends on fields status.
|
||||
void modify(const char* field_name, const char* div_text); ///< Modifies a specified field.
|
||||
static bool valid_field_name(const char* name) ///< must begin with _a-zA-Z
|
||||
{
|
||||
return name && (*name == '_' || (('a' <= *name && *name <= 'z') || ('A' <= *name && *name <= 'Z')));
|
||||
}
|
||||
void modify(const char* field_name, const char* div_text); ///< Modifies a specified field. May throw placa::error
|
||||
|
||||
field_reference field(const char* name);///< Returns a field with the specified name.
|
||||
|
||||
@@ -152,6 +170,8 @@ namespace nana
|
||||
private:
|
||||
implement * impl_;
|
||||
};
|
||||
|
||||
|
||||
}//end namespace nana
|
||||
#include <nana/pop_ignore_diagnostic>
|
||||
|
||||
|
||||
@@ -35,7 +35,10 @@ namespace nana{
|
||||
}//end namespace drawerbase
|
||||
|
||||
class group
|
||||
: public widget_object<category::widget_tag, drawerbase::panel::drawer, general_events, drawerbase::group::scheme>
|
||||
: public widget_object<category::widget_tag,
|
||||
drawerbase::panel::drawer,
|
||||
general_events,
|
||||
drawerbase::group::scheme>
|
||||
{
|
||||
struct implement;
|
||||
public:
|
||||
@@ -56,7 +59,6 @@ namespace nana{
|
||||
group(window parent, const rectangle& = {}, bool visible = true);
|
||||
|
||||
/// The construction that creates the widget and set the title or caption
|
||||
|
||||
group(window parent, ///< a handle to the parent
|
||||
::std::string title, ///< caption of the group
|
||||
bool formatted = false, ///< Enable/disable the formatted text for the title
|
||||
|
||||
@@ -1292,7 +1292,10 @@ the nana::detail::basic_window member pointer scheme
|
||||
\example listbox_Resolver.cpp
|
||||
*/
|
||||
class listbox
|
||||
: public widget_object<category::widget_tag, drawerbase::listbox::trigger, drawerbase::listbox::listbox_events, drawerbase::listbox::scheme>,
|
||||
: public widget_object<category::widget_tag,
|
||||
drawerbase::listbox::trigger,
|
||||
drawerbase::listbox::listbox_events,
|
||||
drawerbase::listbox::scheme>,
|
||||
public concepts::any_objective<drawerbase::listbox::size_type, 2>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -77,7 +77,10 @@ namespace nana
|
||||
|
||||
/// Spinbox Widget
|
||||
class spinbox
|
||||
: public widget_object <category::widget_tag, drawerbase::spinbox::drawer, drawerbase::spinbox::spinbox_events, ::nana::widgets::skeletons::text_editor_scheme>
|
||||
: public widget_object <category::widget_tag,
|
||||
drawerbase::spinbox::drawer,
|
||||
drawerbase::spinbox::spinbox_events,
|
||||
::nana::widgets::skeletons::text_editor_scheme>
|
||||
{
|
||||
public:
|
||||
/// Constructs a spinbox.
|
||||
|
||||
@@ -350,7 +350,9 @@ namespace nana
|
||||
/// \brief Displays a hierarchical list of items, such as the files and directories on a disk.
|
||||
/// See also in [documentation](http://nanapro.org/en-us/documentation/widgets/treebox.htm)
|
||||
class treebox
|
||||
:public widget_object <category::widget_tag, drawerbase::treebox::trigger, drawerbase::treebox::treebox_events, drawerbase::treebox::scheme>
|
||||
:public widget_object <category::widget_tag,
|
||||
drawerbase::treebox::trigger,
|
||||
drawerbase::treebox::treebox_events, drawerbase::treebox::scheme>
|
||||
{
|
||||
public:
|
||||
/// A type refers to the item and is also used to iterate through the nodes.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
/**
|
||||
* An Implementation of Place for Layout
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* (See accompanying file LICENSE or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/gui/place.cpp
|
||||
* @contributors: Ariel Vina-Rodriguez
|
||||
* @file nana/gui/place.cpp
|
||||
* @contributors Ariel Vina-Rodriguez
|
||||
* dankan1890(PR#156)
|
||||
*/
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
|
||||
namespace nana
|
||||
{
|
||||
namespace place_parts
|
||||
struct badname: place::error
|
||||
{
|
||||
//check the name
|
||||
void check_field_name(const char* name)
|
||||
{
|
||||
if (*name && (*name != '_' && !(('a' <= *name && *name <= 'z') || ('A' <= *name && *name <= 'Z'))))
|
||||
throw std::invalid_argument("nana.place: bad field name");
|
||||
}
|
||||
}//end namespace place_parts
|
||||
|
||||
explicit badname( ::std::string what,
|
||||
const place& plc,
|
||||
const char* name = "unknown",
|
||||
std::string::size_type pos = std::string::npos)
|
||||
:place::error(what + ": bad field name '" + (name ? name : "nullptr") + "'.",
|
||||
plc, (name ? name : "nullptr"), pos)
|
||||
{}
|
||||
};
|
||||
typedef place_parts::number_t number_t;
|
||||
typedef place_parts::repeated_array repeated_array;
|
||||
|
||||
@@ -54,6 +54,20 @@ namespace nana
|
||||
class tokenizer
|
||||
{
|
||||
public:
|
||||
/// \todo add member full_what and overrider what() in internal exeptions
|
||||
struct error : std::invalid_argument
|
||||
{
|
||||
error(std::string what,
|
||||
const tokenizer& tok)
|
||||
|
||||
: std::invalid_argument{ what + " from tokenizer " },
|
||||
pos{tok.pos()},
|
||||
div_str(tok.divstr_)
|
||||
{}
|
||||
std::string::size_type pos;
|
||||
std::string div_str;
|
||||
};
|
||||
|
||||
enum class token
|
||||
{
|
||||
div_start, div_end, splitter,
|
||||
@@ -73,7 +87,7 @@ namespace nana
|
||||
return idstr_;
|
||||
}
|
||||
|
||||
const number_t& number() const
|
||||
const number_t& number() const noexcept
|
||||
{
|
||||
return number_;
|
||||
}
|
||||
@@ -93,9 +107,9 @@ namespace nana
|
||||
return parameters_;
|
||||
}
|
||||
|
||||
std::size_t pos() const noexcept
|
||||
std::string::size_type pos() const noexcept
|
||||
{
|
||||
return (sp_ - divstr_);
|
||||
return static_cast<std::string::size_type>(sp_ - divstr_);
|
||||
}
|
||||
|
||||
token read()
|
||||
@@ -137,9 +151,13 @@ namespace nana
|
||||
while (true)
|
||||
{
|
||||
sp_ = _m_eat_whitespace(sp_);
|
||||
auto tk = read();
|
||||
if (token::number != tk && token::variable != tk && token::repeated != tk)
|
||||
_m_throw_error("invalid array element");
|
||||
auto tk = read(); // try ??
|
||||
|
||||
if ( token::number != tk
|
||||
&& token::variable != tk
|
||||
&& token::repeated != tk)
|
||||
|
||||
throw error("invalid array element. Expected a number, variable or repaet", *this);
|
||||
|
||||
if (!repeated)
|
||||
{
|
||||
@@ -165,7 +183,7 @@ namespace nana
|
||||
return (repeated ? token::reparray : token::array);
|
||||
|
||||
if (ch != ',')
|
||||
_m_throw_error("invalid array");
|
||||
throw error("invalid array", *this);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -183,7 +201,7 @@ namespace nana
|
||||
if (token::number == read())
|
||||
parameters_.push_back(number_);
|
||||
else
|
||||
_m_throw_error("invalid parameter.");
|
||||
throw error("invalid parameter. Expected a number", *this);
|
||||
|
||||
sp_ = _m_eat_whitespace(sp_);
|
||||
char ch = *sp_++;
|
||||
@@ -192,7 +210,7 @@ namespace nana
|
||||
return token::parameters;
|
||||
|
||||
if (ch != ',')
|
||||
_m_throw_error("invalid parameter.");
|
||||
throw error("invalid parameter. Expected a ','", *this);
|
||||
}
|
||||
break;
|
||||
case '.': case '-':
|
||||
@@ -211,7 +229,7 @@ namespace nana
|
||||
return token::number;
|
||||
}
|
||||
else
|
||||
_m_throw_error("invalid character '" + std::string(1, *sp_) + "'");
|
||||
throw error("invalid character '" + std::string(1, *sp_) + "'", *this);
|
||||
break;
|
||||
default:
|
||||
if ('0' <= *sp_ && *sp_ <= '9')
|
||||
@@ -269,14 +287,14 @@ namespace nana
|
||||
{
|
||||
auto idstr = idstr_;
|
||||
if (token::equal != read())
|
||||
_m_throw_error("an equal sign is required after '" + idstr + "'");
|
||||
throw error("an equal sign is required after '" + idstr + "'", *this);
|
||||
|
||||
return ('g' == idstr[0] ? token::grid : token::margin);
|
||||
}
|
||||
else if ("collapse" == idstr_)
|
||||
{
|
||||
if (token::parameters != read())
|
||||
_m_throw_error("a parameter list is required after 'collapse'");
|
||||
throw error("a parameter list is required after 'collapse'", *this);
|
||||
return token::collapse;
|
||||
}
|
||||
else if (!idstr_.empty())
|
||||
@@ -333,22 +351,14 @@ namespace nana
|
||||
return token::identifier;
|
||||
}
|
||||
|
||||
std::string err = "an invalid character '";
|
||||
err += *sp_;
|
||||
err += "'";
|
||||
_m_throw_error(err);
|
||||
throw error("invalid character '" + std::string(1, *sp_) + "'", *this);
|
||||
return token::error; //Useless, just for syntax correction.
|
||||
}
|
||||
private:
|
||||
void _m_throw_error(const std::string& err)
|
||||
{
|
||||
throw std::runtime_error("nana::place: " + err + " at " + std::to_string(static_cast<unsigned>(sp_ - divstr_)));
|
||||
}
|
||||
|
||||
void _m_attr_number_value()
|
||||
{
|
||||
if (token::equal != read())
|
||||
_m_throw_error("an equal sign is required after '" + idstr_ + "'");
|
||||
throw error("an equal sign is required after '" + idstr_ + "'", *this);
|
||||
|
||||
auto p = _m_eat_whitespace(sp_);
|
||||
|
||||
@@ -358,7 +368,7 @@ namespace nana
|
||||
|
||||
auto len = _m_number(p, neg_ptr != p);
|
||||
if (0 == len)
|
||||
_m_throw_error("the '" + idstr_ + "' requires a number(integer or real or percent)");
|
||||
throw error("the '" + idstr_ + "' requires a number (integer, real or percent)", *this);
|
||||
|
||||
sp_ += len + (p - sp_);
|
||||
}
|
||||
@@ -367,7 +377,7 @@ namespace nana
|
||||
{
|
||||
auto idstr = idstr_;
|
||||
if (token::equal != read())
|
||||
_m_throw_error("an equal sign is required after '" + idstr + "'");
|
||||
throw error("an equal sign is required after '" + idstr + "'", *this);
|
||||
|
||||
sp_ = _m_eat_whitespace(sp_);
|
||||
|
||||
@@ -385,19 +395,21 @@ namespace nana
|
||||
case token::reparray:
|
||||
break;
|
||||
default:
|
||||
_m_throw_error("a (repeated) array is required after '" + idstr + "'");
|
||||
throw error("a (repeated) array is required after '" + idstr + "'", *this);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* _m_eat_whitespace(const char* sp) noexcept
|
||||
{
|
||||
while (*sp && !std::isgraph(*sp))
|
||||
while (*sp && !std::isgraph(int(*sp)))
|
||||
++sp;
|
||||
return sp;
|
||||
}
|
||||
|
||||
std::size_t _m_number(const char* sp, bool negative) noexcept
|
||||
{
|
||||
/// \todo use std::from_char<int>() etc.
|
||||
|
||||
const char* allstart = sp;
|
||||
sp = _m_eat_whitespace(sp);
|
||||
|
||||
@@ -462,8 +474,8 @@ namespace nana
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
const char* divstr_;
|
||||
const char* sp_;
|
||||
const char* divstr_{};
|
||||
const char* sp_{};
|
||||
std::string idstr_;
|
||||
number_t number_;
|
||||
std::vector<number_t> array_;
|
||||
@@ -482,7 +494,6 @@ namespace nana
|
||||
return (vert ? pos.y : pos.x);
|
||||
}
|
||||
|
||||
|
||||
static bool is_idchar(int ch) noexcept
|
||||
{
|
||||
return ('_' == ch || std::isalnum(ch));
|
||||
@@ -490,6 +501,7 @@ namespace nana
|
||||
|
||||
static std::size_t find_idstr(const std::string& text, const char* idstr, std::size_t off = 0)
|
||||
{
|
||||
if (!idstr) return text.npos; /// ??
|
||||
const auto len = std::strlen(idstr);
|
||||
|
||||
size_t pos;
|
||||
@@ -596,6 +608,20 @@ namespace nana
|
||||
//struct implement
|
||||
struct place::implement
|
||||
{
|
||||
/// usefull ??
|
||||
struct error : std::invalid_argument
|
||||
{
|
||||
error(std::string what,
|
||||
std::string field = "unknown",
|
||||
std::string::size_type pos = std::string::npos)
|
||||
|
||||
: std::invalid_argument{ what + " from place implementation " },
|
||||
pos{ pos },
|
||||
field { field.empty() ? "unnamed" : field }
|
||||
{}
|
||||
std::string::size_type pos;
|
||||
std::string field;
|
||||
};
|
||||
class field_gather;
|
||||
class field_dock;
|
||||
|
||||
@@ -643,6 +669,8 @@ namespace nana
|
||||
: public place::field_interface
|
||||
{
|
||||
public:
|
||||
|
||||
/// \todo introduce a place::implement::field_gather::error ??
|
||||
struct element_t
|
||||
{
|
||||
window handle;
|
||||
@@ -692,13 +720,13 @@ namespace nana
|
||||
return nullptr;
|
||||
}
|
||||
private:
|
||||
void _m_insert_widget(window wd, bool to_fasten)
|
||||
void _m_insert_widget(window wd, bool to_fasten) /// \todo better errors caption of failed windows, field
|
||||
{
|
||||
if (API::empty_window(wd))
|
||||
throw std::invalid_argument("Place: An invalid window handle.");
|
||||
throw place::error("Failed to insert an invalid window handle.", *place_ptr_);
|
||||
|
||||
if (API::get_parent_window(wd) != place_ptr_->window_handle())
|
||||
throw std::invalid_argument("Place: the window is not a child of place bind window");
|
||||
throw place::error("Failed to insert a window which is not a child of the place-binded window", *place_ptr_);
|
||||
|
||||
//Listen to destroy of a window
|
||||
//It will delete the element and recollocate when the window destroyed.
|
||||
@@ -1984,11 +2012,11 @@ namespace nana
|
||||
return;
|
||||
|
||||
auto fieldstr = div.substr(bound.first, bound.second - bound.first);
|
||||
_m_remove_attr(fieldstr, "weight");
|
||||
_m_remove_attr(fieldstr, "weight"); /// \todo and higth, width ?
|
||||
|
||||
std::string::size_type tag_pos{ left ? div.find('<', bound.second + 2) : div.rfind('>', bound.first - 2) };
|
||||
if (div.npos == tag_pos)
|
||||
throw std::invalid_argument("please report an issue if it throws");
|
||||
throw place::implement::error("please report an issue: the splitter was unable to update division " + div, name);
|
||||
|
||||
auto other_bound = get_field_boundary(div, tag_pos);
|
||||
|
||||
@@ -2704,7 +2732,7 @@ namespace nana
|
||||
return static_cast<int>(arg.real());
|
||||
|
||||
const char* pos_strs[] = { "1st", "2nd", "3rd", "4th" };
|
||||
throw std::invalid_argument("nana.place: the type of the " + std::string{pos_strs[pos]} +"th parameter for collapse should be integer.");
|
||||
throw place_parts::tokenizer::error("the type of the " + std::string{pos_strs[pos]} +" parameter for collapse should be integer.", tknizer);
|
||||
}
|
||||
|
||||
//implicitly_started indicates whether the field in div-text starts without < mark.
|
||||
@@ -2732,13 +2760,14 @@ namespace nana
|
||||
bool invisible = false;
|
||||
|
||||
token tk = token::eof;
|
||||
try {
|
||||
for (tk = tknizer.read(); (tk != token::eof && tk != token::div_end); tk = tknizer.read())
|
||||
{
|
||||
switch (tk)
|
||||
{
|
||||
case token::dock:
|
||||
if (token::eof != div_type && token::dock != div_type)
|
||||
throw std::invalid_argument("nana.place: conflict of div type at " + std::to_string(tknizer.pos()));
|
||||
throw std::invalid_argument("conflict of div type -expected dock type-");
|
||||
|
||||
div_type = token::dock;
|
||||
break;
|
||||
@@ -2807,7 +2836,7 @@ namespace nana
|
||||
case token::collapse:
|
||||
{
|
||||
if (tknizer.parameters().size() != 4)
|
||||
throw std::invalid_argument("nana.place: collapse requires 4 parameters.");
|
||||
throw std::invalid_argument("collapse requires 4 parameters");
|
||||
|
||||
::nana::rectangle col{
|
||||
get_parameter(tknizer, 0),
|
||||
@@ -2903,7 +2932,7 @@ namespace nana
|
||||
}
|
||||
|
||||
if (implicitly_started && (tk == token::div_end))
|
||||
throw std::invalid_argument("nana.place: the div-text ends prematurely at " + std::to_string(tknizer.pos()));
|
||||
throw std::invalid_argument("the div-text ends prematurely");
|
||||
|
||||
field_gather * attached_field = nullptr;
|
||||
|
||||
@@ -2918,7 +2947,7 @@ namespace nana
|
||||
{
|
||||
//The fields are allowed to have a same name. E.g.
|
||||
//place.div("A <B><C>");
|
||||
//place.modify("A", "<B>"); Here the same name B must be allowed, otherwise it throws runtime error.
|
||||
//place.modify("A", "<B>"); Here the same name B must be allowed, otherwise it throws std::invalid_argument.
|
||||
|
||||
bool allow_same_name = false;
|
||||
if (!ignore_duplicate.empty())
|
||||
@@ -2937,7 +2966,7 @@ namespace nana
|
||||
}
|
||||
|
||||
if (!allow_same_name)
|
||||
throw std::runtime_error("place, the name '" + name + "' is redefined.");
|
||||
throw std::invalid_argument("redefined field name");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2951,7 +2980,7 @@ namespace nana
|
||||
|
||||
for (auto& ch : children)
|
||||
if (ch->weigth_type == unmatch)
|
||||
throw std::invalid_argument("nana.place: unmatch vertical-height/horizontal-width between division '"
|
||||
throw std::invalid_argument("unmatch vertical-height/horizontal-width between division '"
|
||||
+ name + "' and children division '" + ch->name);
|
||||
|
||||
div.reset(new div_arrange(token::vert == div_type, std::move(name), std::move(arrange)));
|
||||
@@ -2983,7 +3012,7 @@ namespace nana
|
||||
div.reset(new div_switchable(std::move(name), this));
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("nana.place: invalid division type.");
|
||||
throw std::invalid_argument("invalid division type.");
|
||||
}
|
||||
div->weigth_type = weight_type;
|
||||
|
||||
@@ -3076,7 +3105,25 @@ namespace nana
|
||||
div->visible = !(undisplayed || invisible);
|
||||
div->fit = fit;
|
||||
div->fit_parameters = std::move(fit_parameters);
|
||||
|
||||
}
|
||||
catch (place::error& ) { throw; }
|
||||
catch ( error& ) { throw; }
|
||||
catch (place_parts::tokenizer::error& e)
|
||||
{
|
||||
throw error(e.what(), name, e.pos);
|
||||
}
|
||||
catch (std::invalid_argument& e)
|
||||
{
|
||||
throw error(e.what(), name, tknizer.pos());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
throw error(std::string{"unexpected error: "}+e.what(), name, tknizer.pos());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw error("unknow error", name, tknizer.pos());
|
||||
}
|
||||
return div;
|
||||
}
|
||||
|
||||
@@ -3213,7 +3260,8 @@ namespace nana
|
||||
void place::bind(window wd)
|
||||
{
|
||||
if (impl_->window_handle)
|
||||
throw std::runtime_error("place.bind: it has already bound to a window.");
|
||||
throw error(" bind('"+ API::window_caption(wd).substr(0, 80)
|
||||
+ "'): it was already bound to another window.", *this);
|
||||
|
||||
impl_->window_handle = wd;
|
||||
impl_->event_size_handle = API::events(wd).resized.connect_unignorable([this](const arg_resized& arg)
|
||||
@@ -3241,21 +3289,37 @@ namespace nana
|
||||
}
|
||||
|
||||
void place::div(std::string div_text)
|
||||
{
|
||||
try
|
||||
{
|
||||
place_parts::tokenizer tknizer(div_text.c_str());
|
||||
impl_->disconnect();
|
||||
auto div = impl_->scan_div(tknizer, true);
|
||||
try
|
||||
{
|
||||
impl_->connect(div.get()); //throws if there is a redefined name of field.
|
||||
impl_->root_division.reset(); //clear attachments div-fields
|
||||
impl_->root_division.swap(div);
|
||||
impl_->div_text.swap(div_text);
|
||||
}
|
||||
catch (place::error & ) { throw; }
|
||||
catch (place::implement::error & e)
|
||||
{
|
||||
throw error("failed to set div('" + div_text + "'): " + e.what(), *this, e.field, e.pos);
|
||||
}
|
||||
catch (place_parts::tokenizer::error & e)
|
||||
{
|
||||
throw error("failed to set div('" + div_text + "'): " + e.what(), *this, "", e.pos);
|
||||
}
|
||||
catch (std::invalid_argument & e)
|
||||
{
|
||||
throw error("failed to set div('" + div_text + "'): " + e.what(), *this);
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
throw error("failed to set div('"+div_text+"'): unexpected error: " +e.what(), *this );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
//redefined a name of field
|
||||
throw;
|
||||
throw error("failed to set div('" + div_text + "'): unknonw error", *this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3272,23 +3336,15 @@ namespace nana
|
||||
void place::modify(const char* name, const char* div_text)
|
||||
{
|
||||
if (nullptr == div_text)
|
||||
throw std::invalid_argument("nana.place: invalid div-text");
|
||||
throw error("modify(): invalid div-text (=nullptr)", *this);
|
||||
|
||||
if (nullptr == name) name = "";
|
||||
|
||||
//check the name, it throws std::invalid_argument
|
||||
//if name violate the naming convention.
|
||||
place_parts::check_field_name(name);
|
||||
if (! valid_field_name(name) )
|
||||
throw badname("modify()", *this, name);
|
||||
|
||||
auto div_ptr = impl_->search_div_name(impl_->root_division.get(), name);
|
||||
if (!div_ptr)
|
||||
{
|
||||
std::string what = "nana::place: field '";
|
||||
what += name;
|
||||
what += "' is not found.";
|
||||
throw error("modify(): field was not found", *this, name);
|
||||
|
||||
throw std::invalid_argument(what);
|
||||
}
|
||||
|
||||
std::unique_ptr<implement::division>* replaced = nullptr;
|
||||
|
||||
@@ -3342,23 +3398,44 @@ namespace nana
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
catch (place::error & )
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw;
|
||||
}
|
||||
catch (place::implement::error & e)
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw error("failed to modify('"+std::string(name) +", "+ div_text + "'): " + e.what(), *this, e.field, e.pos);
|
||||
}
|
||||
catch (place_parts::tokenizer::error & e)
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw error("failed to modify('" + std::string(name) + ", " + div_text + "'): " + e.what(), *this, "", e.pos);
|
||||
}
|
||||
catch (std::invalid_argument & e)
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw error("failed to modify('" + std::string(name) + ", " + div_text + "'): " + e.what(), *this);
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw error("failed to modify('" + std::string(name) + ", " + div_text + "'): unexpected error: " + e.what(), *this);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
replaced->swap(impl_->tmp_replaced);
|
||||
throw error("failed to modify('" + std::string(name) + ", " + div_text + "'): unknonw error", *this);
|
||||
}
|
||||
}
|
||||
|
||||
place::field_reference place::field(const char* name)
|
||||
{
|
||||
if (nullptr == name)
|
||||
name = "";
|
||||
if (!valid_field_name(name))
|
||||
throw badname("field()", *this, name);
|
||||
|
||||
//check the name, it throws std::invalid_argument
|
||||
//if name violate the naming convention.
|
||||
place_parts::check_field_name(name);
|
||||
|
||||
//get the field with specified name, if no such field with specified name
|
||||
//get the field with the specified name. If no such field with specified name
|
||||
//then create one.
|
||||
auto & p = impl_->fields[name];
|
||||
if (nullptr == p)
|
||||
@@ -3367,12 +3444,12 @@ namespace nana
|
||||
if ((!p->attached) && impl_->root_division)
|
||||
{
|
||||
//search the division with the specified name,
|
||||
//and attached the division to the field
|
||||
//and attaches the division to the field
|
||||
auto div = implement::search_div_name(impl_->root_division.get(), name);
|
||||
if (div)
|
||||
{
|
||||
if (div->field && (div->field != p))
|
||||
throw std::runtime_error("nana.place: unexpected error, the division attaches an unexpected field.");
|
||||
throw error("field(): the division attaches an unexpected field", *this, name);
|
||||
|
||||
div->field = p;
|
||||
p->attached = div;
|
||||
@@ -3449,10 +3526,8 @@ namespace nana
|
||||
|
||||
void place::field_visible(const char* name, bool vsb)
|
||||
{
|
||||
if (!name) name = "";
|
||||
|
||||
//May throw std::invalid_argument
|
||||
place_parts::check_field_name(name);
|
||||
if (!valid_field_name(name))
|
||||
throw badname("field_visible()", *this, name);
|
||||
|
||||
auto div = impl_->search_div_name(impl_->root_division.get(), name);
|
||||
if (div)
|
||||
@@ -3464,10 +3539,8 @@ namespace nana
|
||||
|
||||
bool place::field_visible(const char* name) const
|
||||
{
|
||||
if (!name) name = "";
|
||||
|
||||
//May throw std::invalid_argument
|
||||
place_parts::check_field_name(name);
|
||||
if (!valid_field_name(name))
|
||||
throw badname("field_visible()", *this, name);
|
||||
|
||||
auto div = impl_->search_div_name(impl_->root_division.get(), name);
|
||||
return (div && div->visible);
|
||||
@@ -3475,10 +3548,8 @@ namespace nana
|
||||
|
||||
void place::field_display(const char* name, bool dsp)
|
||||
{
|
||||
if (!name) name = "";
|
||||
|
||||
//May throw std::invalid_argument
|
||||
place_parts::check_field_name(name);
|
||||
if (!valid_field_name(name))
|
||||
throw badname("field_display()", *this, name);
|
||||
|
||||
auto div = impl_->search_div_name(impl_->root_division.get(), name);
|
||||
if (div)
|
||||
@@ -3491,10 +3562,8 @@ namespace nana
|
||||
|
||||
bool place::field_display(const char* name) const
|
||||
{
|
||||
if (!name) name = "";
|
||||
|
||||
//May throw std::invalid_argument
|
||||
place_parts::check_field_name(name);
|
||||
if (!valid_field_name(name))
|
||||
throw badname("field_display()", *this, name);
|
||||
|
||||
auto div = impl_->search_div_name(impl_->root_division.get(), name);
|
||||
return (div && div->display);
|
||||
@@ -3531,9 +3600,8 @@ namespace nana
|
||||
|
||||
place& place::dock(const std::string& name, std::string factory_name, std::function<std::unique_ptr<widget>(window)> factory)
|
||||
{
|
||||
//check the name, it throws std::invalid_argument
|
||||
//if name violate the naming convention.
|
||||
place_parts::check_field_name(name.data());
|
||||
if (!valid_field_name(name.data()))
|
||||
throw badname("dock()", *this, name.data());
|
||||
|
||||
auto & dock_ptr = impl_->docks[name];
|
||||
if (!dock_ptr)
|
||||
@@ -3543,7 +3611,7 @@ namespace nana
|
||||
if (!factory_name.empty())
|
||||
{
|
||||
if (impl_->dock_factoris.find(factory_name) != impl_->dock_factoris.end())
|
||||
throw std::invalid_argument("nana::place - the specified factory name(" + factory_name + ") already exists");
|
||||
throw error("dock() - the specified factory name(" + factory_name + ") already exists", *this, name);
|
||||
|
||||
impl_->dock_factoris[factory_name] = dock_ptr;
|
||||
dock_ptr->factories[factory_name] = std::move(factory);
|
||||
@@ -3579,7 +3647,7 @@ namespace nana
|
||||
{
|
||||
auto i = impl_->dock_factoris.find(factory);
|
||||
if (i == impl_->dock_factoris.end())
|
||||
throw std::invalid_argument("invalid factory name(" + factory + ") of dockpane");
|
||||
throw std::invalid_argument("nana::place::dock_create - invalid factory name(" + factory + ") of dockpane");
|
||||
|
||||
auto dock_ptr = i->second;
|
||||
if (dock_ptr->attached)
|
||||
@@ -3600,7 +3668,27 @@ namespace nana
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
place::error::error(const std::string& what,
|
||||
const place& plc,
|
||||
std::string field,
|
||||
std::string::size_type pos)
|
||||
|
||||
: std::invalid_argument{ "from widget '"
|
||||
+ API::window_caption(plc.window_handle()).substr(0,80)
|
||||
+ "'; nana::place error "
|
||||
+ what
|
||||
+ "' in field '" + field
|
||||
+ (pos == std::string::npos ? "' " : "' at position " + std::to_string(pos))
|
||||
+ " in div_text:\n" + plc.div() },
|
||||
base_what{ what },
|
||||
owner_caption{ API::window_caption(plc.window_handle()).substr(0,80) },
|
||||
div_text{ plc.div() },
|
||||
field{ field },
|
||||
pos{ pos }
|
||||
{}
|
||||
//end class place
|
||||
|
||||
}//end namespace nana
|
||||
|
||||
#include <nana/pop_ignore_diagnostic>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
/**
|
||||
* Parts of Class Place
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2003-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* (See accompanying file LICENSE or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/gui/place_parts.hpp
|
||||
* @file nana/gui/place_parts.hpp
|
||||
*/
|
||||
#ifndef NANA_GUI_PLACE_PARTS_HPP
|
||||
#define NANA_GUI_PLACE_PARTS_HPP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* A Categorize Implementation
|
||||
* Nana C++ Library(http://www.nanapro.org)
|
||||
* Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
|
||||
@@ -7,7 +7,7 @@
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/gui/widgets/categorize.cpp
|
||||
* @file nana/gui/widgets/categorize.cpp
|
||||
*/
|
||||
|
||||
#include <nana/gui/wvl.hpp>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
* A group widget implementation
|
||||
* Nana C++ Library(http://www.nanaro.org)
|
||||
* Copyright(C) 2015-2018 Jinhao(cnjinhao@hotmail.com)
|
||||
* Copyright(C) 2015-2019 Jinhao(cnjinhao@hotmail.com)
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* (See accompanying file LICENSE or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* @file: nana/gui/widgets/group.cpp
|
||||
* @file nana/gui/widgets/group.cpp
|
||||
*
|
||||
* @Author: Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
|
||||
* @author Stefan Pfeifer(st-321), Ariel Vina-Rodriguez (qPCR4vir)
|
||||
*
|
||||
* @brief group is a widget used to visually group and layout other widgets.
|
||||
*
|
||||
* @contributor:
|
||||
* @contributor
|
||||
* dankan1890(https://github.com/dankan1890)
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user