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