Editor: Support triggering tooltips from keyboard

There's an option in Text Editor->Behavior->Mouse and Keyboard to enable
tooltips upon pressing and releasing the ALT key.

Task-number: QTCREATORBUG-6644
Change-Id: I782ddf5cdbfbffd7847497f654efb3391220f1b6
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Leandro Melo
2011-12-08 13:23:41 +01:00
committed by hjk
parent 0ba1234108
commit 7f3764bfe3
7 changed files with 59 additions and 24 deletions

View File

@@ -1524,8 +1524,13 @@ void BaseTextEditorWidget::keyPressEvent(QKeyEvent *e)
d->m_moveLineUndoHack = false; d->m_moveLineUndoHack = false;
d->clearVisibleFoldedBlock(); d->clearVisibleFoldedBlock();
if (e->key() == Qt::Key_Escape) { if (e->key() == Qt::Key_Alt
if (d->m_snippetOverlay->isVisible()) { && d->m_behaviorSettings.m_keyboardTooltips) {
d->m_maybeFakeTooltipEvent = true;
} else {
d->m_maybeFakeTooltipEvent = false;
if (e->key() == Qt::Key_Escape
&& d->m_snippetOverlay->isVisible()) {
e->accept(); e->accept();
d->m_snippetOverlay->hide(); d->m_snippetOverlay->hide();
d->m_snippetOverlay->clear(); d->m_snippetOverlay->clear();
@@ -2345,12 +2350,12 @@ bool BaseTextEditorWidget::scrollWheelZoomingEnabled() const
void BaseTextEditorWidget::setConstrainTooltips(bool b) void BaseTextEditorWidget::setConstrainTooltips(bool b)
{ {
d->m_behaviorSettings.m_constrainTooltips = b; d->m_behaviorSettings.m_constrainHoverTooltips = b;
} }
bool BaseTextEditorWidget::constrainTooltips() const bool BaseTextEditorWidget::constrainTooltips() const
{ {
return d->m_behaviorSettings.m_constrainTooltips; return d->m_behaviorSettings.m_constrainHoverTooltips;
} }
void BaseTextEditorWidget::setCamelCaseNavigationEnabled(bool b) void BaseTextEditorWidget::setCamelCaseNavigationEnabled(bool b)
@@ -2445,6 +2450,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
m_highlightCurrentLine(true), m_highlightCurrentLine(true),
m_requestMarkEnabled(true), m_requestMarkEnabled(true),
m_lineSeparatorsAllowed(false), m_lineSeparatorsAllowed(false),
m_maybeFakeTooltipEvent(false),
m_visibleWrapColumn(0), m_visibleWrapColumn(0),
m_linkPressed(false), m_linkPressed(false),
m_delayedUpdateTimer(0), m_delayedUpdateTimer(0),
@@ -2573,6 +2579,16 @@ QPoint BaseTextEditorWidget::toolTipPosition(const QTextCursor &c) const
); );
} }
void BaseTextEditorWidget::processTooltipRequest(const QTextCursor &c)
{
const QPoint toolTipPoint = toolTipPosition(c);
bool handled = false;
BaseTextEditor *ed = editor();
emit ed->tooltipOverrideRequested(ed, toolTipPoint, c.position(), &handled);
if (!handled)
emit ed->tooltipRequested(ed, toolTipPoint, c.position());
}
bool BaseTextEditorWidget::viewportEvent(QEvent *event) bool BaseTextEditorWidget::viewportEvent(QEvent *event)
{ {
d->m_contentsChanged = false; d->m_contentsChanged = false;
@@ -2583,7 +2599,7 @@ bool BaseTextEditorWidget::viewportEvent(QEvent *event)
} else if (event->type() == QEvent::ToolTip) { } else if (event->type() == QEvent::ToolTip) {
if (QApplication::keyboardModifiers() & Qt::ControlModifier if (QApplication::keyboardModifiers() & Qt::ControlModifier
|| (!(QApplication::keyboardModifiers() & Qt::ShiftModifier) || (!(QApplication::keyboardModifiers() & Qt::ShiftModifier)
&& d->m_behaviorSettings.m_constrainTooltips)) { && d->m_behaviorSettings.m_constrainHoverTooltips)) {
// Tooltips should be eaten when either control is pressed (so they don't get in the // Tooltips should be eaten when either control is pressed (so they don't get in the
// way of code navigation) or if they are in constrained mode and shift is not pressed. // way of code navigation) or if they are in constrained mode and shift is not pressed.
return true; return true;
@@ -2600,14 +2616,7 @@ bool BaseTextEditorWidget::viewportEvent(QEvent *event)
return true; return true;
} }
// Allow plugins to show tooltips processTooltipRequest(cursorForPosition(pos));
const QTextCursor c = cursorForPosition(pos);
const QPoint toolTipPoint = toolTipPosition(c);
bool handled = false;
BaseTextEditor *ed = editor();
emit ed->tooltipOverrideRequested(ed, toolTipPoint, c.position(), &handled);
if (!handled)
emit ed->tooltipRequested(ed, toolTipPoint, c.position());
return true; return true;
} }
return QPlainTextEdit::viewportEvent(event); return QPlainTextEdit::viewportEvent(event);
@@ -4241,9 +4250,13 @@ void BaseTextEditorWidget::keyReleaseEvent(QKeyEvent *e)
if (e->key() == Qt::Key_Control) { if (e->key() == Qt::Key_Control) {
clearLink(); clearLink();
} else if (e->key() == Qt::Key_Shift } else if (e->key() == Qt::Key_Shift
&& d->m_behaviorSettings.m_constrainTooltips && d->m_behaviorSettings.m_constrainHoverTooltips
&& ToolTip::instance()->isVisible()) { && ToolTip::instance()->isVisible()) {
ToolTip::instance()->hide(); ToolTip::instance()->hide();
} else if (e->key() == Qt::Key_Alt
&& d->m_maybeFakeTooltipEvent) {
d->m_maybeFakeTooltipEvent = false;
processTooltipRequest(textCursor());
} }
QPlainTextEdit::keyReleaseEvent(e); QPlainTextEdit::keyReleaseEvent(e);

