File indexing completed on 2024-04-21 15:03:34

0001 /*
0002     SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include "documentation_tip.h"
0007 
0008 #include <KWindowSystem>
0009 
0010 #include <QDebug>
0011 #include <QHBoxLayout>
0012 #include <QScreen>
0013 
0014 DocTip::DocTip(QWidget *parent)
0015     : QFrame(parent)
0016     , m_textView(new QTextBrowser(this))
0017 {
0018     setFocusPolicy(Qt::NoFocus);
0019     setWindowFlags(Qt::ToolTip | Qt::BypassGraphicsProxyWidget);
0020 
0021     m_textView->setFrameStyle(QFrame::Box | QFrame::Raised);
0022 
0023     setFixedWidth(250);
0024     setFixedHeight(150);
0025 
0026     auto layout = new QHBoxLayout(this);
0027     layout->setContentsMargins({});
0028     layout->setSpacing(0);
0029     setContentsMargins({});
0030     layout->addWidget(&m_stack);
0031     m_stack.addWidget(m_textView);
0032 }
0033 
0034 QWidget *DocTip::currentWidget()
0035 {
0036     return m_stack.currentWidget();
0037 }
0038 
0039 void DocTip::clearWidgets()
0040 {
0041     for (auto *widget : m_widgets) {
0042         widget->deleteLater();
0043     }
0044     m_widgets.clear();
0045 }
0046 
0047 void DocTip::setText(const QString &s)
0048 {
0049     m_textView->setPlainText(s);
0050     if (m_stack.currentWidget() != m_textView) {
0051         m_stack.removeWidget(m_stack.currentWidget());
0052         m_stack.addWidget(m_textView);
0053     }
0054     Q_ASSERT(m_stack.count() == 1);
0055 }
0056 
0057 void DocTip::setWidget(QWidget *widget)
0058 {
0059     if (auto w = m_stack.currentWidget()) {
0060         if (w != m_textView) {
0061             m_widgets.push_back(w);
0062         }
0063         m_stack.removeWidget(w);
0064     }
0065 
0066     if (!widget) {
0067         return;
0068     }
0069 
0070     m_stack.addWidget(widget);
0071 
0072     Q_ASSERT(m_stack.count() == 1);
0073 }
0074 
0075 void DocTip::updatePosition()
0076 {
0077     auto parent = parentWidget();
0078     if (!parent) {
0079         qWarning() << Q_FUNC_INFO << "Unexpected null parent!";
0080         return;
0081     }
0082 
0083     const auto screen = parent->screen();
0084     if (!screen) {
0085         // No screen, no tooltips
0086         return;
0087     }
0088 
0089     const auto screenRight = screen->availableGeometry().right();
0090     auto parentRight = parent->geometry().right();
0091     constexpr int Margin = 8;
0092 
0093     const bool wayland = KWindowSystem::isPlatformWayland();
0094 
0095     int x = 0;
0096     // is the completion widget too far right?
0097     if ((parentRight + this->width()) > screenRight) {
0098         // let's hope there is enough available space to the left of parent
0099         x = (parent->x() - this->width()) - Margin;
0100     } else {
0101         // we have enough space on the right
0102         x = parent->x() + parent->width() + Margin;
0103     }
0104 
0105     if (x != this->x()) {
0106         // On way land move() doesn't work, but if hide and then show again
0107         // window is positioned correctly. This is a hack, and if there is
0108         // a better solution, we can replace it
0109         if (wayland) {
0110             hide();
0111             move(x, parent->y());
0112             show();
0113         } else {
0114             move(x, parent->y());
0115         }
0116     }
0117 }
0118 
0119 #include "moc_documentation_tip.cpp"