File indexing completed on 2024-04-21 11:36:06
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"