diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp index b12377d751905122a4863684fc30bc48d2aca382..7004371279a7993195e63dc427bb89a96f57d85e 100644 --- a/src/plugins/qmljseditor/qmljshoverhandler.cpp +++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp @@ -41,6 +41,7 @@ #include <texteditor/itexteditor.h> #include <texteditor/basetexteditor.h> #include <texteditor/tooltip/tooltip.h> +#include <texteditor/tooltip/tipcontents.h> using namespace Core; using namespace QmlJS; @@ -235,12 +236,16 @@ void HoverHandler::operateTooltip(TextEditor::ITextEditor *editor, const QPoint TextEditor::ToolTip::instance()->hide(); else { if (m_colorTip.isValid()) { - TextEditor::ToolTip::instance()->showColor(point, m_colorTip, editor->widget()); + TextEditor::ToolTip::instance()->show(point, + TextEditor::ColorContent(m_colorTip), + editor->widget()); } else { if (matchingHelpCandidate() != -1) addF1ToToolTip(); - TextEditor::ToolTip::instance()->showText(point, toolTip(), editor->widget()); + TextEditor::ToolTip::instance()->show(point, + TextEditor::TextContent(toolTip()), + editor->widget()); } } } diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp index 21aaa6368756c7fdf5a591f512a463cc3a5ded98..1a0ec60f450428f66dc66ad4e3818dc108b4e38b 100644 --- a/src/plugins/texteditor/basehoverhandler.cpp +++ b/src/plugins/texteditor/basehoverhandler.cpp @@ -32,6 +32,7 @@ #include "basetexteditor.h" #include "displaysettings.h" #include "tooltip.h" +#include "tipcontents.h" #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> @@ -167,7 +168,7 @@ void BaseHoverHandler::operateTooltip(ITextEditor *editor, const QPoint &point) if (m_matchingHelpCandidate != -1) addF1ToToolTip(); - TextEditor::ToolTip::instance()->showText(point, m_toolTip, editor->widget()); + ToolTip::instance()->show(point, TextContent(m_toolTip), editor->widget()); } } diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index d125565c439236b38c7209be1ee910b951d071dd..f7475990e9228f962da43bbaa8834ef404c7196e 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -40,6 +40,8 @@ #include "texteditorconstants.h" #include "texteditorplugin.h" #include "syntaxhighlighter.h" +#include "tooltip.h" +#include "tipcontents.h" #include <aggregation/aggregate.h> #include <coreplugin/actionmanager/actionmanager.h> @@ -79,7 +81,6 @@ #include <QtGui/QTextBlock> #include <QtGui/QTextLayout> #include <QtGui/QToolBar> -#include <QtGui/QToolTip> #include <QtGui/QInputDialog> #include <QtGui/QMenu> @@ -1087,7 +1088,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) Locker inKeyPressEvent(&d->m_inKeyPressEvent); viewport()->setCursor(Qt::BlankCursor); - QToolTip::hideText(); + ToolTip::instance()->hide(); d->m_moveLineUndoHack = false; d->clearVisibleFoldedBlock(); @@ -2041,7 +2042,10 @@ bool BaseTextEditor::viewportEvent(QEvent *event) RefactorMarker refactorMarker = d->m_refactorOverlay->markerAt(pos); if (refactorMarker.isValid() && !refactorMarker.tooltip.isEmpty()) { - QToolTip::showText(he->globalPos(), refactorMarker.tooltip, viewport(), refactorMarker.rect); + ToolTip::instance()->show(he->globalPos(), + TextContent(refactorMarker.tooltip), + viewport(), + refactorMarker.rect); return true; } diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro index a140d718b96ca38ba79af7cc4357b851105b51f9..e9e1ba4c946d66ba794a28fcfc3bcacd930d8d8e 100644 --- a/src/plugins/texteditor/texteditor.pro +++ b/src/plugins/texteditor/texteditor.pro @@ -67,7 +67,8 @@ SOURCES += texteditorplugin.cpp \ tooltip/tooltip.cpp \ tooltip/tips.cpp \ tooltip/tipcontents.cpp \ - basehoverhandler.cpp + basehoverhandler.cpp \ + tooltip/tipfactory.cpp HEADERS += texteditorplugin.h \ textfilewizard.h \ @@ -136,7 +137,9 @@ HEADERS += texteditorplugin.h \ tooltip/tooltip.h \ tooltip/tips.h \ tooltip/tipcontents.h \ - basehoverhandler.h + basehoverhandler.h \ + tooltip/effects.h \ + tooltip/tipfactory.h FORMS += behaviorsettingspage.ui \ displaysettingspage.ui \ diff --git a/src/plugins/texteditor/tooltip/effects.h b/src/plugins/texteditor/tooltip/effects.h new file mode 100644 index 0000000000000000000000000000000000000000..038195b457a30b6b3792a552f6f7257a743f1725 --- /dev/null +++ b/src/plugins/texteditor/tooltip/effects.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef EFFECTS_H +#define EFFECTS_H + +#include <QtCore/QtGlobal> + +// This is a copy of a Qt private header. Please read comments in tooltip.h. + +QT_BEGIN_NAMESPACE + +class QWidget; + +struct QEffects +{ + enum Direction { + LeftScroll = 0x0001, + RightScroll = 0x0002, + UpScroll = 0x0004, + DownScroll = 0x0008 + }; + + typedef uint DirFlags; +}; + +extern void Q_GUI_EXPORT qScrollEffect(QWidget*, QEffects::DirFlags dir = QEffects::DownScroll, int time = -1); +extern void Q_GUI_EXPORT qFadeEffect(QWidget*, int time = -1); + +QT_END_NAMESPACE + +#endif // EFFECTS_H diff --git a/src/plugins/texteditor/tooltip/tipcontents.cpp b/src/plugins/texteditor/tooltip/tipcontents.cpp index 3854f52bbd91327057f373f2227a99457e646143..2ebd15782423b15993056c37752769faab9c6097 100644 --- a/src/plugins/texteditor/tooltip/tipcontents.cpp +++ b/src/plugins/texteditor/tooltip/tipcontents.cpp @@ -29,8 +29,9 @@ #include "tipcontents.h" +#include <QtCore/QtGlobal> + using namespace TextEditor; -using namespace Internal; TipContent::TipContent() {} @@ -38,39 +39,82 @@ TipContent::TipContent() TipContent::~TipContent() {} -QColorContent::QColorContent(const QColor &color) : m_color(color) +ColorContent::ColorContent(const QColor &color) : m_color(color) {} -QColorContent::~QColorContent() +ColorContent::~ColorContent() {} -bool TipContent::equals(const QColorContent *colorContent) const +TipContent *ColorContent::clone() const { - Q_UNUSED(colorContent) - return false; + return new ColorContent(*this); } -bool QColorContent::isValid() const +int ColorContent::typeId() const +{ + return COLOR_CONTENT_ID; +} + +bool ColorContent::isValid() const { return m_color.isValid(); } -int QColorContent::showTime() const +int ColorContent::showTime() const { return 4000; } -bool QColorContent::equals(const TipContent *tipContent) const +bool ColorContent::equals(const TipContent &tipContent) const { - return tipContent->equals(this); + if (typeId() == tipContent.typeId()) { + if (m_color == static_cast<const ColorContent &>(tipContent).m_color) + return true; + } + return false; } -bool QColorContent::equals(const QColorContent *colorContent) const +const QColor &ColorContent::color() const { - return m_color == colorContent->color(); + return m_color; } -const QColor &QColorContent::color() const +TextContent::TextContent(const QString &text) : m_text(text) +{} + +TextContent::~TextContent() +{} + +TipContent *TextContent::clone() const { - return m_color; + return new TextContent(*this); +} + +int TextContent::typeId() const +{ + return TEXT_CONTENT_ID; +} + +bool TextContent::isValid() const +{ + return !m_text.isEmpty(); +} + +int TextContent::showTime() const +{ + return 10000 + 40 * qMax(0, m_text.length() - 100); +} + +bool TextContent::equals(const TipContent &tipContent) const +{ + if (typeId() == tipContent.typeId()) { + if (m_text == static_cast<const TextContent &>(tipContent).m_text) + return true; + } + return false; +} + +const QString &TextContent::text() const +{ + return m_text; } diff --git a/src/plugins/texteditor/tooltip/tipcontents.h b/src/plugins/texteditor/tooltip/tipcontents.h index 2bae742fd449639b179fc54627e5da40328f827e..894f53537d7ea2d5cabddf54b1e5d603a62caa9e 100644 --- a/src/plugins/texteditor/tooltip/tipcontents.h +++ b/src/plugins/texteditor/tooltip/tipcontents.h @@ -30,43 +30,68 @@ #ifndef TIPCONTENTS_H #define TIPCONTENTS_H +#include "texteditor/texteditor_global.h" + +#include <QtCore/QString> #include <QtGui/QColor> namespace TextEditor { -namespace Internal { - -class QColorContent; -class TipContent +class TEXTEDITOR_EXPORT TipContent { -public: +protected: TipContent(); + +public: virtual ~TipContent(); + virtual TipContent *clone() const = 0; + virtual int typeId() const = 0; virtual bool isValid() const = 0; virtual int showTime() const = 0; - virtual bool equals(const TipContent *tipContent) const = 0; - virtual bool equals(const QColorContent *colorContent) const; + virtual bool equals(const TipContent &tipContent) const = 0; }; -class QColorContent : public TipContent +class TEXTEDITOR_EXPORT ColorContent : public TipContent { public: - QColorContent(const QColor &color); - virtual ~QColorContent(); + ColorContent(const QColor &color); + virtual ~ColorContent(); + virtual TipContent *clone() const; + virtual int typeId() const; virtual bool isValid() const; virtual int showTime() const; - virtual bool equals(const TipContent *tipContent) const; - virtual bool equals(const QColorContent *colorContent) const; + virtual bool equals(const TipContent &tipContent) const; const QColor &color() const; + static const int COLOR_CONTENT_ID = 0; + private: QColor m_color; }; -} // namespace Internal +class TEXTEDITOR_EXPORT TextContent : public TipContent +{ +public: + TextContent(const QString &text); + virtual ~TextContent(); + + virtual TipContent *clone() const; + virtual int typeId() const; + virtual bool isValid() const; + virtual int showTime() const; + virtual bool equals(const TipContent &tipContent) const; + + const QString &text() const; + + static const int TEXT_CONTENT_ID = 1; + +private: + QString m_text; +}; + } // namespace TextEditor #endif // TIPCONTENTS_H diff --git a/src/plugins/texteditor/tooltip/tipfactory.cpp b/src/plugins/texteditor/tooltip/tipfactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ceeebe46cfb3dc634a474e5f12288acae2fb5e6c --- /dev/null +++ b/src/plugins/texteditor/tooltip/tipfactory.cpp @@ -0,0 +1,55 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "tipfactory.h" +#include "tipcontents.h" +#include "tips.h" + +using namespace TextEditor; +using namespace Internal; + +TipFactory::TipFactory() +{} + +TipFactory::~TipFactory() +{} + +QTipLabel *TipFactory::createTip(const TipContent &content, QWidget *w) +{ + QTipLabel *tip = 0; + if (content.typeId() == TextContent::TEXT_CONTENT_ID) + tip = new TextTip(w); + else if (content.typeId() == ColorContent::COLOR_CONTENT_ID) + tip = new ColorTip(w); + + if (tip) + tip->setContent(content); + + return tip; +} diff --git a/src/plugins/texteditor/tooltip/tipfactory.h b/src/plugins/texteditor/tooltip/tipfactory.h new file mode 100644 index 0000000000000000000000000000000000000000..09710873a1ef2e3d7ae47b9c2e250e55103287fb --- /dev/null +++ b/src/plugins/texteditor/tooltip/tipfactory.h @@ -0,0 +1,58 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef TIPFACTORY_H +#define TIPFACTORY_H + +#include <QtGui/QWidget> + +QT_BEGIN_NAMESPACE +class QTipLabel; +QT_END_NAMESPACE + +namespace TextEditor { + +class TipContent; + +namespace Internal { + +class TipFactory +{ +public: + TipFactory(); + virtual ~TipFactory(); + Q_DISABLE_COPY(TipFactory) + + virtual QTipLabel *createTip(const TipContent &content, QWidget *w); +}; + +} // namespace Internal +} // namespace TextEditor + +#endif // TIPFACTORY_H diff --git a/src/plugins/texteditor/tooltip/tips.cpp b/src/plugins/texteditor/tooltip/tips.cpp index 2825f1c9554912cc9651d304485c8afe00e2b5b6..606d622590b8cfaad1370d3fb746a9f5e11f2ce6 100644 --- a/src/plugins/texteditor/tooltip/tips.cpp +++ b/src/plugins/texteditor/tooltip/tips.cpp @@ -33,7 +33,13 @@ #include <QtCore/QRect> #include <QtGui/QColor> #include <QtGui/QPainter> +#include <QtGui/QPen> #include <QtGui/QPixmap> +#include <QtGui/QStyle> +#include <QtGui/QFontMetrics> +#include <QtGui/QTextDocument> +#include <QtGui/QStylePainter> +#include <QtGui/QStyleOptionFrame> using namespace TextEditor; using namespace Internal; @@ -53,31 +59,36 @@ namespace { } } -Tip::Tip(QWidget *parent) : QFrame(parent) -{ - setWindowFlags(Qt::ToolTip); - setAutoFillBackground(true); - ensurePolished(); -} +QT_BEGIN_NAMESPACE -Tip::~Tip() +QTipLabel::QTipLabel(QWidget *parent) : + QLabel(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), + m_tipContent(0) {} -void Tip::setContent(const QSharedPointer<TipContent> &content) +QTipLabel::~QTipLabel() { - m_content = content; + if (m_tipContent) + delete m_tipContent; +} + +void QTipLabel::setContent(const TipContent &content) +{ + if (m_tipContent) + delete m_tipContent; + m_tipContent = content.clone(); configure(); } -const QSharedPointer<TipContent> &Tip::content() const -{ return m_content; } +const TipContent &QTipLabel::content() const +{ return *m_tipContent; } + +QT_END_NAMESPACE -ColorTip::ColorTip(QWidget *parent) : Tip(parent) +ColorTip::ColorTip(QWidget *parent) : QTipLabel(parent) { - setFrameStyle(QFrame::Box); resize(QSize(40, 40)); - - m_tilePixMap = tilePixMap(9); + m_tilePixMap = tilePixMap(10); } ColorTip::~ColorTip() @@ -88,13 +99,87 @@ void ColorTip::configure() update(); } +bool ColorTip::handleContentReplacement(const TipContent &content) const +{ + if (content.typeId() == ColorContent::COLOR_CONTENT_ID) + return true; + return false; +} + void ColorTip::paintEvent(QPaintEvent *event) { + const QColor &color = static_cast<const ColorContent &>(content()).color(); + + QPen pen; + pen.setWidth(1); + if (color.value() > 100) + pen.setColor(color.darker()); + else + pen.setColor(color.lighter()); + QPainter painter(this); - QRect r(1, 1, width() - 2, height() - 2); + painter.setPen(pen); + painter.setBrush(color); + QRect r(1, 1, rect().width() - 2, rect().height() - 2); painter.drawTiledPixmap(r, m_tilePixMap); - painter.setBrush(static_cast<QColorContent *>(content().data())->color()); - painter.drawRect(rect()); + painter.drawRect(r); + + QLabel::paintEvent(event); +} + +TextTip::TextTip(QWidget *parent) : QTipLabel(parent) +{ + setForegroundRole(QPalette::ToolTipText); + setBackgroundRole(QPalette::ToolTipBase); + ensurePolished(); + setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, this)); + setFrameStyle(QFrame::NoFrame); + setAlignment(Qt::AlignLeft); + setIndent(1); + setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0); +} + +TextTip::~TextTip() +{} + +void TextTip::configure() +{ + const QString &text = static_cast<const TextContent &>(content()).text(); + setWordWrap(Qt::mightBeRichText(text)); + setText(text); + QFontMetrics fm(font()); + QSize extra(1, 0); + // Make it look good with the default ToolTip font on Mac, which has a small descent. + if (fm.descent() == 2 && fm.ascent() >= 11) + ++extra.rheight(); + resize(sizeHint() + extra); +} + +bool TextTip::handleContentReplacement(const TipContent &content) const +{ + if (content.typeId() == TextContent::TEXT_CONTENT_ID) + return true; + return false; +} + +void TextTip::paintEvent(QPaintEvent *event) +{ + QStylePainter p(this); + QStyleOptionFrame opt; + opt.init(this); + p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); + p.end(); + + QLabel::paintEvent(event); +} + +void TextTip::resizeEvent(QResizeEvent *event) +{ + QStyleHintReturnMask frameMask; + QStyleOption option; + option.init(this); + if (style()->styleHint(QStyle::SH_ToolTip_Mask, &option, this, &frameMask)) + setMask(frameMask.region); - QFrame::paintEvent(event); + QLabel::resizeEvent(event); } diff --git a/src/plugins/texteditor/tooltip/tips.h b/src/plugins/texteditor/tooltip/tips.h index b7dc9d3af41a12df45e13ff84a685326621be70a..38f73bc5cac684f6704ed9e135de7a36312750b3 100644 --- a/src/plugins/texteditor/tooltip/tips.h +++ b/src/plugins/texteditor/tooltip/tips.h @@ -31,50 +31,71 @@ #define TIPS_H #include <QtCore/QSharedPointer> -#include <QtGui/QFrame> +#include <QtGui/QLabel> #include <QtGui/QPixmap> -QT_BEGIN_NAMESPACE -class QColor; -QT_END_NAMESPACE - namespace TextEditor { -namespace Internal { - class TipContent; +} + +QT_BEGIN_NAMESPACE -class Tip : public QFrame +// Please do not change the name of this class. Detailed comments in tooltip.h. +class QTipLabel : public QLabel { Q_OBJECT protected: - Tip(QWidget *parent); + QTipLabel(QWidget *parent); public: - virtual ~Tip(); + virtual ~QTipLabel(); - void setContent(const QSharedPointer<TipContent> &content); - const QSharedPointer<TipContent> &content() const; + void setContent(const TextEditor::TipContent &content); + const TextEditor::TipContent &content() const; -private: virtual void configure() = 0; + virtual bool handleContentReplacement(const TextEditor::TipContent &content) const = 0; - QSharedPointer<TipContent> m_content; +private: + TextEditor::TipContent *m_tipContent; }; -class ColorTip : public Tip +QT_END_NAMESPACE + +namespace TextEditor { +namespace Internal { + +class ColorTip : public QTipLabel { Q_OBJECT public: ColorTip(QWidget *parent); virtual ~ColorTip(); -private: virtual void configure(); + virtual bool handleContentReplacement(const TipContent &content) const; + +private: virtual void paintEvent(QPaintEvent *event); QPixmap m_tilePixMap; }; +class TextTip : public QTipLabel +{ + Q_OBJECT +public: + TextTip(QWidget *parent); + virtual ~TextTip(); + + virtual void configure(); + virtual bool handleContentReplacement(const TipContent &content) const; + +private: + virtual void paintEvent(QPaintEvent *event); + virtual void resizeEvent(QResizeEvent *event); +}; + } // namespace Internal } // namespace TextEditor diff --git a/src/plugins/texteditor/tooltip/tooltip.cpp b/src/plugins/texteditor/tooltip/tooltip.cpp index 52c14789717f4113211e7bf03cb8d725aa1afbdc..c5f34107cb6374c02cd7fb5366130087ff681561 100644 --- a/src/plugins/texteditor/tooltip/tooltip.cpp +++ b/src/plugins/texteditor/tooltip/tooltip.cpp @@ -30,25 +30,30 @@ #include "tooltip.h" #include "tips.h" #include "tipcontents.h" +#include "tipfactory.h" +#include "effects.h" #include <QtCore/QString> #include <QtGui/QColor> #include <QtGui/QApplication> #include <QtGui/QDesktopWidget> -#include <QtGui/QToolTip> #include <QtGui/QKeyEvent> +#include <QtGui/QMouseEvent> using namespace TextEditor; using namespace Internal; -ToolTip::ToolTip() : m_tip(0), m_widget(0) +ToolTip::ToolTip() : m_tipFactory(new TipFactory), m_tip(0), m_widget(0) { connect(&m_showTimer, SIGNAL(timeout()), this, SLOT(hideTipImmediately())); connect(&m_hideDelayTimer, SIGNAL(timeout()), this, SLOT(hideTipImmediately())); } ToolTip::~ToolTip() -{ m_tip = 0; } +{ + m_tip = 0; + delete m_tipFactory; +} ToolTip *ToolTip::instance() { @@ -56,77 +61,109 @@ ToolTip *ToolTip::instance() return &tooltip; } -void ToolTip::showText(const QPoint &pos, const QString &text, QWidget *w) -{ - hideTipImmediately(); - QToolTip::showText(pos, text, w); -} - -void ToolTip::showColor(const QPoint &pos, const QColor &color, QWidget *w) +void ToolTip::show(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect) { - hideQtTooltip(); - QSharedPointer<TipContent> colorContent(new QColorContent(color)); - if (acceptShow(colorContent, pos, w) && colorContent->isValid()) { + if (acceptShow(content, pos, w, rect)) { #ifndef Q_WS_WIN - m_tip = new ColorTip(w); + m_tip = m_tipFactory->createTip(content, w); #else - m_tip = new ColorTip(QApplication::desktop()->screen(tipScreen(pos, w))); + m_tip = m_tipFactory->createTip(content, QApplication::desktop()->screen(tipScreen(pos,w))); #endif - setUp(colorContent, pos, w); + setUp(pos, content, w, rect); qApp->installEventFilter(this); showTip(); } } -bool ToolTip::isVisible() const +void ToolTip::show(const QPoint &pos, const TipContent &content, QWidget *w) { - return QToolTip::isVisible() || (m_tip && m_tip->isVisible()); + show(pos, content, w, QRect()); } -bool ToolTip::acceptShow(const QSharedPointer<TipContent> &content, const QPoint &pos, QWidget *w) +bool ToolTip::acceptShow(const TipContent &content, + const QPoint &pos, + QWidget *w, + const QRect &rect) { - if (m_tip && m_tip->isVisible()) { - if (!content->isValid()) { - hideTipWithDelay(); - return false; - } else { + if (!validateContent(content)) + return false; + + if (isVisible()) { + if (m_tip->handleContentReplacement(content)) { // Reuse current tip. QPoint localPos = pos; if (w) localPos = w->mapFromGlobal(pos); - if (requiresSetUp(content, w)) - setUp(content, pos, w); + if (tipChanged(localPos, content, w)) { + setUp(pos, content, w, rect); + m_tip->setContent(content); + } return false; } + hideTipImmediately(); + } + return true; +} + +bool ToolTip::validateContent(const TipContent &content) +{ + if (!content.isValid()) { + if (isVisible()) + hideTipWithDelay(); + return false; } return true; } -void ToolTip::setUp(const QSharedPointer<TipContent> &content, const QPoint &pos, QWidget *w) +void ToolTip::setUp(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect) { - m_tip->setContent(content); placeTip(pos, w); - m_widget = w; - m_showTimer.start(content->showTime()); + setTipRect(w, rect); + if (m_hideDelayTimer.isActive()) + m_hideDelayTimer.stop(); + m_showTimer.start(content.showTime()); } -bool ToolTip::requiresSetUp(const QSharedPointer<TipContent> &tipContent, QWidget *w) const +bool ToolTip::tipChanged(const QPoint &pos, const TipContent &content, QWidget *w) const { - if (!m_tip->content()->equals(tipContent.data())) - return true; - if (m_widget != w) + if (!m_tip->content().equals(content) || m_widget != w) return true; + if (!m_rect.isNull()) + return !m_rect.contains(pos); return false; } +void ToolTip::setTipRect(QWidget *w, const QRect &rect) +{ + if (!m_rect.isNull() && !w) + qWarning("ToolTip::show: Cannot pass null widget if rect is set"); + else{ + m_widget = w; + m_rect = rect; + } +} + +bool ToolTip::isVisible() const +{ + return m_tip && m_tip->isVisible(); +} + void ToolTip::showTip() { +#if !defined(QT_NO_EFFECTS) && !defined(Q_WS_MAC) + if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip)) + qFadeEffect(m_tip); + else if (QApplication::isEffectEnabled(Qt::UI_AnimateTooltip)) + qScrollEffect(m_tip); + else + m_tip->show(); +#else m_tip->show(); +#endif } void ToolTip::hide() { - hideQtTooltip(); hideTipWithDelay(); } @@ -148,12 +185,6 @@ void ToolTip::hideTipImmediately() qApp->removeEventFilter(this); } -void ToolTip::hideQtTooltip() -{ - if (QToolTip::isVisible()) - QToolTip::hideText(); -} - void ToolTip::placeTip(const QPoint &pos, QWidget *w) { #ifdef Q_WS_MAC @@ -197,8 +228,6 @@ int ToolTip::tipScreen(const QPoint &pos, QWidget *w) const bool ToolTip::eventFilter(QObject *o, QEvent *event) { - Q_UNUSED(o) - switch (event->type()) { #ifdef Q_WS_MAC case QEvent::KeyPress: @@ -226,6 +255,12 @@ bool ToolTip::eventFilter(QObject *o, QEvent *event) hideTipImmediately(); break; + case QEvent::MouseMove: + if (o == m_widget && + !m_rect.isNull() && + !m_rect.contains(static_cast<QMouseEvent*>(event)->pos())) { + hideTipWithDelay(); + } default: break; } diff --git a/src/plugins/texteditor/tooltip/tooltip.h b/src/plugins/texteditor/tooltip/tooltip.h index dd93c888ed4eb6928b2e56c50aa6be92c9d584c1..def3bc7fc558af886334f8e197984b6d51cc2661 100644 --- a/src/plugins/texteditor/tooltip/tooltip.h +++ b/src/plugins/texteditor/tooltip/tooltip.h @@ -35,24 +35,30 @@ #include <QtCore/QSharedPointer> #include <QtCore/QObject> #include <QtCore/QTimer> +#include <QtCore/QRect> + +/* + * In its current form QToolTip is not extensible. So this is an attempt to provide a more + * flexible and customizable tooltip mechanism for Creator. Part of the code here is duplicated + * from QToolTip. This includes a private Qt header and the non-exported class QTipLabel, which + * here serves as a base tip class. Please notice that Qt relies on this particular class name in + * order to correctly apply the native styles for tooltips. Therefore the QTipLabel name should + * not be changed. + */ QT_BEGIN_NAMESPACE class QPoint; -class QString; -class QColor; class QWidget; +class QTipLabel; QT_END_NAMESPACE namespace TextEditor { namespace Internal { -class Tip; -class TipContent; +class TipFactory; } -/* - * This class contains some code duplicated from QTooltip. It would be good to make that reusable. - */ +class TipContent; class TEXTEDITOR_EXPORT ToolTip : public QObject { @@ -65,33 +71,31 @@ public: static ToolTip *instance(); - void showText(const QPoint &pos, const QString &text, QWidget *w = 0); - void showColor(const QPoint &pos, const QColor &color, QWidget *w = 0); + void show(const QPoint &pos, const TipContent &content, QWidget *w = 0); + void show(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect); void hide(); bool isVisible() const; virtual bool eventFilter(QObject *o, QEvent *event); +private slots: + void hideTipImmediately(); + private: - bool acceptShow(const QSharedPointer<Internal::TipContent> &content, - const QPoint &pos, - QWidget *w); - void setUp(const QSharedPointer<Internal::TipContent> &content, - const QPoint &pos, - QWidget *w); - bool requiresSetUp(const QSharedPointer<Internal::TipContent> &content, QWidget *w) const; + bool acceptShow(const TipContent &content, const QPoint &pos, QWidget *w, const QRect &rect); + bool validateContent(const TipContent &content); + void setUp(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect); + bool tipChanged(const QPoint &pos, const TipContent &content, QWidget *w) const; + void setTipRect(QWidget *w, const QRect &rect); void placeTip(const QPoint &pos, QWidget *w); int tipScreen(const QPoint &pos, QWidget *w) const; void showTip(); void hideTipWithDelay(); - void hideQtTooltip(); -private slots: - void hideTipImmediately(); - -private: - Internal::Tip *m_tip; + Internal::TipFactory *m_tipFactory; + QTipLabel *m_tip; QWidget *m_widget; + QRect m_rect; QTimer m_showTimer; QTimer m_hideDelayTimer; };