/* $Id: treepath.hg,v 1.15 2006/02/25 12:38:11 murrayc Exp $ */ /* Copyright(C) 1998-2002 The gtkmm Development Team * * This library is free software, ) you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation, ) either * version 2 of the License, or(at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY, ) without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library, ) if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ // This is for including the config header before any code (such as // the #ifndef GTKMM_DISABLE_DEPRECATED in deprecated classes) is generated: _CONFIGINCLUDE(gtkmmconfig.h) _DEFS(gtkmm,gtk) #include #include #include GLIBMM_USING_STD(random_access_iterator_tag) GLIBMM_USING_STD(reverse_iterator) namespace Gtk { /** A path is essentially a potential node. It is a location on a model that may * or may not actually correspond to a node on a specific model. * * A Path can be converted into either an array of unsigned integers or a string. The string * form is a list of numbers separated by a colon. Each number refers to the * offset at that level. Thus, the path "0" refers to the root node and the * path "2:4" refers to the fifth child of the third node. * * Typedefed as Gtk::TreeModel::Path. * @ingroup TreeView */ class TreePath { _CLASS_BOXEDTYPE(TreePath, GtkTreePath, gtk_tree_path_new, gtk_tree_path_copy, gtk_tree_path_free) _IGNORE(gtk_tree_path_copy, gtk_tree_path_free, gtk_tree_path_compare, gtk_tree_path_get_indices) public: typedef unsigned int size_type; typedef int difference_type; typedef int value_type; typedef int& reference; typedef const int& const_reference; // Use plain pointers for simplicity. typedef int* iterator; typedef const int* const_iterator; #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #else typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; #endif /* GLIBMM_HAVE_SUN_REVERSE_ITERATOR */ explicit TreePath(size_type n, value_type value = 0); explicit TreePath(const Glib::ustring& path); explicit TreePath(const TreeModel::iterator& iter); template inline TreePath(In pbegin, In pend); void clear(); // I think it's OK for this assignment to be implicit. It's very useful. TreePath& operator=(const TreeModel::iterator& iter); template inline void assign(In pbegin, In pend); template void append(In pbegin, In pend); _WRAP_METHOD(void push_back(int index), gtk_tree_path_append_index) _WRAP_METHOD(void push_front(int index), gtk_tree_path_prepend_index) size_type size() const; bool empty() const; reference operator[](size_type i); const_reference operator[](size_type i) const; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; // Note: there is no advantage in not inlining these methods. // We can't change them without breaking ABI anyway. reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } reference front() { return *begin(); } const_reference front() const { return *begin(); } reference back() { return *rbegin(); } const_reference back() const { return *rbegin(); } _WRAP_METHOD(void next(), gtk_tree_path_next) _WRAP_METHOD(bool prev(), gtk_tree_path_prev) _WRAP_METHOD(bool up(), gtk_tree_path_up) _WRAP_METHOD(void down(), gtk_tree_path_down) _WRAP_METHOD(bool is_ancestor(const TreePath& descendant) const, gtk_tree_path_is_ancestor) _WRAP_METHOD(bool is_descendant(const TreePath& ancestor) const, gtk_tree_path_is_descendant) _WRAP_METHOD(Glib::ustring to_string() const, gtk_tree_path_to_string) #m4begin _WRAP_COMPARE(gtk_tree_path_compare) #m4end _WRAP_METHOD(void append_index(int index), gtk_tree_path_append_index, deprecated "replaced by push_back()") _WRAP_METHOD(void prepend_index(int index), gtk_tree_path_prepend_index, deprecated "replaced by push_front().") _WRAP_METHOD(int get_depth() const, gtk_tree_path_get_depth, deprecated "replaced by size().") _DEPRECATE_IFDEF_START /// @deprecated replaced by begin(), end(), and operator[] Glib::ArrayHandle get_indices() const; _DEPRECATE_IFDEF_END _IGNORE(gtk_tree_path_get_depth) /** * Obtains a Gtk::TreeModel and Gtk::TreeModel::Path from selection data of target type * "GTK_TREE_MODEL_ROW". Normally called from a drag_data_received handler. * This function can only be used if @a selection_data originates from the same * process that's calling this function, because a pointer to the tree model * is being passed around. If you aren't in the same process, then you'll * get memory corruption. In the Gtk::TreeDragDest drag_data_received signal handler, * you can assume that selection data of type "GTK_TREE_MODEL_ROW" is * from the current process. * * @param selection_data a #SelectionData * @param model a Gtk::TreeModel * @param path a row in model * * @return true if the selection_data had target type "GTK_TREE_MODEL_ROW" and * is otherwise valid **/ static bool get_from_selection_data(const SelectionData& selection_data, Glib::RefPtr& model, TreePath& path); //TODO: Add an override that takes a const TreeModel (and deprecate the current version). /// See description in the other overload. static bool get_from_selection_data(const SelectionData& selection_data, TreePath& path); /** * Sets selection data of target type "GTK_TREE_MODEL_ROW". Normally used * in a drag_data_get signal handler. * * @param selection_data some #SelectionData * @param model: a Gtk::TreeModel * * @return true if the selection_data had the proper target type to allow us to set a tree row **/ bool set_in_selection_data(SelectionData& selection_data, const Glib::RefPtr& model) const; }; #ifndef DOXYGEN_SHOULD_SKIP_THIS template void TreePath::append(In pbegin, In pend) { // push_back() can't throw -- if it could, this code wouldn't be strongly exception-safe. for(; pbegin != pend; ++pbegin) this->push_back(*pbegin); } template inline TreePath::TreePath(In pbegin, In pend) { this->append(pbegin, pend); } template inline void TreePath::assign(In pbegin, In pend) { TreePath temp (pbegin, pend); this->swap(temp); } /* Traits for use of TreePath in a Glib::ListHandle<>. */ struct TreePath_Traits { typedef TreePath CppType; typedef const GtkTreePath* CType; typedef GtkTreePath* CTypeNonConst; static CType to_c_type(const CppType& item) { return item.gobj(); } static CType to_c_type(CType item) { return item; } static CppType to_cpp_type(CType item) { return CppType(const_cast(item)); } static void release_c_type(CType item) { gtk_tree_path_free(const_cast(item)); } }; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ } // namespace Gtk