switch to using boost::signals2 instead of sigc++, at least for libardour. not finish...
[ardour.git] / gtk2_ardour / keyboard.cc
1 /*
2     Copyright (C) 2001 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 "pbd/error.h"
21 #include "pbd/file_utils.h"
22
23 #include "ardour/filesystem_paths.h"
24
25 #include "keyboard.h"
26 #include "opts.h"
27
28 #include "i18n.h"
29
30 using namespace std;
31 using namespace Gtk;
32 using namespace PBD;
33 using namespace ARDOUR;
34 using Gtkmm2ext::Keyboard;
35
36 static void
37 accel_map_changed (GtkAccelMap* /*map*/,
38                    gchar* /*path*/,
39                    guint /*key*/,
40                    GdkModifierType /*mod*/,
41                    gpointer /*arg*/)
42 {
43         Keyboard::keybindings_changed ();
44 }
45
46 void
47 ArdourKeyboard::setup_keybindings ()
48 {
49         using namespace ARDOUR_COMMAND_LINE;
50         string default_bindings = "mnemonic-us.bindings";
51         vector<string> strs;
52
53         binding_files.clear ();
54
55         ARDOUR::find_bindings_files (binding_files);
56
57         /* set up the per-user bindings path */
58
59         strs.push_back (Glib::get_home_dir());
60         strs.push_back (".ardour3");
61         strs.push_back ("ardour.bindings");
62
63         user_keybindings_path = Glib::build_filename (strs);
64
65         if (Glib::file_test (user_keybindings_path, Glib::FILE_TEST_EXISTS)) {
66                 std::pair<string,string> newpair;
67                 newpair.first = _("your own");
68                 newpair.second = user_keybindings_path;
69                 binding_files.insert (newpair);
70         }
71
72         /* check to see if they gave a style name ("SAE", "ergonomic") or
73            an actual filename (*.bindings)
74         */
75
76         if (!keybindings_path.empty() && keybindings_path.find (".bindings") == string::npos) {
77
78                 // just a style name - allow user to
79                 // specify the layout type.
80
81                 char* layout;
82
83                 if ((layout = getenv ("ARDOUR_KEYBOARD_LAYOUT")) != 0 && layout[0] != '\0') {
84
85                         /* user-specified keyboard layout */
86
87                         keybindings_path += '-';
88                         keybindings_path += layout;
89
90                 } else {
91
92                         /* default to US/ANSI - we have to pick something */
93
94                         keybindings_path += "-us";
95                 }
96
97                 keybindings_path += ".bindings";
98         }
99
100         if (keybindings_path.empty()) {
101
102                 /* no path or binding name given: check the user one first */
103
104                 if (!Glib::file_test (user_keybindings_path, Glib::FILE_TEST_EXISTS)) {
105
106                         keybindings_path = "";
107
108                 } else {
109
110                         keybindings_path = user_keybindings_path;
111                 }
112         }
113
114         /* if we still don't have a path at this point, use the default */
115
116         if (keybindings_path.empty()) {
117                 keybindings_path = default_bindings;
118         }
119
120         while (true) {
121
122                 if (!Glib::path_is_absolute (keybindings_path)) {
123
124                         /* not absolute - look in the usual places */
125                         sys::path keybindings_file;
126
127                         SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
128
129                         if ( ! find_file_in_search_path (spath, keybindings_path, keybindings_file)) {
130
131                                 if (keybindings_path == default_bindings) {
132                                         error << _("Default keybindings not found - Ardour will be hard to use!") << endmsg;
133                                         return;
134                                 } else {
135                                         warning << string_compose (_("Key bindings file \"%1\" not found. Default bindings used instead"),
136                                                                    keybindings_path)
137                                                 << endmsg;
138                                         keybindings_path = default_bindings;
139                                 }
140
141                         } else {
142
143                                 /* use it */
144
145                                 keybindings_path = keybindings_file.to_string();
146                                 break;
147
148                         }
149
150                 } else {
151
152                         /* path is absolute already */
153
154                         if (!Glib::file_test (keybindings_path, Glib::FILE_TEST_EXISTS)) {
155                                 if (keybindings_path == default_bindings) {
156                                         error << _("Default keybindings not found - Ardour will be hard to use!") << endmsg;
157                                         return;
158                                 } else {
159                                         warning << string_compose (_("Key bindings file \"%1\" not found. Default bindings used instead"),
160                                                                    keybindings_path)
161                                                 << endmsg;
162                                         keybindings_path = default_bindings;
163                                 }
164
165                         } else {
166                                 break;
167                         }
168                 }
169         }
170
171         load_keybindings (keybindings_path);
172
173         /* catch changes */
174
175         GtkAccelMap* accelmap = gtk_accel_map_get();
176         g_signal_connect (accelmap, "changed", (GCallback) accel_map_changed, 0);
177 }
178
179 Selection::Operation
180 ArdourKeyboard::selection_type (guint state)
181 {
182         /* note that there is no modifier for "Add" */
183
184         if (modifier_state_equals (state, RangeSelectModifier)) {
185                 return Selection::Extend;
186         } else if (modifier_state_equals (state, PrimaryModifier)) {
187                 return Selection::Toggle;
188         } else {
189                 return Selection::Set;
190         }
191 }
192
193