View File

@@ -563,6 +563,8 @@ private:
bool camelCaseRight(QTextCursor &cursor, QTextCursor::MoveMode mode); bool camelCaseRight(QTextCursor &cursor, QTextCursor::MoveMode mode);
bool camelCaseLeft(QTextCursor &cursor, QTextCursor::MoveMode mode); bool camelCaseLeft(QTextCursor &cursor, QTextCursor::MoveMode mode);
void processTooltipRequest(const QTextCursor &c);
void transformSelection(Internal::TransformationMethod method); void transformSelection(Internal::TransformationMethod method);
private slots: private slots:

View File

@@ -245,6 +245,7 @@ public:
uint m_lineSeparatorsAllowed : 1; uint m_lineSeparatorsAllowed : 1;
uint autoParenthesisOverwriteBackup : 1; uint autoParenthesisOverwriteBackup : 1;
uint surroundWithEnabledOverwriteBackup : 1; uint surroundWithEnabledOverwriteBackup : 1;
uint m_maybeFakeTooltipEvent : 1;
int m_visibleWrapColumn; int m_visibleWrapColumn;
QTextCharFormat m_linkFormat; QTextCharFormat m_linkFormat;

View File

@@ -41,6 +41,7 @@ static const char mouseNavigationKey[] = "MouseNavigation";
static const char scrollWheelZoomingKey[] = "ScrollWheelZooming"; static const char scrollWheelZoomingKey[] = "ScrollWheelZooming";
static const char constrainTooltips[] = "ConstrainTooltips"; static const char constrainTooltips[] = "ConstrainTooltips";
static const char camelCaseNavigationKey[] = "CamelCaseNavigation"; static const char camelCaseNavigationKey[] = "CamelCaseNavigation";
static const char keyboardTooltips[] = "KeyboardTooltips";
static const char groupPostfix[] = "BehaviorSettings"; static const char groupPostfix[] = "BehaviorSettings";
namespace TextEditor { namespace TextEditor {
@@ -48,8 +49,9 @@ namespace TextEditor {
BehaviorSettings::BehaviorSettings() : BehaviorSettings::BehaviorSettings() :
m_mouseNavigation(true), m_mouseNavigation(true),
m_scrollWheelZooming(true), m_scrollWheelZooming(true),
m_constrainTooltips(false), m_constrainHoverTooltips(false),
m_camelCaseNavigation(true) m_camelCaseNavigation(true),
m_keyboardTooltips(false)
{ {
} }
@@ -68,8 +70,9 @@ void BehaviorSettings::toMap(const QString &prefix, QVariantMap *map) const
{ {
map->insert(prefix + QLatin1String(mouseNavigationKey), m_mouseNavigation); map->insert(prefix + QLatin1String(mouseNavigationKey), m_mouseNavigation);
map->insert(prefix + QLatin1String(scrollWheelZoomingKey), m_scrollWheelZooming); map->insert(prefix + QLatin1String(scrollWheelZoomingKey), m_scrollWheelZooming);
map->insert(prefix + QLatin1String(constrainTooltips), m_constrainTooltips); map->insert(prefix + QLatin1String(constrainTooltips), m_constrainHoverTooltips);
map->insert(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation); map->insert(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation);
map->insert(prefix + QLatin1String(keyboardTooltips), m_keyboardTooltips);
} }
void BehaviorSettings::fromMap(const QString &prefix, const QVariantMap &map) void BehaviorSettings::fromMap(const QString &prefix, const QVariantMap &map)
@@ -78,18 +81,21 @@ void BehaviorSettings::fromMap(const QString &prefix, const QVariantMap &map)
map.value(prefix + QLatin1String(mouseNavigationKey), m_mouseNavigation).toBool(); map.value(prefix + QLatin1String(mouseNavigationKey), m_mouseNavigation).toBool();
m_scrollWheelZooming = m_scrollWheelZooming =
map.value(prefix + QLatin1String(scrollWheelZoomingKey), m_scrollWheelZooming).toBool(); map.value(prefix + QLatin1String(scrollWheelZoomingKey), m_scrollWheelZooming).toBool();
m_constrainTooltips = m_constrainHoverTooltips =
map.value(prefix + QLatin1String(constrainTooltips), m_constrainTooltips).toBool(); map.value(prefix + QLatin1String(constrainTooltips), m_constrainHoverTooltips).toBool();
m_camelCaseNavigation = m_camelCaseNavigation =
map.value(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation).toBool(); map.value(prefix + QLatin1String(camelCaseNavigationKey), m_camelCaseNavigation).toBool();
m_keyboardTooltips =
map.value(prefix + QLatin1String(keyboardTooltips), m_keyboardTooltips).toBool();
} }
bool BehaviorSettings::equals(const BehaviorSettings &ds) const bool BehaviorSettings::equals(const BehaviorSettings &ds) const
{ {
return m_mouseNavigation == ds.m_mouseNavigation return m_mouseNavigation == ds.m_mouseNavigation
&& m_scrollWheelZooming == ds.m_scrollWheelZooming && m_scrollWheelZooming == ds.m_scrollWheelZooming
&& m_constrainTooltips == ds.m_constrainTooltips && m_constrainHoverTooltips == ds.m_constrainHoverTooltips
&& m_camelCaseNavigation == ds.m_camelCaseNavigation && m_camelCaseNavigation == ds.m_camelCaseNavigation
&& m_keyboardTooltips == ds.m_keyboardTooltips
; ;
} }

View File

@@ -62,8 +62,9 @@ public:
bool m_mouseNavigation; bool m_mouseNavigation;
bool m_scrollWheelZooming; bool m_scrollWheelZooming;
bool m_constrainTooltips; bool m_constrainHoverTooltips;
bool m_camelCaseNavigation; bool m_camelCaseNavigation;
bool m_keyboardTooltips;
}; };
inline bool operator==(const BehaviorSettings &t1, const BehaviorSettings &t2) { return t1.equals(t2); } inline bool operator==(const BehaviorSettings &t1, const BehaviorSettings &t2) { return t1.equals(t2); }

