Commit 50ad32a2 authored by hjk's avatar hjk
Browse files

Utils: Start simplification of tooltip handling



There's a bit too much unneeded flexibility in there, requiring extra
boiler-plate code on the user side.

Change-Id: I34d03838fb1cd3182fcbb93bf65158ebfc7e2bce
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 89115df9
......@@ -39,146 +39,51 @@
namespace Utils {
TipContent::TipContent()
{}
TipContent::~TipContent()
{}
ColorContent::ColorContent(const QColor &color) : m_color(color)
{}
ColorContent::~ColorContent()
{}
TipContent *ColorContent::clone() const
{
return new ColorContent(*this);
}
int ColorContent::typeId() const
{
return COLOR_CONTENT_ID;
}
bool ColorContent::isValid() const
{
return m_color.isValid();
}
bool ColorContent::isInteractive() const
{
return false;
}
int ColorContent::showTime() const
{
return 4000;
}
bool ColorContent::equals(const TipContent &tipContent) const
{
if (typeId() == tipContent.typeId()) {
if (m_color == static_cast<const ColorContent &>(tipContent).m_color)
return true;
}
return false;
}
const QColor &ColorContent::color() const
{
return m_color;
}
TextContent::TextContent(const QString &text) : m_text(text)
{}
TextContent::~TextContent()
{}
TipContent *TextContent::clone() const
: m_typeId(0), m_widget(0), m_interactive(false)
{
return new TextContent(*this);
}
int TextContent::typeId() const
TipContent::TipContent(const QString &text)
: m_typeId(TEXT_CONTENT_ID), m_text(text), m_widget(0), m_interactive(false)
{
return TEXT_CONTENT_ID;
}
bool TextContent::isValid() const
TipContent::TipContent(const QColor &color)
: m_typeId(COLOR_CONTENT_ID), m_color(color), m_widget(0), m_interactive(false)
{
return !m_text.isEmpty();
}
bool TextContent::isInteractive() const
{
return false;
}
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;
}
WidgetContent::WidgetContent(QWidget *w, bool interactive) :
m_widget(w), m_interactive(interactive)
TipContent::TipContent(QWidget *w, bool interactive)
: m_typeId(WIDGET_CONTENT_ID), m_widget(w), m_interactive(interactive)
{
}
TipContent *WidgetContent::clone() const
{
return new WidgetContent(m_widget, m_interactive);
}
int WidgetContent::typeId() const
{
return WIDGET_CONTENT_ID;
}
bool WidgetContent::isValid() const
bool TipContent::isValid() const
{
if (m_typeId == TEXT_CONTENT_ID)
return !m_text.isEmpty();
if (m_typeId == COLOR_CONTENT_ID)
return m_color.isValid();
return m_widget;
}
bool WidgetContent::isInteractive() const
{
return m_interactive;
}
void WidgetContent::setInteractive(bool i)
{
m_interactive = i;
}
int WidgetContent::showTime() const
int TipContent::showTime() const
{
if (m_typeId == TEXT_CONTENT_ID)
return 10000 + 40 * qMax(0, m_text.length() - 100);
if (m_typeId == COLOR_CONTENT_ID)
return 4000;
return 30000;
}
bool WidgetContent::equals(const TipContent &tipContent) const
bool TipContent::equals(const TipContent &other) const
{
if (typeId() == tipContent.typeId()) {
if (m_widget == static_cast<const WidgetContent &>(tipContent).m_widget)
return true;
}
return false;
return m_typeId == other.m_typeId
&& m_text == other.m_text
&& m_widget == other.m_widget;
}
bool WidgetContent::pinToolTip(QWidget *w, QWidget *parent)
bool TipContent::pinToolTip(QWidget *w, QWidget *parent)
{
QTC_ASSERT(w, return false);
// Find the parent WidgetTip, tell it to pin/release the
......
......@@ -41,86 +41,37 @@ namespace Utils {
class QTCREATOR_UTILS_EXPORT TipContent
{
protected:
TipContent();
public:
virtual ~TipContent();
virtual TipContent *clone() const = 0;
virtual int typeId() const = 0;
virtual bool isValid() const = 0;
virtual bool isInteractive() const = 0;
virtual int showTime() const = 0;
virtual bool equals(const TipContent &tipContent) const = 0;
};
class QTCREATOR_UTILS_EXPORT ColorContent : public TipContent
{
public:
ColorContent(const QColor &color);
virtual ~ColorContent();
virtual TipContent *clone() const;
virtual int typeId() const;
virtual bool isValid() const;
virtual bool isInteractive() const;
virtual int showTime() const;
virtual bool equals(const TipContent &tipContent) const;
const QColor &color() const;
static const int COLOR_CONTENT_ID = 0;
private:
QColor m_color;
};
class QTCREATOR_UTILS_EXPORT TextContent : public TipContent
{
public:
TextContent(const QString &text);
virtual ~TextContent();
virtual TipContent *clone() const;
virtual int typeId() const;
virtual bool isValid() const;
virtual bool isInteractive() 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;
};
// A content for displaying any widget (with a layout).
class QTCREATOR_UTILS_EXPORT WidgetContent : public TipContent
{
public:
explicit WidgetContent(QWidget *w, bool interactive = false);
virtual TipContent *clone() const;
virtual int typeId() const;
virtual bool isValid() const;
virtual int showTime() const;
virtual bool isInteractive() const;
void setInteractive(bool i);
TipContent();
explicit TipContent(const QString &text);
explicit TipContent(const QColor &color);
explicit TipContent(QWidget *w, bool interactive);
int typeId() const { return m_typeId; }
bool isValid() const;
bool isInteractive() const { return m_interactive; }
int showTime() const;
bool equals(const TipContent &other) const;
const QString &text() const { return m_text; }
const QColor &color() const { return m_color; }
QWidget *widget() const { return m_widget; }
virtual bool equals(const TipContent &tipContent) const;
enum {
COLOR_CONTENT_ID = 0,
TEXT_CONTENT_ID = 1,
WIDGET_CONTENT_ID = 42
};
void setInteractive(bool i) { m_interactive = i; }
// Helper to 'pin' (show as real window) a tooltip shown
// using WidgetContent
static bool pinToolTip(QWidget *w, QWidget *parent);
static const int WIDGET_CONTENT_ID = 42;
QWidget *widget() const { return m_widget; }
private:
int m_typeId;
QString m_text;
QColor m_color;
QWidget *m_widget;
bool m_interactive;
};
......
......@@ -51,47 +51,38 @@
namespace Utils {
namespace Internal {
namespace {
// @todo: Reuse...
QPixmap tilePixMap(int size)
{
const int checkerbordSize= size;
QPixmap tilePixmap(checkerbordSize * 2, checkerbordSize * 2);
tilePixmap.fill(Qt::white);
QPainter tilePainter(&tilePixmap);
QColor color(220, 220, 220);
tilePainter.fillRect(0, 0, checkerbordSize, checkerbordSize, color);
tilePainter.fillRect(checkerbordSize, checkerbordSize, checkerbordSize, checkerbordSize, color);
return tilePixmap;
}
// @todo: Reuse...
static QPixmap tilePixMap(int size)
{
const int checkerbordSize= size;
QPixmap tilePixmap(checkerbordSize * 2, checkerbordSize * 2);
tilePixmap.fill(Qt::white);
QPainter tilePainter(&tilePixmap);
QColor color(220, 220, 220);
tilePainter.fillRect(0, 0, checkerbordSize, checkerbordSize, color);
tilePainter.fillRect(checkerbordSize, checkerbordSize, checkerbordSize, checkerbordSize, color);
return tilePixmap;
}
QTipLabel::QTipLabel(QWidget *parent) :
QLabel(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget),
m_tipContent(0)
QLabel(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget)
{}
QTipLabel::~QTipLabel()
{
TipContent *tmpTipContent = m_tipContent;
m_tipContent = 0;
delete tmpTipContent;
}
bool QTipLabel::isInteractive() const
{
return m_tipContent && m_tipContent->isInteractive();
return m_tipContent.isInteractive();
}
void QTipLabel::setContent(const TipContent &content)
{
TipContent *tmpTipContent = m_tipContent;
m_tipContent = content.clone();
delete tmpTipContent;
m_tipContent = content;
}
const TipContent &QTipLabel::content() const
{ return *m_tipContent; }
ColorTip::ColorTip(QWidget *parent) : QTipLabel(parent)
{
......@@ -112,16 +103,14 @@ void ColorTip::configure(const QPoint &pos, QWidget *w)
bool ColorTip::canHandleContentReplacement(const TipContent &content) const
{
if (content.typeId() == ColorContent::COLOR_CONTENT_ID)
return true;
return false;
return content.typeId() == TipContent::COLOR_CONTENT_ID;
}
void ColorTip::paintEvent(QPaintEvent *event)
{
QTipLabel::paintEvent(event);
const QColor &color = static_cast<const ColorContent &>(content()).color();
const QColor &color = content().color();
QPen pen;
pen.setWidth(1);
......@@ -155,8 +144,7 @@ TextTip::~TextTip()
void TextTip::configure(const QPoint &pos, QWidget *w)
{
const QString &text = static_cast<const TextContent &>(content()).text();
setText(text);
setText(content().text());
// Make it look good with the default ToolTip font on Mac, which has a small descent.
QFontMetrics fm(font());
......@@ -183,9 +171,7 @@ void TextTip::configure(const QPoint &pos, QWidget *w)
bool TextTip::canHandleContentReplacement(const TipContent &content) const
{
if (content.typeId() == TextContent::TEXT_CONTENT_ID)
return true;
return false;
return content.typeId() == TipContent::TEXT_CONTENT_ID;
}
void TextTip::paintEvent(QPaintEvent *event)
......@@ -219,8 +205,7 @@ WidgetTip::WidgetTip(QWidget *parent) :
void WidgetTip::configure(const QPoint &pos, QWidget *)
{
const WidgetContent &anyContent = static_cast<const WidgetContent &>(content());
QWidget *widget = anyContent.widget();
QWidget *widget = content().widget();
QTC_ASSERT(widget && m_layout->count() == 0, return);
......
......@@ -31,14 +31,14 @@
#ifndef TIPS_H
#define TIPS_H
#include "tipcontents.h"
#include <QSharedPointer>
#include <QLabel>
#include <QPixmap>
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
namespace Utils { class TipContent; }
#ifndef Q_MOC_RUN
namespace Utils {
namespace Internal {
......@@ -55,7 +55,7 @@ public:
virtual ~QTipLabel();
void setContent(const TipContent &content);
const TipContent &content() const;
const TipContent &content() const { return m_tipContent; }
virtual void configure(const QPoint &pos, QWidget *w) = 0;
virtual bool canHandleContentReplacement(const TipContent &content) const = 0;
......@@ -63,38 +63,38 @@ public:
bool isInteractive() const;
private:
TipContent *m_tipContent;
TipContent m_tipContent;
};
class ColorTip : public QTipLabel
class TextTip : public QTipLabel
{
Q_OBJECT
public:
ColorTip(QWidget *parent);
virtual ~ColorTip();
TextTip(QWidget *parent);
virtual ~TextTip();
virtual void configure(const QPoint &pos, QWidget *w);
virtual bool canHandleContentReplacement(const TipContent &content) const;
private:
virtual void paintEvent(QPaintEvent *event);
QPixmap m_tilePixMap;
virtual void resizeEvent(QResizeEvent *event);
};
class TextTip : public QTipLabel
class ColorTip : public QTipLabel
{
Q_OBJECT
public:
TextTip(QWidget *parent);
virtual ~TextTip();
ColorTip(QWidget *parent);
virtual ~ColorTip();
virtual void configure(const QPoint &pos, QWidget *w);
virtual bool canHandleContentReplacement(const TipContent &content) const;
private:
virtual void paintEvent(QPaintEvent *event);
virtual void resizeEvent(QResizeEvent *event);
QPixmap m_tilePixMap;
};
class WidgetTip : public QTipLabel
......
......@@ -51,8 +51,8 @@ using namespace Internal;
ToolTip::ToolTip() : m_tip(0), m_widget(0)
{
connect(&m_showTimer, SIGNAL(timeout()), this, SLOT(hideTipImmediately()));
connect(&m_hideDelayTimer, SIGNAL(timeout()), this, SLOT(hideTipImmediately()));
connect(&m_showTimer, &QTimer::timeout, this, &ToolTip::hideTipImmediately);
connect(&m_hideDelayTimer, &QTimer::timeout, this, &ToolTip::hideTipImmediately);
}
ToolTip::~ToolTip()
......@@ -66,20 +66,25 @@ ToolTip *ToolTip::instance()
return &tooltip;
}
void ToolTip::show(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect)
void ToolTip::show(const QPoint &pos, const QString &content, QWidget *w, const QRect &rect)
{
instance()->showInternal(pos, content, w, rect);
instance()->showInternal(pos, TipContent(content), w, rect);
}
void ToolTip::move(const QPoint &pos, QWidget *w)
void ToolTip::show(const QPoint &pos, const QColor &color, QWidget *w, const QRect &rect)
{
if (isVisible())
instance()->placeTip(pos, w);
instance()->showInternal(pos, TipContent(color), w, rect);
}
void ToolTip::show(const QPoint &pos, const TipContent &content, QWidget *w)
void ToolTip::show(const QPoint &pos, QWidget *content, QWidget *w, const QRect &rect)
{
show(pos, content, w, QRect());
instance()->showInternal(pos, TipContent(content, true), w, rect);
}
void ToolTip::move(const QPoint &pos, QWidget *w)
{
if (isVisible())
instance()->placeTip(pos, w);
}
bool ToolTip::acceptShow(const TipContent &content,
......@@ -209,13 +214,13 @@ void ToolTip::showInternal(const QPoint &pos, const TipContent &content, QWidget
target = w;
switch (content.typeId()) {
case TextContent::TEXT_CONTENT_ID:
m_tip = new TextTip(target);
break;
case ColorContent::COLOR_CONTENT_ID:
case TipContent::COLOR_CONTENT_ID:
m_tip = new ColorTip(target);
break;
case WidgetContent::WIDGET_CONTENT_ID:
case TipContent::TEXT_CONTENT_ID:
m_tip = new TextTip(target);
break;
case TipContent::WIDGET_CONTENT_ID:
m_tip = new WidgetTip(target);
break;
}
......
......@@ -71,19 +71,16 @@ public:
static ToolTip *instance();
static void show(const QPoint &pos, const TipContent &content, QWidget *w = 0);
static void show(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect);
static void show(const QPoint &pos, const QString &content, QWidget *w = 0, const QRect &rect = QRect());
static void show(const QPoint &pos, const QColor &color, QWidget *w = 0, const QRect &rect = QRect());
static void show(const QPoint &pos, QWidget *content, QWidget *w = 0, const QRect &rect = QRect());
static void move(const QPoint &pos, QWidget *w);
static void hide();
static bool isVisible();
protected slots:
void hideTipImmediately();
protected:
void showInternal(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect);
private:
void showInternal(const QPoint &pos, const TipContent &content, QWidget *w, const QRect &rect);
void hideTipImmediately();
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);
......
......@@ -42,7 +42,6 @@
#include <projectexplorer/session.h>
#include <texteditor/texteditor.h>
#include <utils/tooltip/tooltip.h>
#include <utils/tooltip/tipcontents.h>
#include <utils/qtcassert.h>
#include <utils/checkablemessagebox.h>
......@@ -834,7 +833,7 @@ void BookmarkManager::operateTooltip(QWidget *widget, const QPoint &pos, Bookmar
if (mark->note().isEmpty())
ToolTip::hide();
else
ToolTip::show(pos, TextContent(mark->note()), widget);
ToolTip::show(pos, mark->note(), widget);
}
/* Loads the bookmarks from the session settings. */
......
......@@ -35,7 +35,6 @@
#include <utils/stylehelper.h>
#include <utils/stringutils.h>
#include <utils/tooltip/tooltip.h>
#include <utils/tooltip/tipcontents.h>
#include <utils/theme/theme.h>
#include <QPainter>
......@@ -82,7 +81,7 @@ bool FancyToolButton::event(QEvent *e)
case QEvent::ToolTip:
{
QHelpEvent *he = static_cast<QHelpEvent *>(e);
ToolTip::show(mapToGlobal(he->pos()), TextContent(toolTip()), this);
ToolTip::show(mapToGlobal(he->pos()), toolTip(), this);
return true;
}
default:
......
......@@ -46,7 +46,6 @@
#include <utils/proxyaction.h>
#include <utils/qtcassert.h>
#include <utils/tooltip/tipcontents.h>
#include <utils/tooltip/tooltip.h>
#include <QtConcurrentRun>
......@@ -310,7 +309,7 @@ void FunctionDeclDefLink::apply(CppEditorWidget *editor, bool jumpToMatch)
newTargetFile->apply();
} else {
ToolTip::show(editor->toolTipPosition(linkSelection),
TextContent(tr("Target file was changed, could not apply changes")));
tr("Target file was changed, could not apply changes"));
}