forked from qt-creator/qt-creator
Make find options in tool bar more accessible.
Open a popup that doesn't close on every change of an option. Make the options button accessible through tab. Task-number: QTCREATORBUG-11340 Change-Id: I61b83243ead4b0b3d7075c1e8f8327cd31d9c2c4 Reviewed-by: Bojan Petrovic <bojan85@gmail.com> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
@@ -30,13 +30,14 @@
|
|||||||
#include "execmenu.h"
|
#include "execmenu.h"
|
||||||
#include "fancylineedit.h"
|
#include "fancylineedit.h"
|
||||||
#include "historycompleter.h"
|
#include "historycompleter.h"
|
||||||
|
#include "hostosinfo.h"
|
||||||
#include "qtcassert.h"
|
#include "qtcassert.h"
|
||||||
|
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPainter>
|
#include <QStylePainter>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
@@ -184,6 +185,11 @@ bool FancyLineEdit::isButtonVisible(Side side) const
|
|||||||
return d->m_iconEnabled[side];
|
return d->m_iconEnabled[side];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractButton *FancyLineEdit::button(FancyLineEdit::Side side) const
|
||||||
|
{
|
||||||
|
return d->m_iconbutton[side];
|
||||||
|
}
|
||||||
|
|
||||||
void FancyLineEdit::iconClicked()
|
void FancyLineEdit::iconClicked()
|
||||||
{
|
{
|
||||||
IconButton *button = qobject_cast<IconButton *>(sender());
|
IconButton *button = qobject_cast<IconButton *>(sender());
|
||||||
@@ -480,7 +486,7 @@ IconButton::IconButton(QWidget *parent)
|
|||||||
|
|
||||||
void IconButton::paintEvent(QPaintEvent *)
|
void IconButton::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QStylePainter painter(this);
|
||||||
QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
|
QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
|
||||||
pixmapRect.moveCenter(rect().center());
|
pixmapRect.moveCenter(rect().center());
|
||||||
|
|
||||||
@@ -488,6 +494,18 @@ void IconButton::paintEvent(QPaintEvent *)
|
|||||||
painter.setOpacity(m_iconOpacity);
|
painter.setOpacity(m_iconOpacity);
|
||||||
|
|
||||||
painter.drawPixmap(pixmapRect, m_pixmap);
|
painter.drawPixmap(pixmapRect, m_pixmap);
|
||||||
|
|
||||||
|
if (hasFocus()) {
|
||||||
|
QStyleOptionFocusRect focusOption;
|
||||||
|
focusOption.initFrom(this);
|
||||||
|
focusOption.rect = pixmapRect;
|
||||||
|
if (HostOsInfo::isMacHost()) {
|
||||||
|
focusOption.rect.adjust(-4, -4, 4, 4);
|
||||||
|
painter.drawControl(QStyle::CE_FocusFrame, focusOption);
|
||||||
|
} else {
|
||||||
|
painter.drawPrimitive(QStyle::PE_FrameFocusRect, focusOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconButton::animateShow(bool visible)
|
void IconButton::animateShow(bool visible)
|
||||||
@@ -505,4 +523,20 @@ void IconButton::animateShow(bool visible)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconButton::keyPressEvent(QKeyEvent *ke)
|
||||||
|
{
|
||||||
|
QAbstractButton::keyPressEvent(ke);
|
||||||
|
if (!ke->modifiers() && (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return))
|
||||||
|
click();
|
||||||
|
// do not forward to line edit
|
||||||
|
ke->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconButton::keyReleaseEvent(QKeyEvent *ke)
|
||||||
|
{
|
||||||
|
QAbstractButton::keyReleaseEvent(ke);
|
||||||
|
// do not forward to line edit
|
||||||
|
ke->accept();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ public:
|
|||||||
|
|
||||||
void setAutoHide(bool hide) { m_autoHide = hide; }
|
void setAutoHide(bool hide) { m_autoHide = hide; }
|
||||||
bool hasAutoHide() const { return m_autoHide; }
|
bool hasAutoHide() const { return m_autoHide; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *ke);
|
||||||
|
void keyReleaseEvent(QKeyEvent *ke);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float m_iconOpacity;
|
float m_iconOpacity;
|
||||||
bool m_autoHide;
|
bool m_autoHide;
|
||||||
@@ -89,6 +94,7 @@ public:
|
|||||||
|
|
||||||
void setButtonVisible(Side side, bool visible);
|
void setButtonVisible(Side side, bool visible);
|
||||||
bool isButtonVisible(Side side) const;
|
bool isButtonVisible(Side side) const;
|
||||||
|
QAbstractButton *button(Side side) const;
|
||||||
|
|
||||||
void setButtonToolTip(Side side, const QString &);
|
void setButtonToolTip(Side side, const QString &);
|
||||||
void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy);
|
void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy);
|
||||||
|
|||||||
@@ -42,10 +42,12 @@
|
|||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/flowlayout.h>
|
#include <utils/flowlayout.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
@@ -100,14 +102,15 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_ui.findEdit->setSpecialCompleter(m_findCompleter);
|
m_ui.findEdit->setSpecialCompleter(m_findCompleter);
|
||||||
m_ui.replaceEdit->setSpecialCompleter(m_replaceCompleter);
|
m_ui.replaceEdit->setSpecialCompleter(m_replaceCompleter);
|
||||||
|
|
||||||
QMenu *lineEditMenu = new QMenu(m_ui.findEdit);
|
|
||||||
m_ui.findEdit->setButtonMenu(Utils::FancyLineEdit::Left, lineEditMenu);
|
|
||||||
m_ui.findEdit->setButtonVisible(Utils::FancyLineEdit::Left, true);
|
m_ui.findEdit->setButtonVisible(Utils::FancyLineEdit::Left, true);
|
||||||
m_ui.findEdit->setFiltering(true);
|
m_ui.findEdit->setFiltering(true);
|
||||||
m_ui.findEdit->setPlaceholderText(QString());
|
m_ui.findEdit->setPlaceholderText(QString());
|
||||||
|
m_ui.findEdit->button(Utils::FancyLineEdit::Left)->setFocusPolicy(Qt::TabFocus);
|
||||||
m_ui.replaceEdit->setPlaceholderText(QString());
|
m_ui.replaceEdit->setPlaceholderText(QString());
|
||||||
|
|
||||||
connect(m_ui.findEdit, SIGNAL(textChanged(QString)), this, SLOT(invokeFindIncremental()));
|
connect(m_ui.findEdit, SIGNAL(textChanged(QString)), this, SLOT(invokeFindIncremental()));
|
||||||
|
connect(m_ui.findEdit, SIGNAL(leftButtonClicked()),
|
||||||
|
this, SLOT(findEditButtonClicked()));
|
||||||
|
|
||||||
// invoke{Find,Replace}Helper change the completion model. QueuedConnection is used to perform these
|
// invoke{Find,Replace}Helper change the completion model. QueuedConnection is used to perform these
|
||||||
// changes only after the completer's activated() signal is handled (QTCREATORBUG-8408)
|
// changes only after the completer's activated() signal is handled (QTCREATORBUG-8408)
|
||||||
@@ -222,8 +225,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_caseSensitiveAction->setChecked(false);
|
m_caseSensitiveAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_caseSensitiveAction, SIGNAL(triggered(bool)), this, SLOT(setCaseSensitive(bool)));
|
connect(m_caseSensitiveAction, SIGNAL(toggled(bool)), this, SLOT(setCaseSensitive(bool)));
|
||||||
lineEditMenu->addAction(m_caseSensitiveAction);
|
|
||||||
|
|
||||||
m_wholeWordAction = new QAction(tr("Whole Words Only"), this);
|
m_wholeWordAction = new QAction(tr("Whole Words Only"), this);
|
||||||
m_wholeWordAction->setIcon(QIcon(QLatin1String(":/find/images/wholewords.png")));
|
m_wholeWordAction->setIcon(QIcon(QLatin1String(":/find/images/wholewords.png")));
|
||||||
@@ -231,8 +233,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_wholeWordAction->setChecked(false);
|
m_wholeWordAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_wholeWordAction, SIGNAL(triggered(bool)), this, SLOT(setWholeWord(bool)));
|
connect(m_wholeWordAction, SIGNAL(toggled(bool)), this, SLOT(setWholeWord(bool)));
|
||||||
lineEditMenu->addAction(m_wholeWordAction);
|
|
||||||
|
|
||||||
m_regularExpressionAction = new QAction(tr("Use Regular Expressions"), this);
|
m_regularExpressionAction = new QAction(tr("Use Regular Expressions"), this);
|
||||||
m_regularExpressionAction->setIcon(QIcon(QLatin1String(":/find/images/regexp.png")));
|
m_regularExpressionAction->setIcon(QIcon(QLatin1String(":/find/images/regexp.png")));
|
||||||
@@ -240,8 +241,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_regularExpressionAction->setChecked(false);
|
m_regularExpressionAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_regularExpressionAction, SIGNAL(triggered(bool)), this, SLOT(setRegularExpressions(bool)));
|
connect(m_regularExpressionAction, SIGNAL(toggled(bool)), this, SLOT(setRegularExpressions(bool)));
|
||||||
lineEditMenu->addAction(m_regularExpressionAction);
|
|
||||||
|
|
||||||
m_preserveCaseAction = new QAction(tr("Preserve Case when Replacing"), this);
|
m_preserveCaseAction = new QAction(tr("Preserve Case when Replacing"), this);
|
||||||
m_preserveCaseAction->setIcon(QPixmap(QLatin1String(":/find/images/preservecase.png")));
|
m_preserveCaseAction->setIcon(QPixmap(QLatin1String(":/find/images/preservecase.png")));
|
||||||
@@ -249,8 +249,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_preserveCaseAction->setChecked(false);
|
m_preserveCaseAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_preserveCaseAction, SIGNAL(triggered(bool)), this, SLOT(setPreserveCase(bool)));
|
connect(m_preserveCaseAction, SIGNAL(toggled(bool)), this, SLOT(setPreserveCase(bool)));
|
||||||
lineEditMenu->addAction(m_preserveCaseAction);
|
|
||||||
|
|
||||||
connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate()));
|
connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate()));
|
||||||
connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar()));
|
connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar()));
|
||||||
@@ -554,6 +553,12 @@ void FindToolBar::findFlagsChanged()
|
|||||||
m_currentDocumentFind->highlightAll(getFindText(), effectiveFindFlags());
|
m_currentDocumentFind->highlightAll(getFindText(), effectiveFindFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindToolBar::findEditButtonClicked()
|
||||||
|
{
|
||||||
|
OptionsPopup *popup = new OptionsPopup(m_ui.findEdit);
|
||||||
|
popup->show();
|
||||||
|
}
|
||||||
|
|
||||||
void FindToolBar::updateIcons()
|
void FindToolBar::updateIcons()
|
||||||
{
|
{
|
||||||
FindFlags effectiveFlags = effectiveFindFlags();
|
FindFlags effectiveFlags = effectiveFindFlags();
|
||||||
@@ -685,11 +690,16 @@ void FindToolBar::findPreviousSelected()
|
|||||||
|
|
||||||
bool FindToolBar::focusNextPrevChild(bool next)
|
bool FindToolBar::focusNextPrevChild(bool next)
|
||||||
{
|
{
|
||||||
// close tab order change
|
QAbstractButton *optionsButton = m_ui.findEdit->button(Utils::FancyLineEdit::Left);
|
||||||
|
// close tab order
|
||||||
if (next && m_ui.advancedButton->hasFocus())
|
if (next && m_ui.advancedButton->hasFocus())
|
||||||
|
optionsButton->setFocus(Qt::TabFocusReason);
|
||||||
|
else if (next && optionsButton->hasFocus())
|
||||||
m_ui.findEdit->setFocus(Qt::TabFocusReason);
|
m_ui.findEdit->setFocus(Qt::TabFocusReason);
|
||||||
else if (!next && m_ui.findEdit->hasFocus())
|
else if (!next && optionsButton->hasFocus())
|
||||||
m_ui.advancedButton->setFocus(Qt::TabFocusReason);
|
m_ui.advancedButton->setFocus(Qt::TabFocusReason);
|
||||||
|
else if (!next && m_ui.findEdit->hasFocus())
|
||||||
|
optionsButton->setFocus(Qt::TabFocusReason);
|
||||||
else
|
else
|
||||||
return Utils::StyledBar::focusNextPrevChild(next);
|
return Utils::StyledBar::focusNextPrevChild(next);
|
||||||
return true;
|
return true;
|
||||||
@@ -778,3 +788,69 @@ void FindToolBar::setBackward(bool backward)
|
|||||||
{
|
{
|
||||||
setFindFlag(FindBackward, backward);
|
setFindFlag(FindBackward, backward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionsPopup::OptionsPopup(QWidget *parent)
|
||||||
|
: QWidget(parent, Qt::Popup)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(2, 2, 2, 2);
|
||||||
|
layout->setSpacing(2);
|
||||||
|
setLayout(layout);
|
||||||
|
QCheckBox *firstCheckBox = createCheckboxForCommand(Constants::CASE_SENSITIVE);
|
||||||
|
layout->addWidget(firstCheckBox);
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::WHOLE_WORDS));
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::REGULAR_EXPRESSIONS));
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::PRESERVE_CASE));
|
||||||
|
firstCheckBox->setFocus();
|
||||||
|
move(parent->mapToGlobal(QPoint(0, -sizeHint().height())));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OptionsPopup::event(QEvent *ev)
|
||||||
|
{
|
||||||
|
if (ev->type() == QEvent::ShortcutOverride) {
|
||||||
|
QKeyEvent *ke = static_cast<QKeyEvent *>(ev);
|
||||||
|
if (ke->key() == Qt::Key_Escape && !ke->modifiers()) {
|
||||||
|
ev->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::event(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OptionsPopup::eventFilter(QObject *obj, QEvent *ev)
|
||||||
|
{
|
||||||
|
QCheckBox *checkbox = qobject_cast<QCheckBox *>(obj);
|
||||||
|
if (ev->type() == QEvent::KeyPress && checkbox) {
|
||||||
|
QKeyEvent *ke = static_cast<QKeyEvent *>(ev);
|
||||||
|
if (!ke->modifiers() && (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return)) {
|
||||||
|
checkbox->click();
|
||||||
|
ev->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsPopup::actionChanged()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
QTC_ASSERT(action, return);
|
||||||
|
QCheckBox *checkbox = m_checkboxMap.value(action);
|
||||||
|
QTC_ASSERT(checkbox, return);
|
||||||
|
checkbox->setEnabled(action->isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox *OptionsPopup::createCheckboxForCommand(Id id)
|
||||||
|
{
|
||||||
|
QAction *action = ActionManager::command(id)->action();
|
||||||
|
QCheckBox *checkbox = new QCheckBox(action->text());
|
||||||
|
checkbox->setToolTip(action->toolTip());
|
||||||
|
checkbox->setChecked(action->isChecked());
|
||||||
|
checkbox->setEnabled(action->isEnabled());
|
||||||
|
checkbox->installEventFilter(this); // enter key handling
|
||||||
|
QObject::connect(checkbox, SIGNAL(clicked(bool)), action, SLOT(setChecked(bool)));
|
||||||
|
QObject::connect(action, SIGNAL(changed()), this, SLOT(actionChanged()));
|
||||||
|
m_checkboxMap.insert(action, checkbox);
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,10 +33,15 @@
|
|||||||
#include "ui_findwidget.h"
|
#include "ui_findwidget.h"
|
||||||
#include "currentdocumentfind.h"
|
#include "currentdocumentfind.h"
|
||||||
|
|
||||||
|
#include <coreplugin/id.h>
|
||||||
#include <utils/styledbar.h>
|
#include <utils/styledbar.h>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QCheckBox;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class FindToolBarPlaceHolder;
|
class FindToolBarPlaceHolder;
|
||||||
@@ -44,6 +49,26 @@ class FindPlugin;
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class OptionsPopup : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OptionsPopup(QWidget *parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event(QEvent *ev);
|
||||||
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QCheckBox *createCheckboxForCommand(Id id);
|
||||||
|
|
||||||
|
QMap<QAction *, QCheckBox *> m_checkboxMap;
|
||||||
|
};
|
||||||
|
|
||||||
class FindToolBar : public Utils::StyledBar
|
class FindToolBar : public Utils::StyledBar
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -85,6 +110,7 @@ private slots:
|
|||||||
void updateFindAction();
|
void updateFindAction();
|
||||||
void updateToolBar();
|
void updateToolBar();
|
||||||
void findFlagsChanged();
|
void findFlagsChanged();
|
||||||
|
void findEditButtonClicked();
|
||||||
|
|
||||||
void setCaseSensitive(bool sensitive);
|
void setCaseSensitive(bool sensitive);
|
||||||
void setWholeWord(bool wholeOnly);
|
void setWholeWord(bool wholeOnly);
|
||||||
|
|||||||
Reference in New Issue
Block a user