ardour
treeutils.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program 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
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <iostream>
21 
22 #include "gtkmm2ext/treeutils.h"
23 
24 using namespace Glib;
25 using namespace Gtk;
26 
27 void
28 Gtkmm2ext::treeview_select_one (RefPtr<TreeSelection> selection, RefPtr<TreeModel> /*model*/, TreeView& view,
29  TreeIter /*iter*/, TreePath path, TreeViewColumn* col)
30 {
31  if (!view.row_expanded (path)) {
32  // cerr << "!! selecting a row that isn't expanded! " << path.to_string() << endl;
33  }
34 
35  selection->unselect_all ();
36  view.set_cursor (path, *col, true);
37 }
38 
39 void
40 Gtkmm2ext::treeview_select_previous (TreeView& view, RefPtr<TreeModel> model, TreeViewColumn* col)
41 {
42  RefPtr<TreeSelection> selection = view.get_selection();
43  TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
44 
45  if (selection->count_selected_rows() == 0 || !col || model->children().size() < 2) {
46  return;
47  }
48 
49  TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
50  TreeModel::Path start = *i;
51  TreePath prev = start;
52  TreeIter iter;
53 
54  iter = model->get_iter (prev);
55 
56  if (iter == model->children().begin()) {
57 
58  /* at the start, go to the end */
59 
60  TreeIter x = iter;
61  while (iter != model->children().end()) {
62  x = iter;
63  iter++;
64  }
65 
66  /* "x" is now an iterator for the last row */
67 
68  iter = x;
69  prev = model->get_path (iter);
70 
71  } else {
72 
73  prev.prev();
74  }
75 
76  if (prev == start) {
77  /* can't go back, go up */
78 
79  if (!prev.empty()) {
80  prev.up ();
81  }
82  }
83 
84  iter = model->get_iter (prev);
85 
86  if (iter) {
87 
88  treeview_select_one (selection, model, view, iter, prev, col);
89 
90  } else {
91 
92  /* can't move to previous, so restart at selected and move up the tree */
93 
94  prev = start;
95  prev.up ();
96 
97  if (!prev.empty()) {
98  iter = model->get_iter (prev);
99 
100  if (!iter) {
101  /* can't move up the tree*/
102  return;
103  } else {
104  /* moved up from child to parent, now move to ??? */
105  prev.prev();
106  }
107 
108  iter = model->get_iter (prev);
109  }
110 
111  if (iter) {
112  treeview_select_one (selection, model, view, iter, prev, col);
113  } else {
114 
115  /* we could not forward, so wrap around to the first row */
116 
117  /* grr: no nice way to get an iter for the
118  last row, because there is no operator--
119  for TreeIter
120  */
121 
122  TreeIter x = model->children().begin();
123  TreeIter px = x;
124  while (x != model->children().end()) {
125  px = x;
126  x++;
127  }
128  prev = model->get_path (px);
129  treeview_select_one (selection, model, view, px, prev, col);
130  }
131  }
132 }
133 
134 void
135 Gtkmm2ext::treeview_select_next (TreeView& view, RefPtr<TreeModel> model, TreeViewColumn* col)
136 {
137  RefPtr<TreeSelection> selection = view.get_selection();
138  TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
139 
140  if (selection->count_selected_rows() == 0 || !col || model->children().size() < 2) {
141  return;
142  }
143 
144  /* start with the last selected row, not the first */
145 
146  TreeView::Selection::ListHandle_Path::iterator i = rows.begin();
147  TreeView::Selection::ListHandle_Path::iterator p = i;
148 
149  /* get the last selected row */
150 
151  while (i != rows.end()) {
152  p = i;
153  ++i;
154  }
155 
156  TreeModel::Path start = *p;
157  TreePath next = start;
158  TreeIter iter;
159 
160  /* if the row we intend to start from has children but it is not expanded,
161  do not try to go down.
162  */
163 
164  iter = model->get_iter (start);
165 
166  TreeRow row = (*iter);
167  bool down_allowed = false;
168 
169  if (!row.children().empty()) {
170  TreePath tp = model->get_path (iter);
171 
172  if (!view.row_expanded (tp)) {
173  down_allowed = false;
174  } else {
175  down_allowed = true;
176  }
177  }
178 
179  start = next;
180 
181  if (down_allowed) {
182  next.down ();
183  TreeIter iter = model->get_iter (next);
184  if (!iter) {
185  /* can't go down, so move to next */
186  next = start;
187  next.next ();
188  }
189  } else {
190  next.next ();
191  }
192 
193  iter = model->get_iter (next);
194 
195  if (iter) {
196 
197  treeview_select_one (selection, model, view, iter, next, col);
198 
199  } else {
200 
201  /* can't move down/next, so restart at selected and move up the tree */
202 
203  next = start;
204  next.up ();
205 
206  if (!next.empty()) {
207  iter = model->get_iter (next);
208 
209  if (!iter) {
210  /* can't move up the tree*/
211  return;
212  } else {
213  /* moved up from child to parent, now move to next */
214  next.next();
215  }
216 
217  iter = model->get_iter (next);
218  }
219 
220  if (iter) {
221  treeview_select_one (selection, model, view, iter, next, col);
222  } else {
223  /* we could not forward, so wrap around to the first row */
224  next = model->get_path (model->children().begin());
225  treeview_select_one (selection, model, view, model->children().begin(), next, col);
226  }
227  }
228 }
Definition: ardour_ui.h:130
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
LIBGTKMM2EXT_API void treeview_select_next(Gtk::TreeView &view, Glib::RefPtr< Gtk::TreeModel > model, Gtk::TreeViewColumn *col)
LIBGTKMM2EXT_API void treeview_select_previous(Gtk::TreeView &view, Glib::RefPtr< Gtk::TreeModel > model, Gtk::TreeViewColumn *col)
LIBGTKMM2EXT_API void treeview_select_one(Glib::RefPtr< Gtk::TreeSelection > selection, Glib::RefPtr< Gtk::TreeModel > model, Gtk::TreeView &view, Gtk::TreeIter iter, Gtk::TreePath path, Gtk::TreeViewColumn *col)