/****************************************************************************
** Meta object code from reading C++ file 'qinputdialog.cpp'
**
** Created: Mon Jul 16 17:28:31 2012
**      by: The Qt Meta Object Compiler version 62 (Qt 4.7.4)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/

#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'qinputdialog.cpp' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 62
#error "This file was generated using the moc from 4.7.4. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif

QT_BEGIN_MOC_NAMESPACE
static const uint qt_meta_data_QInputDialogSpinBox[] = {

 // content:
       5,       // revision
       0,       // classname
       0,    0, // classinfo
       2,   14, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       1,       // signalCount

 // signals: signature, parameters, type, tag, flags
      21,   20,   20,   20, 0x05,

 // slots: signature, parameters, type, tag, flags
      39,   20,   20,   20, 0x08,

       0        // eod
};

static const char qt_meta_stringdata_QInputDialogSpinBox[] = {
    "QInputDialogSpinBox\0\0textChanged(bool)\0"
    "notifyTextChanged()\0"
};

const QMetaObject QInputDialogSpinBox::staticMetaObject = {
    { &QSpinBox::staticMetaObject, qt_meta_stringdata_QInputDialogSpinBox,
      qt_meta_data_QInputDialogSpinBox, 0 }
};

#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &QInputDialogSpinBox::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION

const QMetaObject *QInputDialogSpinBox::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}

void *QInputDialogSpinBox::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, qt_meta_stringdata_QInputDialogSpinBox))
        return static_cast<void*>(const_cast< QInputDialogSpinBox*>(this));
    return QSpinBox::qt_metacast(_clname);
}

int QInputDialogSpinBox::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QSpinBox::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: textChanged((*reinterpret_cast< bool(*)>(_a[1]))); break;
        case 1: notifyTextChanged(); break;
        default: ;
        }
        _id -= 2;
    }
    return _id;
}

// SIGNAL 0
void QInputDialogSpinBox::textChanged(bool _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
static const uint qt_meta_data_QInputDialogDoubleSpinBox[] = {

 // content:
       5,       // revision
       0,       // classname
       0,    0, // classinfo
       2,   14, // methods
       0,    0, // properties
       0,    0, // enums/sets
       0,    0, // constructors
       0,       // flags
       1,       // signalCount

 // signals: signature, parameters, type, tag, flags
      27,   26,   26,   26, 0x05,

 // slots: signature, parameters, type, tag, flags
      45,   26,   26,   26, 0x08,

       0        // eod
};

static const char qt_meta_stringdata_QInputDialogDoubleSpinBox[] = {
    "QInputDialogDoubleSpinBox\0\0textChanged(bool)\0"
    "notifyTextChanged()\0"
};

const QMetaObject QInputDialogDoubleSpinBox::staticMetaObject = {
    { &QDoubleSpinBox::staticMetaObject, qt_meta_stringdata_QInputDialogDoubleSpinBox,
      qt_meta_data_QInputDialogDoubleSpinBox, 0 }
};

#ifdef Q_NO_DATA_RELOCATION
const QMetaObject &QInputDialogDoubleSpinBox::getStaticMetaObject() { return staticMetaObject; }
#endif //Q_NO_DATA_RELOCATION

const QMetaObject *QInputDialogDoubleSpinBox::metaObject() const
{
    return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
}

void *QInputDialogDoubleSpinBox::qt_metacast(const char *_clname)
{
    if (!_clname) return 0;
    if (!strcmp(_clname, qt_meta_stringdata_QInputDialogDoubleSpinBox))
        return static_cast<void*>(const_cast< QInputDialogDoubleSpinBox*>(this));
    return QDoubleSpinBox::qt_metacast(_clname);
}

int QInputDialogDoubleSpinBox::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QDoubleSpinBox::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: textChanged((*reinterpret_cast< bool(*)>(_a[1]))); break;
        case 1: notifyTextChanged(); break;
        default: ;
        }
        _id -= 2;
    }
    return _id;
}

// SIGNAL 0
void QInputDialogDoubleSpinBox::textChanged(bool _t1)
{
    void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
    QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
QT_END_MOC_NAMESPACE
