diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 9b2cb294e41..b39af367d59 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -375,4 +375,10 @@ int caseFriendlyCompare(const QString &a, const QString &b) return a.compare(b, Qt::CaseSensitive); } +QString quoteAmpersands(const QString &text) +{ + QString result = text; + return result.replace("&", "&&"); +} + } // namespace Utils diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index b97063609c9..4bd513dc7c9 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -53,6 +53,8 @@ QTCREATOR_UTILS_EXPORT QString withTildeHomePath(const QString &path); // Removes first unescaped ampersand in text QTCREATOR_UTILS_EXPORT QString stripAccelerator(const QString &text); +// Quotes all ampersands +QTCREATOR_UTILS_EXPORT QString quoteAmpersands(const QString &text); QTCREATOR_UTILS_EXPORT bool readMultiLineString(const QJsonValue &value, QString *out); diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 5f6692dcfbd..ace50be9855 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -70,8 +70,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -1695,7 +1696,8 @@ void EditorManagerPrivate::setupSaveActions(IDocument *document, QAction *saveAc revertToSavedAction->setEnabled(hasFile); if (document && !document->displayName().isEmpty()) { - const QString quotedName = QLatin1Char('"') + document->displayName() + QLatin1Char('"'); + const QString quotedName = QLatin1Char('"') + + Utils::quoteAmpersands(document->displayName()) + QLatin1Char('"'); saveAction->setText(tr("&Save %1").arg(quotedName)); saveAsAction->setText(tr("Save %1 &As...").arg(quotedName)); revertToSavedAction->setText(document->isModified() @@ -1718,7 +1720,8 @@ void EditorManagerPrivate::updateActions() QString quotedName; if (curDocument) - quotedName = QLatin1Char('"') + curDocument->displayName() + QLatin1Char('"'); + quotedName = QLatin1Char('"') + Utils::quoteAmpersands(curDocument->displayName()) + + QLatin1Char('"'); setupSaveActions(curDocument, d->m_saveAction, d->m_saveAsAction, d->m_revertToSavedAction); d->m_closeCurrentEditorAction->setEnabled(curDocument); @@ -2397,11 +2400,12 @@ void EditorManager::addSaveAndCloseEditorActions(QMenu *contextMenu, DocumentMod contextMenu->addSeparator(); + const QString quotedDisplayName = Utils::quoteAmpersands(entry->displayName()); d->m_closeCurrentEditorContextAction->setText(entry - ? tr("Close \"%1\"").arg(entry->displayName()) + ? tr("Close \"%1\"").arg(quotedDisplayName) : tr("Close Editor")); d->m_closeOtherDocumentsContextAction->setText(entry - ? tr("Close All Except \"%1\"").arg(entry->displayName()) + ? tr("Close All Except \"%1\"").arg(quotedDisplayName) : tr("Close Other Editors")); d->m_closeCurrentEditorContextAction->setEnabled(entry != nullptr); d->m_closeOtherDocumentsContextAction->setEnabled(entry != nullptr); diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 50d6f51fd29..33c7a71c173 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -1060,7 +1060,8 @@ void MainWindow::aboutToShowRecentFiles() for (int i = 0; i < recentFiles.count(); ++i) { const DocumentManager::RecentFile file = recentFiles[i]; - const QString filePath = QDir::toNativeSeparators(withTildeHomePath(file.first)); + const QString filePath + = Utils::quoteAmpersands(QDir::toNativeSeparators(withTildeHomePath(file.first))); const QString actionText = ActionManager::withNumberAccelerator(filePath, i + 1); QAction *action = menu->addAction(actionText); connect(action, &QAction::triggered, this, [file] { diff --git a/src/plugins/coreplugin/windowsupport.cpp b/src/plugins/coreplugin/windowsupport.cpp index 88a305560c4..5d2ab1c9faa 100644 --- a/src/plugins/coreplugin/windowsupport.cpp +++ b/src/plugins/coreplugin/windowsupport.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -194,7 +195,7 @@ void WindowList::updateTitle(QWidget *window) QString title = window->windowTitle(); if (title.endsWith(QStringLiteral("- ") + Constants::IDE_DISPLAY_NAME)) title.chop(12); - m_windowActions.at(index)->setText(title.trimmed()); + m_windowActions.at(index)->setText(Utils::quoteAmpersands(title.trimmed())); } void WindowList::removeWindow(QWidget *window) diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 4657b68ac24..044b3789768 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -59,9 +59,10 @@ #include #include -#include #include #include +#include +#include #include #include @@ -1358,7 +1359,7 @@ void GitPlugin::updateActions(VcsBasePlugin::ActionState as) updateVersionWarning(); // Note: This menu is visible if there is no repository. Only // 'Create Repository'/'Show' actions should be available. - const QString fileName = state.currentFileName(); + const QString fileName = Utils::quoteAmpersands(state.currentFileName()); for (ParameterAction *fileAction : Utils::asConst(m_fileActions)) fileAction->setParameter(fileName); // If the current file looks like a patch, offer to apply diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index 973f1ea7586..066bb350e9f 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -46,8 +46,9 @@ #include #include -#include #include +#include +#include #include @@ -281,7 +282,7 @@ void ShortCutManager::updateActions(Core::IEditor* currentEditor) QString quotedName; if (currentEditor && document) - quotedName = '"' + document->displayName() + '"'; + quotedName = '"' + Utils::quoteAmpersands(document->displayName()) + '"'; m_saveAsAction.setText(tr("Save %1 As...").arg(quotedName)); m_saveAction.setText(tr("&Save %1").arg(quotedName));