"Fossies" - the Fresh Open Source Software Archive

Member "qt-creator-opensource-src-4.15.1/src/libs/utils/tooltip/tips.cpp" (8 Jun 2021, 9639 Bytes) of package /linux/misc/qt-creator-opensource-src-4.15.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tips.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: opensource-src-4.15.0_vs_opensource-src-4.15.1.

    1 /****************************************************************************
    2 **
    3 ** Copyright (C) 2016 The Qt Company Ltd.
    4 ** Contact: https://www.qt.io/licensing/
    5 **
    6 ** This file is part of Qt Creator.
    7 **
    8 ** Commercial License Usage
    9 ** Licensees holding valid commercial Qt licenses may use this file in
   10 ** accordance with the commercial license agreement provided with the
   11 ** Software or, alternatively, in accordance with the terms contained in
   12 ** a written agreement between you and The Qt Company. For licensing terms
   13 ** and conditions see https://www.qt.io/terms-conditions. For further
   14 ** information use the contact form at https://www.qt.io/contact-us.
   15 **
   16 ** GNU General Public License Usage
   17 ** Alternatively, this file may be used under the terms of the GNU
   18 ** General Public License version 3 as published by the Free Software
   19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
   20 ** included in the packaging of this file. Please review the following
   21 ** information to ensure the GNU General Public License requirements will
   22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
   23 **
   24 ****************************************************************************/
   25 
   26 #include "tips.h"
   27 #include "tooltip.h"
   28 
   29 #include <utils/hostosinfo.h>
   30 #include <utils/qtcassert.h>
   31 
   32 #include <QApplication>
   33 #include <QColor>
   34 #include <QFontMetrics>
   35 #include <QPaintEvent>
   36 #include <QPainter>
   37 #include <QPen>
   38 #include <QPoint>
   39 #include <QRect>
   40 #include <QResizeEvent>
   41 #include <QStyle>
   42 #include <QStylePainter>
   43 #include <QStyleOptionFrame>
   44 #include <QTextDocument>
   45 #include <QScreen>
   46 #include <QWidget>
   47 
   48 #include <memory>
   49 
   50 namespace Utils {
   51 namespace Internal {
   52 
   53 TipLabel::TipLabel(QWidget *parent) :
   54     QLabel(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget)
   55 {
   56 }
   57 
   58 void TipLabel::setContextHelp(const QVariant &help)
   59 {
   60     m_contextHelp = help;
   61     update();
   62 }
   63 
   64 QVariant TipLabel::contextHelp() const
   65 {
   66     return m_contextHelp;
   67 }
   68 
   69 const QMetaObject *TipLabel::metaObject() const
   70 {
   71     // CSS Tooltip styling depends on a the name of this class.
   72     // So set up a minimalist QMetaObject to fake a class name "QTipLabel":
   73 
   74 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
   75     static const uint tip_label_meta_data[15] = { 8 /* moc revision */ };
   76 
   77     static const QMetaObject tipMetaObject {
   78          &QLabel::staticMetaObject,                  // SuperData superdata;
   79          QByteArrayLiteral("QTipLabel").data_ptr(),  // const QByteArrayData *stringdata;
   80          tip_label_meta_data,                        // const uint *data;
   81          nullptr,                                    // StaticMetacallFunction static_metacall;
   82          nullptr,                                    // const SuperData *relatedMetaObjects;
   83          nullptr                                     // void *extradata;
   84     };
   85 #else
   86     static const uint tip_label_meta_data[15] = { 9 /* moc revision */ };
   87 
   88     struct qt_meta_stringdata_Utils_t {
   89         const uint offsetsAndSize[2];
   90         char stringdata0[24];
   91     } qt_meta_stringdata =  { 8, sizeof("QTipLabel"), "QTipLabel" };
   92 
   93     static const QMetaObject tipMetaObject {
   94         &QLabel::staticMetaObject,                    // SuperData superdata
   95         qt_meta_stringdata.offsetsAndSize,            // const uint *stringdata;
   96         tip_label_meta_data,                          // const uint *data;
   97         nullptr,                                      // StaticMetacallFunction static_metacall;
   98         nullptr,                                      // const SuperData *relatedMetaObjects;
   99         nullptr,                                      // QtPrivate::QMetaTypeInterface *const *metaTypes;
  100         nullptr,                                      // void *extradata;
  101     };
  102 #endif
  103 
  104     return &tipMetaObject;
  105 }
  106 
  107 ColorTip::ColorTip(QWidget *parent)
  108     : TipLabel(parent)
  109 {
  110     resize(40, 40);
  111 }
  112 
  113 void ColorTip::setContent(const QVariant &content)
  114 {
  115     m_color = content.value<QColor>();
  116 
  117     const int size = 10;
  118     m_tilePixmap = QPixmap(size * 2, size * 2);
  119     m_tilePixmap.fill(Qt::white);
  120     QPainter tilePainter(&m_tilePixmap);
  121     QColor col(220, 220, 220);
  122     tilePainter.fillRect(0, 0, size, size, col);
  123     tilePainter.fillRect(size, size, size, size, col);
  124 }
  125 
  126 void ColorTip::configure(const QPoint &pos)
  127 {
  128     Q_UNUSED(pos)
  129 
  130     update();
  131 }
  132 
  133 bool ColorTip::canHandleContentReplacement(int typeId) const
  134 {
  135     return typeId == ToolTip::ColorContent;
  136 }
  137 
  138 bool ColorTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
  139 {
  140     return typeId == ToolTip::ColorContent && otherContextHelp == contextHelp() && other == m_color;
  141 }
  142 
  143 void ColorTip::paintEvent(QPaintEvent *event)
  144 {
  145     TipLabel::paintEvent(event);
  146 
  147     QPainter painter(this);
  148     painter.setBrush(m_color);
  149     painter.drawTiledPixmap(rect(), m_tilePixmap);
  150 
  151     QPen pen;
  152     pen.setColor(m_color.value() > 100 ? m_color.darker() : m_color.lighter());
  153     pen.setJoinStyle(Qt::MiterJoin);
  154     const QRectF borderRect = QRectF(rect()).adjusted(0.5, 0.5, -0.5, -0.5);
  155     painter.setPen(pen);
  156     painter.drawRect(borderRect);
  157 }
  158 
  159 TextTip::TextTip(QWidget *parent) : TipLabel(parent)
  160 {
  161     setForegroundRole(QPalette::ToolTipText);
  162     setBackgroundRole(QPalette::ToolTipBase);
  163     ensurePolished();
  164     setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, nullptr, this));
  165     setFrameStyle(QFrame::NoFrame);
  166     setAlignment(Qt::AlignLeft);
  167     setIndent(1);
  168     setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, nullptr, this) / 255.0);
  169 }
  170 
  171 static bool likelyContainsLink(const QString &s)
  172 {
  173     return s.contains(QLatin1String("href"), Qt::CaseInsensitive);
  174 }
  175 
  176 void TextTip::setContent(const QVariant &content)
  177 {
  178     if (content.canConvert<QString>()) {
  179         m_text = content.toString();
  180     } else if (content.canConvert<TextItem>()) {
  181         auto item = content.value<TextItem>();
  182         m_text = item.first;
  183         m_format = item.second;
  184     }
  185 
  186     bool containsLink = likelyContainsLink(m_text);
  187     setOpenExternalLinks(containsLink);
  188 }
  189 
  190 bool TextTip::isInteractive() const
  191 {
  192     return likelyContainsLink(m_text);
  193 }
  194 
  195 void TextTip::configure(const QPoint &pos)
  196 {
  197     setTextFormat(m_format);
  198     setText(m_text);
  199 
  200     // Make it look good with the default ToolTip font on Mac, which has a small descent.
  201     QFontMetrics fm(font());
  202     int extraHeight = 0;
  203     if (fm.descent() == 2 && fm.ascent() >= 11)
  204         ++extraHeight;
  205 
  206     // Try to find a nice width without unnecessary wrapping.
  207     setWordWrap(false);
  208     int tipWidth = sizeHint().width();
  209 
  210     QScreen *screen = QGuiApplication::screenAt(pos);
  211     if (!screen)
  212         screen = QGuiApplication::primaryScreen();
  213 
  214     const int screenWidth = screen->availableGeometry().width();
  215     const int maxDesiredWidth = int(screenWidth * .5);
  216     if (tipWidth > maxDesiredWidth) {
  217         setWordWrap(true);
  218         tipWidth = maxDesiredWidth;
  219     }
  220 
  221     resize(tipWidth, heightForWidth(tipWidth) + extraHeight);
  222 }
  223 
  224 bool TextTip::canHandleContentReplacement(int typeId) const
  225 {
  226     return typeId == ToolTip::TextContent;
  227 }
  228 
  229 int TextTip::showTime() const
  230 {
  231     return 10000 + 40 * qMax(0, m_text.size() - 100);
  232 }
  233 
  234 bool TextTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
  235 {
  236     return typeId == ToolTip::TextContent && otherContextHelp == contextHelp()
  237            && ((other.canConvert<QString>() && other.toString() == m_text)
  238                || (other.canConvert<TextItem>()
  239                    && other.value<TextItem>() == TextItem(m_text, m_format)));
  240 }
  241 
  242 void TextTip::paintEvent(QPaintEvent *event)
  243 {
  244     QStylePainter p(this);
  245     QStyleOptionFrame opt;
  246     opt.initFrom(this);
  247     p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
  248     p.end();
  249 
  250     QLabel::paintEvent(event);
  251 }
  252 
  253 void TextTip::resizeEvent(QResizeEvent *event)
  254 {
  255     QStyleHintReturnMask frameMask;
  256     QStyleOption option;
  257     option.initFrom(this);
  258     if (style()->styleHint(QStyle::SH_ToolTip_Mask, &option, this, &frameMask))
  259         setMask(frameMask.region);
  260 
  261     QLabel::resizeEvent(event);
  262 }
  263 
  264 WidgetTip::WidgetTip(QWidget *parent) :
  265     TipLabel(parent), m_layout(new QVBoxLayout)
  266 {
  267     m_layout->setContentsMargins(0, 0, 0, 0);
  268     setLayout(m_layout);
  269 }
  270 
  271 void WidgetTip::setContent(const QVariant &content)
  272 {
  273     m_widget = content.value<QWidget *>();
  274 }
  275 
  276 void WidgetTip::configure(const QPoint &pos)
  277 {
  278     QTC_ASSERT(m_widget && m_layout->count() == 0, return);
  279 
  280     move(pos);
  281     m_layout->addWidget(m_widget);
  282     m_layout->setSizeConstraint(QLayout::SetFixedSize);
  283     adjustSize();
  284 }
  285 
  286 void WidgetTip::pinToolTipWidget(QWidget *parent)
  287 {
  288     QTC_ASSERT(m_layout->count(), return);
  289 
  290     // Pin the content widget: Rip the widget out of the layout
  291     // and re-show as a tooltip, with delete on close.
  292     const QPoint screenPos = mapToGlobal(QPoint(0, 0));
  293     // Remove widget from layout
  294     if (!m_layout->count())
  295         return;
  296 
  297     QLayoutItem *item = m_layout->takeAt(0);
  298     QWidget *widget = item->widget();
  299     delete item;
  300     if (!widget)
  301         return;
  302 
  303     widget->setParent(parent, Qt::Tool|Qt::FramelessWindowHint);
  304     widget->move(screenPos);
  305     widget->show();
  306     widget->setAttribute(Qt::WA_DeleteOnClose);
  307 }
  308 
  309 bool WidgetTip::canHandleContentReplacement(int typeId) const
  310 {
  311     // Always create a new widget.
  312     Q_UNUSED(typeId)
  313     return false;
  314 }
  315 
  316 bool WidgetTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
  317 {
  318     return typeId == ToolTip::WidgetContent && otherContextHelp == contextHelp()
  319             && other.value<QWidget *>() == m_widget;
  320 }
  321 
  322 } // namespace Internal
  323 } // namespace Utils