diff options
author | Eike Ziller <eike.ziller@digia.com> | 2014-02-25 18:38:35 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@digia.com> | 2014-02-28 13:43:20 +0100 |
commit | 8e51a93d37e824fc4c43d993a761ad36d24764f2 (patch) | |
tree | 83f4b5c65b1a02b91272af643eb748891050bc84 | |
parent | 880a834b119dc7b25cc64c7b7a381e9a43aa6bf4 (diff) | |
download | qt-creator-8e51a93d37e824fc4c43d993a761ad36d24764f2.tar.gz |
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>
-rw-r--r-- | src/libs/utils/fancylineedit.cpp | 38 | ||||
-rw-r--r-- | src/libs/utils/fancylineedit.h | 6 | ||||
-rw-r--r-- | src/plugins/coreplugin/find/findtoolbar.cpp | 100 | ||||
-rw-r--r-- | src/plugins/coreplugin/find/findtoolbar.h | 26 |
4 files changed, 156 insertions, 14 deletions
diff --git a/src/libs/utils/fancylineedit.cpp b/src/libs/utils/fancylineedit.cpp index 0fbfe6dece..dcb1cb834f 100644 --- a/src/libs/utils/fancylineedit.cpp +++ b/src/libs/utils/fancylineedit.cpp @@ -30,13 +30,14 @@ #include "execmenu.h" #include "fancylineedit.h" #include "historycompleter.h" +#include "hostosinfo.h" #include "qtcassert.h" #include <QAbstractItemView> #include <QDebug> #include <QKeyEvent> #include <QMenu> -#include <QPainter> +#include <QStylePainter> #include <QPropertyAnimation> #include <QStyle> @@ -184,6 +185,11 @@ bool FancyLineEdit::isButtonVisible(Side side) const return d->m_iconEnabled[side]; } +QAbstractButton *FancyLineEdit::button(FancyLineEdit::Side side) const +{ + return d->m_iconbutton[side]; +} + void FancyLineEdit::iconClicked() { IconButton *button = qobject_cast<IconButton *>(sender()); @@ -480,7 +486,7 @@ IconButton::IconButton(QWidget *parent) void IconButton::paintEvent(QPaintEvent *) { - QPainter painter(this); + QStylePainter painter(this); QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height()); pixmapRect.moveCenter(rect().center()); @@ -488,6 +494,18 @@ void IconButton::paintEvent(QPaintEvent *) painter.setOpacity(m_iconOpacity); 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) @@ -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 diff --git a/src/libs/utils/fancylineedit.h b/src/libs/utils/fancylineedit.h index ae58dcb7bf..a03331fba3 100644 --- a/src/libs/utils/fancylineedit.h +++ b/src/libs/utils/fancylineedit.h @@ -60,6 +60,11 @@ public: void setAutoHide(bool hide) { m_autoHide = hide; } bool hasAutoHide() const { return m_autoHide; } + +protected: + void keyPressEvent(QKeyEvent *ke); + void keyReleaseEvent(QKeyEvent *ke); + private: float m_iconOpacity; bool m_autoHide; @@ -89,6 +94,7 @@ public: void setButtonVisible(Side side, bool visible); bool isButtonVisible(Side side) const; + QAbstractButton *button(Side side) const; void setButtonToolTip(Side side, const QString &); void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy); diff --git a/src/plugins/coreplugin/find/findtoolbar.cpp b/src/plugins/coreplugin/find/findtoolbar.cpp index 8ac3fa1406..2d2e0d4595 100644 --- a/src/plugins/coreplugin/find/findtoolbar.cpp +++ b/src/plugins/coreplugin/find/findtoolbar.cpp @@ -42,10 +42,12 @@ #include <utils/hostosinfo.h> #include <utils/flowlayout.h> +#include <utils/qtcassert.h> #include <QDebug> #include <QSettings> +#include <QCheckBox> #include <QClipboard> #include <QCompleter> #include <QKeyEvent> @@ -100,14 +102,15 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen m_ui.findEdit->setSpecialCompleter(m_findCompleter); 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->setFiltering(true); m_ui.findEdit->setPlaceholderText(QString()); + m_ui.findEdit->button(Utils::FancyLineEdit::Left)->setFocusPolicy(Qt::TabFocus); m_ui.replaceEdit->setPlaceholderText(QString()); 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 // 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); cmd = Core::ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE, globalcontext); mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_caseSensitiveAction, SIGNAL(triggered(bool)), this, SLOT(setCaseSensitive(bool))); - lineEditMenu->addAction(m_caseSensitiveAction); + connect(m_caseSensitiveAction, SIGNAL(toggled(bool)), this, SLOT(setCaseSensitive(bool))); m_wholeWordAction = new QAction(tr("Whole Words Only"), this); m_wholeWordAction->setIcon(QIcon(QLatin1String(":/find/images/wholewords.png"))); @@ -231,8 +233,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen m_wholeWordAction->setChecked(false); cmd = Core::ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS, globalcontext); mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_wholeWordAction, SIGNAL(triggered(bool)), this, SLOT(setWholeWord(bool))); - lineEditMenu->addAction(m_wholeWordAction); + connect(m_wholeWordAction, SIGNAL(toggled(bool)), this, SLOT(setWholeWord(bool))); m_regularExpressionAction = new QAction(tr("Use Regular Expressions"), this); m_regularExpressionAction->setIcon(QIcon(QLatin1String(":/find/images/regexp.png"))); @@ -240,8 +241,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen m_regularExpressionAction->setChecked(false); cmd = Core::ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS, globalcontext); mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_regularExpressionAction, SIGNAL(triggered(bool)), this, SLOT(setRegularExpressions(bool))); - lineEditMenu->addAction(m_regularExpressionAction); + connect(m_regularExpressionAction, SIGNAL(toggled(bool)), this, SLOT(setRegularExpressions(bool))); m_preserveCaseAction = new QAction(tr("Preserve Case when Replacing"), this); m_preserveCaseAction->setIcon(QPixmap(QLatin1String(":/find/images/preservecase.png"))); @@ -249,8 +249,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen m_preserveCaseAction->setChecked(false); cmd = Core::ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE, globalcontext); mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_preserveCaseAction, SIGNAL(triggered(bool)), this, SLOT(setPreserveCase(bool))); - lineEditMenu->addAction(m_preserveCaseAction); + connect(m_preserveCaseAction, SIGNAL(toggled(bool)), this, SLOT(setPreserveCase(bool))); connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate())); connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar())); @@ -554,6 +553,12 @@ void FindToolBar::findFlagsChanged() m_currentDocumentFind->highlightAll(getFindText(), effectiveFindFlags()); } +void FindToolBar::findEditButtonClicked() +{ + OptionsPopup *popup = new OptionsPopup(m_ui.findEdit); + popup->show(); +} + void FindToolBar::updateIcons() { FindFlags effectiveFlags = effectiveFindFlags(); @@ -685,11 +690,16 @@ void FindToolBar::findPreviousSelected() 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()) + optionsButton->setFocus(Qt::TabFocusReason); + else if (next && optionsButton->hasFocus()) m_ui.findEdit->setFocus(Qt::TabFocusReason); - else if (!next && m_ui.findEdit->hasFocus()) + else if (!next && optionsButton->hasFocus()) m_ui.advancedButton->setFocus(Qt::TabFocusReason); + else if (!next && m_ui.findEdit->hasFocus()) + optionsButton->setFocus(Qt::TabFocusReason); else return Utils::StyledBar::focusNextPrevChild(next); return true; @@ -778,3 +788,69 @@ void FindToolBar::setBackward(bool 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; +} diff --git a/src/plugins/coreplugin/find/findtoolbar.h b/src/plugins/coreplugin/find/findtoolbar.h index fb90dfbf1f..50e7f1a20b 100644 --- a/src/plugins/coreplugin/find/findtoolbar.h +++ b/src/plugins/coreplugin/find/findtoolbar.h @@ -33,10 +33,15 @@ #include "ui_findwidget.h" #include "currentdocumentfind.h" +#include <coreplugin/id.h> #include <utils/styledbar.h> #include <QTimer> +QT_BEGIN_NAMESPACE +class QCheckBox; +QT_END_NAMESPACE + namespace Core { class FindToolBarPlaceHolder; @@ -44,6 +49,26 @@ class FindPlugin; 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 { Q_OBJECT @@ -85,6 +110,7 @@ private slots: void updateFindAction(); void updateToolBar(); void findFlagsChanged(); + void findEditButtonClicked(); void setCaseSensitive(bool sensitive); void setWholeWord(bool wholeOnly); |