1/*
2 * Copyright 1998-2002 The gtkmm Development Team
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include <gtkmm/treemodel.h>
20#include <glibmm/utility.h>
21#include <gtk/gtk.h>
22
23
24namespace Gtk
25{
26
27TreePath::TreePath(GtkTreePath* gobject, bool make_a_copy)
28:
29  // For BoxedType wrappers, make_a_copy is true by default.  The static
30  // BoxedType wrappers must always take a copy, thus make_a_copy = true
31  // ensures identical behaviour if the default argument is used.
32  gobject_ (gobject ? (make_a_copy ? gtk_tree_path_copy(gobject) : gobject) : gtk_tree_path_new())
33{}
34
35TreePath::TreePath(TreePath::size_type n, TreePath::value_type value)
36:
37  gobject_(gtk_tree_path_new())
38{
39  for(; n > 0; --n)
40    gtk_tree_path_append_index(gobject_, value);
41}
42
43TreePath::TreePath(const Glib::ustring& path)
44:
45  gobject_ (gtk_tree_path_new_from_string(path.c_str()))
46{
47  if (!gobject_)
48    gobject_ = gtk_tree_path_new();
49}
50
51TreePath::TreePath(const TreeModel::iterator& iter)
52:
53  // The GtkTreePath* is always newly created.
54  gobject_ (gtk_tree_model_get_path(iter.get_model_gobject(), const_cast<GtkTreeIter*>(iter.gobj())))
55{
56  if (!gobject_)
57    gobject_ = gtk_tree_path_new();
58}
59
60TreePath& TreePath::operator=(const TreeModel::iterator& iter)
61{
62  TreePath temp(iter);
63  swap(temp);
64  return *this;
65}
66
67void TreePath::clear()
68{
69  TreePath empty_path;
70  swap(empty_path);
71}
72
73TreePath::size_type TreePath::size() const
74{
75  return gtk_tree_path_get_depth(gobject_);
76}
77
78_DEPRECATE_IFDEF_START
79TreePath::operator const void*() const
80{
81  return !empty() ? GINT_TO_POINTER(1) : nullptr;
82}
83_DEPRECATE_IFDEF_END
84
85TreePath::operator bool() const
86{
87  return !empty();
88}
89
90bool TreePath::empty() const
91{
92  return (gtk_tree_path_get_depth(gobject_) == 0);
93}
94
95TreePath::reference TreePath::operator[](TreePath::size_type i)
96{
97  int *const indices = gtk_tree_path_get_indices(gobject_);
98  return indices[i];
99}
100
101TreePath::const_reference TreePath::operator[](TreePath::size_type i) const
102{
103  const int *const indices = gtk_tree_path_get_indices(gobject_);
104  return indices[i];
105}
106
107TreePath::iterator TreePath::begin()
108{
109  return gtk_tree_path_get_indices(gobject_);
110}
111
112TreePath::iterator TreePath::end()
113{
114  return gtk_tree_path_get_indices(gobject_) + gtk_tree_path_get_depth(gobject_);
115}
116
117TreePath::const_iterator TreePath::begin() const
118{
119  return gtk_tree_path_get_indices(gobject_);
120}
121
122TreePath::const_iterator TreePath::end() const
123{
124  return gtk_tree_path_get_indices(gobject_) + gtk_tree_path_get_depth(gobject_);
125}
126
127bool TreePath::get_from_selection_data(const SelectionData& selection_data, Glib::RefPtr<TreeModel>& model, TreePath& path) //static
128{
129  GtkTreeModel* src_model = nullptr;
130  GtkTreePath* src_path = nullptr;
131  gboolean result = gtk_tree_get_row_drag_data(const_cast<GtkSelectionData*>(selection_data.gobj()), &src_model, &src_path);
132
133  model = Glib::wrap(src_model, true /* take_copy=true */);
134
135  //gtk_tree_get_row_drag_data gives us ownership of src_path.
136  path = Glib::wrap(src_path, false /* take_copy=false */);
137
138  return result;
139}
140
141bool TreePath::get_from_selection_data(const SelectionData& selection_data, TreePath& path) //static
142{
143  GtkTreePath* src_path = nullptr;
144  gboolean result = gtk_tree_get_row_drag_data(const_cast<GtkSelectionData*>(selection_data.gobj()), nullptr, &src_path);
145
146  //gtk_tree_get_row_drag_data gives us ownership of src_path.
147  path = Glib::wrap(src_path, false /* take_copy=false */);
148
149  return result;
150}
151
152
153bool TreePath::set_in_selection_data(SelectionData& selection_data, const Glib::RefPtr<const TreeModel>& model) const
154{
155  return gtk_tree_set_row_drag_data(selection_data.gobj(), const_cast<GtkTreeModel*>(model->gobj()), const_cast<GtkTreePath*>(gobj()));
156}
157
158} // namespace Gtk
159