#include "qcd_core.h" #include "cdutils_k.h" #include "cdutils_core.h" #include "piqt.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace CDUtils; int __QCore_Initializer__::count_(0); QCDCore * __QCore_Initializer__::__instance__(0); __QCore_Initializer__::__QCore_Initializer__() { count_++; if (count_ > 1) return; __instance__ = new QCDCore(); } __QCore_Initializer__::~__QCore_Initializer__() { count_--; if (count_ > 0) return; if (__instance__ != 0) { delete __instance__; __instance__ = 0; } } QCDCore::QCDCore() { setObjectName("QCDCore"); setName("QCDCore"); CONNECTU(&K, changedGlobal, this, K_ChangedGlobal); updating = direct_on = false; } QCDCore::~QCDCore() { } void QCDCore::K_ChangedGlobal() { QMetaObject::invokeMethod(this, "updateBindedWidgets", Qt::QueuedConnection); } void QCDCore::slotBool(bool v) { QWidget * w = (QWidget*)sender(); if (!w || updating) return; QList > pathes = binded_widgets.values(w); foreach (const PIDeque & path, pathes) K[path].setValue(PIString::fromBool(v)); K.calculate(); emit updateViewRequest(); } void QCDCore::slotInt(int v) { QWidget * w = (QWidget*)sender(); if (!w || updating) return; QList > pathes = binded_widgets.values(w); foreach (const PIDeque & path, pathes) K[path].setValue(PIString::fromNumber(v)); finishEdit(pathes); } void QCDCore::slotDouble(double v) { QWidget * w = (QWidget*)sender(); if (!w || updating) return; QList > pathes = binded_widgets.values(w); foreach (const PIDeque & path, pathes) K[path].setValue(PIString::fromNumber(v)); finishEdit(pathes); } void QCDCore::slotText(QString v) { QWidget * w = (QWidget*)sender(); if (!w || updating) return; QList > pathes = binded_widgets.values(w); foreach (const PIDeque & path, pathes) K[path].setValue(Q2PIString(v)); finishEdit(pathes); } void QCDCore::slotVariant(QVariant v) { QWidget * w = (QWidget*)sender(); if (!w || updating) return; QList > pathes = binded_widgets.values(w); foreach (const PIDeque & path, pathes) K[path].setVariantValue(Q2PIVariant(v)); finishEdit(pathes); } void QCDCore::slotDestroyed(QObject * o) { if (!o) return; if (!binded_widgets.contains((QWidget*)o)) return; binded_widgets.remove((QWidget*)o); } int QCDCore::bindWindow(QWidget * wnd) { if (!wnd) return 0; //K.root().makePath(); return bindWidgets(wnd->findChildren()); } int QCDCore::bindWidgets(QList wl) { int ret = 0; foreach (QWidget * w, wl) if (bindWidget(w)) ++ret; return ret; } bool QCDCore::bindWidget(QWidget * w) { if (!w) return false; QString on = w->objectName(); QString cn = w->metaObject()->className(); if (cn == "CDView") { bindView(w); return false; } PIVector ak = K.root().children(); piForeachC (CDType * k, ak) { if (!on.endsWith(PI2QString(k->pathString().join("_")))) continue; if (bindWidget(w, *k)) return true; } return false; } bool QCDCore::bindWidget(QWidget * w, const CDType & k) { if (!w) return false; //piCout << "bind..." << k.name() << k.path(); QString cn = w->metaObject()->className(); bool ok = false; if (cn == "QCheckBox" || cn == "QGroupBox") { connect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)), Qt::UniqueConnection); ok = true; } if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar") { connect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)), Qt::UniqueConnection); ok = true; } if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox") { connect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)), Qt::UniqueConnection); ok = true; } if (cn == "QLineEdit" || cn == "CLineEdit") { connect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)), Qt::UniqueConnection); ok = true; } if (cn == "QVariantEdit") { connect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)), Qt::UniqueConnection); ok = true; } if (cn == "CDView") { bindView(w); } connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(slotDestroyed(QObject*)), Qt::UniqueConnection); setWidgetValue(w, k); if (!ok) return false; //piCout << k.name() << k.path() << "ok"; binded_widgets.insert(w, k.path()); return true; } void QCDCore::updateBindedWidgets() { QMapIterator > it(binded_widgets); QWidgetList to_remove; updating = true; while (it.hasNext()) { QWidget * w = it.next().key(); if (!K.exists(it.value())) to_remove << w; else setWidgetValue(w, K[it.value()]); } foreach (QWidget * w, to_remove) unbindWidget(w); updating = false; } void QCDCore::bindView(QWidget * v) { CDView * w = qobject_cast(v); if (!w) return; connect(this, SIGNAL(updateViewRequest()), w, SLOT(refreshValues()), Qt::UniqueConnection); } void QCDCore::setWidgetValue(QWidget * w, const CDType & k) { if (!w) return; QString cn = w->metaObject()->className(); if (cn == "QCheckBox") qobject_cast(w)->setChecked(k.toBool()); if (cn == "QGroupBox") qobject_cast(w)->setChecked(k.toBool()); if (cn == "QSpinBox") qobject_cast(w)->setValue(k.toInt()); if (cn == "QSlider") qobject_cast(w)->setValue(k.toInt()); if (cn == "QScrollBar") qobject_cast(w)->setValue(k.toInt()); if (cn == "QDoubleSpinBox") qobject_cast(w)->setValue(k.toDouble()); if (cn == "SpinSlider") qobject_cast(w)->setValue(k.toDouble()); if (cn == "QLineEdit") qobject_cast(w)->setText(PI2QString(k.value())); if (cn == "CLineEdit") qobject_cast(w)->setText(PI2QString(k.value())); if (cn == "EvalSpinBox") qobject_cast(w)->setValue(k.toDouble()); if (cn == "QVariantEdit") qobject_cast(w)->setValue(PI2QVariant(k.variantValue())); } void QCDCore::finishEdit(const QList > & pathes) { K.calculate(); if (direct_on) { foreach (const PIDeque & path, pathes) K.directChange(K[path]); } emit updateViewRequest(); } int QCDCore::unbindWindow(QWidget * wnd) { if (!wnd) return 0; return unbindWidgets(wnd->findChildren()); } int QCDCore::unbindWidgets(QList wl) { int ret = 0; foreach (QWidget * w, wl) if (unbindWidget(w)) ++ret; return ret; } bool QCDCore::unbindWidget(QWidget * w) { if (!w) return false; //qDebug() << "unbind" << w; if (!binded_widgets.contains(w)) return false; QString cn = w->metaObject()->className(); if (cn == "QCheckBox" || cn == "QGroupBox") disconnect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool))); if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar") disconnect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int))); if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox") disconnect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double))); if (cn == "QLineEdit" || cn == "CLineEdit") disconnect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString))); if (cn == "QVariantEdit") disconnect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant))); //qDebug() << "remove b" << binded_widgets.size(); binded_widgets.remove(w); //qDebug() << "remove a" << binded_widgets.size(); return true; } void QCDCore::unbindAllWidgets() { QMap > bwm = binded_widgets; QMapIterator > it(bwm); while (it.hasNext()) { QWidget * w = it.next().key(); unbindWidget(w); } binded_widgets.clear(); } void QCDCore::updateBindedWidget(const CDType & k_) { QMapIterator > it(binded_widgets); updating = true; while (it.hasNext()) { QWidget * w = it.next().key(); const CDType & k(K[it.value()]); if (k.path() != k_.path()) continue; setWidgetValue(w, k); } updating = false; }