forked from qt-creator/qt-creator
PathChooser: Allow for chooser-only selection of files/directories
Makes the line edit disabled and read-only in that case. We also need to change the custom context menu from the line edit to the path chooser itself, because disabled widgets do not show a context menu, but we still want to see the select & copy, and the special items for opening explorer or terminal. Task-number: QTCREATORBUG-23798 Change-Id: Ib653b4eaaedfbe54c614377795ddc52d21ac12c0 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
committed by
Eike Ziller
parent
5838b40c6d
commit
69b0a2cafc
@@ -175,13 +175,15 @@ public:
|
|||||||
Environment m_environment;
|
Environment m_environment;
|
||||||
BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
|
BinaryVersionToolTipEventFilter *m_binaryVersionToolTipEventFilter = nullptr;
|
||||||
QList<QAbstractButton *> m_buttons;
|
QList<QAbstractButton *> m_buttons;
|
||||||
MacroExpander *m_macroExpander;
|
MacroExpander *m_macroExpander = globalMacroExpander();
|
||||||
|
|
||||||
|
bool m_isReadOnly = false;
|
||||||
|
bool m_isFileDialogOnly = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
PathChooserPrivate::PathChooserPrivate() :
|
PathChooserPrivate::PathChooserPrivate()
|
||||||
m_hLayout(new QHBoxLayout),
|
: m_hLayout(new QHBoxLayout)
|
||||||
m_lineEdit(new FancyLineEdit),
|
, m_lineEdit(new FancyLineEdit)
|
||||||
m_macroExpander(globalMacroExpander())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,9 +225,13 @@ PathChooser::PathChooser(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
d->m_hLayout->setContentsMargins(0, 0, 0, 0);
|
d->m_hLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
d->m_lineEdit->setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
d->m_lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
|
||||||
|
|
||||||
connect(d->m_lineEdit, &FancyLineEdit::customContextMenuRequested, this, &PathChooser::contextMenuRequested);
|
connect(this,
|
||||||
|
&FancyLineEdit::customContextMenuRequested,
|
||||||
|
this,
|
||||||
|
&PathChooser::contextMenuRequested);
|
||||||
connect(d->m_lineEdit, &FancyLineEdit::validReturnPressed, this, &PathChooser::returnPressed);
|
connect(d->m_lineEdit, &FancyLineEdit::validReturnPressed, this, &PathChooser::returnPressed);
|
||||||
connect(d->m_lineEdit, &QLineEdit::textChanged, this,
|
connect(d->m_lineEdit, &QLineEdit::textChanged, this,
|
||||||
[this] { emit rawPathChanged(rawPath()); });
|
[this] { emit rawPathChanged(rawPath()); });
|
||||||
@@ -268,6 +274,7 @@ void PathChooser::insertButton(int index, const QString &text, QObject *context,
|
|||||||
connect(button, &QAbstractButton::clicked, context, callback);
|
connect(button, &QAbstractButton::clicked, context, callback);
|
||||||
d->m_hLayout->insertWidget(index + 1/*line edit*/, button);
|
d->m_hLayout->insertWidget(index + 1/*line edit*/, button);
|
||||||
d->m_buttons.insert(index, button);
|
d->m_buttons.insert(index, button);
|
||||||
|
updateReadOnlyStateOfSubwidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PathChooser::browseButtonLabel()
|
QString PathChooser::browseButtonLabel()
|
||||||
@@ -344,15 +351,24 @@ void PathChooser::setFilePath(const FilePath &fn)
|
|||||||
|
|
||||||
bool PathChooser::isReadOnly() const
|
bool PathChooser::isReadOnly() const
|
||||||
{
|
{
|
||||||
return d->m_lineEdit->isReadOnly();
|
return d->m_isReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathChooser::setReadOnly(bool b)
|
void PathChooser::setReadOnly(bool b)
|
||||||
{
|
{
|
||||||
d->m_lineEdit->setReadOnly(b);
|
d->m_isReadOnly = b;
|
||||||
const auto buttons = d->m_buttons;
|
updateReadOnlyStateOfSubwidgets();
|
||||||
for (QAbstractButton *button : buttons)
|
}
|
||||||
button->setEnabled(!b);
|
|
||||||
|
bool PathChooser::isFileDialogOnly() const
|
||||||
|
{
|
||||||
|
return d->m_isFileDialogOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathChooser::setFileDialogOnly(bool b)
|
||||||
|
{
|
||||||
|
d->m_isFileDialogOnly = b;
|
||||||
|
updateReadOnlyStateOfSubwidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathChooser::slotBrowse()
|
void PathChooser::slotBrowse()
|
||||||
@@ -442,16 +458,31 @@ void PathChooser::slotBrowse()
|
|||||||
|
|
||||||
void PathChooser::contextMenuRequested(const QPoint &pos)
|
void PathChooser::contextMenuRequested(const QPoint &pos)
|
||||||
{
|
{
|
||||||
if (QMenu *menu = d->m_lineEdit->createStandardContextMenu()) {
|
if (!d->m_lineEdit->rect().contains(pos))
|
||||||
|
return;
|
||||||
|
QMenu *menu = d->m_lineEdit->createStandardContextMenu();
|
||||||
|
if (!menu)
|
||||||
|
menu = new QMenu;
|
||||||
|
if (s_aboutToShowContextMenuHandler)
|
||||||
|
s_aboutToShowContextMenuHandler(this, menu);
|
||||||
|
if (!menu->actions().isEmpty()) {
|
||||||
menu->setAttribute(Qt::WA_DeleteOnClose);
|
menu->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
menu->popup(mapToGlobal(pos));
|
||||||
if (s_aboutToShowContextMenuHandler)
|
} else {
|
||||||
s_aboutToShowContextMenuHandler(this, menu);
|
delete menu;
|
||||||
|
|
||||||
menu->popup(d->m_lineEdit->mapToGlobal(pos));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathChooser::updateReadOnlyStateOfSubwidgets()
|
||||||
|
{
|
||||||
|
const bool readOnlyLineEdit = d->m_isReadOnly || d->m_isFileDialogOnly;
|
||||||
|
d->m_lineEdit->setEnabled(!readOnlyLineEdit);
|
||||||
|
d->m_lineEdit->setReadOnly(readOnlyLineEdit);
|
||||||
|
setFocusPolicy(d->m_lineEdit->focusPolicy());
|
||||||
|
for (QAbstractButton *button : qAsConst(d->m_buttons))
|
||||||
|
button->setEnabled(!d->m_isReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
bool PathChooser::isValid() const
|
bool PathChooser::isValid() const
|
||||||
{
|
{
|
||||||
return d->m_lineEdit->isValid();
|
return d->m_lineEdit->isValid();
|
||||||
|
@@ -138,6 +138,9 @@ public:
|
|||||||
bool isReadOnly() const;
|
bool isReadOnly() const;
|
||||||
void setReadOnly(bool b);
|
void setReadOnly(bool b);
|
||||||
|
|
||||||
|
bool isFileDialogOnly() const;
|
||||||
|
void setFileDialogOnly(bool b);
|
||||||
|
|
||||||
void triggerChanged();
|
void triggerChanged();
|
||||||
|
|
||||||
// global handler for adding context menus to ALL pathchooser
|
// global handler for adding context menus to ALL pathchooser
|
||||||
@@ -156,6 +159,7 @@ private:
|
|||||||
QString makeDialogTitle(const QString &title);
|
QString makeDialogTitle(const QString &title);
|
||||||
void slotBrowse();
|
void slotBrowse();
|
||||||
void contextMenuRequested(const QPoint &pos);
|
void contextMenuRequested(const QPoint &pos);
|
||||||
|
void updateReadOnlyStateOfSubwidgets();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void validChanged(bool validState);
|
void validChanged(bool validState);
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
#include "cmakeprojectconstants.h"
|
#include "cmakeprojectconstants.h"
|
||||||
|
|
||||||
#include <android/androidconstants.h>
|
#include <android/androidconstants.h>
|
||||||
|
#include <projectexplorer/buildaspects.h>
|
||||||
#include <projectexplorer/buildinfo.h>
|
#include <projectexplorer/buildinfo.h>
|
||||||
#include <projectexplorer/buildmanager.h>
|
#include <projectexplorer/buildmanager.h>
|
||||||
#include <projectexplorer/buildsteplist.h>
|
#include <projectexplorer/buildsteplist.h>
|
||||||
@@ -67,6 +68,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Core::Id id)
|
|||||||
displayName(),
|
displayName(),
|
||||||
BuildConfiguration::Unknown));
|
BuildConfiguration::Unknown));
|
||||||
|
|
||||||
|
buildDirectoryAspect()->setFileDialogOnly(true);
|
||||||
|
|
||||||
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID);
|
||||||
|
|
||||||
|
@@ -109,6 +109,7 @@ public:
|
|||||||
Utils::FilePath m_baseFileName;
|
Utils::FilePath m_baseFileName;
|
||||||
bool m_readOnly = false;
|
bool m_readOnly = false;
|
||||||
bool m_showToolTipOnLabel = false;
|
bool m_showToolTipOnLabel = false;
|
||||||
|
bool m_fileDialogOnly = false;
|
||||||
|
|
||||||
template<class Widget> void updateWidgetFromCheckStatus(Widget *w)
|
template<class Widget> void updateWidgetFromCheckStatus(Widget *w)
|
||||||
{
|
{
|
||||||
@@ -257,6 +258,13 @@ void BaseStringAspect::setExpectedKind(const PathChooser::Kind expectedKind)
|
|||||||
d->m_pathChooserDisplay->setExpectedKind(expectedKind);
|
d->m_pathChooserDisplay->setExpectedKind(expectedKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseStringAspect::setFileDialogOnly(bool requireFileDialog)
|
||||||
|
{
|
||||||
|
d->m_fileDialogOnly = requireFileDialog;
|
||||||
|
if (d->m_pathChooserDisplay)
|
||||||
|
d->m_pathChooserDisplay->setFileDialogOnly(requireFileDialog);
|
||||||
|
}
|
||||||
|
|
||||||
void BaseStringAspect::setEnvironment(const Environment &env)
|
void BaseStringAspect::setEnvironment(const Environment &env)
|
||||||
{
|
{
|
||||||
d->m_environment = env;
|
d->m_environment = env;
|
||||||
@@ -337,6 +345,7 @@ void BaseStringAspect::addToLayout(LayoutBuilder &builder)
|
|||||||
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
|
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
|
||||||
this, &BaseStringAspect::setValue);
|
this, &BaseStringAspect::setValue);
|
||||||
builder.addItem(d->m_pathChooserDisplay.data());
|
builder.addItem(d->m_pathChooserDisplay.data());
|
||||||
|
d->m_pathChooserDisplay->setFileDialogOnly(d->m_fileDialogOnly);
|
||||||
break;
|
break;
|
||||||
case LineEditDisplay:
|
case LineEditDisplay:
|
||||||
d->m_lineEditDisplay = new FancyLineEdit;
|
d->m_lineEditDisplay = new FancyLineEdit;
|
||||||
|
@@ -127,6 +127,7 @@ public:
|
|||||||
void setPlaceHolderText(const QString &placeHolderText);
|
void setPlaceHolderText(const QString &placeHolderText);
|
||||||
void setHistoryCompleter(const QString &historyCompleterKey);
|
void setHistoryCompleter(const QString &historyCompleterKey);
|
||||||
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
|
void setExpectedKind(const Utils::PathChooser::Kind expectedKind);
|
||||||
|
void setFileDialogOnly(bool requireFileDialog);
|
||||||
void setEnvironment(const Utils::Environment &env);
|
void setEnvironment(const Utils::Environment &env);
|
||||||
void setBaseFileName(const Utils::FilePath &baseFileName);
|
void setBaseFileName(const Utils::FilePath &baseFileName);
|
||||||
void setReadOnly(bool readOnly);
|
void setReadOnly(bool readOnly);
|
||||||
|
Reference in New Issue
Block a user