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