+void accelerator_clear_button_clicked(GtkButton *btn, gpointer dialogptr)
+{
+ command_list_dialog_t &dialog = * (command_list_dialog_t *) dialogptr;
+
+ if(dialog.m_waiting_for_key)
+ {
+ // just unhighlight, user wanted to cancel
+ dialog.m_waiting_for_key = false;
+ 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);
+ dialog.m_model = NULL;
+ return;
+ }
+
+ GtkTreeSelection *sel = gtk_tree_view_get_selection(dialog.m_list);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ if(!gtk_tree_selection_get_selected(sel, &model, &iter))
+ return;
+
+ GValue val;
+ memset(&val, 0, sizeof(val));
+ gtk_tree_model_get_value(GTK_TREE_MODEL(model), &iter, 0, &val);
+ const char *commandName = g_value_get_string(&val);;
+
+ // clear the ACTUAL accelerator too!
+ disconnect_accelerator(commandName);
+
+ Shortcuts::iterator thisShortcutIterator = g_shortcuts.find(commandName);
+ if(thisShortcutIterator == g_shortcuts.end())
+ return;
+ thisShortcutIterator->second.first = accelerator_null();
+
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 1, "", -1);
+
+ g_value_unset(&val);
+}
+
+void accelerator_edit_button_clicked(GtkButton *btn, gpointer dialogptr)
+{
+ command_list_dialog_t &dialog = * (command_list_dialog_t *) dialogptr;
+
+ // 1. find selected row
+ GtkTreeSelection *sel = gtk_tree_view_get_selection(dialog.m_list);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ if(!gtk_tree_selection_get_selected(sel, &model, &iter))
+ return;
+ dialog.m_command_iter = iter;
+ dialog.m_model = model;
+
+ // 2. disallow changing the row
+ //gtk_widget_set_sensitive(GTK_WIDGET(dialog.m_list), false);
+
+ // 3. highlight the row
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 2, true, -1);
+
+ // 4. grab keyboard focus
+ dialog.m_waiting_for_key = true;
+}
+
+gboolean accelerator_window_key_press(GtkWidget *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_Shift_L:
+ case GDK_Shift_R:
+ case GDK_Control_L:
+ case GDK_Control_R:
+ case GDK_Caps_Lock:
+ case GDK_Shift_Lock:
+ case GDK_Meta_L:
+ case GDK_Meta_R:
+ case GDK_Alt_L:
+ case GDK_Alt_R:
+ case GDK_Super_L:
+ case GDK_Super_R:
+ case GDK_Hyper_L:
+ case GDK_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;
+ GtkWidget *widget;
+ GtkTreeModel *model;
+ public:
+ bool allow;
+ VerifyAcceleratorNotTaken(const char *name, const Accelerator &accelerator, GtkWidget *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?";
+ EMessageBoxReturn r = gtk_MessageBox (widget, msg.c_str(), "Key already used", eMB_YESNOCANCEL);
+ if(r == eIDYES)
+ {
+ // 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 == eIDCANCEL)
+ {
+ // 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())
+ {
+ accelerator_parse(i->second.first, new_text);
+ StringOutputStream modifiers;
+ modifiers << i->second.first;
+ gtk_list_store_set(GTK_LIST_STORE(model), &row, 1, modifiers.c_str(), -1);
+ }
+};
+*/
+