File indexing completed on 2024-05-19 04:38:48

0001 /*
0002     SPDX-FileCopyrightText: 2008 Vladimir Prus <ghost@cs.msu.su>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "breakpointdetails.h"
0008 
0009 #include <QVBoxLayout>
0010 #include <QLabel>
0011 #include <QGridLayout>
0012 #include <QWhatsThis>
0013 #include <QSpinBox>
0014 
0015 #include <KLocalizedString>
0016 
0017 #include "../breakpoint/breakpoint.h"
0018 
0019 using namespace KDevelop;
0020 
0021 class KDevelop::BreakpointDetailsPrivate
0022 {
0023 public:
0024     QLabel* status;
0025     QLabel* hits;
0026     QSpinBox* ignore;
0027     Breakpoint* currentBreakpoint = nullptr;
0028 };
0029 
0030 BreakpointDetails::BreakpointDetails(QWidget *parent)
0031     : QWidget(parent)
0032     , d_ptr(new BreakpointDetailsPrivate)
0033 {
0034     Q_D(BreakpointDetails);
0035 
0036     auto* layout = new QVBoxLayout(this);
0037 
0038     d->status = new QLabel(this);
0039     connect(d->status, &QLabel::linkActivated,
0040             this, &BreakpointDetails::showExplanation);
0041     layout->addWidget(d->status);
0042 
0043     auto* hitsLayout = new QGridLayout();
0044     layout->addLayout(hitsLayout);
0045 
0046     hitsLayout->setContentsMargins(0, 0, 0, 0);
0047 
0048     d->hits = new QLabel(i18n("Not hit yet"), this);
0049     d->hits->setWordWrap(true);
0050     hitsLayout->addWidget(d->hits, 0, 0, 1, 3);
0051 
0052     auto* l2 = new QLabel(i18n("Ignore"), this);
0053     hitsLayout->addWidget(l2, 2, 0);
0054 
0055     d->ignore = new QSpinBox(this);
0056     hitsLayout->addWidget(d->ignore, 2, 1);
0057     d->ignore->setRange(0, 99999);
0058     connect(d->ignore, QOverload<int>::of(&QSpinBox::valueChanged), this, &BreakpointDetails::setIgnoreHits);
0059 
0060     auto* l3 = new QLabel(i18n("next hits"), this);
0061     hitsLayout->addWidget(l3, 2, 2);
0062 
0063     layout->addStretch();
0064 
0065     setItem(nullptr); //initialize with no breakpoint active
0066 }
0067 
0068 BreakpointDetails::~BreakpointDetails() = default;
0069 
0070 void KDevelop::BreakpointDetails::setIgnoreHits(int ignoreHits)
0071 {
0072     Q_D(BreakpointDetails);
0073 
0074     if (!d->currentBreakpoint)
0075         return;
0076     d->currentBreakpoint->setIgnoreHits(ignoreHits);
0077 }
0078 
0079 
0080 void BreakpointDetails::setItem(Breakpoint *breakpoint)
0081 {
0082     Q_D(BreakpointDetails);
0083 
0084     d->currentBreakpoint = breakpoint;
0085 
0086     if (!breakpoint) {
0087         d->status->hide();
0088         d->hits->hide();
0089         d->ignore->setEnabled(false);
0090         return;
0091     }
0092 
0093     d->ignore->setValue(breakpoint->ignoreHits());
0094 
0095     if (breakpoint->state() == Breakpoint::NotStartedState) {
0096         d->status->hide();
0097         d->hits->hide();
0098         d->ignore->setEnabled(true);
0099         return;
0100     }
0101 
0102     d->status->show();
0103     d->hits->show();
0104     d->ignore->setEnabled(true);
0105 
0106     if (breakpoint->errorText().isEmpty()) {
0107         switch (breakpoint->state()) {
0108             case Breakpoint::NotStartedState:
0109                 Q_ASSERT(0);
0110                 break;
0111             case Breakpoint::PendingState:
0112                 d->status->setText(i18n("Breakpoint is <a href=\"pending\">pending</a>"));
0113                 break;
0114             case Breakpoint::DirtyState:
0115                 d->status->setText(i18n("Breakpoint is <a href=\"dirty\">dirty</a>"));
0116                 break;
0117             case Breakpoint::CleanState:
0118                 d->status->setText(i18n("Breakpoint is active"));
0119                 break;
0120         }
0121 
0122         if (breakpoint->hitCount() == -1)
0123             d->hits->clear();
0124         else if (breakpoint->hitCount())
0125             d->hits->setText(i18np("Hit %1 time", "Hit %1 times", breakpoint->hitCount()));
0126         else
0127             d->hits->setText(i18n("Not hit yet"));
0128     } else {
0129         d->status->setText(i18n("Breakpoint has errors"));
0130         d->hits->setText(breakpoint->errorText());
0131     }
0132 }
0133 
0134 void BreakpointDetails::showExplanation(const QString& link)
0135 {
0136     Q_D(BreakpointDetails);
0137 
0138     QPoint pos = d->status->mapToGlobal(d->status->geometry().topLeft());
0139     if (link == QLatin1String("pending"))
0140     {
0141         QWhatsThis::showText(pos,
0142                                 i18n("<b>Breakpoint is pending</b>"
0143                                 "<p>Pending breakpoints are those that have "
0144                                 "been passed to GDB, but which are not yet "
0145                                 "installed in the target, because GDB cannot "
0146                                 "find the function or file to which the breakpoint "
0147                                 "refers. The most common case is a breakpoint "
0148                                 "in a shared library: GDB will insert this "
0149                                 "breakpoint only when the library is loaded.</p>"),
0150                                 d->status);
0151     }
0152     else if (link == QLatin1String("dirty"))
0153     {
0154         QWhatsThis::showText(pos,
0155                                 i18n("<b>Breakpoint is dirty</b>"
0156                                 "<p>The breakpoint has not yet been passed "
0157                                 "to the debugger.</p>"),
0158                                 d->status);
0159     }
0160 }
0161 
0162 #include "moc_breakpointdetails.cpp"