ProjectExplorer: Let ArgumentsAspect use a multi-line edit

... for cases in which lots of arguments should be provided.

Fixes: QTCREATORBUG-17890
Change-Id: I4744cd58c957e36d9a91e9de994f24589b02c1cc
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2019-06-11 17:21:45 +02:00
parent 91ba57399c
commit 467154e54a
4 changed files with 149 additions and 9 deletions

View File

@@ -200,3 +200,61 @@ QPixmap DetailsButton::cacheRendering(const QSize &size, bool checked)
style()->drawPrimitive(checked ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown, &arrowOpt, &p, this);
return pixmap;
}
ExpandButton::ExpandButton(QWidget *parent) : QAbstractButton(parent)
{
setCheckable(true);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
}
QSize ExpandButton::sizeHint() const
{
return {fontMetrics().horizontalAdvance(text()) + 26, HostOsInfo::isMacHost() ? 34 : 22};
}
void ExpandButton::paintEvent(QPaintEvent *e)
{
QWidget::paintEvent(e);
QPainter p(this);
QPixmap &pixmap = isChecked() ? m_checkedPixmap : m_uncheckedPixmap;
if (pixmap.isNull() || pixmap.size() / pixmap.devicePixelRatio() != contentsRect().size())
pixmap = cacheRendering();
p.drawPixmap(contentsRect(), pixmap);
if (isDown()) {
p.setPen(Qt::NoPen);
p.setBrush(QColor(0, 0, 0, 20));
p.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 1, 1);
}
if (hasFocus()) {
QStyleOptionFocusRect option;
option.initFrom(this);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &p, this);
}
}
QPixmap ExpandButton::cacheRendering()
{
const QSize size = contentsRect().size();
const qreal pixelRatio = devicePixelRatio();
QPixmap pixmap(size * pixelRatio);
pixmap.setDevicePixelRatio(pixelRatio);
pixmap.fill(Qt::transparent);
QPainter p(&pixmap);
p.setRenderHint(QPainter::Antialiasing, true);
p.translate(0.5, 0.5);
p.setPen(Qt::NoPen);
p.drawRoundedRect(0, 0, size.width(), size.height(), 1, 1);
int arrowsize = 15;
QStyleOption arrowOpt;
arrowOpt.initFrom(this);
QPalette pal = arrowOpt.palette;
pal.setBrush(QPalette::All, QPalette::Text, QColor(0, 0, 0));
arrowOpt.rect = QRect(size.width() - arrowsize - 6, height() / 2 - arrowsize / 2,
arrowsize, arrowsize);
arrowOpt.palette = pal;
style()->drawPrimitive(isChecked() ? QStyle::PE_IndicatorArrowUp
: QStyle::PE_IndicatorArrowDown, &arrowOpt, &p, this);
return pixmap;
}

View File

@@ -78,4 +78,22 @@ private:
QPixmap m_uncheckedPixmap;
float m_fader;
};
class QTCREATOR_UTILS_EXPORT ExpandButton : public QAbstractButton
{
Q_OBJECT
public:
ExpandButton(QWidget *parent = nullptr);
private:
void paintEvent(QPaintEvent *e) override;
QSize sizeHint() const override;
QPixmap cacheRendering();
QPixmap m_checkedPixmap;
QPixmap m_uncheckedPixmap;
};
} // namespace Utils

View File

