File indexing completed on 2024-05-19 04:38:51
0001 /* 0002 SPDX-FileCopyrightText: 2008 Vladimir Prus <ghost@cs.msu.su> 0003 SPDX-FileCopyrightText: 2009 Niko Sams <niko.sams@gmail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "variabletooltip.h" 0009 0010 #include <QWidget> 0011 #include <QHBoxLayout> 0012 #include <QApplication> 0013 #include <QMouseEvent> 0014 #include <QHeaderView> 0015 #include <QPushButton> 0016 #include <QScrollBar> 0017 #include <QDesktopWidget> 0018 #include <KLocalizedString> 0019 #include <QPainter> 0020 0021 #include "variablecollection.h" 0022 #include "../util/treeview.h" 0023 #include "../interfaces/ivariablecontroller.h" 0024 #include "../../util/activetooltip.h" 0025 #include "../../interfaces/icore.h" 0026 #include "../../interfaces/idebugcontroller.h" 0027 0028 namespace KDevelop { 0029 0030 class SizeGrip : public QWidget 0031 { 0032 Q_OBJECT 0033 public: 0034 explicit SizeGrip(QWidget* parent) : QWidget(parent) { 0035 m_parent = parent; 0036 } 0037 protected: 0038 void paintEvent(QPaintEvent *) override 0039 { 0040 QPainter painter(this); 0041 QStyleOptionSizeGrip opt; 0042 opt.init(this); 0043 opt.corner = Qt::BottomRightCorner; 0044 style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, this); 0045 } 0046 0047 void mousePressEvent(QMouseEvent* e) override 0048 { 0049 if (e->button() == Qt::LeftButton) { 0050 m_pos = e->globalPos(); 0051 m_startSize = m_parent->size(); 0052 e->ignore(); 0053 } 0054 } 0055 void mouseReleaseEvent(QMouseEvent*) override 0056 { 0057 m_pos = QPoint(); 0058 } 0059 void mouseMoveEvent(QMouseEvent* e) override 0060 { 0061 if (!m_pos.isNull()) { 0062 m_parent->resize( 0063 m_startSize.width() + (e->globalPos().x() - m_pos.x()), 0064 m_startSize.height() + (e->globalPos().y() - m_pos.y()) 0065 ); 0066 } 0067 } 0068 private: 0069 QWidget *m_parent; 0070 QSize m_startSize; 0071 QPoint m_pos; 0072 }; 0073 0074 VariableToolTip::VariableToolTip(QWidget* parent, const QPoint& position, 0075 const QString& identifier) 0076 : ActiveToolTip(parent, position) 0077 { 0078 setPalette( QApplication::palette() ); 0079 0080 m_model = new TreeModel(QVector<QString>{i18n("Name"), i18n("Value"), i18n("Type")}, this); 0081 0082 auto* tr = new TooltipRoot(m_model); 0083 m_model->setRootItem(tr); 0084 m_var = ICore::self()->debugController()->currentSession()-> 0085 variableController()->createVariable( 0086 m_model, tr, identifier); 0087 tr->init(m_var); 0088 m_var->attachMaybe(this, "variableCreated"); 0089 0090 auto* l = new QVBoxLayout(this); 0091 l->setContentsMargins(0, 0, 0, 0); 0092 0093 m_view = new AsyncTreeView(*m_model, this); 0094 m_view->setModel(m_model); 0095 m_view->header()->resizeSection(0, 150); 0096 m_view->header()->resizeSection(1, 90); 0097 m_view->setSelectionBehavior(QAbstractItemView::SelectRows); 0098 m_view->setSelectionMode(QAbstractItemView::SingleSelection); 0099 m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0100 m_view->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); 0101 l->addWidget(m_view); 0102 0103 const QModelIndex varIndex = m_model->indexForItem(m_var, 0); 0104 m_itemHeight = m_view->indexRowSizeHint(varIndex); 0105 connect(m_view->verticalScrollBar(), 0106 &QScrollBar::rangeChanged, 0107 this, 0108 &VariableToolTip::slotRangeChanged); 0109 0110 m_selection = m_view->selectionModel(); 0111 m_selection->select(varIndex, 0112 QItemSelectionModel::Rows | QItemSelectionModel::ClearAndSelect); 0113 0114 auto* buttonBox = new QHBoxLayout(); 0115 buttonBox->setContentsMargins(11, 0, 11, 6); 0116 auto* watchThisButton = new QPushButton(i18n("Watch This")); 0117 buttonBox->addWidget(watchThisButton); 0118 auto* stopOnChangeButton = new QPushButton(i18n("Stop on Change")); 0119 buttonBox->addWidget(stopOnChangeButton); 0120 0121 connect(watchThisButton, &QPushButton::clicked, 0122 this, [this](){ slotLinkActivated(QStringLiteral("add_watch")); }); 0123 connect(stopOnChangeButton, &QPushButton::clicked, 0124 this, [this](){ slotLinkActivated(QStringLiteral("add_watchpoint")); }); 0125 0126 auto* inner = new QHBoxLayout(); 0127 l->addLayout(inner); 0128 inner->setContentsMargins(0, 0, 0, 0); 0129 inner->addLayout(buttonBox); 0130 inner->addStretch(); 0131 0132 auto* g = new SizeGrip(this); 0133 g->setFixedSize(16, 16); 0134 inner->addWidget(g, 0, (Qt::Alignment)(Qt::AlignRight | Qt::AlignBottom)); 0135 0136 move(position); 0137 } 0138 0139 void VariableToolTip::variableCreated(bool hasValue) 0140 { 0141 m_view->resizeColumns(); 0142 if (hasValue) { 0143 ActiveToolTip::showToolTip(this, 0.0); 0144 } else { 0145 close(); 0146 } 0147 } 0148 0149 void VariableToolTip::slotLinkActivated(const QString& link) 0150 { 0151 Variable* v = m_var; 0152 QItemSelection s = m_selection->selection(); 0153 if (!s.empty()) 0154 { 0155 TreeItem* const item = m_model->itemForIndex(s.front().topLeft()); 0156 if (item) 0157 { 0158 auto* v2 = qobject_cast<Variable*>(item); 0159 if (v2) 0160 v = v2; 0161 } 0162 } 0163 0164 IDebugSession *session = ICore::self()->debugController()->currentSession(); 0165 if (session && session->state() != IDebugSession::NotStartedState && session->state() != IDebugSession::EndedState) { 0166 if (link == QLatin1String("add_watch")) { 0167 session->variableController()->addWatch(v); 0168 } else if (link == QLatin1String("add_watchpoint")) { 0169 session->variableController()->addWatchpoint(v); 0170 } 0171 } 0172 close(); 0173 } 0174 0175 void VariableToolTip::slotRangeChanged(int min, int max) 0176 { 0177 Q_ASSERT(min == 0); 0178 Q_UNUSED(min); 0179 QRect rect = QApplication::desktop()->screenGeometry(this); 0180 if (pos().y() + height() + max*m_itemHeight < rect.bottom()) 0181 resize(width(), height() + max*m_itemHeight); 0182 else 0183 { 0184 // Oh, well, I'm sorry, but here's the scrollbar you was 0185 // longing to see 0186 m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); 0187 } 0188 } 0189 0190 } 0191 0192 #include "variabletooltip.moc" 0193 #include "moc_variabletooltip.cpp"