[gtkmm] Gtk::TreeView: Use std::strtol() and friends
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::TreeView: Use std::strtol() and friends
- Date: Fri, 20 Oct 2017 11:43:34 +0000 (UTC)
commit b90f88423b72c99da8e971e2bd23ff64c39b21aa
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Fri Oct 20 13:40:41 2017 +0200
Gtk::TreeView: Use std::strtol() and friends
Use std::strtol(), strtoul(), strtoll(), strtoull(), strtof(), strtod(),
strtold() for converting a string to a numerical value in
_auto_store_on_cellrenderer_text_edited_numerical<>().
This patch was inspired by a patch by Justinas <vygis d gmail com>.
Bug 765044
gtk/src/treeview.ccg | 76 +++++++++++++++++++++++++++++++++++++++++++++++++-
gtk/src/treeview.hg | 70 +++++++++++++++++++++++++++++++--------------
2 files changed, 123 insertions(+), 23 deletions(-)
---
diff --git a/gtk/src/treeview.ccg b/gtk/src/treeview.ccg
index 83e3679..5c98f11 100644
--- a/gtk/src/treeview.ccg
+++ b/gtk/src/treeview.ccg
@@ -15,8 +15,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <climits> // INT_MIN, etc.
#include <glibmm/vectorutils.h>
-
#include <gtkmm/treeviewcolumn.h>
#include <gtkmm/treeview_private.h>
#include <gtkmm/treemodel.h>
@@ -472,4 +472,78 @@ void TreeView::unset_row_separator_func()
gtk_tree_view_set_row_separator_func(gobj(), nullptr, nullptr, nullptr);
}
+namespace TreeView_Private
+{
+// Complete specializations of _convert_from_ustring_to_numeric_type()
+
+// Floating point specializations
+template<>
+float _convert_from_ustring_to_numeric_type<float>(const Glib::ustring& text)
+{
+ return std::strtof(text.c_str(), nullptr);
+}
+
+template<>
+long double _convert_from_ustring_to_numeric_type<long double>(const Glib::ustring& text)
+{
+ return std::strtold(text.c_str(), nullptr);
+}
+
+// Integral specializations
+template<>
+short _convert_from_ustring_to_numeric_type<short>(const Glib::ustring& text)
+{
+ const auto result = std::strtol(text.c_str(), nullptr, 0);
+ return (result < SHRT_MIN) ? SHRT_MIN :
+ ((result > SHRT_MAX) ? SHRT_MAX : static_cast<short>(result));
+}
+
+template<>
+unsigned short _convert_from_ustring_to_numeric_type<unsigned short>(const Glib::ustring& text)
+{
+ const auto result = std::strtoul(text.c_str(), nullptr, 0);
+ return (result > USHRT_MAX) ? USHRT_MAX : static_cast<unsigned short>(result);
+}
+
+template<>
+int _convert_from_ustring_to_numeric_type<int>(const Glib::ustring& text)
+{
+ const auto result = std::strtol(text.c_str(), nullptr, 0);
+ return (result < INT_MIN) ? INT_MIN :
+ ((result > INT_MAX) ? INT_MAX : static_cast<int>(result));
+}
+
+template<>
+unsigned int _convert_from_ustring_to_numeric_type<unsigned int>(const Glib::ustring& text)
+{
+ const auto result = std::strtoul(text.c_str(), nullptr, 0);
+ return (result > UINT_MAX) ? UINT_MAX : static_cast<unsigned int>(result);
+}
+
+template<>
+long _convert_from_ustring_to_numeric_type<long>(const Glib::ustring& text)
+{
+ return std::strtol(text.c_str(), nullptr, 0);
+}
+
+template<>
+unsigned long _convert_from_ustring_to_numeric_type<unsigned long>(const Glib::ustring& text)
+{
+ return std::strtoul(text.c_str(), nullptr, 0);
+}
+
+template<>
+long long _convert_from_ustring_to_numeric_type<long long>(const Glib::ustring& text)
+{
+ return std::strtoll(text.c_str(), nullptr, 0);
+}
+
+template<>
+unsigned long long _convert_from_ustring_to_numeric_type<unsigned long long>(const Glib::ustring& text)
+{
+ return std::strtoull(text.c_str(), nullptr, 0);
+}
+
+} // namespace TreeView_Private
+
} // namespace Gtk
diff --git a/gtk/src/treeview.hg b/gtk/src/treeview.hg
index a47247d..bbcb99e 100644
--- a/gtk/src/treeview.hg
+++ b/gtk/src/treeview.hg
@@ -20,7 +20,7 @@
_CONFIGINCLUDE(gtkmmconfig.h)
#include <vector>
-
+#include <cstdlib> // std::strto*()
#include <gtkmm/container.h>
#include <gtkmm/treeviewcolumn.h>
#include <gtkmm/treeselection.h>
@@ -69,6 +69,9 @@ namespace TreeView_Private
template <class ColumnType> inline
void _auto_cell_data_func(Gtk::CellRenderer* cell, const Gtk::TreeModel::const_iterator& iter, int
model_column, const Glib::ustring& format);
+
+ template <typename T>
+ T _convert_from_ustring_to_numeric_type(const Glib::ustring& text);
}
#endif //DOXYGEN_SHOULD_SKIP_THIS
@@ -203,7 +206,7 @@ public:
* This convenience template uses TreeView::Column::set_cell_data_func(), so the numeric formatting will
* be deactivated if you specify your own cell_data callback by calling set_cell_data_func() again.
*
- * Note that the user's input will be interpreted as decimal (base 10), regardless of the @a format.
+ * Note that the @a format does not influence the interpretation of the user's input.
*
* @param title The text to be used in the title header of this column.
* @param model_column The column in the TreeModel that will be rendered by this View column.
@@ -889,7 +892,6 @@ int TreeView::append_column_numeric_editable(const Glib::ustring& title, const T
int cols_count = append_column_numeric(title, model_column, format);
//connect signal handlers for auto-storing of edited cell data
- //Note: This will only work for base-10 (decimal) formatted numbers:
CellRenderer *const cell = get_column_cell_renderer(cols_count - 1);
if(cell)
{
@@ -1000,7 +1002,7 @@ void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::Cel
)
);
- //We use bind<1> instead of bind because some compilers need the extra hint.
+ //We use bind<-1> instead of bind because some compilers need the extra hint.
}
}
@@ -1054,6 +1056,46 @@ void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::Cel
namespace TreeView_Private
{
+// Primary template falls back to std::strtod()
+template <typename T>
+T _convert_from_ustring_to_numeric_type(const Glib::ustring& text)
+{
+ return std::strtod(text.c_str(), nullptr);
+}
+
+// Floating point specializations
+template<>
+float _convert_from_ustring_to_numeric_type<float>(const Glib::ustring& text);
+
+template<>
+long double _convert_from_ustring_to_numeric_type<long double>(const Glib::ustring& text);
+
+// Integral specializations
+template<>
+short _convert_from_ustring_to_numeric_type<short>(const Glib::ustring& text);
+
+template<>
+unsigned short _convert_from_ustring_to_numeric_type<unsigned short>(const Glib::ustring& text);
+
+template<>
+int _convert_from_ustring_to_numeric_type<int>(const Glib::ustring& text);
+
+template<>
+unsigned int _convert_from_ustring_to_numeric_type<unsigned int>(const Glib::ustring& text);
+
+template<>
+long _convert_from_ustring_to_numeric_type<long>(const Glib::ustring& text);
+
+template<>
+unsigned long _convert_from_ustring_to_numeric_type<unsigned long>(const Glib::ustring& text);
+
+template<>
+long long _convert_from_ustring_to_numeric_type<long long>(const Glib::ustring& text);
+
+template<>
+unsigned long long _convert_from_ustring_to_numeric_type<unsigned long long>(const Glib::ustring& text);
+
+
template <class ColumnType> inline
void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,
const Gtk::TreeModelColumn<ColumnType>& model_column)
{
@@ -1147,25 +1189,9 @@ void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path
auto iter = model->get_iter(path);
if(iter)
{
- //std::istringstream astream(new_text); //Put it in a stream.
- //ColumnType new_value = ColumnType();
- //new_value << astream; //Get it out of the stream as the numerical type.
-
- //Convert the text to a number, using the same logic used by GtkCellRendererText when it stores
numbers.
- ColumnType new_value = ColumnType();
- try
- {
- new_value = static_cast<ColumnType>( std::stod(new_text) );
- }
- catch(const std::invalid_argument&)
- {
- //Intentionally ignored.
- //Applications can use their own logic if they want to handle invalid input differently.
- }
-
- //Store the user's new text in the model:
+ // Convert the user's new text to a number, and store the number in the model:
Gtk::TreeRow row = *iter;
- row.set_value(model_column, (ColumnType)new_value);
+ row.set_value(model_column, _convert_from_ustring_to_numeric_type<ColumnType>(new_text));
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]