@@ -32,15 +32,17 @@
#include "runconfiguration.h"
#include "target.h"
#include <utils/utilsicons.h>
#include <utils/detailsbutton.h>
#include <utils/fancylineedit.h>
#include <utils/pathchooser.h>
#include <utils/qtcprocess.h>
#include <utils/utilsicons.h>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QFormLayout>
#include <QPlainTextEdit>
#include <QToolButton>
using namespace Utils;
@@ -286,6 +288,8 @@ void ArgumentsAspect::setArguments(const QString &arguments)
}
if (m_chooser && m_chooser->text() != arguments)
m_chooser->setText(arguments);
if (m_multiLineChooser && m_multiLineChooser->toPlainText() != arguments)
m_multiLineChooser->setPlainText(arguments);
}
void ArgumentsAspect::fromMap(const QVariantMap &map)
@@ -297,25 +301,77 @@ void ArgumentsAspect::fromMap(const QVariantMap &map)
else
m_arguments = args.toString();
if (m_chooser)
m_multiLine = map.value(settingsKey() + ".multi", false).toBool();
if (m_multiLineButton)
m_multiLineButton->setChecked(m_multiLine);
if (!m_multiLine && m_chooser)
m_chooser->setText(m_arguments);
if (m_multiLine && m_multiLineChooser)
m_multiLineChooser->setPlainText(m_arguments);
}
void ArgumentsAspect::toMap(QVariantMap &map) const
{
map.insert(settingsKey(), m_arguments);
map.insert(settingsKey() + ".multi", m_multiLine);
}
QWidget *ArgumentsAspect::setupChooser()
{
if (m_multiLine) {
if (!m_multiLineChooser) {
m_multiLineChooser = new QPlainTextEdit;
connect(m_multiLineChooser.data(), &QPlainTextEdit::textChanged,
this, [this] { setArguments(m_multiLineChooser->toPlainText()); });
}
m_multiLineChooser->setPlainText(m_arguments);
return m_multiLineChooser.data();
}
if (!m_chooser) {
m_chooser = new FancyLineEdit;
m_chooser->setHistoryCompleter(settingsKey());
connect(m_chooser.data(), &QLineEdit::textChanged, this, &ArgumentsAspect::setArguments);
}
m_chooser->setText(m_arguments);
return m_chooser.data();
}
void ArgumentsAspect::addToConfigurationLayout(QFormLayout *layout)
{
QTC_CHECK(!m_chooser);
m_chooser = new FancyLineEdit(layout->parentWidget());
m_chooser->setHistoryCompleter(settingsKey());
m_chooser->setText(m_arguments);
QTC_CHECK(!m_chooser && !m_multiLineChooser && !m_multiLineButton);
connect(m_chooser.data(), &QLineEdit::textChanged, this, &ArgumentsAspect::setArguments);
layout->addRow(tr("Command line arguments:"), m_chooser);
const auto container = new QWidget;
const auto containerLayout = new QHBoxLayout(container);
containerLayout->setContentsMargins(0, 0, 0, 0);
containerLayout->addWidget(setupChooser());
m_multiLineButton = new ExpandButton;
m_multiLineButton->setToolTip(tr("Toggle multi-line mode"));
m_multiLineButton->setChecked(m_multiLine);
connect(m_multiLineButton, &QCheckBox::clicked, this, [this](bool checked) {
if (m_multiLine == checked)
return;
m_multiLine = checked;
setupChooser();
QWidget *oldWidget = nullptr;
QWidget *newWidget = nullptr;
if (m_multiLine) {
oldWidget = m_chooser.data();
newWidget = m_multiLineChooser.data();
} else {
oldWidget = m_multiLineChooser.data();
newWidget = m_chooser.data();
}
QTC_ASSERT(!oldWidget == !newWidget, return);
if (oldWidget) {
QTC_ASSERT(oldWidget->parentWidget()->layout(), return);
oldWidget->parentWidget()->layout()->replaceWidget(oldWidget, newWidget);
delete oldWidget;
}
});
containerLayout->addWidget(m_multiLineButton);
containerLayout->setAlignment(m_multiLineButton, Qt::AlignTop);
layout->addRow(tr("Command line arguments:"), container);
}
/*!

View File

@@ -31,9 +31,12 @@
QT_BEGIN_NAMESPACE
class QCheckBox;
class QPlainTextEdit;
class QToolButton;
QT_END_NAMESPACE
namespace Utils { class ExpandButton; }
namespace ProjectExplorer {
class PROJECTEXPLORER_EXPORT TerminalAspect : public ProjectConfigurationAspect
@@ -113,8 +116,13 @@ private:
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
QWidget *setupChooser();
QString m_arguments;
QPointer<Utils::FancyLineEdit> m_chooser;
QPointer<QPlainTextEdit> m_multiLineChooser;
QPointer<Utils::ExpandButton> m_multiLineButton;
bool m_multiLine = false;
mutable bool m_currentlyExpanding = false;
};