diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index 59e1242f5d45bf725beae0f9c84d975887bad559..4d8685b009fdc7f0a4f4b1197d62966b7f8c0923 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -39,6 +39,7 @@ #include <QDebug> #include <QFileDialog> #include <QHBoxLayout> +#include <QMenu> #include <QPushButton> #include <QStandardPaths> @@ -66,6 +67,8 @@ static QString appBundleExpandedPath(const QString &path) return path; } +Utils::PathChooser::AboutToShowContextMenuHandler Utils::PathChooser::s_aboutToShowContextMenuHandler; + namespace Utils { // ------------------ BinaryVersionToolTipEventFilter @@ -221,6 +224,9 @@ PathChooser::PathChooser(QWidget *parent) : { d->m_hLayout->setContentsMargins(0, 0, 0, 0); + d->m_lineEdit->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(d->m_lineEdit, &FancyLineEdit::customContextMenuRequested, this, &PathChooser::contextMenuRequested); connect(d->m_lineEdit, &FancyLineEdit::validReturnPressed, this, &PathChooser::returnPressed); connect(d->m_lineEdit, &QLineEdit::textChanged, this, [this] { emit changed(rawPath()); }); connect(d->m_lineEdit, &FancyLineEdit::validChanged, this, &PathChooser::validChanged); @@ -422,6 +428,18 @@ void PathChooser::slotBrowse() triggerChanged(); } +void PathChooser::contextMenuRequested(const QPoint &pos) +{ + if (QMenu *menu = d->m_lineEdit->createStandardContextMenu()) { + menu->setAttribute(Qt::WA_DeleteOnClose); + + if (s_aboutToShowContextMenuHandler) + s_aboutToShowContextMenuHandler(this, menu); + + menu->popup(d->m_lineEdit->mapToGlobal(pos)); + } +} + bool PathChooser::isValid() const { return d->m_lineEdit->isValid(); @@ -437,6 +455,11 @@ void PathChooser::triggerChanged() d->m_lineEdit->triggerChanged(); } +void PathChooser::setAboutToShowContextMenuHandler(PathChooser::AboutToShowContextMenuHandler handler) +{ + s_aboutToShowContextMenuHandler = handler; +} + FancyLineEdit::ValidationFunction PathChooser::defaultValidationFunction() const { return std::bind(&PathChooser::validatePath, this, std::placeholders::_1, std::placeholders::_2); diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h index 64beffa91a63ad1e225f9e0ba63218221966332f..5e701a9e93d9e2f48bf8bb15beb86c63c7db887c 100644 --- a/src/libs/utils/pathchooser.h +++ b/src/libs/utils/pathchooser.h @@ -140,11 +140,17 @@ public: void triggerChanged(); + // global handler for adding context menus to ALL pathchooser + // used by the coreplugin to add "Open in Terminal" and "Open in Explorer" context menu actions + using AboutToShowContextMenuHandler = std::function<void (Utils::PathChooser *, QMenu *)>; + static void setAboutToShowContextMenuHandler(AboutToShowContextMenuHandler handler); + private: bool validatePath(FancyLineEdit *edit, QString *errorMessage) const; // Returns overridden title or the one from <title> QString makeDialogTitle(const QString &title); void slotBrowse(); + void contextMenuRequested(const QPoint &pos); signals: void validChanged(bool validState); @@ -161,6 +167,7 @@ public slots: private: PathChooserPrivate *d; + static AboutToShowContextMenuHandler s_aboutToShowContextMenuHandler; }; } // namespace Utils diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 7d75bb79ebe2281056a75c076f366bfa99d43da3..f52fd82849286923b4faf5fb8f5cd33c4d610c77 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -44,9 +44,11 @@ #include <coreplugin/find/findplugin.h> #include <coreplugin/locator/locator.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/fileutils.h> #include <extensionsystem/pluginerroroverview.h> #include <extensionsystem/pluginmanager.h> +#include <utils/pathchooser.h> #include <utils/macroexpander.h> #include <utils/savefile.h> #include <utils/stringutils.h> @@ -57,6 +59,7 @@ #include <QDebug> #include <QDateTime> #include <QDir> +#include <QMenu> using namespace Core; using namespace Core::Internal; @@ -229,6 +232,8 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) // Make sure all wizards are there when the user might access the keyboard shortcuts: connect(ICore::instance(), &ICore::optionsDialogRequested, []() { IWizardFactory::allWizardFactories(); }); + Utils::PathChooser::setAboutToShowContextMenuHandler(&CorePlugin::addToPathChooserContextMenu); + return success; } @@ -271,6 +276,27 @@ void CorePlugin::fileOpenRequest(const QString &f) remoteCommand(QStringList(), QString(), QStringList(f)); } +void CorePlugin::addToPathChooserContextMenu(Utils::PathChooser *pathChooser, QMenu *menu) +{ + QList<QAction*> actions = menu->actions(); + QAction *firstAction = actions.isEmpty() ? nullptr : actions.first(); + + auto *showInGraphicalShell = new QAction(Core::FileUtils::msgGraphicalShellAction(), menu); + connect(showInGraphicalShell, &QAction::triggered, pathChooser, [pathChooser]() { + Core::FileUtils::showInGraphicalShell(pathChooser, pathChooser->path()); + }); + menu->insertAction(firstAction, showInGraphicalShell); + + auto *showInTerminal = new QAction(Core::FileUtils::msgTerminalAction(), menu); + connect(showInTerminal, &QAction::triggered, pathChooser, [pathChooser]() { + Core::FileUtils::openTerminal(pathChooser->path()); + }); + menu->insertAction(firstAction, showInTerminal); + + if (firstAction) + menu->insertSeparator(firstAction); +} + ExtensionSystem::IPlugin::ShutdownFlag CorePlugin::aboutToShutdown() { m_findPlugin->aboutToShutdown(); diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index fd82e709d61d45a0e4a3d42bdd1f2c7aaa00adbc..6401b72156868141f522808b1f8e0450af8529c3 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -33,7 +33,14 @@ #include <extensionsystem/iplugin.h> -namespace Utils { class Theme; } +QT_BEGIN_NAMESPACE +class QMenu; +QT_END_NAMESPACE + +namespace Utils { +class PathChooser; +class Theme; +} namespace Core { @@ -77,6 +84,7 @@ private slots: private: void parseArguments(const QStringList & arguments); + static void addToPathChooserContextMenu(Utils::PathChooser *pathChooser, QMenu *menu); MainWindow *m_mainWindow; EditMode *m_editMode;