View File

@@ -101,6 +101,8 @@ BehaviorSettingsWidget::BehaviorSettingsWidget(QWidget *parent)
this, SLOT(slotBehaviorSettingsChanged())); this, SLOT(slotBehaviorSettingsChanged()));
connect(d->m_ui.camelCaseNavigation, SIGNAL(clicked()), connect(d->m_ui.camelCaseNavigation, SIGNAL(clicked()),
this, SLOT(slotBehaviorSettingsChanged())); this, SLOT(slotBehaviorSettingsChanged()));
connect(d->m_ui.keyboardTooltips, SIGNAL(clicked()),
this, SLOT(slotBehaviorSettingsChanged()));
connect(d->m_ui.utf8BomBox, SIGNAL(currentIndexChanged(int)), connect(d->m_ui.utf8BomBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(slotExtraEncodingChanged())); this, SLOT(slotExtraEncodingChanged()));
connect(d->m_ui.encodingBox, SIGNAL(currentIndexChanged(int)), connect(d->m_ui.encodingBox, SIGNAL(currentIndexChanged(int)),
@@ -177,16 +179,18 @@ void BehaviorSettingsWidget::setAssignedBehaviorSettings(const BehaviorSettings
{ {
d->m_ui.mouseNavigation->setChecked(behaviorSettings.m_mouseNavigation); d->m_ui.mouseNavigation->setChecked(behaviorSettings.m_mouseNavigation);
d->m_ui.scrollWheelZooming->setChecked(behaviorSettings.m_scrollWheelZooming); d->m_ui.scrollWheelZooming->setChecked(behaviorSettings.m_scrollWheelZooming);
d->m_ui.constrainTooltips->setChecked(behaviorSettings.m_constrainTooltips); d->m_ui.constrainTooltips->setChecked(behaviorSettings.m_constrainHoverTooltips);
d->m_ui.camelCaseNavigation->setChecked(behaviorSettings.m_camelCaseNavigation); d->m_ui.camelCaseNavigation->setChecked(behaviorSettings.m_camelCaseNavigation);
d->m_ui.keyboardTooltips->setChecked(behaviorSettings.m_keyboardTooltips);
} }
void BehaviorSettingsWidget::assignedBehaviorSettings(BehaviorSettings *behaviorSettings) const void BehaviorSettingsWidget::assignedBehaviorSettings(BehaviorSettings *behaviorSettings) const
{ {
behaviorSettings->m_mouseNavigation = d->m_ui.mouseNavigation->isChecked(); behaviorSettings->m_mouseNavigation = d->m_ui.mouseNavigation->isChecked();
behaviorSettings->m_scrollWheelZooming = d->m_ui.scrollWheelZooming->isChecked(); behaviorSettings->m_scrollWheelZooming = d->m_ui.scrollWheelZooming->isChecked();
behaviorSettings->m_constrainTooltips = d->m_ui.constrainTooltips->isChecked(); behaviorSettings->m_constrainHoverTooltips = d->m_ui.constrainTooltips->isChecked();
behaviorSettings->m_camelCaseNavigation = d->m_ui.camelCaseNavigation->isChecked(); behaviorSettings->m_camelCaseNavigation = d->m_ui.camelCaseNavigation->isChecked();
behaviorSettings->m_keyboardTooltips = d->m_ui.keyboardTooltips->isChecked();
} }
void BehaviorSettingsWidget::setAssignedExtraEncodingSettings( void BehaviorSettingsWidget::setAssignedExtraEncodingSettings(
@@ -221,6 +225,7 @@ QString BehaviorSettingsWidget::collectUiKeywords() const
<< sep << d->m_ui.scrollWheelZooming->text() << sep << d->m_ui.scrollWheelZooming->text()
<< sep << d->m_ui.constrainTooltips->text() << sep << d->m_ui.constrainTooltips->text()
<< sep << d->m_ui.camelCaseNavigation->text() << sep << d->m_ui.camelCaseNavigation->text()
<< sep << d->m_ui.keyboardTooltips->text()
<< sep << d->m_ui.groupBoxStorageSettings->title() << sep << d->m_ui.groupBoxStorageSettings->title()
<< sep << d->m_ui.groupBoxEncodings->title() << sep << d->m_ui.groupBoxEncodings->title()
<< sep << d->m_ui.groupBoxMouse->title(); << sep << d->m_ui.groupBoxMouse->title();

View File

@@ -337,7 +337,14 @@ Specifies how backspace interacts with indentation.
<item> <item>
<widget class="QCheckBox" name="constrainTooltips"> <widget class="QCheckBox" name="constrainTooltips">
<property name="text"> <property name="text">
<string>Enable &amp;tooltips only when Shift key is down</string> <string>Enable hover &amp;tooltips only when Shift key is down</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="keyboardTooltips">
<property name="text">
<string>Enable &amp;keyboard tooltips when pressing and releasing the Alt key</string>
</property> </property>
</widget> </widget>
</item> </item>