Merge pull request #759 from ispyisail/fix-shortcut-conflict-scope

Scope shortcut conflict detection to the category (fixes #757)
This commit is contained in:
ispyisail
2026-09-12 23:07:36 +12:00
committed by GitHub
+20 -2
View File
@@ -56,6 +56,15 @@ static QString normalizedForSearch(const QString &text)
return stripped.toCaseFolded();
}
namespace {
/// Key a shortcut for conflict detection: two actions collide only when they
/// share a sequence *within the same category*. See FINDINGS / upstream #757.
QString conflictKey(const QString &category, const QString &sequence)
{
return category + QLatin1Char('\x1f') + sequence;
}
}
/**
@brief ShortcutsConfigPage::ShortcutsConfigPage
@param parent
@@ -276,18 +285,27 @@ void ShortcutsConfigPage::applyFilter()
*/
void ShortcutsConfigPage::checkConflicts()
{
// Scope the comparison to the category, not the whole registry.
// QElectroTech deliberately registers one key per editor window --
// Undo/Redo/New/Open/Save and Ctrl+Shift+S each exist three times, once
// for the diagram, element and titleblock editors -- and those are not
// collisions: they act on different windows. Comparing globally flagged
// 60 of the 95 shipped defaults as conflicts, which made the indicator
// meaningless. The category is the registry's existing per-window
// grouping, so it is the scope key.
QHash<QString, QList<int>> sequence_to_rows;
for (int row = 0; row < m_rows.size(); ++row) {
const QString sequence_text = m_rows.at(row).edit->keySequence().toString();
if (!sequence_text.isEmpty()) {
sequence_to_rows[sequence_text] << row;
sequence_to_rows[conflictKey(m_rows.at(row).category, sequence_text)] << row;
}
}
for (int row = 0; row < m_rows.size(); ++row) {
Row &current_row = m_rows[row];
const QString sequence_text = current_row.edit->keySequence().toString();
const QList<int> &conflicting_rows = sequence_to_rows.value(sequence_text);
const QList<int> &conflicting_rows =
sequence_to_rows.value(conflictKey(current_row.category, sequence_text));
const bool conflicted = !sequence_text.isEmpty() && conflicting_rows.size() > 1;
current_row.conflicted = conflicted;