Files
qt-creator/src/plugins/debugger/watchdelegatewidgets.cpp
con d1023c7614 It's 2011 now.
Reviewed-by: hjk
2011-01-12 09:46:24 +01:00

351 lines
9.4 KiB
C++

/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "watchdelegatewidgets.h"
#include <QtGui/QDoubleValidator>
#include <QtCore/QDebug>
#include <utils/qtcassert.h>
enum { debug = 0 };
namespace Debugger {
namespace Internal {
// Basic watch line edit.
WatchLineEdit::WatchLineEdit(QWidget *parent) : QLineEdit(parent)
{
}
QVariant WatchLineEdit::modelData() const
{
return QVariant(text());
}
void WatchLineEdit::setModelData(const QVariant &v)
{
if (debug)
qDebug("WatchLineEdit::setModelData(%s, '%s')", v.typeName(), qPrintable(v.toString()));
setText(v.toString());
}
/* ------ IntegerWatchLineEdit helpers:
* Integer validator using different number bases. */
class IntegerValidator : public QValidator {
public:
explicit IntegerValidator(QObject *parent);
virtual State validate(QString &, int &) const;
int base() const { return m_base; }
void setBase(int b) { m_base = b; }
bool isSigned() const { return m_signed; }
void setSigned(bool s) { m_signed = s; }
bool isBigInt() const { return m_bigInt; }
void setBigInt(bool b) { m_bigInt = b; }
static State validateEntry(const QString &s, int base, bool signedV, bool bigInt);
private:
static inline bool isCharAcceptable(const QChar &c, int base);
int m_base;
bool m_signed;
bool m_bigInt;
};
IntegerValidator::IntegerValidator(QObject *parent) :
QValidator(parent), m_base(10), m_signed(true), m_bigInt(false)
{
}
// Check valid digits depending on base.
bool IntegerValidator::isCharAcceptable(const QChar &c, int base)
{
if (c.isLetter())
return base == 16 && c.toLower().toAscii() <= 'f';
if (!c.isDigit())
return false;
const int digit = c.toAscii() - '0';
if (base == 8 && digit > 7)
return false;
if (base == 2 && digit > 1)
return false;
return true;
}
QValidator::State IntegerValidator::validate(QString &s, int &) const
{
return IntegerValidator::validateEntry(s, m_base, m_signed, m_bigInt);
}
QValidator::State IntegerValidator::validateEntry(const QString &s, int base, bool signedV, bool bigInt)
{
const int size = s.size();
if (!size)
return QValidator::Intermediate;
int pos = 0;
// Skip sign.
if (signedV && s.at(pos) == '-') {
pos++;
if (pos == size)
return QValidator::Intermediate;
}
// Hexadecimal: '0x'?
if (base == 16 && pos + 2 <= size
&& s.at(pos) == QLatin1Char('0') && s.at(pos + 1) == QLatin1Char('x')) {
pos+= 2;
if (pos == size)
return QValidator::Intermediate;
}
// Check characters past sign.
for (; pos < size; pos++)
if (!isCharAcceptable(s.at(pos), base))
return QValidator::Invalid;
// Check conversion unless big integer
if (bigInt)
return QValidator::Acceptable;
bool ok;
if (signedV) {
s.toLongLong(&ok, base);
} else {
s.toULongLong(&ok, base);
}
return ok ? QValidator::Acceptable : QValidator::Intermediate;
}
IntegerWatchLineEdit::IntegerWatchLineEdit(QWidget *parent) :
WatchLineEdit(parent),
m_validator(new IntegerValidator(this))
{
setValidator(m_validator);
}
bool IntegerWatchLineEdit::isUnsignedHexNumber(const QString &v)
{
return IntegerValidator::validateEntry(v, 16, false, true) == QValidator::Acceptable;
}
int IntegerWatchLineEdit::base() const
{
return m_validator->base();
}
void IntegerWatchLineEdit::setBase(int b)
{
QTC_ASSERT(b, return; )
m_validator->setBase(b);
}
bool IntegerWatchLineEdit::isSigned() const
{
return m_validator->isSigned();
}
void IntegerWatchLineEdit::setSigned(bool s)
{
m_validator->setSigned(s);
}
bool IntegerWatchLineEdit::isBigInt() const
{
return m_validator->isBigInt();
}
void IntegerWatchLineEdit::setBigInt(bool b)
{
m_validator->setBigInt(b);
}
QVariant IntegerWatchLineEdit::modelDataI() const
{
if (isBigInt()) // Big integer: Plain text
return QVariant(text());
bool ok;
if (isSigned()) {
const qint64 value = text().toLongLong(&ok, base());
if (ok)
return QVariant(value);
} else {
const quint64 value = text().toULongLong(&ok, base());
if (ok)
return QVariant(value);
}
return QVariant();
}
QVariant IntegerWatchLineEdit::modelData() const
{
const QVariant data = modelDataI();
if (debug)
qDebug("IntegerLineEdit::modelData(): base=%d, signed=%d, bigint=%d returns %s '%s'",
base(), isSigned(), isBigInt(), data.typeName(), qPrintable(data.toString()));
return data;
}
void IntegerWatchLineEdit::setModelData(const QVariant &v)
{
if (debug)
qDebug(">IntegerLineEdit::setModelData(%s, '%s'): base=%d, signed=%d, bigint=%d",
v.typeName(), qPrintable(v.toString()),
base(), isSigned(), isBigInt());
switch (v.type()) {
case QVariant::Int:
case QVariant::LongLong: {
const qint64 iv = v.toLongLong();
setSigned(true);
setText(QString::number(iv, base()));
}
break;
case QVariant::UInt:
case QVariant::ULongLong: {
const quint64 iv = v.toULongLong();
setSigned(false);
setText(QString::number(iv, base()));
}
break;
case QVariant::ByteArray:
setNumberText(QString::fromAscii(v.toByteArray()));
break;
case QVariant::String:
setNumberText(v.toString());
break;
default:
qWarning("Invalid value (%s) passed to IntegerLineEdit::setModelData",
v.typeName());
setText(QString(QLatin1Char('0')));
break;
}
if (debug)
qDebug("<IntegerLineEdit::setModelData(): base=%d, signed=%d, bigint=%d",
base(), isSigned(), isBigInt());
}
void IntegerWatchLineEdit::setNumberText(const QString &t)
{
setText(t);
}
// ------------- FloatWatchLineEdit
FloatWatchLineEdit::FloatWatchLineEdit(QWidget *parent) :
WatchLineEdit(parent)
{
setValidator(new QDoubleValidator(this));
}
QVariant FloatWatchLineEdit::modelData() const
{
return QVariant(text().toDouble());
}
void FloatWatchLineEdit::setModelData(const QVariant &v)
{
if (debug)
qDebug("FloatWatchLineEdit::setModelData(%s, '%s')",
v.typeName(), qPrintable(v.toString()));
switch (v.type()) {
break;
case QVariant::Double:
case QVariant::String:
setText(v.toString());
break;
case QVariant::ByteArray:
setText(QString::fromAscii(v.toByteArray()));
break;
default:
qWarning("Invalid value (%s) passed to FloatWatchLineEdit::setModelData",
v.typeName());
setText(QString::number(0.0));
break;
}
}
WatchLineEdit *WatchLineEdit::create(QVariant::Type t, QWidget *parent)
{
switch (t) {
case QVariant::Bool:
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
return new IntegerWatchLineEdit(parent);
break;
case QVariant::Double:
return new FloatWatchLineEdit(parent);
default:
break;
}
return new WatchLineEdit(parent);
}
BooleanComboBox::BooleanComboBox(QWidget *parent) : QComboBox(parent)
{
QStringList items;
items << QLatin1String("false") << QLatin1String("true");
addItems(items);
}
QVariant BooleanComboBox::modelData() const
{
// As not to confuse debuggers with 'true', 'false', we return integers 1,0.
const int rc = currentIndex() == 1 ? 1 : 0;
return QVariant(rc);
}
void BooleanComboBox::setModelData(const QVariant &v)
{
if (debug)
qDebug("BooleanComboBox::setModelData(%s, '%s')", v.typeName(), qPrintable(v.toString()));
bool value = false;
switch (v.type()) {
case QVariant::Bool:
value = v.toBool();
break;
case QVariant::Int:
case QVariant::UInt:
case QVariant::LongLong:
case QVariant::ULongLong:
value = v.toInt() != 0;
break;
default:
qWarning("Invalid value (%s) passed to BooleanComboBox::setModelData", v.typeName());
break;
}
setCurrentIndex(value ? 1 : 0);
}
} // namespace Internal
} // namespace Debugger