+ uint32_t gtk_legal_keyval = kb.key();
+ possibly_translate_keyval_to_make_legal_accelerator (gtk_legal_keyval);
+ KeyboardKey gtk_binding (kb.state(), gtk_legal_keyval);
+
+
+ bool entry_exists = Gtk::AccelMap::lookup_entry (what->get_accel_path(), gtk_key);
+
+ if (!entry_exists || gtk_key.get_key() == 0) {
+
+ /* there is a trick happening here. It turns out that
+ * gtk_accel_map_add_entry() performs no validation checks on
+ * the accelerator keyval. This means we can use it to define
+ * ANY accelerator, even if they violate GTK's rules
+ * (e.g. about not using navigation keys). This works ONLY when
+ * the entry in the GTK accelerator map has not already been
+ * added. The entries will be added by the GTK UIManager when
+ * building menus, so this code must be called before that
+ * happens.
+ */
+
+ Gtk::AccelMap::add_entry (what->get_accel_path(),
+ gtk_binding.key(),
+ (Gdk::ModifierType) gtk_binding.state());
+ } else {
+ warning << string_compose (_("There is more than one key binding defined for %1. Both will work, but only the first will be visible in menus"), what->get_accel_path()) << endmsg;
+ }
+
+ if (!Gtk::AccelMap::lookup_entry (what->get_accel_path(), gtk_key) || gtk_key.get_key() == 0) {
+ cerr << "GTK binding using " << gtk_binding << " failed for " << what->get_accel_path() << " existing = " << gtk_key.get_key() << " + " << gtk_key.get_mod() << endl;
+ }
+}
+
+bool
+Bindings::replace (KeyboardKey kb, Operation op, string const & action_name, bool can_save)
+{