[gtkmm] Gtk::TextIter: Use sigc::slot in forward/backward_find_char()
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::TextIter: Use sigc::slot in forward/backward_find_char()
- Date: Fri, 13 Jan 2017 15:13:41 +0000 (UTC)
commit b66d67d0d429af85228e0ba6ef2713697adf59ca
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Fri Jan 13 16:10:09 2017 +0100
Gtk::TextIter: Use sigc::slot in forward/backward_find_char()
A function pointer in a glib/gtk+ function is usually represented by
a sigc::slot in the wrapping C++ method. Let's do that here, too.
gtk/src/textiter.ccg | 53 ++++++++++++++++++-
gtk/src/textiter.hg | 148 ++++++++++++++++++++------------------------------
2 files changed, 112 insertions(+), 89 deletions(-)
---
diff --git a/gtk/src/textiter.ccg b/gtk/src/textiter.ccg
index 1570514..6cecaf6 100644
--- a/gtk/src/textiter.ccg
+++ b/gtk/src/textiter.ccg
@@ -21,13 +21,64 @@
#include <gtkmm/textmark.h>
#include <gtkmm/textchildanchor.h>
+/**** Gtk::TextIterBase *******************************************************/
+
+namespace
+{
+gboolean TextIterBase_find_char_callback(gunichar ch, void* user_data)
+{
+ try
+ {
+ auto slot = static_cast<Gtk::TextIterBase::SlotFindChar*>(user_data);
+ return (*slot)(ch);
+ }
+ catch (...)
+ {
+ Glib::exception_handlers_invoke();
+ return false;
+ }
+}
+
+} // anonymous namespace
+
namespace Gtk
{
+bool TextIterBase::forward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
+{
+ // Use the original slot (not a copy).
+ auto slot_copy = const_cast<SlotFindChar*>(&slot);
-/**** Gtk::TextIterBase *******************************************************/
+ return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
+}
+
+bool TextIterBase::forward_find_char(const SlotFindChar& slot)
+{
+ // Use the original slot (not a copy).
+ auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+ return gtk_text_iter_forward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
+}
+
+bool TextIterBase::backward_find_char(const SlotFindChar& slot, const TextIterBase& limit)
+{
+ // Use the original slot (not a copy).
+ auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+ return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, limit.gobj());
+}
+
+bool TextIterBase::backward_find_char(const SlotFindChar& slot)
+{
+ // Use the original slot (not a copy).
+ auto slot_copy = const_cast<SlotFindChar*>(&slot);
+
+ return gtk_text_iter_backward_find_char(gobj(), &TextIterBase_find_char_callback, slot_copy, nullptr);
+}
} // namespace Gtk
+/**** Gtk::TextIter and Gtk::TextConstIter ************************************/
+
namespace Glib
{
// Can't have overloaded functions that differ only in return type.
diff --git a/gtk/src/textiter.hg b/gtk/src/textiter.hg
index e3afb84..056bc07 100644
--- a/gtk/src/textiter.hg
+++ b/gtk/src/textiter.hg
@@ -17,7 +17,6 @@
#include <vector>
#include <pangomm/language.h>
-#include <glibmm/exceptionhandler.h>
#include <gtkmm/texttag.h>
#include <gtk/gtk.h> /* we need the definition of GtkTextIter */
@@ -52,6 +51,7 @@ class TextIterBase
_CLASS_BOXEDTYPE_STATIC(TextIterBase, GtkTextIter)
_IGNORE(gtk_text_iter_copy, gtk_text_iter_free, gtk_text_iter_equal)
_IGNORE(gtk_text_iter_assign)
+
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = gunichar;
@@ -73,29 +73,6 @@ public:
*/
explicit operator bool() const;
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-protected:
- template <typename Predicate>
- struct PredicateAdapter
- {
- Predicate predicate_;
- inline explicit PredicateAdapter(const Predicate& predicate);
- static gboolean gtk_callback(gunichar uc, void* user_data);
- };
-
- _WRAP_METHOD(bool forward_find_char_impl(GtkTextCharPredicate predicate,
- void* user_data,
- const GtkTextIter* limit), gtk_text_iter_forward_find_char)
-
- _WRAP_METHOD(bool backward_find_char_impl(GtkTextCharPredicate predicate,
- void* user_data,
- const GtkTextIter* limit), gtk_text_iter_backward_find_char)
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-public:
-
_WRAP_METHOD(int get_offset() const, gtk_text_iter_get_offset)
_WRAP_METHOD(int get_line() const, gtk_text_iter_get_line)
_WRAP_METHOD(int get_line_offset() const, gtk_text_iter_get_line_offset)
@@ -191,14 +168,65 @@ public:
_WRAP_METHOD(bool forward_to_tag_toggle(const Glib::RefPtr<const TextTag>& tag = Glib::RefPtr<const
TextTag>()), gtk_text_iter_forward_to_tag_toggle)
_WRAP_METHOD(bool backward_to_tag_toggle(const Glib::RefPtr<const TextTag>& tag = Glib::RefPtr<const
TextTag>()), gtk_text_iter_backward_to_tag_toggle)
- template <typename Predicate>
- bool forward_find_char(const Predicate& predicate, const TextIterBase& limit);
- template <typename Predicate>
- bool forward_find_char(const Predicate& predicate);
- template <typename Predicate>
- bool backward_find_char(const Predicate& predicate, const TextIterBase& limit);
- template <typename Predicate>
- bool backward_find_char(const Predicate& predicate);
+ /** A slot that will be called on each consecutive character.
+ * forward_find_char() and backward_find_char() advance the iterator one
+ * character at a time until the slot returns <tt>true</tt>.
+ *
+ * For instance,
+ * @code
+ * bool on_find_char(gunichar ch);
+ * @endcode
+ *
+ * @newin{3,90}
+ */
+ using SlotFindChar = sigc::slot<bool(gunichar)>;
+
+ // _WRAP_METHOD can't be used here, because user_data is not the last parameter
+ // in the gtk+ functions.
+ //_WRAP_METHOD(bool forward_find_char(const SlotFindChar& slot{pred}, const TextIterBase& limit{.?}),
+ // gtk_text_iter_forward_find_char, slot_name slot, slot_callback TextIterBase_find_char_callback,
no_slot_copy)
+ //_WRAP_METHOD(bool backward_find_char(const SlotFindChar& slot{pred}, const TextIterBase& limit{.?}),
+ // gtk_text_iter_backward_find_char, slot_name slot, slot_callback TextIterBase_find_char_callback,
no_slot_copy)
+ _IGNORE(gtk_text_iter_forward_find_char, gtk_text_iter_backward_find_char)
+
+ /** Advances this iterator, calling @a slot on each character.
+ *
+ * If @a slot returns <tt>true</tt>, %forward_find_char() returns <tt>true</tt>
+ * and stops scanning.
+ * If @a slot never returns <tt>true</tt>, this iterator is set to @a limit.
+ *
+ * @param slot A function to be called on each character.
+ * @param limit Search limit.
+ * @return Whether a match was found.
+ */
+ bool forward_find_char(const SlotFindChar& slot, const TextIterBase& limit);
+
+ /** Advances this iterator, calling @a slot on each character.
+ *
+ * If @a slot returns <tt>true</tt>, %forward_find_char() returns <tt>true</tt>
+ * and stops scanning.
+ * If @a slot never returns <tt>true</tt>, this iterator is set to the end iterator.
+ *
+ * @param slot A function to be called on each character.
+ * @return Whether a match was found.
+ */
+ bool forward_find_char(const SlotFindChar& slot);
+
+ /** Same as forward_find_char(const SlotFindChar& slot, const TextIterBase& limit),
+ * but goes backward.
+ *
+ * @param slot Function to be called on each character.
+ * @param limit Search limit.
+ * @return Whether a match was found.
+ */
+ bool backward_find_char(const SlotFindChar& slot, const TextIterBase& limit);
+
+ /** Same as forward_find_char(const SlotFindChar& slot), but goes backward.
+ *
+ * @param slot Function to be called on each character.
+ * @return Whether a match was found.
+ */
+ bool backward_find_char(const SlotFindChar& slot);
_WRAP_METHOD(int compare(const TextIterBase& rhs) const, gtk_text_iter_compare)
_WRAP_METHOD(bool in_range(const TextIterBase& start, const TextIterBase& end) const,
gtk_text_iter_in_range)
@@ -327,30 +355,6 @@ public:
/**** Gtk::TextIterBase *******************************************************/
-template <typename Predicate> inline
-TextIterBase::PredicateAdapter<Predicate>::PredicateAdapter(const Predicate& predicate)
-:
- predicate_(predicate)
-{}
-
-// static
-template <typename Predicate>
-gboolean TextIterBase::PredicateAdapter<Predicate>::gtk_callback(gunichar uc, void* user_data)
-{
- try
- {
- // This will either use Predicate::operator(), or call a function pointer.
- // The explicit conditional expression avoids relying on an implicit
- // conversion of the return type to int, which might be not available.
- return (static_cast<TextIterBase::PredicateAdapter<Predicate>*>(user_data)->predicate_(uc)) ? 1 : 0;
- }
- catch(...)
- {
- Glib::exception_handlers_invoke();
- return 0;
- }
-}
-
inline
TextIterBase::value_type TextIterBase::operator*() const
{
@@ -363,38 +367,6 @@ TextIterBase::operator bool() const
return !is_end();
}
-template <typename Predicate>
-bool TextIterBase::forward_find_char(const Predicate& predicate, const TextIterBase& limit)
-{
- typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
- PredAdapter adapter(predicate);
- return this->forward_find_char_impl(&PredAdapter::gtk_callback, &adapter, limit.gobj());
-}
-
-template <typename Predicate>
-bool TextIterBase::forward_find_char(const Predicate& predicate)
-{
- typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
- PredAdapter adapter(predicate);
- return this->forward_find_char_impl(&PredAdapter::gtk_callback, &adapter, nullptr);
-}
-
-template <typename Predicate>
-bool TextIterBase::backward_find_char(const Predicate& predicate, const TextIterBase& limit)
-{
- typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
- PredAdapter adapter(predicate);
- return this->backward_find_char_impl(&PredAdapter::gtk_callback, &adapter, limit.gobj());
-}
-
-template <typename Predicate>
-bool TextIterBase::backward_find_char(const Predicate& predicate)
-{
- typedef TextIterBase::PredicateAdapter<Predicate> PredAdapter;
- PredAdapter adapter(predicate);
- return this->backward_find_char_impl(&PredAdapter::gtk_callback, &adapter, nullptr);
-}
-
/**** Gtk::TextIter ***********************************************************/
inline
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]