allow libsndfile to open BWF files; fix -Woverload-virtuals being in CCFLAGS instead...
[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 <gtkmm2ext/selector.h>
26 #include <gtkmm2ext/utils.h>
27 #include <pbd/pathscanner.h>
28 #include <pbd/error.h>
29
30 using namespace std;
31 using namespace Gtkmm2ext;
32
33 Selector::Selector (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg,
34                     vector<string> titles)
35 {
36         scroll.add (tview);
37         scroll.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
38
39         pack_start (scroll, true, true);
40
41         vector<string>::iterator i;
42         for (i = titles.begin(); i != titles.end(); ++i) {
43                 Gtk::TreeModelColumn<Glib::ustring> title;
44                 column_records.add(title);
45         }
46
47         lstore = Gtk::ListStore::create(column_records);
48         tview.set_model(lstore);
49
50         update_contents.connect(mem_fun(*this,&Selector::rescan));
51
52         tview.show ();
53
54         refiller = func;
55         refill_arg = arg;
56         selected_row = -1;
57         selected_column = -1;
58 }
59
60 Selector::~Selector ()
61
62 {
63         /* ensure that any row data set with set_row_data_full() is deleted */
64         hide_all ();
65         lstore.clear ();
66 }
67
68 void
69 Selector::on_map()
70
71 {
72         Gtk::VBox::on_map ();
73
74         selected_row = -1;
75         selected_column = -1;
76         refill();
77 }
78
79 void
80 Selector::on_show()
81 {
82         VBox::on_show();
83
84         rescan();
85 }
86
87 void
88 Selector::reset (void (*func)(Glib::RefPtr<Gtk::ListStore>, void *), void *arg)
89
90 {
91         refiller = func;
92         refill_arg = arg;
93         selected_row = -1;
94         selected_column = -1;
95
96         refill();
97 }
98
99 void
100 Selector::refill ()
101
102 {
103         if (refiller) {
104                 lstore.clear ();
105                 refiller (lstore, refill_arg);
106         }
107 }
108
109 gint
110 Selector::_accept (gpointer arg)
111
112 {
113         ((Selector *) arg)->accept ();
114         return FALSE;
115 }
116
117 gint
118 Selector::_chosen (gpointer arg)
119
120 {
121         ((Selector *) arg)->chosen ();
122         return FALSE;
123 }
124
125 gint
126 Selector::_shift_clicked (gpointer arg)
127 {
128         ((Selector *) arg)->shift_clicked ();
129         return FALSE;
130 }
131
132 gint
133 Selector::_control_clicked (gpointer arg)
134 {
135         ((Selector *) arg)->control_clicked ();
136         return FALSE;
137 }
138
139 void
140 Selector::accept ()
141 {
142         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
143         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
144
145         if (iter) {
146
147                 selection_made (new Result (tview, tree_sel));
148         } else {
149                 cancel ();
150         }
151 }
152
153 void
154 Selector::chosen ()
155 {
156         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
157         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
158         
159         if (iter) {
160                 choice_made (new Result (tview, tree_sel));
161         } else {
162                 cancel ();
163         }
164 }
165
166 void
167 Selector::shift_clicked ()
168 {
169         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
170         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
171
172         if (iter) {
173                 shift_made (new Result (tview, tree_sel));
174         } else {
175                 cancel ();
176         }
177 }
178
179 void
180 Selector::control_clicked ()
181 {
182         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
183         Gtk::TreeModel::iterator iter = tree_sel->get_selected();
184
185         if (iter) {
186                 control_made (new Result (tview, tree_sel));
187         } else {
188                 cancel ();
189         }
190 }
191
192 void
193 Selector::cancel ()
194 {
195         Glib::RefPtr<Gtk::TreeSelection> tree_sel = tview.get_selection();
196         tree_sel->unselect_all();
197
198         selection_made (new Result (tview, tree_sel));
199 }
200
201 void
202 Selector::rescan ()
203
204 {
205         selected_row = -1;
206         selected_column = -1;
207         refill ();
208         show_all ();
209 }
210
211 struct string_cmp {
212     bool operator()(const string* a, const string* b) {
213             return *a < *b;
214     }
215 };
216
217 bool
218 TreeView_Selector::on_button_press_event(GdkEventButton* ev)
219 {
220         bool return_value = TreeView::on_button_press_event(ev);
221
222         if (ev && (ev->type == GDK_BUTTON_RELEASE || ev->type == GDK_2BUTTON_PRESS)) {
223                 if (ev->state & Gdk::CONTROL_MASK) {
224                         gtk_idle_add (Selector::_control_clicked, this);
225                 } else if (ev->state & Gdk::SHIFT_MASK) {
226                         gtk_idle_add (Selector::_shift_clicked, this);
227                 } else if (ev->type == GDK_2BUTTON_PRESS) {
228                         gtk_idle_add (Selector::_accept, this);
229                 } else {
230                         gtk_idle_add (Selector::_chosen, this);
231                 }
232         }
233
234         return return_value;
235 }