bool ShortcutChooser::onShortcutKeyPress(GdkEventKey* ev) { std::string statusText(""); /** greebo: Workaround for allowing Shift+TAB as well (Tab becomes ISO_Left_Tab in that case) */ if (ev->keyval == GDK_ISO_Left_Tab) { ev->keyval = GDK_Tab; } // Store the shortcut string representation into the Entry field _entry->set_text(GlobalEventManager().getGDKEventStr(ev)); // Store this key/modifier combination for later use (UPPERCASE!) _keyval = gdk_keyval_to_upper(ev->keyval); _state = ev->state; IEventPtr foundEvent = GlobalEventManager().findEvent(ev); // Only display the note if any event was found and it's not the "self" event if (!foundEvent->empty() && foundEvent != _event) { statusText = (boost::format(_("Note: This is already assigned to: <b>%s</b>")) % GlobalEventManager().getEventName(foundEvent)).str(); } _statusWidget->set_markup(statusText); return true; // don't propagate }
// Loads the default shortcuts from the registry void EventManager::loadAccelerators() { if (_debugMode) { std::cout << "EventManager: Loading accelerators...\n"; } xml::NodeList shortcutSets = GlobalRegistry().findXPath("user/ui/input//shortcuts"); if (_debugMode) { std::cout << "Found " << shortcutSets.size() << " sets.\n"; } // If we have two sets of shortcuts, delete the default ones if (shortcutSets.size() > 1) { GlobalRegistry().deleteXPath("user/ui/input//shortcuts[@name='default']"); } // Find all accelerators xml::NodeList shortcutList = GlobalRegistry().findXPath("user/ui/input/shortcuts//shortcut"); if (shortcutList.size() > 0) { rMessage() << "EventManager: Shortcuts found in Registry: " << static_cast<int>(shortcutList.size()) << std::endl; for (unsigned int i = 0; i < shortcutList.size(); i++) { const std::string key = shortcutList[i].getAttributeValue("key"); if (_debugMode) { std::cout << "Looking up command: " << shortcutList[i].getAttributeValue("command") << "\n"; std::cout << "Key is: >> " << key << " << \n"; } // Try to lookup the command IEventPtr event = findEvent(shortcutList[i].getAttributeValue("command")); // Check for a non-empty key string if (key != "") { // Check for valid command definitions were found if (!event->empty()) { // Get the modifier string (e.g. "SHIFT+ALT") const std::string modifierStr = shortcutList[i].getAttributeValue("modifiers"); if (!duplicateAccelerator(key, modifierStr, event)) { // Create the accelerator object IAccelerator& accelerator = addAccelerator(key, modifierStr); // Connect the newly created accelerator to the command accelerator.connectEvent(event); } } else { rWarning() << "EventManager: Cannot load shortcut definition (command invalid)." << std::endl; } } } } else { // No accelerator definitions found! rWarning() << "EventManager: No shortcut definitions found..." << std::endl; } }
/* Checks the passed xmlNode for a recognized item (ToolButton, ToggleToolButton, Separator) * Returns the widget or NULL if nothing useful is found */ GtkWidget* ToolbarManager::createToolItem(xml::Node& node) { const std::string nodeName = node.getName(); GtkWidget* toolItem; if (nodeName == "separator") { toolItem = GTK_WIDGET(gtk_separator_tool_item_new()); } else if (nodeName == "toolbutton" || nodeName == "toggletoolbutton") { // Found a button, load the values that are shared by both types const std::string name = node.getAttributeValue("name"); const std::string icon = node.getAttributeValue("icon"); const std::string tooltip = _(node.getAttributeValue("tooltip").c_str()); const std::string action = node.getAttributeValue("action"); if (nodeName == "toolbutton") { // Create a new GtkToolButton and assign the right callback toolItem = GTK_WIDGET(gtk_tool_button_new(NULL, name.c_str())); } else { // Create a new GtkToggleToolButton and assign the right callback toolItem = GTK_WIDGET(gtk_toggle_tool_button_new()); } IEventPtr event = GlobalEventManager().findEvent(action); if (!event->empty()) { event->connectWidget(GTK_WIDGET(toolItem)); // Tell the event to update the state of this button event->updateWidgets(); } else { globalErrorStream() << "ToolbarManager: Failed to lookup command " << action << std::endl; } // Set the tooltip, if not empty if (tooltip != "") { gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolItem), _tooltips, tooltip.c_str(), ""); } // Load and assign the icon, if specified if (icon != "") { GtkWidget* image = gtk_image_new_from_pixbuf(GlobalUIManager().getLocalPixbufWithMask(icon)); gtk_widget_show(image); gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(toolItem), image); } } else { return NULL; } gtk_widget_show(toolItem); return toolItem; }
// Connects the given accelerator to the given command (identified by the string) void EventManager::connectAccelerator(IAccelerator& accelerator, const std::string& command) { IEventPtr event = findEvent(command); if (!event->empty()) { // Command found, connect it to the accelerator by passing its pointer accelerator.connectEvent(event); } else { // Command NOT found rWarning() << "EventManager: Unable to connect command: " << command << std::endl; } }
// Checks if the eventName is already registered and writes to rMessage, if so bool EventManager::alreadyRegistered(const std::string& eventName) { // Try to find the command and see if it's already registered IEventPtr foundEvent = findEvent(eventName); if (foundEvent->empty()) { return false; } else { rWarning() << "EventManager: Event " << eventName << " already registered!" << std::endl; return true; } }
void EventManager::disconnectAccelerator(const std::string& command) { IEventPtr event = findEvent(command); if (!event->empty()) { // Cycle through the accelerators and check for matches for (AcceleratorList::iterator i = _accelerators.begin(); i != _accelerators.end(); i++) { if (i->match(event)) { // Connect the accelerator to the empty event (disable the accelerator) i->connectEvent(_emptyEvent); i->setKey(0); i->setModifiers(0); } } } else { // Command NOT found rWarning() << "EventManager: Unable to disconnect command: " << command << std::endl; } }
bool ShortcutChooser::assignShortcut() { bool shortcutsChanged = false; // Check, if the user has pressed a meaningful key if (_keyval != 0) { // Construct an eventkey structure to be passed to the EventManager query GdkEventKey eventKey; eventKey.keyval = _keyval; eventKey.state = _state; // Try to lookup an existing command with the same shortcut IEventPtr foundEvent = GlobalEventManager().findEvent(&eventKey); // Only react on non-empty and non-"self" events if (!foundEvent->empty() && foundEvent != _event) { // There is already a command connected to this shortcut, ask the user const std::string foundEventName = GlobalEventManager().getEventName(foundEvent); // Construct the message std::string message = (boost::format(_("The specified shortcut is already assigned to <b>%s</b>" "\nOverwrite the current setting and assign this shortcut to <b>%s</b> instead?")) % foundEventName % _commandName).str(); // Fire up the dialog to ask the user what action to take IDialogPtr popup = GlobalDialogManager().createMessageBox( _("Overwrite existing shortcut?"), message, ui::IDialog::MESSAGE_ASK); // Only react on "YES" if (popup->run() == ui::IDialog::RESULT_YES) { // Disconnect both the found command and the new command GlobalEventManager().disconnectAccelerator(foundEventName); GlobalEventManager().disconnectAccelerator(_commandName); // Create a new accelerator and connect it to the selected command IAccelerator& accel = GlobalEventManager().addAccelerator(&eventKey); GlobalEventManager().connectAccelerator(accel, _commandName); shortcutsChanged = true; } } else { // No command is using the accelerator up to now, so assign it // Disconnect the current command to avoid duplicate accelerators GlobalEventManager().disconnectAccelerator(_commandName); // Create a new accelerator and connect it to the selected command IAccelerator& accel = GlobalEventManager().addAccelerator(&eventKey); GlobalEventManager().connectAccelerator(accel, _commandName); shortcutsChanged = true; } } else { // No key is specified, disconnect the command GlobalEventManager().disconnectAccelerator(_commandName); shortcutsChanged = true; } return shortcutsChanged; }