globally remove all trailing whitespace from ardour code base.
[ardour.git] / libs / gtkmm2ext / selector.cc
1 /*
2     Copyright (C) 1999 Paul Barton-Davis
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation; either version 2 of the License, or
6     (at your option) any later version.
7
8     This program 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
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17     $Id$
18 */
19
20 #include <algorithm>
21 #include <functional>
22 #include <vector>
23 #include <string>
24
25 #include <glibmm.h>
26 #include <gdkmm.h>
27
28 #include "gtkmm2ext/keyboard.h"
29 #include "gtkmm2ext/selector.h"
30 #include "gtkmm2ext/utils.h"
31
32 using namespace std;
33 using namespace Gtkmm2ext;
34
35 Selector::Selector (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg,
36                     vector<string> titles)
37 {
38         scroll.add (tview);
39         scroll.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
40
41         pack_start (scroll, true, true);
42
43         vector<string>::iterator i;
44         for (i = titles.begin(); i != titles.end(); ++i) {
45                 Gtk::TreeModelColumn<Glib::ustring> title;
46                 column_records.add(title);
47         }
48
49         lstore = Gtk::ListStore::create(column_records);
50         tview.set_model(lstore);
51
52         update_contents.connect(mem_fun(*this,&Selector::rescan));
53
54         tview.show ();
55
56         refiller = func;
57         refill_arg = arg;
58         selected_row = -1;
59         selected_column = -1;
60 }
61
62 Selector::~Selector ()
63
64 {
65         /* ensure that any row data set with set_row_data_full() is deleted */
66         hide_all ();
67         lstore.clear ();
68 }
69
70 void
71 Selector::on_map()
72
73 {
74         Gtk::VBox::on_map ();
75
76         selected_row = -1;
77         selected_column = -1;
78         refill();
79 }
80
81 void
82 Selector::on_show()
83 {
84         VBox::on_show();
85
86         rescan();
87 }
88
89 void
90 Selector::reset (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg)
91
92 {
93         refiller = func;
94         refill_arg = arg;
95         selected_row = -1;
96         selected_column = -1;
97
98         refill();
99 }
100
101 void
102 Selector::refill ()
103
104 {
105         if (refiller) {
106                 lstore.clear ();
107                 refiller (lstore, refill_arg);
108         }
109 }
110
111 gint
112 Selector::_accept (gpointer arg)
113
114 {
115         ((Selector *) arg)->accept ();
116         return FALSE;
117 }
118
119 gint
120 Selector::_chosen (gpointer arg)
121
122 {
123         ((Selector *) arg)->chosen ();
124         return FALSE;
125 }
126
127 gint
128 Selector::_shift_clicked (gpointer arg)
129 {
130         ((Selector *) arg)->shift_clicked ();
131         return FALSE;
132 }
133
134 gint
135 Selector::_control_clicked (gpointer arg)
136 {
137         ((Selector *) arg)->control_clicked ();
138         return FALSE;
139 }
140
141 void
142 Selector::accept ()
143 {
144         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
145         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
146
147         if (iter) {
148
149                 selection_made (new Result (tview, tree_sel));
150         } else {
151                 cancel ();
152         }
153 }
154
155 void
156 Selector::chosen ()
157 {
158         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
159         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
160         
161         if (iter) {
162                 choice_made (new Result (tview, tree_sel));
163         } else {
164                 cancel ();
165         }
166 }
167
168 void
169 Selector::shift_clicked ()
170 {
171         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
172         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
173
174         if (iter) {
175                 shift_made (new Result (tview, tree_sel));
176         } else {
177                 cancel ();
178         }
179 }
180
181 void
182 Selector::control_clicked ()
183 {
184         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
185         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
186
187         if (iter) {
188                 control_made (new Result (tview, tree_sel));
189         } else {
190                 cancel ();
191         }
192 }
193
194 void
195 Selector::cancel ()
196 {
197         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
198         tree_sel->unselect_all();
199
200         selection_made (new Result (tview, tree_sel));
201 }
202
203 void
204 Selector::rescan ()
205
206 {
207         selected_row = -1;
208         selected_column = -1;
209         refill ();
210         show_all ();
211 }
212
213 struct string_cmp {
214     bool operator()(const string* a, const string* b) {
215             return *a < *b;
216     }
217 };
218
219 bool
220 TreeView_Selector::on_button_press_event(GdkEventButton* ev)
221 {
222         bool return_value = TreeView::on_button_press_event(ev);
223
224         if (ev && (ev->type == GDK_BUTTON_RELEASE || ev->type == GDK_2BUTTON_PRESS)) {
225                 if (ev->state & Keyboard::PrimaryModifier) {
226                         g_idle_add (Selector::_control_clicked, this);
227                 } else if (ev->state & Keyboard::TertiaryModifier) {
228                         g_idle_add (Selector::_shift_clicked, this);
229                 } else if (ev->type == GDK_2BUTTON_PRESS) {
230                         g_idle_add (Selector::_accept, this);
231                 } else {
232                         g_idle_add (Selector::_chosen, this);
233                 }
234         }
235
236         return return_value;
237 }