+ // 4. grab keyboard focus
+ dialog.m_waiting_for_key = true;
+}
+
+bool accelerator_window_key_press( ui::Widget widget, GdkEventKey *event, gpointer dialogptr ){
+ command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
+
+ if ( !dialog.m_waiting_for_key ) {
+ return false;
+ }
+
+#if 0
+ if ( event->is_modifier ) {
+ return false;
+ }
+#else
+ switch ( event->keyval )
+ {
+ case GDK_KEY_Shift_L:
+ case GDK_KEY_Shift_R:
+ case GDK_KEY_Control_L:
+ case GDK_KEY_Control_R:
+ case GDK_KEY_Caps_Lock:
+ case GDK_KEY_Shift_Lock:
+ case GDK_KEY_Meta_L:
+ case GDK_KEY_Meta_R:
+ case GDK_KEY_Alt_L:
+ case GDK_KEY_Alt_R:
+ case GDK_KEY_Super_L:
+ case GDK_KEY_Super_R:
+ case GDK_KEY_Hyper_L:
+ case GDK_KEY_Hyper_R:
+ return false;
+ }
+#endif
+
+ dialog.m_waiting_for_key = false;
+
+ // 7. find the name of the accelerator
+ GValue val;
+ memset( &val, 0, sizeof( val ) );
+ gtk_tree_model_get_value( GTK_TREE_MODEL( dialog.m_model ), &dialog.m_command_iter, 0, &val );
+ const char *commandName = g_value_get_string( &val );;
+ Shortcuts::iterator thisShortcutIterator = g_shortcuts.find( commandName );
+ if ( thisShortcutIterator == g_shortcuts.end() ) {
+ gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+ gtk_widget_set_sensitive( GTK_WIDGET( dialog.m_list ), true );
+ return true;
+ }
+
+ // 8. build an Accelerator
+ Accelerator newAccel( event->keyval, (GdkModifierType) event->state );
+
+ // 8. verify the key is still free, show a dialog to ask what to do if not
+ class VerifyAcceleratorNotTaken : public CommandVisitor
+ {
+ const char *commandName;
+ const Accelerator &newAccel;
+ ui::Widget widget;
+ GtkTreeModel *model;
+public:
+ bool allow;
+ VerifyAcceleratorNotTaken( const char *name, const Accelerator &accelerator, ui::Widget w, GtkTreeModel *m ) : commandName( name ), newAccel( accelerator ), widget( w ), model( m ), allow( true ){
+ }
+ void visit( const char* name, Accelerator& accelerator ){
+ if ( !strcmp( name, commandName ) ) {
+ return;
+ }
+ if ( !allow ) {
+ return;
+ }
+ if ( accelerator.key == 0 ) {
+ return;
+ }
+ if ( accelerator == newAccel ) {
+ StringOutputStream msg;
+ msg << "The command " << name << " is already assigned to the key " << accelerator << ".\n\n"
+ << "Do you want to unassign " << name << " first?";
+ auto r = widget.alert( msg.c_str(), "Key already used", ui::alert_type::YESNOCANCEL );
+ if ( r == ui::alert_response::YES ) {
+ // clear the ACTUAL accelerator too!
+ disconnect_accelerator( name );
+ // delete the modifier
+ accelerator = accelerator_null();
+ // empty the cell of the key binds dialog
+ GtkTreeIter i;
+ if ( gtk_tree_model_get_iter_first( GTK_TREE_MODEL( model ), &i ) ) {
+ for (;; )
+ {
+ GValue val;
+ memset( &val, 0, sizeof( val ) );
+ gtk_tree_model_get_value( GTK_TREE_MODEL( model ), &i, 0, &val );
+ const char *thisName = g_value_get_string( &val );;
+ if ( !strcmp( thisName, name ) ) {
+ gtk_list_store_set( GTK_LIST_STORE( model ), &i, 1, "", -1 );
+ }
+ g_value_unset( &val );
+ if ( !gtk_tree_model_iter_next( GTK_TREE_MODEL( model ), &i ) ) {
+ break;
+ }
+ }
+ }
+ }
+ else if ( r == ui::alert_response::CANCEL ) {
+ // aborted
+ allow = false;
+ }
+ }
+ }
+ } verify_visitor( commandName, newAccel, widget, dialog.m_model );
+ GlobalShortcuts_foreach( verify_visitor );
+
+ gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
+ gtk_widget_set_sensitive( GTK_WIDGET( dialog.m_list ), true );
+
+ if ( verify_visitor.allow ) {
+ // clear the ACTUAL accelerator first
+ disconnect_accelerator( commandName );
+
+ thisShortcutIterator->second.first = newAccel;
+
+ // write into the cell
+ StringOutputStream modifiers;
+ modifiers << newAccel;
+ gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 1, modifiers.c_str(), -1 );
+
+ // set the ACTUAL accelerator too!
+ connect_accelerator( commandName );
+ }
+
+ g_value_unset( &val );
+
+ dialog.m_model = NULL;
+
+ return true;
+}
+
+/*
+ GtkTreeIter row;
+ GValue val;
+ if(!model) {g_error("Unable to get model from cell renderer");}
+ gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &row, path_string);
+
+ gtk_tree_model_get_value(GTK_TREE_MODEL(model), &row, 0, &val);
+ const char *name = g_value_get_string(&val);
+ Shortcuts::iterator i = g_shortcuts.find(name);
+ if(i != g_shortcuts.end())