Commit 3658bdac authored by hjk's avatar hjk

Debugger: Use primitive internal widget instead of matplotview

This practically removes any functionality beyond plain plot display,
but does that at least reliably, cross-platform, without dependency
on 3rd party python packages.

Change-Id: Iaff2f78595394522f32264c642df20dd48b83f8b
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent 3e82dcad
This diff is collapsed.
......@@ -1615,8 +1615,6 @@ class Dumper(DumperBase):
self.qmlBreakpoints.append(Resolver(self, args))
def exitGdb(self, _):
if hasPlot:
matplotQuit()
gdb.execute("quit")
def loadDumpers(self, args):
......
......@@ -62,14 +62,12 @@ def qdump__QByteArray(d, value):
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
displayFormat = d.currentItemFormat()
if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedLatin1, elided=elided)
elif displayFormat == SeparateLatin1StringFormat:
d.putValue(p, Hex2EncodedLatin1, elided=elided)
d.putField("editformat", DisplayLatin1String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
elif displayFormat == Utf8StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedUtf8, elided=elided)
elif displayFormat == SeparateUtf8StringFormat:
d.putValue(p, Hex2EncodedUtf8, elided=elided)
......@@ -546,8 +544,7 @@ def qdump__QFiniteStack(d, value):
size = int(value["_size"])
d.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
d.putItemCount(size)
if d.isExpanded():
d.putPlotData(value["_array"], size, d.templateArgument(value.type, 0))
d.putPlotData(value["_array"], size, d.templateArgument(value.type, 0))
def qdump__QFlags(d, value):
......@@ -847,9 +844,7 @@ def qdump__QImage(d, value):
d.putType("void *")
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif displayFormat == SeparateFormat:
if displayFormat == SeparateFormat:
# This is critical for performance. Writing to an external
# file using the following is faster when using GDB.
# file = tempfile.mkstemp(prefix="gdbpy_")
......@@ -1743,9 +1738,7 @@ def qdump__QString(d, value):
data, size, alloc = d.stringData(value)
d.putNumChild(size)
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif displayFormat == SeparateFormat:
if displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", d.encodeString(value, limit=100000))
if d.isExpanded():
......@@ -1897,9 +1890,7 @@ def qdump__QUrl(d, value):
d.putValue(url, Hex4EncodedLittleEndian)
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif displayFormat == SeparateFormat:
if displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", url)
......
......@@ -711,15 +711,15 @@ def qdump__std__vector(d, value):
d.checkPointer(alloc)
d.putItemCount(size)
if d.isExpanded():
if isBool:
if isBool:
if d.isExpanded():
with Children(d, size, maxNumChild=10000, childType=type):
base = d.pointerValue(start)
for i in d.childRange():
q = base + int(i / 8)
d.putBoolItem(str(i), (int(d.extractPointer(q)) >> (i % 8)) & 1)
else:
d.putPlotData(start, size, type)
else:
d.putPlotData(start, size, type)
def qdump__std__vector__QNX(d, value):
innerType = d.templateArgument(value.type, 0)
......
......@@ -246,7 +246,8 @@ enum DebuggerDisplay {
DisplayUtf16String = 2,
DisplayImageFile = 3,
DisplayLatin1String = 4,
DisplayUtf8String = 5
DisplayUtf8String = 5,
DisplayPlotData = 6
};
// Decode string data as returned by the dumper helpers.
QString decodeData(const QByteArray &baIn, int encoding);
......
......@@ -114,11 +114,15 @@ ImageViewer::ImageViewer(QWidget *parent)
connect(m_imageWidget, &ImageWidget::clicked, this, &ImageViewer::clicked);
}
void ImageViewer::setImage(const QImage &i)
void ImageViewer::setImage(const QImage &image)
{
m_imageWidget->setImage(i);
m_info = tr("Size: %1x%2, %3 byte, format: %4, depth: %5")
.arg(i.width()).arg(i.height()).arg(i.byteCount()).arg(i.format()).arg(i.depth());
m_imageWidget->setImage(image);
clicked(QString());
}
void ImageViewer::setInfo(const QString &info)
{
m_info = info;
clicked(QString());
}
......@@ -165,4 +169,77 @@ void ImageViewer::contextMenuEvent(QContextMenuEvent *ev)
openImageViewer(image);
}
//
//
//
PlotViewer::PlotViewer(QWidget *parent)
: QWidget(parent)
{
}
void PlotViewer::setData(const PlotViewer::Data &data)
{
m_data = data;
update();
}
void PlotViewer::setInfo(const QString &description)
{
m_info = description;
update();
}
void PlotViewer::paintEvent(QPaintEvent *)
{
QPainter pain(this);
const int n = int(m_data.size());
const int w = width();
const int h = height();
const int b = 10; // Border width.
pain.fillRect(rect(), Qt::white);
double ymin = 0;
double ymax = 0;
for (int i = 0; i < n; ++i) {
const double v = m_data.at(i);
if (v < ymin)
ymin = v;
else if (v > ymax)
ymax = v;
}
const double d = ymin == ymax ? (h / 2 - b) : (ymax - ymin);
const int k = 1; // Length of cross marker arms.
for (int i = 0; i + 1 < n; ++i) {
// Lines between points.
const int x1 = b + i * (w - 2 * b) / (n - 1);
const int x2 = b + (i + 1) * (w - 2 * b) / (n - 1);
const int y1 = h - (b + int((m_data[i] - ymin) * (h - 2 * b) / d));
const int y2 = h - (b + int((m_data[i + 1] - ymin) * (h - 2 * b) / d));
pain.drawLine(x1, y1, x2, y2);
if (i == 0) {
// Little cross marker on first point
pain.drawLine(x1 - k, y1 - k, x1 + k, y1 + k);
pain.drawLine(x1 + k, y1 - k, x1 - k, y1 + k);
}
// ... and all subsequent points.
pain.drawLine(x2 - k, y2 - k, x2 + k, y2 + k);
pain.drawLine(x2 + k, y2 - k, x2 - k, y2 + k);
}
if (n) {
pain.drawText(10, 10,
QString::fromLatin1("%5 items. X: %1..%2, Y: %3...%4").arg(0).arg(n).arg(ymin).arg(ymax).arg(n));
} else {
pain.drawText(10, 10,
QString::fromLatin1("Container is empty"));
}
}
#include "imageviewer.moc"
......@@ -33,6 +33,8 @@
#include <QWidget>
#include <vector>
QT_BEGIN_NAMESPACE
class QScrollArea;
class QLabel;
......@@ -49,19 +51,36 @@ class ImageViewer : public QWidget
public:
explicit ImageViewer(QWidget *parent = 0);
void setImage(const QImage &);
void setImage(const QImage &image);
void setInfo(const QString &description);
protected:
void contextMenuEvent(QContextMenuEvent *);
private slots:
private:
void clicked(const QString &);
private:
QScrollArea *m_scrollArea;
ImageWidget *m_imageWidget;
QLabel *m_infoLabel;
QString m_info;
};
class PlotViewer : public QWidget
{
Q_OBJECT
public:
explicit PlotViewer(QWidget *parent = 0);
typedef std::vector<double> Data;
void setData(const Data &data);
void setInfo(const QString &description);
void paintEvent(QPaintEvent *ev);
private:
Data m_data;
QString m_info;
};
#endif // IMAGEVIEWER_H
......@@ -122,6 +122,7 @@ WatchData::WatchData() :
id(0),
state(InitialState),
editformat(StopDisplay),
editencoding(Unencoded8Bit),
address(0),
origaddr(0),
size(0),
......@@ -552,14 +553,12 @@ void parseChildrenData(const WatchData &data0, const GdbMi &item,
GdbMi children = item["children"];
data.updateType(item["type"]);
GdbMi mi = item["editvalue"];
if (mi.isValid())
data.editvalue = mi.data();
mi = item["editformat"];
data.editformat = DebuggerDisplay(mi.toInt());
data.editvalue = item["editvalue"].data();
data.editformat = DebuggerDisplay(item["editformat"].toInt());
data.editencoding = DebuggerEncoding(item["editencoding"].toInt());
mi = item["valueelided"];
GdbMi mi = item["valueelided"];
if (mi.isValid())
data.elided = mi.toInt();
......@@ -658,6 +657,52 @@ void parseWatchData(const WatchData &data0, const GdbMi &input,
parseChildrenData(data0, input, itemHandler, childHandler, arrayDecoder);
}
template <class T>
void readNumericVectorHelper(std::vector<double> *v, const QByteArray &ba)
{
const T *p = (const T *) ba.data();
std::copy(p, p + ba.size() / sizeof(T), std::back_insert_iterator<std::vector<double> >(*v));
}
void readNumericVector(std::vector<double> *v, const QByteArray &rawData, DebuggerEncoding encoding)
{
switch (encoding) {
case Hex2EncodedInt1:
readNumericVectorHelper<signed char>(v, rawData);
break;
case Hex2EncodedInt2:
readNumericVectorHelper<short>(v, rawData);
break;
case Hex2EncodedInt4:
readNumericVectorHelper<int>(v, rawData);
break;
case Hex2EncodedInt8:
readNumericVectorHelper<qint64>(v, rawData);
break;
case Hex2EncodedUInt1:
readNumericVectorHelper<uchar>(v, rawData);
break;
case Hex2EncodedUInt2:
readNumericVectorHelper<ushort>(v, rawData);
break;
case Hex2EncodedUInt4:
readNumericVectorHelper<uint>(v, rawData);
break;
case Hex2EncodedUInt8:
readNumericVectorHelper<quint64>(v, rawData);
break;
case Hex2EncodedFloat4:
readNumericVectorHelper<float>(v, rawData);
break;
case Hex2EncodedFloat8:
readNumericVectorHelper<double>(v, rawData);
break;
default:
qDebug() << "ENCODING ERROR: " << encoding;
}
}
} // namespace Internal
} // namespace Debugger
......@@ -37,6 +37,7 @@
#include <QMetaType>
#include <functional>
#include <vector>
namespace Debugger {
namespace Internal {
......@@ -113,6 +114,7 @@ public:
QString value; // Displayed value
QByteArray editvalue; // Displayed value
DebuggerDisplay editformat; // Format of displayed value
DebuggerEncoding editencoding; // Encoding of displayed value
QByteArray type; // Type for further processing
QString displayedType; // Displayed type (optional)
quint64 address; // Displayed address of the actual object
......@@ -134,6 +136,10 @@ void decodeArrayData(std::function<void(const WatchData &)> itemHandler,
const QByteArray &rawData,
int encoding);
void readNumericVector(std::vector<double> *,
const QByteArray &rawData,
DebuggerEncoding encoding);
void parseChildrenData(const WatchData &parent, const GdbMi &child,
std::function<void(const WatchData &)> itemHandler,
std::function<void(const WatchData &, const GdbMi &)> childHandler,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment