OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / watchdelegatewidgets.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "watchdelegatewidgets.h"
34
35 #include <QtGui/QDoubleValidator>
36 #include <QtCore/QDebug>
37
38 #include <utils/qtcassert.h>
39
40 enum { debug = 0 };
41
42 namespace Debugger {
43 namespace Internal {
44
45 // Basic watch line edit.
46 WatchLineEdit::WatchLineEdit(QWidget *parent)
47     : QLineEdit(parent)
48 {}
49
50 QVariant WatchLineEdit::modelData() const
51 {
52     return QVariant(text());
53 }
54
55 void WatchLineEdit::setModelData(const QVariant &v)
56 {
57     if (debug)
58         qDebug("WatchLineEdit::setModelData(%s, '%s')", v.typeName(), qPrintable(v.toString()));
59     setText(v.toString());
60 }
61
62  /* ------ IntegerWatchLineEdit helpers:
63   *        Integer validator using different number bases. */
64 class IntegerValidator : public QValidator
65 {
66 public:
67     explicit IntegerValidator(QObject *parent);
68     virtual State validate(QString &, int &) const;
69
70     int base() const           { return m_base; }
71     void setBase(int b)        { m_base = b; }
72     bool isSigned() const      { return m_signed; }
73     void setSigned(bool s)     { m_signed = s; }
74     bool isBigInt() const      { return m_bigInt; }
75     void setBigInt(bool b)     { m_bigInt = b; }
76
77     static State validateEntry(const QString &s, int base, bool signedV, bool bigInt);
78
79 private:
80     static inline bool isCharAcceptable(const QChar &c, int base);
81
82     int m_base;
83     bool m_signed;
84     bool m_bigInt;
85 };
86
87 IntegerValidator::IntegerValidator(QObject *parent) :
88     QValidator(parent), m_base(10), m_signed(true), m_bigInt(false)
89 {
90 }
91
92 // Check valid digits depending on base.
93 bool IntegerValidator::isCharAcceptable(const QChar &c, int base)
94 {
95     if (c.isLetter())
96         return base == 16 && c.toLower().toAscii() <= 'f';
97     if (!c.isDigit())
98         return false;
99     const int digit = c.toAscii() - '0';
100     if (base == 8 && digit > 7)
101         return false;
102     if (base == 2 && digit > 1)
103         return false;
104     return true;
105 }
106
107 QValidator::State IntegerValidator::validate(QString &s, int &) const
108 {
109     return IntegerValidator::validateEntry(s, m_base, m_signed, m_bigInt);
110 }
111
112 QValidator::State IntegerValidator::validateEntry(const QString &s, int base, bool signedV, bool bigInt)
113 {
114     const int size = s.size();
115     if (!size)
116         return QValidator::Intermediate;
117     int pos = 0;
118     // Skip sign.
119     if (signedV && s.at(pos) == '-') {
120         pos++;
121         if (pos == size)
122             return QValidator::Intermediate;
123     }
124     // Hexadecimal: '0x'?
125     if (base == 16 && pos + 2 <= size
126         && s.at(pos) == QLatin1Char('0') && s.at(pos + 1) == QLatin1Char('x')) {
127         pos+= 2;
128         if (pos == size)
129             return QValidator::Intermediate;
130     }
131
132     // Check characters past sign.
133     for (; pos < size; pos++)
134         if (!isCharAcceptable(s.at(pos), base))
135             return QValidator::Invalid;
136     // Check conversion unless big integer
137     if (bigInt)
138         return QValidator::Acceptable;
139     bool ok;
140     if (signedV) {
141         s.toLongLong(&ok, base);
142     } else {
143         s.toULongLong(&ok, base);
144     }
145     return ok ? QValidator::Acceptable : QValidator::Intermediate;
146 }
147
148 IntegerWatchLineEdit::IntegerWatchLineEdit(QWidget *parent) :
149     WatchLineEdit(parent),
150     m_validator(new IntegerValidator(this))
151 {
152     setValidator(m_validator);
153 }
154
155 bool IntegerWatchLineEdit::isUnsignedHexNumber(const QString &v)
156 {
157     return IntegerValidator::validateEntry(v, 16, false, true) == QValidator::Acceptable;
158 }
159
160 int IntegerWatchLineEdit::base() const
161 {
162     return m_validator->base();
163 }
164
165 void IntegerWatchLineEdit::setBase(int b)
166 {
167     QTC_ASSERT(b, return; )
168     m_validator->setBase(b);
169 }
170
171 bool IntegerWatchLineEdit::isSigned() const
172 {
173     return m_validator->isSigned();
174 }
175
176 void IntegerWatchLineEdit::setSigned(bool s)
177 {
178     m_validator->setSigned(s);
179 }
180
181 bool IntegerWatchLineEdit::isBigInt() const
182 {
183     return m_validator->isBigInt();
184 }
185
186 void IntegerWatchLineEdit::setBigInt(bool b)
187 {
188     m_validator->setBigInt(b);
189 }
190
191 QVariant IntegerWatchLineEdit::modelDataI() const
192 {
193     if (isBigInt()) // Big integer: Plain text
194         return QVariant(text());
195     bool ok;
196     if (isSigned()) {
197         const qint64 value = text().toLongLong(&ok, base());
198         if (ok)
199             return QVariant(value);
200     } else {
201         const quint64 value = text().toULongLong(&ok, base());
202         if (ok)
203             return QVariant(value);
204     }
205     return QVariant();
206 }
207
208 QVariant IntegerWatchLineEdit::modelData() const
209 {
210     const QVariant data = modelDataI();
211     if (debug)
212         qDebug("IntegerLineEdit::modelData(): base=%d, signed=%d, bigint=%d returns %s '%s'",
213                base(), isSigned(), isBigInt(), data.typeName(), qPrintable(data.toString()));
214     return data;
215 }
216
217 void IntegerWatchLineEdit::setModelData(const QVariant &v)
218 {
219     if (debug)
220         qDebug(">IntegerLineEdit::setModelData(%s, '%s'): base=%d, signed=%d, bigint=%d",
221                v.typeName(), qPrintable(v.toString()),
222                base(), isSigned(), isBigInt());
223     switch (v.type()) {
224     case QVariant::Int:
225     case QVariant::LongLong: {
226         const qint64 iv = v.toLongLong();
227         setSigned(true);
228         setText(QString::number(iv, base()));
229     }
230         break;
231     case QVariant::UInt:
232     case QVariant::ULongLong: {
233          const quint64 iv = v.toULongLong();
234          setSigned(false);
235          setText(QString::number(iv, base()));
236         }
237         break;
238     case QVariant::ByteArray:
239         setNumberText(QString::fromAscii(v.toByteArray()));
240         break;
241     case QVariant::String:
242         setNumberText(v.toString());
243         break;
244     default:
245         qWarning("Invalid value (%s) passed to IntegerLineEdit::setModelData",
246                  v.typeName());
247         setText(QString(QLatin1Char('0')));
248         break;
249     }
250     if (debug)
251         qDebug("<IntegerLineEdit::setModelData(): base=%d, signed=%d, bigint=%d",
252                base(), isSigned(), isBigInt());
253 }
254
255 void IntegerWatchLineEdit::setNumberText(const QString &t)
256 {
257     setText(t);
258 }
259
260 // ------------- FloatWatchLineEdit
261 FloatWatchLineEdit::FloatWatchLineEdit(QWidget *parent) :
262     WatchLineEdit(parent)
263 {
264     setValidator(new QDoubleValidator(this));
265 }
266
267 QVariant FloatWatchLineEdit::modelData() const
268 {
269     return QVariant(text().toDouble());
270 }
271
272 void FloatWatchLineEdit::setModelData(const QVariant &v)
273 {
274     if (debug)
275         qDebug("FloatWatchLineEdit::setModelData(%s, '%s')",
276                v.typeName(), qPrintable(v.toString()));
277     switch (v.type()) {
278         break;
279     case QVariant::Double:
280     case QVariant::String:
281         setText(v.toString());
282         break;
283     case QVariant::ByteArray:
284         setText(QString::fromAscii(v.toByteArray()));
285         break;
286     default:
287         qWarning("Invalid value (%s) passed to FloatWatchLineEdit::setModelData",
288                  v.typeName());
289         setText(QString::number(0.0));
290         break;
291     }
292 }
293
294 WatchLineEdit *WatchLineEdit::create(QVariant::Type t, QWidget *parent)
295 {
296     switch (t) {
297     case QVariant::Bool:
298     case QVariant::Int:
299     case QVariant::UInt:
300     case QVariant::LongLong:
301     case QVariant::ULongLong:
302         return new IntegerWatchLineEdit(parent);
303         break;
304     case QVariant::Double:
305         return new FloatWatchLineEdit(parent);
306     default:
307         break;
308     }
309     return new WatchLineEdit(parent);
310 }
311
312 BooleanComboBox::BooleanComboBox(QWidget *parent) : QComboBox(parent)
313 {
314     QStringList items;
315     items << QLatin1String("false") << QLatin1String("true");
316     addItems(items);
317 }
318
319 QVariant BooleanComboBox::modelData() const
320 {
321     // As not to confuse debuggers with 'true', 'false', we return integers 1,0.
322     const int rc = currentIndex() == 1 ? 1 : 0;
323     return QVariant(rc);
324 }
325
326 void BooleanComboBox::setModelData(const QVariant &v)
327 {
328     if (debug)
329         qDebug("BooleanComboBox::setModelData(%s, '%s')", v.typeName(), qPrintable(v.toString()));
330
331     bool value = false;
332     switch (v.type()) {
333     case QVariant::Bool:
334         value = v.toBool();
335         break;
336     case QVariant::Int:
337     case QVariant::UInt:
338     case QVariant::LongLong:
339     case QVariant::ULongLong:
340         value = v.toInt() != 0;
341         break;
342     default:
343         qWarning("Invalid value (%s) passed to BooleanComboBox::setModelData", v.typeName());
344         break;
345     }
346     setCurrentIndex(value ? 1 : 0);
347 }
348
349 } // namespace Internal
350 } // namespace Debugger