1/* Copyright(C) 2002 The gtkmm Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or(at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
16 */
17
18// This is for including the config header before any code (such as
19// the #ifndef GTKMM_DISABLE_DEPRECATED in deprecated classes) is generated:
20_CONFIGINCLUDE(gtkmmconfig.h)
21
22#include <vector>
23
24#include <gtkmm/container.h>
25#include <gtkmm/treeviewcolumn.h>
26#include <gtkmm/treeselection.h>
27#include <gtkmm/treemodelcolumn.h>
28#include <gtkmm/cellrenderer.h>
29#include <gtkmm/scrollable.h>
30#include <gtkmm/targetentry.h>
31#include <gtkmm/entry.h>
32#include <gtkmm/tooltip.h>
33
34_DEFS(gtkmm,gtk)
35_PINCLUDE(gtkmm/private/container_p.h)
36
37namespace Gtk
38{
39
40_CC_INCLUDE(gtk/gtk.h)
41_WRAP_ENUM(TreeViewDropPosition, GtkTreeViewDropPosition)
42_WRAP_ENUM(TreeViewGridLines, GtkTreeViewGridLines)
43
44
45#ifndef DOXYGEN_SHOULD_SKIP_THIS
46
47class TreeView;
48
49namespace TreeView_Private
50{
51/* This helper function is not a member of TreeView just for the reason that
52 * there are compilers that have problems compiling it otherwise. E.g. in gcc
53 * 2.95.3 a compiler bug prevents member functions from refering to specialized
54 * member function templates and that's what we do here: In function
55 * _connect_auto_store_editable_signal_handler we build a slot from
56 * TreeView::_auto_store_on_cellrenderer_*_edited. (The latter must be member
57 * functions of TreeView since we connect them to signals and we want the
58 * connections to vanish when the TreeView dies, of course.)
59 */
60  template <class ColumnType> inline
61  void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer, const Gtk::TreeModelColumn<ColumnType>& model_column);
62
63  template <class ColumnType> inline
64  void _connect_auto_store_numeric_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer, const Gtk::TreeModelColumn<ColumnType>& model_column);
65
66  template<class ColumnType> inline
67  void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
68
69  template <class ColumnType> inline
70  void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
71
72  template <class ColumnType> inline
73  void _auto_cell_data_func(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter, int model_column, const Glib::ustring& format);
74}
75
76#endif //DOXYGEN_SHOULD_SKIP_THIS
77
78
79//class TreeViewColumn;
80class TreeModel;
81
82/** @defgroup TreeView TreeView Classes
83 * These classes are used with the Gtk::TreeView widget.
84 */
85
86/** The TreeView widget displays the model (Gtk::TreeModel) data and allows the user to interact with it.
87 * The View can show all of the model's columns, or just some, and it can show them in various ways.
88 * You must provide the TreeModel in the constructor, or with set_model().
89 *
90 * Add View columns with append_column(), append_column_editable(), append_column_numeric(),
91 * append_column_numeric_editable(), insert_column(), or insert_column_editable().
92 *
93 * You can manipulate the selection by obtaining the @link Gtk::TreeSelection Gtk::TreeView::Selection@endlink from get_selection().
94 *
95 * @ingroup Widgets
96 * @ingroup Containers
97 * @ingroup TreeView
98 */
99class TreeView
100 : public Container,
101   public Scrollable
102{
103  _CLASS_GTKOBJECT(TreeView, GtkTreeView, GTK_TREE_VIEW, Gtk::Container, GtkContainer)
104  _IMPLEMENTS_INTERFACE(Scrollable)
105  _IGNORE(gtk_tree_view_get_path_at_pos, gtk_tree_view_set_destroy_count_func, gtk_tree_view_get_cursor
106          gtk_tree_view_insert_column_with_data_func, gtk_tree_view_get_drag_dest_row, gtk_tree_view_get_dest_row_at_pos)
107public:
108  /**  A visible column in a Gtk::TreeView widget.
109   */
110  typedef TreeViewColumn Column;
111
112  /** A selection object for Gtk::TreeView.
113   */
114  typedef TreeSelection Selection;
115
116  /** Default constructor.
117   */
118  _CTOR_DEFAULT()
119
120  /**
121     Constructor that binds to a TreeModel.
122   */
123  _WRAP_CTOR(TreeView(const Glib::RefPtr<TreeModel>& model), gtk_tree_view_new_with_model)
124
125  _WRAP_METHOD(Glib::RefPtr<TreeModel> get_model(), gtk_tree_view_get_model, refreturn)
126  _WRAP_METHOD(Glib::RefPtr<const TreeModel> get_model() const, gtk_tree_view_get_model, refreturn)
127  _WRAP_METHOD(void set_model(const Glib::RefPtr<TreeModel>& model), gtk_tree_view_set_model)
128
129  /** Remove the model from the TreeView.
130   *
131   * @see set_model().
132   *
133   * @newin{2,8}
134   */
135  void unset_model();
136
137  _WRAP_METHOD(Glib::RefPtr<TreeSelection> get_selection(), gtk_tree_view_get_selection, refreturn)
138  _WRAP_METHOD(Glib::RefPtr<const TreeSelection> get_selection() const, gtk_tree_view_get_selection, refreturn, constversion)
139  _IGNORE(gtk_tree_view_get_hadjustment, gtk_tree_view_get_vadjustment,
140    gtk_tree_view_set_hadjustment, gtk_tree_view_set_vadjustment) //deprecated
141
142  _WRAP_METHOD(bool get_headers_visible() const, gtk_tree_view_get_headers_visible)
143  _WRAP_METHOD(void set_headers_visible(bool headers_visible = true), gtk_tree_view_set_headers_visible)
144  _WRAP_METHOD(void columns_autosize(), gtk_tree_view_columns_autosize)
145  _WRAP_METHOD(bool get_headers_clickable() const, gtk_tree_view_get_headers_clickable)
146  _WRAP_METHOD(void set_headers_clickable(bool setting = true), gtk_tree_view_set_headers_clickable)
147  _WRAP_METHOD(void set_rules_hint(bool setting = true), gtk_tree_view_set_rules_hint, deprecated "Don't use this API. There is no replacement.")
148  _WRAP_METHOD(bool get_rules_hint() const, gtk_tree_view_get_rules_hint, deprecated "Don't use this API. There is no replacement.")
149
150  _WRAP_METHOD(void set_activate_on_single_click(bool single = true), gtk_tree_view_set_activate_on_single_click)
151  _WRAP_METHOD(bool get_activate_on_single_click() const, gtk_tree_view_get_activate_on_single_click)
152
153  _WRAP_METHOD(int append_column(TreeViewColumn& column), gtk_tree_view_append_column)
154
155  /** Appends a View column with the appropriate CellRenderer for the Model column.
156   *
157   * The CellRenderer can only be created automatically for some basic
158   * column types, such as Glib::ustring, int, double, bool, and Gdk::Pixbuf.
159   * If the type is not supported then the following warning will be shown:
160   * GLib-GObject-WARNING **: unable to set property `text' of type
161   * `gchararray' from value of type `glibmm__CustomBoxed_t'.
162   *
163   * If the default formatting is not sufficient, or the numeric type is
164   * not supported, then you could use append_column_numeric(). Or you
165   * could create the TreeView::Column and/or CellRenderer
166   * manually and use TreeViewColumn::set_cell_data_func() to provide a callback
167   * that converts the model value into a string representation with .
168   *
169   * @param title The text to be used in the title header of this column.
170   * @param model_column The column in the TreeModel that will be rendered by this View column.
171   * @result The number of columns in the View after appending.
172   */
173  template <class ColumnType> inline
174  int append_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column);
175
176  /** Like append_column(), but only for numeric types, which will be displayed in the specified format.
177   * This convenience template uses TreeView::Column::set_cell_data_func(), so the numeric formatting will
178   * be deactivated if you specify your own cell_data callback by calling set_cell_data_func() again.
179   *
180   * @param title The text to be used in the title header of this column.
181   * @param model_column The column in the TreeModel that will be rendered by this View column.
182   * @param format A printf-style format, such as "%d", used to create a text representation of the number.
183   * @result The number of columns in the View after appending.
184   */
185  template <class ColumnType> inline
186  int append_column_numeric(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, const Glib::ustring& format);
187
188  //TODO: danielk suggested use of Glib::Value to simplify/improve this.
189  /** Appends a View column with the appropriate CellRenderer for the Model
190   * column.  The compiler will attempt to instantiate appropriate template
191   * code to automatically store user changes in the model.  To intercept the
192   * user's change and implement non-default logic, or if the compiler can't
193   * instantiate appropriate code for your model type, you could use
194   * append_column() and connect a signal handler to the CellRenderer.
195   *
196   * @see append_column_numeric_editable().
197   *
198   * @param title The text to be used in the title header of this column.
199   * @param model_column The column in the TreeModel that will be rendered by this View column.
200   * @result The number of columns in the View after appending.
201   */
202  template <class ColumnType> inline
203  int append_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column);
204
205  /** Like append_column_editable(), but only for numeric types, which will be displayed in the specified format.
206   * This convenience template uses TreeView::Column::set_cell_data_func(), so the numeric formatting will
207   * be deactivated if you specify your own cell_data callback by calling set_cell_data_func() again.
208   *
209   * Note that the user's input will be interpreted as decimal (base 10), regardless of the @a format.
210   *
211   * @param title The text to be used in the title header of this column.
212   * @param model_column The column in the TreeModel that will be rendered by this View column.
213   * @param format A printf-style format, such as "%d", used to create a text representation of the number.
214   * @result The number of columns in the View after appending.
215   */
216  template <class ColumnType> inline
217  int append_column_numeric_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, const Glib::ustring& format);
218
219
220  /// Creates a View column containing the CellRenderer, and appends it.
221  int append_column(const Glib::ustring& title, CellRenderer& cell);
222
223  _WRAP_METHOD(int remove_column(TreeViewColumn& column), gtk_tree_view_remove_column)
224
225  /// Removes all View columns.
226  void remove_all_columns();
227
228  _WRAP_METHOD(int insert_column(TreeViewColumn& column, int position), gtk_tree_view_insert_column)
229
230  /** Creates a View column containing the CellRenderer, and inserts it.
231   *
232   * @param title The text to be used in the title header of this column.
233   * @param cell The CellRenderer.
234   * @param position The position at which the CellRenderer should be inserted.
235   * @result The number of columns in the View after inserting.
236   */
237  int insert_column(const Glib::ustring& title, CellRenderer& cell, int position);
238
239  _IGNORE(gtk_tree_view_insert_column_with_attributes)
240
241  /** Inserts a View column with the appropriate CellRenderer for the Model column.
242   *
243   * @param title The text to be used in the title header of this column.
244   * @param model_column The column in the TreeModel that will be rendered by this View column.
245   * @param position The position at which the CellRenderer should be inserted.
246   * @result The number of columns in the View after inserting.
247   */
248  template <class ColumnType> inline
249  int insert_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position);
250
251  /** Inserts a View column with the appropriate CellRenderer for the Model
252   * column.  The compiler will attempt to instantiate appropriate template
253   * code to automatically store user changes in the model.  To intercept the
254   * user's change and implement non-default logic, or if the compiler can't
255   * instantiate appropriate code for your model type, you should use
256   * insert_column() and connect a signal handler to the CellRenderer.
257   *
258   * @param title The text to be used in the title header of this column.
259   * @param model_column The column in the TreeModel that will be rendered by this View column.
260   * @param position The position at which the CellRenderer should be inserted.
261   * @result The number of columns in the View after inserting.
262   */
263  template <class ColumnType> inline
264  int insert_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position);
265
266_DEPRECATE_IFDEF_START
267  /** @deprecated Use SlotTreeCellData instead.
268   */
269  typedef TreeViewColumn::SlotCellData SlotCellData;
270_DEPRECATE_IFDEF_END
271
272  typedef TreeViewColumn::SlotTreeCellData SlotTreeCellData;
273
274  /**
275   * Inserts a new column into the TreeView with the given cell
276   * renderer and a SlotTreeCellData to set cell renderer attributes
277   * (normally using data from the model).
278   *
279   * @param position Position to insert, -1 for append
280   * @param title column title
281   * @param cell cell renderer for column
282   * @param slot function to set attributes of cell renderer
283   * @return number of columns in the TreeView after the insert
284   */
285  int insert_column_with_data_func(int position, const Glib::ustring& title, CellRenderer& cell, const SlotTreeCellData& slot);
286
287  _WRAP_METHOD(guint get_n_columns() const, gtk_tree_view_get_n_columns)
288
289  _WRAP_METHOD(TreeViewColumn* get_column(int n), gtk_tree_view_get_column)
290  _WRAP_METHOD(const TreeViewColumn* get_column(int n) const, gtk_tree_view_get_column, constversion)
291
292  //The column index is of the view, not the model, so we do not need TreeViewColumn* get_column(TreeViewColumn& base_column).
293
294  /** Gets the CellRenderer for that column.
295    * You should dynamic_cast<> to the expected derived CellRenderer type.
296    * This assumes that the TreeViewColumn contains only one CellRenderer.
297    *
298    * @param n The position of the view column.
299    * @result The CellRenderer.
300    */
301  CellRenderer* get_column_cell_renderer(int n);
302
303 //TODO: Add TreeViewColumn* get_column_cell_renderer(TreeViewColumn& base_column); and a const one.
304
305
306  /** Gets the CellRenderer for that column.
307    * You should dynamic_cast<> to the expected derived CellRenderer type.
308    * This assumes that the TreeViewColumn contains only one CellRenderer.
309    *
310    * @param n The position of the view column.
311    * @result The CellRenderer.
312    */
313  const CellRenderer* get_column_cell_renderer(int n) const;
314
315#m4 _CONVERSION(`GList*',`std::vector<TreeViewColumn*>',`Glib::ListHandler<TreeViewColumn*>::list_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
316  _WRAP_METHOD(std::vector<TreeViewColumn*> get_columns(), gtk_tree_view_get_columns)
317#m4 _CONVERSION(`GList*',`std::vector<const TreeViewColumn*>',`Glib::ListHandler<const TreeViewColumn*>::list_to_vector($3, Glib::OWNERSHIP_SHALLOW)')
318  _WRAP_METHOD(std::vector<const TreeViewColumn*> get_columns() const, gtk_tree_view_get_columns)
319
320  _WRAP_METHOD(void move_column_after(TreeViewColumn& column, TreeViewColumn& base_column), gtk_tree_view_move_column_after)
321
322  /** This method moves column to the first position in the view.
323   *
324   * @param column The view column that will be moved
325   */
326  void move_column_to_start(TreeViewColumn& column);
327
328  _WRAP_METHOD(void set_expander_column(TreeViewColumn& column), gtk_tree_view_set_expander_column)
329
330  /** This method resets the expander arrow to the default - the first visible column.
331   * @see set_expander_column().
332   */
333  void reset_expander_column();
334
335  _WRAP_METHOD(TreeViewColumn* get_expander_column(), gtk_tree_view_get_expander_column)
336  _WRAP_METHOD(const TreeViewColumn* get_expander_column() const, gtk_tree_view_get_expander_column, constversion)
337
338  /** For instance,
339   * bool on_column_drop(TreeView*, tree_view, TreeViewColumn* column, TreeViewColumn* prev_column, TreeViewColumn* next_column)
340   *
341   * This function is called on every column pair in turn at the beginning of a column drag to determine where a
342   * drop can take place. The arguments passed to the function are: the tree_view, the view Column being dragged,
343   * and the two view Columns determining the drop spot. If either of the view Column arguments for the drop spot
344   * are 0, then they indicate an edge.
345   */
346  typedef sigc::slot<bool, TreeView*, TreeViewColumn*,  TreeViewColumn*, TreeViewColumn*> SlotColumnDrop;
347
348  /** Sets a callback slot for determining where a column may be dropped when dragged.
349   * This function is called on every column pair in turn at the beginning of a column drag to determine where a
350   * drop can take place. The arguments passed to the function are: the tree_view, the view Column being dragged,
351   * and the two view Columns determining the drop spot. If either of the view Column arguments for the drop spot
352   * are 0, then they indicate an edge.
353   *
354   * See unset_column_drag_function().
355   *
356   * @param slot A callback function to determine which columns are reorderable.
357   */
358  void set_column_drag_function(const SlotColumnDrop& slot);
359  _IGNORE(gtk_tree_view_set_column_drag_function)
360
361  /** See set_column_drag_function(). After this method has been called, the TreeView reverts to the default behavior of
362  * allowing all columns to be dropped everywhere.
363  */
364  void unset_column_drag_function();
365
366  _WRAP_METHOD(void scroll_to_point(int tree_x, int tree_y), gtk_tree_view_scroll_to_point)
367
368  /** Moves the alignments of tree view to the position specified by @a column and @a path.
369   * @a row_align determines where the row is placed, and @a col_align determines where
370   * column is placed. Both are expected to be between 0.0 and 1.0. 0.0 means left/top
371   * alignment, 1.0 means right/bottom alignment, 0.5 means center.
372   *
373   * This function only works if the model is set, and @a path is a valid row on the model.
374   * If the model changes before the tree view is realized, the centered path will be
375   * modified to reflect this change.
376   *
377   * @param path The path of the row to move to.
378   * @param column The Gtk::TreeViewColumn to move horizontally to.
379   * @param row_align The vertical alignment of the row specified by @a path.
380   * @param col_align The horizontal alignment of the column specified by @a column.
381   */
382  void scroll_to_cell(const TreeModel::Path& path, TreeViewColumn& column, float row_align, float col_align);
383  _IGNORE(gtk_tree_view_scroll_to_cell)
384
385  /** Moves the alignments of tree view to the position specified by @a column and @a path.
386   * The tree does the minimum amount of work to scroll the cell onto the screen. This means
387   * that the cell will be scrolled to the edge closest to it's current position. If the cell
388   * is currently visible on the screen, nothing is done.
389   *
390   * This function only works if the model is set, and @a path is a valid row on the model.
391   * If the model changes before the tree_view is realized, the centered path will be modified
392   * to reflect this change.
393   *
394   * @param path The path of the row to move to.
395   * @param column The Gtk::TreeViewColumn to move horizontally to.
396   */
397  void scroll_to_cell(const TreeModel::Path& path, TreeViewColumn& column);
398
399  /** Moves the alignments of tree view to the position specified by @a path.
400   * @a row_align determines where the row is placed, and is expected to be between 0.0
401   * and 1.0.  0.0 means top alignment, 1.0 means bottom alignment, 0.5 means center.
402   *
403   * This function only works if the model is set, and @a path is a valid row on the model.
404   * If the model changes before the tree view is realized, the centered path will be
405   * modified to reflect this change.
406   *
407   * @param path The path of the row to move to.
408   * @param row_align The vertical alignment of the row specified by @a path.
409   */
410  void scroll_to_row(const TreeModel::Path& path, float row_align);
411
412  /** Moves the alignments of tree view to the position specified by @a path.
413   * The tree does the minimum amount of work to scroll the row onto the screen. This means
414   * that the row will be scrolled to the edge closest to it's current position. If the row
415   * is currently visible on the screen, nothing is done.
416   *
417   * This function only works if the model is set, and @a path is a valid row on the model.
418   * If the model changes before the tree view is realized, the centered path will be
419   * modified to reflect this change.
420   *
421   * @param path The path of the row to move to.
422   */
423  void scroll_to_row(const TreeModel::Path& path);
424
425  /** Moves the alignments of tree view to the position specified by @a column.
426   * @a col_align determines where the column is placed, and is expected to be between 0.0
427   * and 1.0.  0.0 means left alignment, 1.0 means right alignment, 0.5 means center.
428   *
429   * This function only works if the model is set.  If the model changes before the tree
430   * view is realized, the centered path will be modified to reflect this change.
431   *
432   * @param column The Gtk::TreeViewColumn to move horizontally to.
433   * @param col_align The horizontal alignment of the column specified by @a column.
434   */
435  void scroll_to_column(TreeViewColumn& column, float col_align);
436
437  /** Moves the alignments of tree view to the position specified by @a column.
438   * The tree does the minimum amount of work to scroll the column onto the screen. This means
439   * that the column will be scrolled to the edge closest to it's current position. If the column
440   * is currently visible on the screen, nothing is done.
441   *
442   * This function only works if the model is set.  If the model changes before the
443   * tree view is realized, the centered path will be modified to reflect this change.
444   *
445   * @param column The Gtk::TreeViewColumn to move horizontally to.
446   */
447  void scroll_to_column(TreeViewColumn& column);
448
449  _WRAP_METHOD(void row_activated(const TreeModel::Path& path,TreeViewColumn& column), gtk_tree_view_row_activated)
450  _WRAP_METHOD(void expand_all(), gtk_tree_view_expand_all)
451  _WRAP_METHOD(void collapse_all(), gtk_tree_view_collapse_all)
452  _WRAP_METHOD(void expand_to_path(const TreeModel::Path& path), gtk_tree_view_expand_to_path)
453  _WRAP_METHOD(bool expand_row(const TreeModel::Path& path, bool open_all), gtk_tree_view_expand_row)
454  _WRAP_METHOD(bool collapse_row(const TreeModel::Path& path), gtk_tree_view_collapse_row)
455
456  /** For example,
457   * void on_map_expanded_rows(TreeView* tree_view, const TreeModel::Path& path);
458   */
459  typedef sigc::slot<void, TreeView*, const TreeModel::Path&> SlotMapping;
460
461  /** Calls the callback slot on all expanded rows.
462   * @param slot A callback function to be called.
463   */
464  void map_expanded_rows(const SlotMapping& slot);
465  _IGNORE(gtk_tree_view_map_expanded_rows)
466
467  _WRAP_METHOD(bool row_expanded(const TreeModel::Path& path), gtk_tree_view_row_expanded)
468  _WRAP_METHOD(void set_reorderable(bool reorderable = true), gtk_tree_view_set_reorderable)
469  _WRAP_METHOD(bool get_reorderable() const, gtk_tree_view_get_reorderable)
470
471  //TODO: Add set_cursor(path, ModelColumnBase&, start_editing)?
472  _WRAP_METHOD(void set_cursor(const TreeModel::Path& path, TreeViewColumn& focus_column, bool start_editing = false), gtk_tree_view_set_cursor)
473
474  _WRAP_METHOD(void set_cursor(const TreeModel::Path& path, TreeViewColumn& focus_column, CellRenderer& focus_cell, bool start_editing = false), gtk_tree_view_set_cursor_on_cell)
475
476
477  /** Sets the current keyboard focus to be at path , and selects it.
478   * This is useful when you want to focus the user's attention on a particular row.
479   * This function is often followed by Gtk::widget::grab_focus(tree_view)
480   * in order to give keyboard focus to the widget.
481   *
482   *  @param path A reference to cursor path.
483   */
484  void set_cursor(const TreeModel::Path& path);
485
486  /**  Fills in path and focus_column with the current path and focus column.
487   *
488   *  @param path A reference to be filled with the current cursor path
489   *  @param focus_column A reference to be filled with the current focus column
490   */
491  void get_cursor(TreeModel::Path& path, TreeViewColumn*& focus_column);
492
493/* Layout information */
494  _WRAP_METHOD(Glib::RefPtr<Gdk::Window> get_bin_window(), gtk_tree_view_get_bin_window, refreturn)
495  _WRAP_METHOD(Glib::RefPtr<const Gdk::Window> get_bin_window() const, gtk_tree_view_get_bin_window, refreturn, constversion)
496
497  /** Finds the path at the point (@a x, @a y), relative to bin_window coordinates
498   * (please see get_bin_window()).
499   * That is, @a x and @a y are relative to an events coordinates. @a x and @a y must
500   * come from an event on the TreeView only where event->window ==
501   * get_bin_window(). It is primarily for
502   * things like popup menus. @a path will be filled
503   * with the TreeModel::Path at that point. @a column will be filled
504   * with the column at that point.  @a cell_x and @a cell_y return the coordinates
505   * relative to the cell background (i.e. the background_area passed to
506   * Gtk::CellRenderer::render()).  This method is only meaningful if
507   * the TreeView is realized.
508   *
509   * For converting widget coordinates (eg. the ones you get from
510   * Widget::property_query_tooltip()), please see
511   * convert_widget_to_bin_window_coords().
512   *
513   * @param x The x position to be identified (relative to bin_window).
514   * @param y The y position to be identified (relative to bin_window).
515   * @param path A reference to a TreeModel::Path to be filled in
516   * @param column A reference to a TreeViewColumn pointer to be filled in
517   * @param cell_x A reference where the X coordinate relative to the cell
518   *   can be placed
519   * @param cell_y A reference where the Y coordinate relative to the cell
520   *   can be placed
521   * @return true if a row exists at that coordinate.
522   *
523   * @newin{2,8}
524   */
525  bool get_path_at_pos(int x, int y, TreeModel::Path& path, TreeViewColumn*& column, int& cell_x, int& cell_y) const;
526
527  /** Finds the path at the point (@a x, @a y), relative to bin_window coordinates
528   * (please see get_bin_window()).
529   * That is, @a x and @a y are relative to an events coordinates. @a x and @a y must
530   * come from an event on the TreeView only where event->window ==
531   * get_bin_window(). It is primarily for
532   * things like popup menus. @a path will be filled
533   * with the TreeModel::Path at that point.
534   * This method is only meaningful if the TreeView is realized.
535   *
536   * For converting widget coordinates (eg. the ones you get from
537   * Widget::property_query_tooltip()), please see
538   * convert_widget_to_bin_window_coords().
539   *
540   * @param x The x position to be identified (relative to bin_window).
541   * @param y The y position to be identified (relative to bin_window).
542   * @param path A reference to a TreeModel::Path to be filled in
543   * @return true if a row exists at that coordinate.
544   *
545   * newin{2,16}
546   */
547  bool get_path_at_pos(int x, int y, TreeModel::Path& path) const;
548
549  //We ignore the fact that one of the arguments can be 0 - it does not seem useful.
550  _WRAP_METHOD(void get_cell_area(const TreeModel::Path& path, TreeViewColumn& column, Gdk::Rectangle& rect) const, gtk_tree_view_get_cell_area)
551
552  _WRAP_METHOD(void get_background_area(const TreeModel::Path& path, TreeViewColumn& column, Gdk::Rectangle& rect) const, gtk_tree_view_get_background_area)
553  //We ignore the fact that one of the arguments can be 0 - it does not seem useful.
554
555  _WRAP_METHOD(void get_visible_rect(Gdk::Rectangle&  visible_rect) const, gtk_tree_view_get_visible_rect)
556
557   bool get_visible_range(TreeModel::Path& start_path, TreeModel::Path& end_path) const;
558  _IGNORE(gtk_tree_view_get_visible_range)
559
560  //TODO: Documentation
561  bool is_blank_at_pos(int x, int y, TreePath& path, TreeViewColumn*& column, int& cell_x, int& cell_y) const;
562  _IGNORE(gtk_tree_view_is_blank_at_pos)
563
564  //TODO: Documentation
565  bool is_blank_at_pos(int x, int y) const;
566
567
568/* Drag-and-Drop support */
569  _IGNORE(gtk_tree_view_enable_model_drag_source)
570
571  /**
572   * Turns the TreeView into a drag source for automatic DND.
573   *
574   * @param targets Standard container of targets that the drag will support.
575   * @param start_button_mask Mask of allowed buttons to start drag.
576   * @param actions The bitmask of possible actions for a drag from this widget.
577   */
578  void enable_model_drag_source(const std::vector<TargetEntry>& targets,
579                                Gdk::ModifierType start_button_mask = Gdk::MODIFIER_MASK,
580                                Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
581
582  // Uses the default "GTK_TREE_MODEL_ROW" target, which the TreeView can handle automatically.
583
584  /** Turns the TreeView into a drag source for automatic DND.
585   *
586   * @param start_button_mask Mask of allowed buttons to start drag.
587   * @param actions The bitmask of possible actions for a drag from this widget.
588   */
589  void enable_model_drag_source(Gdk::ModifierType start_button_mask = Gdk::MODIFIER_MASK,
590                                Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
591
592  _IGNORE(gtk_tree_view_enable_model_drag_dest)
593
594  /** Turns the TreeView into a drop destination for automatic DND.
595   *
596   * @param targets The table of targets that the drag will support.
597   * @param actions The bitmask of possible actions for a drag from this widget.
598   */
599  void enable_model_drag_dest(const std::vector<TargetEntry>& targets, Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
600
601  /** Turns the TreeView into a drop destination for automatic DND.  This uses the default
602   *  "GTK_TREE_MODEL_ROW" target, which the TreeView can handle automatically.
603   *
604   * @param actions The bitmask of possible actions for a drag from this widget.
605   */
606  void enable_model_drag_dest(Gdk::DragAction actions = Gdk::ACTION_COPY | Gdk::ACTION_MOVE);
607
608  /** Undoes the effect of enable_model_drag_source()
609   */
610  _WRAP_METHOD(void unset_rows_drag_source(), gtk_tree_view_unset_rows_drag_source)
611
612  /** Undoes the effect of enable_model_drag_dest()
613   */
614  _WRAP_METHOD(void unset_rows_drag_dest(), gtk_tree_view_unset_rows_drag_dest)
615
616
617  /* These are useful to implement your own custom stuff. */
618
619  /** Sets the row that is highlighted for feedback.
620   * See also unset_drag_dest_row().
621   *
622   * @param path The path of the row to highlight
623   * @param pos Specifies whether to drop before, after or into the row
624   */
625  _WRAP_METHOD(void set_drag_dest_row(const TreeModel::Path& path, TreeViewDropPosition pos), gtk_tree_view_set_drag_dest_row)
626
627  /** Remove an existing highlight.
628   * See set_drag_dest_row().
629   *
630   * @newin{3,2}
631   */
632  void unset_drag_dest_row();
633
634  /** Gets information about the row that is highlighted for feedback.
635   *
636   * @param path Return location for the path of the highlighted row
637   * @param pos Return location for the drop position
638   */
639  void get_drag_dest_row(TreeModel::Path& path, TreeViewDropPosition& pos) const;
640
641  /** Determines the destination row for a given position.
642   *
643   * @param drag_x The x position to determine the destination row for
644   * @param drag_y The y position to determine the destination row for
645   * @param path Return location for the path of the highlighted row
646   * @param pos Return location for the drop position
647   */
648  bool get_dest_row_at_pos(int drag_x, int drag_y, TreeModel::Path& path, TreeViewDropPosition& pos) const;
649
650#m4 _CONVERSION(`cairo_surface_t*',`Cairo::RefPtr<Cairo::Surface>',`Cairo::RefPtr<Cairo::Surface>(new Cairo::Surface($3, true /* take reference */))')
651  _WRAP_METHOD(Cairo::RefPtr<Cairo::Surface> create_row_drag_icon(const TreeModel::Path& path) const, gtk_tree_view_create_row_drag_icon)
652
653/* Interactive search */
654  _WRAP_METHOD(void set_enable_search(bool enable_search = true), gtk_tree_view_set_enable_search)
655  _WRAP_METHOD(bool get_enable_search() const, gtk_tree_view_get_enable_search)
656  _WRAP_METHOD(int get_search_column() const, gtk_tree_view_get_search_column)
657  _WRAP_METHOD(void set_search_column(const TreeModelColumnBase& column), gtk_tree_view_set_search_column)
658  _WRAP_METHOD(void set_search_column(int column), gtk_tree_view_set_search_column)
659
660  ///void on_search_equal(const Glib::RefPtr<TreeModel>& model, int column, const Glib::ustring& key, const TreeModel::iterator& iter)
661  typedef sigc::slot<bool, const Glib::RefPtr<TreeModel>&, int, const Glib::ustring&, const TreeModel::iterator&> SlotSearchEqual;
662  //SlotSearchEqual get_search_equal_func();
663  _IGNORE(gtk_tree_view_get_search_equal_func)
664
665  /** Sets the compare function for the interactive search capabilities.
666   *
667   * @param slot The compare function to use during the search
668   */
669  void set_search_equal_func(const SlotSearchEqual& slot);
670  _IGNORE(gtk_tree_view_set_search_equal_func)
671
672  _WRAP_METHOD(Entry* get_search_entry(), gtk_tree_view_get_search_entry)
673  _WRAP_METHOD(const Entry* get_search_entry() const, gtk_tree_view_get_search_entry, constversion)
674  _WRAP_METHOD(void set_search_entry(Entry& entry), gtk_tree_view_set_search_entry)
675
676  ///void on_search_position(Gtk::Widget* search_dialog)
677  typedef sigc::slot<void, Gtk::Widget* /* search_dialog */> SlotSearchPosition;
678  void set_search_position_func(const SlotSearchPosition& slot);
679  _IGNORE(gtk_tree_view_get_search_position_func, gtk_tree_view_set_search_position_func)
680
681  _WRAP_METHOD(void convert_widget_to_tree_coords(int wx, int wy, int& tx, int& ty) const, gtk_tree_view_convert_widget_to_tree_coords)
682  _WRAP_METHOD(void convert_tree_to_widget_coords(int tx, int ty, int& wx, int& wy) const, gtk_tree_view_convert_tree_to_widget_coords)
683  _WRAP_METHOD(void convert_widget_to_bin_window_coords(int wx, int wy, int& bx, int& by) const, gtk_tree_view_convert_widget_to_bin_window_coords)
684  _WRAP_METHOD(void convert_bin_window_to_widget_coords(int bx, int by, int& wx, int& wy) const, gtk_tree_view_convert_bin_window_to_widget_coords)
685  _WRAP_METHOD(void convert_tree_to_bin_window_coords(int tx, int ty, int& bx, int& by) const, gtk_tree_view_convert_tree_to_bin_window_coords)
686  _WRAP_METHOD(void convert_bin_window_to_tree_coords(int bx, int by, int& tx, int& ty) const, gtk_tree_view_convert_bin_window_to_tree_coords)
687
688
689  _WRAP_METHOD(void set_fixed_height_mode(bool enable = true), gtk_tree_view_set_fixed_height_mode)
690  _WRAP_METHOD(bool get_fixed_height_mode() const, gtk_tree_view_get_fixed_height_mode)
691  _WRAP_METHOD(void set_hover_selection(bool hover = true), gtk_tree_view_set_hover_selection)
692  _WRAP_METHOD(bool get_hover_selection() const, gtk_tree_view_get_hover_selection)
693  _WRAP_METHOD(void set_hover_expand(bool expand = true), gtk_tree_view_set_hover_expand)
694  _WRAP_METHOD(bool get_hover_expand() const, gtk_tree_view_get_hover_expand)
695  _WRAP_METHOD(void set_rubber_banding(bool enable = true), gtk_tree_view_set_rubber_banding)
696  _WRAP_METHOD(bool get_rubber_banding() const, gtk_tree_view_get_rubber_banding)
697
698  //TODO: Rename to get_is?
699  _WRAP_METHOD(bool is_rubber_banding_active() const, gtk_tree_view_is_rubber_banding_active)
700
701  /** The slot type for determining whether the row pointed to by the iterator should be rendered as a separator.
702   * Return true if the row is a separator.
703   * A common way to implement this is to have a boolean column in the model, whose values the slot returns.
704   *
705   * For instance,
706   * bool on_row_separator(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::iterator& iter);
707   */
708  typedef sigc::slot<bool, const Glib::RefPtr<TreeModel>&, const TreeModel::iterator&> SlotRowSeparator;
709
710  /** Sets the row separator function, which is used to determine whether a row should be drawn as a separator.
711   */
712  void set_row_separator_func(const SlotRowSeparator& slot);
713  _IGNORE(gtk_tree_view_set_row_separator_func, gtk_tree_view_get_row_separator_func)
714
715  /** Removes the row separator function, so no separators are drawn.
716   * See set_row_separator_func().
717   *
718   * @newin{3,2}
719   */
720  void unset_row_separator_func();
721
722  _WRAP_METHOD(void set_grid_lines(TreeViewGridLines grid_lines), gtk_tree_view_set_grid_lines)
723  _WRAP_METHOD(TreeViewGridLines get_grid_lines() const, gtk_tree_view_get_grid_lines)
724
725  _WRAP_METHOD(void set_enable_tree_lines(bool enable = true), gtk_tree_view_set_enable_tree_lines)
726  _WRAP_METHOD(bool get_enable_tree_lines() const, gtk_tree_view_get_enable_tree_lines)
727
728  _WRAP_METHOD(void set_show_expanders(bool enabled = true), gtk_tree_view_set_show_expanders)
729  _WRAP_METHOD(bool get_show_expanders() const, gtk_tree_view_get_show_expanders)
730  _WRAP_METHOD(void set_level_indentation(int indentation), gtk_tree_view_set_level_indentation)
731  _WRAP_METHOD(int get_level_indentation() const, gtk_tree_view_get_level_indentation)
732
733  _WRAP_METHOD(void set_tooltip_row(const Glib::RefPtr<Tooltip>& tooltip, const TreePath& path), gtk_tree_view_set_tooltip_row)
734
735  //Note that we use pointers instead of references because any one of the 3 arguments may be NULL, and we don't want that many method overloads:
736#m4 _CONVERSION(`const TreeModel::Path*',`GtkTreePath*',`(($3) ? const_cast<GtkTreePath*>(($3)->gobj()) : nullptr)')
737  _WRAP_METHOD(void set_tooltip_cell(const Glib::RefPtr<Tooltip>& tooltip, const TreeModel::Path* path, TreeViewColumn* column, CellRenderer* cell), gtk_tree_view_set_tooltip_cell)
738
739  _IGNORE(gtk_tree_view_get_tooltip_context)
740
741  /**
742   * @param x: the x coordinate (relative to widget coordinates)
743   * @param y: the y coordinate (relative to widget coordinates)
744   * @param keyboard_tip: whether this is a keyboard tooltip or not
745   * @param path: a reference to receive a Gtk::TreePath
746   *
747   * This function is supposed to be used in a Gtk::Widget::query-tooltip
748   * signal handler for Gtk::TreeView. The x, y and keyboard_tip values
749   * which are received in the signal handler, should be passed to this
750   * function without modification.
751   *
752   * The return value indicates whether there is an tree view row at the given
753   * coordinates (true) or not (false) for mouse tooltips. For keyboard
754   * tooltips the row returned will be the cursor item. When true, then the
755   * path which has been provided will be set to point to
756   * that row and the corresponding model. x and y will always be converted
757   * to be relative to Gtk::TreeView's bin_window if keyboard_tooltip is false.
758   *
759   * Return value: whether or not the given tooltip context points to a row.
760   *
761   * @newin{2,12}
762   */
763  bool get_tooltip_context_path(int& x, int& y,
764                                bool keyboard_tip,
765                                TreeModel::Path& path);
766
767  /**
768   * @param x: the x coordinate (relative to widget coordinates)
769   * @param y: the y coordinate (relative to widget coordinates)
770   * @param keyboard_tip: whether this is a keyboard tooltip or not
771   * @param iter: a pointer to receive a Gtk::TreeIter
772   *
773   * This function is supposed to be used in a Gtk::Widget::query-tooltip
774   * signal handler for Gtk::TreeView. The x, y and keyboard_tip values
775   * which are received in the signal handler, should be passed to this
776   * function without modification.
777   *
778   * The return value indicates whether there is an tree view row at the given
779   * coordinates (true) or not (false) for mouse tooltips. For keyboard
780   * tooltips the row returned will be the cursor item. When true, then the
781   * iter which has been provided will be set to point to
782   * that row and the corresponding model. x and y will always be converted
783   * to be relative to Gtk::TreeView's bin_window if keyboard_tooltip is false.
784   *
785   * Return value: whether or not the given tooltip context points to a row.
786   *
787   * @newin{2,12}
788   */
789  bool get_tooltip_context_iter(int& x, int& y,
790                                bool keyboard_tip,
791                                Gtk::TreeModel::iterator& iter);
792
793  _WRAP_METHOD(void set_tooltip_column(int column), gtk_tree_view_set_tooltip_column)
794  _WRAP_METHOD(int get_tooltip_column() const, gtk_tree_view_get_tooltip_column)
795
796#m4begin
797dnl // We need this special conversion here since the C++ Gtk::TreeIter carries
798dnl // a pointer to the Gtk::TreeModel, whereas the plain GtkTreeIter struct does
799dnl // not.  Fortunately we can use the `self' parameter to get our hands on the
800dnl // GtkTreeModel*.
801_CONVERSION(`GtkTreeIter*',`const TreeModel::iterator&',`TreeModel::iterator(gtk_tree_view_get_model(self), $3)')
802#m4end
803
804  _WRAP_SIGNAL(void row_activated(const TreeModel::Path& path, TreeViewColumn* column) , "row-activated")
805  _WRAP_SIGNAL(bool test_expand_row(const TreeModel::iterator& iter, const TreeModel::Path& path), "test-expand-row")
806  _WRAP_SIGNAL(bool test_collapse_row(const TreeModel::iterator& iter, const TreeModel::Path& path), "test-collapse-row")
807  _WRAP_SIGNAL(void row_expanded(const TreeModel::iterator& iter, const TreeModel::Path& path), "row-expanded")
808  _WRAP_SIGNAL(void row_collapsed(const TreeModel::iterator& iter, const TreeModel::Path& path), "row-collapsed")
809  _WRAP_SIGNAL(void cursor_changed(), "cursor-changed")
810  _WRAP_SIGNAL(void columns_changed(), "columns-changed")
811
812  //Don't wrap these. They are keybinding signals, and their API broke for GTK+ 2.2.
813  _IGNORE_SIGNAL("move-cursor")
814  _IGNORE_SIGNAL("select-all")
815  _IGNORE_SIGNAL("unselect-all")
816  _IGNORE_SIGNAL("select-cursor-row")
817  _IGNORE_SIGNAL("toggle-cursor-row")
818  _IGNORE_SIGNAL("expand-collapse-cursor-row")
819  _IGNORE_SIGNAL("select-cursor-parent")
820  _IGNORE_SIGNAL("start-interactive-search")
821
822
823  _WRAP_PROPERTY("model", Glib::RefPtr<TreeModel>)
824  _WRAP_PROPERTY("headers-visible", bool)
825  _WRAP_PROPERTY("headers-clickable", bool)
826  _WRAP_PROPERTY("expander-column", TreeViewColumn*)
827  _WRAP_PROPERTY("reorderable", bool)
828  _WRAP_PROPERTY("rules-hint", bool, deprecated "Don't use this API. There is no replacement.")
829  _WRAP_PROPERTY("enable-search", bool)
830  _WRAP_PROPERTY("search-column", int)
831  _WRAP_PROPERTY("fixed-height-mode", bool)
832  _WRAP_PROPERTY("hover-selection", bool)
833  _WRAP_PROPERTY("hover-expand", bool)
834  _WRAP_PROPERTY("show-expanders", bool)
835  _WRAP_PROPERTY("level-indentation", bool)
836  _WRAP_PROPERTY("rubber-banding", bool)
837  _WRAP_PROPERTY("enable-grid-lines", bool)
838  _WRAP_PROPERTY("enable-tree-lines", bool)
839  _WRAP_PROPERTY("tooltip-column", int)
840  _WRAP_PROPERTY("activate-on-single-click", bool)
841
842protected:
843
844#ifndef DOXYGEN_SHOULD_SKIP_THIS
845  template<class ColumnType> friend
846  void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
847
848  template <class ColumnType> friend
849  void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
850
851  void _auto_store_on_cellrenderer_toggle_edited_with_model(const Glib::ustring& path_string, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
852
853  // This is no longer used, but we must keep it to prevent linker errors with already-compiled applications,
854  // For instance, applications that were compiled with the older versions of the templates that did use this method.
855  // TODO: Remove this when we can break API.
856  void _auto_store_on_cellrenderer_toggle_edited(const Glib::ustring& path_string, int model_column);
857
858  template<class ColumnType> friend
859  void TreeView_Private::_connect_auto_store_editable_signal_handler(TreeView*, CellRenderer*, const TreeModelColumn<ColumnType>&);
860
861#endif //DOXYGEN_SHOULD_SKIP_THIS
862};
863
864
865
866template <class ColumnType> inline
867int TreeView::append_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column)
868{
869  // compilation will fail if there is no appropriate TreeViewColumn
870  // constructor for this model column type.
871  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );
872
873  return append_column(*pViewColumn);
874}
875
876//This is here because sigc::bind once did not work on all platforms, but now it does..
877#define GTKMM_HAVE_SIGC_BIND 1
878
879#ifdef GTKMM_HAVE_SIGC_BIND
880
881template <class ColumnType> inline
882int TreeView::append_column_numeric(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, const Glib::ustring& format)
883{
884  TreeViewColumn* const pViewColumn = Gtk::manage( new TreeViewColumn(title) );
885
886  //Use a CellRendererText:
887  //We don't use TreeView::Column::append_column(model_column) to generate an appropriate CellRenderer,
888  //because that uses set_renderer(), which renders the model value using the automatic glib "transformations" (number-string conversions). As well as being unnecessary here, those automatic conversions can't handle all numeric types.
889  CellRenderer* pCellRenderer = manage( new CellRendererText() );
890  pViewColumn->pack_start(*pCellRenderer);
891
892
893  //Some compilers don't like us to give the pointer to a template function directly to sigc::ptr_fun():
894  typedef void (*type_fptr)(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter, int model_column, const Glib::ustring& format);
895  type_fptr fptr = TreeView_Private::_auto_cell_data_func<ColumnType>;
896
897  //Connect a cell_data callback, to show the number's text representation in the specified format:
898  //We use sigc::bind<-1> twice here, instead of sigc::bind() once, because some compilers need the extra hint.
899  Gtk::TreeViewColumn::SlotTreeCellData slot = sigc::bind<-1>(
900    sigc::bind<-1>( sigc::ptr_fun(fptr), format),
901    model_column.index()
902  );
903
904  pViewColumn->set_cell_data_func(*pCellRenderer, slot);
905
906  return append_column(*pViewColumn);
907}
908
909#endif //GTKMM_HAVE_SIGC_BIND
910
911template <class ColumnType> inline
912int TreeView::append_column_numeric_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, const Glib::ustring& format)
913{
914  int cols_count = append_column_numeric(title, model_column, format);
915
916  //connect signal handlers for auto-storing of edited cell data
917  //Note: This will only work for base-10 (decimal) formatted numbers:
918  CellRenderer *const cell = get_column_cell_renderer(cols_count - 1);
919  if(cell)
920  {
921    TreeView_Private::_connect_auto_store_numeric_editable_signal_handler<ColumnType>(this, cell, model_column);
922  }
923
924  return cols_count;
925}
926
927template <class ColumnType> inline
928int TreeView::append_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column)
929{
930  //Don't use this in a header, because it gives warnings when disabled: g_assert(model_column.type() != 0);
931
932  // compilation will fail if there is no appropriate TreeViewColumn
933  // constructor for this model column type.
934  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );
935
936  //connect signal handlers for auto-storing of edited cell data
937  CellRenderer* pCellRender = pViewColumn->get_first_cell();
938  TreeView_Private::_connect_auto_store_editable_signal_handler<ColumnType>(this, pCellRender, model_column);
939
940  return append_column(*pViewColumn);
941}
942
943template <class ColumnType> inline
944int TreeView::insert_column(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position)
945{
946  // compilation will fail if there is no appropriate TreeViewColumn
947  // constructor for this model column type.
948  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );
949
950  return insert_column(*pViewColumn, position);
951}
952
953template <class ColumnType> inline
954int TreeView::insert_column_editable(const Glib::ustring& title, const TreeModelColumn<ColumnType>& model_column, int position)
955{
956  // compilation will fail if there is no appropriate TreeViewColumn
957  // constructor for this model column type.
958  TreeViewColumn *const pViewColumn = Gtk::manage( new TreeViewColumn(title, model_column) );
959
960   //connect signal handlers for auto-storing of edited cell data
961  CellRenderer* pCellRender = pViewColumn->get_first_cell();
962  TreeView_Private::_connect_auto_store_editable_signal_handler(this, pCellRender, model_column);
963
964  return insert_column(*pViewColumn, position);
965}
966
967
968#ifndef DOXYGEN_SHOULD_SKIP_THIS
969namespace TreeView_Private
970{
971
972//Template specializations, for different model column types:
973//TODO: Move these specializations into the .ccg file - I tried, but the int specialization was not used by the compiler. murrayc.
974
975// append_column_editable<>() and insert_column_editable<>() call template function
976// _connect_auto_store_editable_signal_handler<ColumnType>().
977// There are 3 versions of _connect_auto_store_editable_signal_handler<>():
978//
979// 1. The default version for string data. It connects
980//    CellRendererText::signal_edited() to template function
981//    _auto_store_on_cellrenderer_text_edited_string<ColumnType>().
982//
983// 2. A bool specialization. It connects CellRendererToggle::signal_toggled()
984//    to function _auto_store_on_cellrenderer_toggle_edited_with_model().
985//
986// 3. Several identical (except for the type name) specializations for numeric data.
987//    They call _connect_auto_store_numeric_editable_signal_handler<ColumnType>(),
988//    which connects CellRendererText::signal_edited() to template function
989//    _auto_store_on_cellrenderer_text_edited_numerical<ColumnType>().
990//
991// We need all those specializations with identical implementations, because we
992// chose to avoid multiple specializations for the string types by dealing with
993// string types in the default implementation.
994//
995// With these numeric specializations append_column_editable<>() and
996// insert_column_editable<>() can be used for the same numeric types as
997// append_column<>() and insert_column<>(). Those are fundamental types in the
998// GType system, and Glib registers conversion functions from those types to
999// gchararray with g_value_register_transform_func().
1000// 'short' is not one of those types. It can be handled only by
1001// append_column_numeric<>() and append_column_numeric_editable<>().
1002
1003#ifdef GTKMM_HAVE_SIGC_BIND
1004
1005//bool specialization:
1006template<> inline
1007void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer, const Gtk::TreeModelColumn<bool>& model_column)
1008{
1009  Gtk::CellRendererToggle* pCellToggle = dynamic_cast<Gtk::CellRendererToggle*>(pCellRenderer);
1010  if(pCellToggle)
1011  {
1012    //Set the appropriate property,
1013    pCellToggle->property_activatable() = true;
1014
1015    //Connect to the appropriate signal, sending the model_column too
1016
1017    sigc::slot<void, const Glib::ustring&, int> slot_temp =
1018      sigc::bind<-1>(
1019        sigc::mem_fun(*this_p, &Gtk::TreeView::_auto_store_on_cellrenderer_toggle_edited_with_model),
1020        this_p->get_model()
1021      );
1022
1023    pCellToggle->signal_toggled().connect(
1024      sigc::bind<-1>(
1025        slot_temp,
1026        model_column.index()
1027      )
1028    );
1029
1030    //We use bind<1> instead of bind because some compilers need the extra hint.
1031  }
1032}
1033
1034//int specialization:
1035template<> inline
1036void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<int>& model_column)
1037{
1038  _connect_auto_store_numeric_editable_signal_handler<int>(this_p, pCellRenderer, model_column);
1039}
1040
1041//unsigned int specialization:
1042template<> inline
1043void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<unsigned int>& model_column)
1044{
1045  _connect_auto_store_numeric_editable_signal_handler<unsigned int>(this_p, pCellRenderer, model_column);
1046}
1047
1048//long specialization:
1049template<> inline
1050void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<long>& model_column)
1051{
1052  _connect_auto_store_numeric_editable_signal_handler<long>(this_p, pCellRenderer, model_column);
1053}
1054
1055//unsigned long specialization:
1056template<> inline
1057void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<unsigned long>& model_column)
1058{
1059  _connect_auto_store_numeric_editable_signal_handler<unsigned long>(this_p, pCellRenderer, model_column);
1060}
1061
1062//float specialization:
1063template<> inline
1064void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<float>& model_column)
1065{
1066  _connect_auto_store_numeric_editable_signal_handler<float>(this_p, pCellRenderer, model_column);
1067}
1068
1069//double specialization:
1070template<> inline
1071void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<double>& model_column)
1072{
1073  _connect_auto_store_numeric_editable_signal_handler<double>(this_p, pCellRenderer, model_column);
1074}
1075
1076#endif //GTKMM_HAVE_SIGC_BIND
1077
1078} // namespace TreeView_Private
1079#endif //DOXYGEN_SHOULD_SKIP_THIS
1080
1081
1082#ifndef DOXYGEN_SHOULD_SKIP_THIS
1083namespace TreeView_Private
1084{
1085
1086#ifdef GTKMM_HAVE_SIGC_BIND
1087
1088template <class ColumnType> inline
1089void _connect_auto_store_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer, const Gtk::TreeModelColumn<ColumnType>& model_column)
1090{
1091  //Don't use this in a header, because it gives warnings when disabled: g_assert(model_column.type() != 0);
1092
1093  //The different CellRenderers have different "edited" signals,
1094  //and numerical values need to convert the text value to a number,
1095  //so there are specializations for this template.
1096
1097  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
1098
1099  //Set the appropriate property,
1100  //and connect to the appropriate signal, sending the model_column too,
1101  if(pCellText)
1102  {
1103    pCellText->property_editable() = true;
1104
1105    //Some compilers (IRIX MipsPro) don't like us to give the pointer to a template function directly to sigc::ptr_fun():
1106    typedef void (*type_func)(const Glib::ustring&, const Glib::ustring&, int, const Glib::RefPtr<Gtk::TreeModel>&);
1107    type_func func = &(Gtk::TreeView_Private::_auto_store_on_cellrenderer_text_edited_string<ColumnType>);
1108    sigc::slot<void, const Glib::ustring&, const Glib::ustring&, int, const Glib::RefPtr<Gtk::TreeModel>&> theslot  =
1109      sigc::ptr_fun(func);
1110
1111    //We use bind<-1> twice here, instead of using bind() once, because some compilers need the extra hint.
1112    pCellText->signal_edited().connect(
1113      sigc::bind<-1>(
1114        sigc::bind<-1>( theslot, this_p->get_model()),
1115        model_column.index()
1116      )
1117    );
1118  }
1119}
1120
1121template<class ColumnType> inline
1122void _connect_auto_store_numeric_editable_signal_handler(Gtk::TreeView* this_p, Gtk::CellRenderer* pCellRenderer,  const Gtk::TreeModelColumn<ColumnType>& model_column)
1123{
1124  //The different CellRenderers have different "edited" signals,
1125  //and numerical values need to convert the text value to a number.
1126
1127  Gtk::CellRendererText* pCellText = dynamic_cast<Gtk::CellRendererText*>(pCellRenderer);
1128  if(pCellText)
1129  {
1130    //Set the appropriate property.
1131    pCellText->property_editable() = true;
1132
1133    //Some compilers don't like us to give the pointer to a template function directly to sigc::ptr_fun():
1134    typedef void (*type_fptr)(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model);
1135    type_fptr fptr = _auto_store_on_cellrenderer_text_edited_numerical<ColumnType>;
1136
1137    //Connect to the appropriate signal, sending the model_column too.
1138    //We use bind<-1> twice here, instead of using bind() once, because some compilers need the extra hint.
1139    pCellText->signal_edited().connect(
1140      sigc::bind<-1>(
1141        sigc::bind<-1>(
1142          sigc::ptr_fun(fptr),
1143          this_p->get_model() ),
1144        model_column.index()
1145      )
1146    );
1147  }
1148}
1149
1150#endif //GTKMM_HAVE_SIGC_BIND
1151
1152template <class ColumnType> inline
1153void _auto_store_on_cellrenderer_text_edited_string(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model)
1154{
1155  Gtk::TreePath path(path_string);
1156
1157  //Get the row from the path:
1158  if(model)
1159  {
1160    Gtk::TreeModel::iterator iter = model->get_iter(path);
1161    if(iter)
1162    {
1163        //Store the user's new text in the model:
1164        Gtk::TreeRow row = *iter;
1165        row.set_value(model_column, (ColumnType)new_text);
1166    }
1167  }
1168}
1169
1170template <class ColumnType> inline
1171void _auto_store_on_cellrenderer_text_edited_numerical(const Glib::ustring& path_string, const Glib::ustring& new_text, int model_column, const Glib::RefPtr<Gtk::TreeModel>& model)
1172{
1173  //This is used on numerical model columns:
1174
1175  Gtk::TreePath path(path_string);
1176
1177  //Get the row from the path:
1178  if(model)
1179  {
1180    Gtk::TreeModel::iterator iter = model->get_iter(path);
1181    if(iter)
1182    {
1183      //std::istringstream astream(new_text); //Put it in a stream.
1184      //ColumnType new_value = ColumnType();
1185      //new_value << astream; //Get it out of the stream as the numerical type.
1186
1187      //Convert the text to a number, using the same logic used by GtkCellRendererText when it stores numbers.
1188      ColumnType new_value = ColumnType();
1189      try
1190      {
1191        new_value =  static_cast<ColumnType>( std::stod(new_text) );
1192      }
1193      catch(const std::invalid_argument&)
1194      {
1195         //Intentionally ignored.
1196         //Applications can use their own logic if they want to handle invalid input differently.
1197      }
1198
1199      //Store the user's new text in the model:
1200      Gtk::TreeRow row = *iter;
1201      row.set_value(model_column, (ColumnType)new_value);
1202    }
1203  }
1204}
1205
1206template <class ColumnType> inline
1207void _auto_cell_data_func(Gtk::CellRenderer* cell, const Gtk::TreeModel::iterator& iter, int model_column, const Glib::ustring& format)
1208{
1209  Gtk::CellRendererText* pTextRenderer = dynamic_cast<Gtk::CellRendererText*>(cell);
1210  if(!pTextRenderer)
1211  {
1212    g_warning("gtkmm: TextView: append_column_numeric() was used with a non-numeric type.");
1213  }
1214  else
1215  {
1216    if(iter)
1217    {
1218      //Get the value from the model.
1219      Gtk::TreeModel::Row row = *iter;
1220      ColumnType value = ColumnType();
1221      row.get_value(model_column, value);
1222
1223      //Convert it to a string representation:
1224      char buff[20];
1225      int used = g_snprintf(buff, sizeof(buff), format.c_str(), value); //value must be a numeric type.
1226      if(used > 0)
1227      {
1228        //Show the text representation in the view:
1229        pTextRenderer->property_text() = buff;
1230      }
1231    }
1232  }
1233}
1234
1235} // namespace TreeView_Private
1236#endif //DOXYGEN_SHOULD_SKIP_THIS
1237
1238} // namespace Gtk
1239