#include "cdgraphics.h" // #include "ui_qcd_graphic.h" #include "cdutils_core.h" #include "cdutils_x.h" #include "graphic.h" #include "piqt.h" #include "qcd_core.h" #include "qcd_graphic.h" #include "qcd_model.h" #include #include #include #include #include #include #include using namespace CDUtils; QStringList CDUtils::getList(const PIVector> & x_list) { QStringList ret; for (const auto & p: x_list) ret << PI2QString(CDCore::pathToString(p)); return ret; } PIVector> CDUtils::setList(const QStringList & l) { PIVector> ret; for (const auto & s: l) ret << CDCore::stringToPath(Q2PIString(s)); return ret; } GDockWidget::GDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) { da = p; menu = new QMenu(this); QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this); connect(a, SIGNAL(triggered(bool)), this, SLOT(rename())); dactions << a; a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this); connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest())); dactions << a; menu_x = new QMenu(this); menu_x->setTitle(tr("Remove X")); graphic = new CDGraphicWidget(); graphic->graphic()->viewport()->setAcceptDrops(true); graphic->graphic()->viewport()->installEventFilter(this); setWidget(graphic); } void GDockWidget::addX(const CDType & t) { if (t.cd_type() != CDType::cdX) return; PIDeque xp = t.path(); if (x_list.contains(xp)) return; x_list << xp; int gind = graphic->graphic()->graphicsCount(); graphic->graphic()->setGraphicsCount(gind + 1); graphic->graphic()->setGraphicName(PI2QString(t.pathString().join(".")), gind); } void GDockWidget::drawX(const PIMap> & data) { for (int i = 0; i < x_list.size_s(); ++i) { PIString sp = CDCore::pathToString(x_list[i]); PIVector ch(data.at(sp)); for (int j = 0; j < ch.size_s(); ++j) graphic->graphic()->addPoint(ch[j], i, false); } graphic->graphic()->updateGraphics(); } QByteArray GDockWidget::save() const { ChunkStream cs; cs.add(1, windowTitle()) .add(2, getList(x_list)) .add(3, graphic->graphic()->save()) .add(4, graphic->evalSpinBoxHistory()->expression()) .add(5, graphic->evalSpinBoxVisible()->expression()); return cs.data(); } void GDockWidget::load(QByteArray ba) { if (ba.isEmpty()) return; ChunkStream cs(ba); while (!cs.atEnd()) { switch (cs.read()) { case 1: setWindowTitle(cs.getData()); break; case 2: x_list = setList(cs.getData()); break; case 3: graphic->graphic()->load(cs.getData()); break; case 4: graphic->evalSpinBoxHistory()->setExpression(cs.getData()); break; case 5: graphic->evalSpinBoxVisible()->setExpression(cs.getData()); break; default: break; } } } void GDockWidget::changedGlobal() { for (int i = 0; i < x_list.size_s(); ++i) { if (!X.exists(x_list[i])) { x_list.remove(i); graphic->graphic()->removeGraphic(i); --i; continue; } graphic->graphic()->setGraphicName(PI2QString(X[x_list[i]].pathString().join(".")), i); } } bool GDockWidget::eventFilter(QObject * o, QEvent * e) { // if (o == graphic->viewport()) { switch (e->type()) { case QEvent::DragMove: { QDragMoveEvent * de = (QDragMoveEvent *)e; const QMimeData * mime = de->mimeData(); // qDebug() << "enter" << mime; if (!mime) break; if (!mime->text().startsWith("x")) break; de->setDropAction(Qt::CopyAction); de->accept(); return true; } break; case QEvent::DragEnter: { QDragEnterEvent * de = (QDragEnterEvent *)e; const QMimeData * mime = de->mimeData(); // qDebug() << "enter" << mime; if (!mime) break; if (!mime->text().startsWith("x")) break; de->setDropAction(Qt::CopyAction); de->accept(); return true; } break; case QEvent::Drop: { QDropEvent * de = (QDropEvent *)e; const QMimeData * mime = de->mimeData(); if (!mime) break; // qDebug() << "drop" << mime->text(); if (!mime->text().startsWith("x")) break; addX(X[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]); de->accept(); return true; } break; default: break; } //} return QWidget::eventFilter(o, e); } void GDockWidget::contextMenuEvent(QContextMenuEvent * e) { if (graphic->graphic()->underMouse()) return; qDeleteAll(menu_x->actions()); menu_x->clear(); for (int i = 0; i < graphic->graphic()->graphicsCount(); ++i) { QPixmap icon(da->iconSize()); icon.fill(graphic->graphic()->graphic(i).pen.color()); QAction * a = new QAction(QIcon(icon), graphic->graphic()->graphic(i).name, this); a->setData(i); connect(a, SIGNAL(triggered(bool)), this, SLOT(removeX())); menu_x->addAction(a); } QMenu * mwm = da->createPopupMenu(); menu->clear(); menu->addActions(dactions); menu->addMenu(menu_x); menu->addSeparator(); menu->addActions(mwm->actions()); menu->popup(e->globalPos()); mwm->deleteLater(); } CDGraphicWidget * GDockWidget::viewportGraphic(QObject * o) const { if (!o) return 0; while (!qobject_cast(o) && o) o = o->parent(); return qobject_cast(o); } void GDockWidget::rename() { QString nn = QInputDialog::getText(this, tr("Rename area"), tr("New area name:"), QLineEdit::Normal, windowTitle()); if (nn.isEmpty()) return; setWindowTitle(nn); } void GDockWidget::removeX() { QAction * a = qobject_cast(sender()); if (!a) return; int ind = a->data().toInt(); if (ind < 0 || ind >= x_list.size_s()) return; x_list.remove(ind); graphic->graphic()->removeGraphic(ind); } CDGraphics::CDGraphics(QWidget * parent): QWidget(parent), Ui::CDGraphics() { setupUi(this); da = new QMainWindow(); da->setWindowFlags(frame->windowFlags()); da->setDockNestingEnabled(true); layoutMain->addWidget(da); } CDGraphics::~CDGraphics() {} void CDGraphics::reset() { qDeleteAll(docks); docks.clear(); } QByteArray CDGraphics::save() const { ChunkStream cs; QVector dstates; foreach(GDockWidget * d, docks) { dstates << d->save(); } cs.add(1, docks.size()).add(2, dstates).add(3, da->saveState()); X.lock(); cs.add(4, getList(X.enabledList())); X.unlock(); cs.add(5, buttonConfigVisible->isChecked()); return cs.data(); } void CDGraphics::load(QByteArray ba) { reset(); if (ba.isEmpty()) return; ChunkStream cs(ba); while (!cs.atEnd()) { switch (cs.read()) { case 1: { int s = cs.getData(); piForTimes(s) addGraphic(); } break; case 2: { QVector dstates = cs.getData>(); for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i) docks[i]->load(dstates[i]); } break; case 3: da->restoreState(cs.getData()); break; case 4: X.lock(); X.setEnabledList(setList(cs.getData())); X.unlock(); break; case 5: buttonConfigVisible->setChecked(cs.getData()); break; default: break; } } } GDockWidget * CDGraphics::graphicDock(Graphic * o) const { if (!o) return 0; foreach(GDockWidget * d, docks) if (d->widget() == o) return d; return 0; } void CDGraphics::addGraphic() { GDockWidget * dw = new GDockWidget(QString("area %1").arg(docks.size()), da); connect(dw, SIGNAL(removeRequest()), this, SLOT(removeGraphic())); connect(buttonConfigVisible, SIGNAL(toggled(bool)), dw->graphic, SLOT(setConfigVisible(bool))); connect(buttonLegendVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setLegendVisible(bool))); connect(buttonBorderInputsVisible, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setBorderInputsVisible(bool))); connect(buttonPause, SIGNAL(clicked(bool)), dw->graphic->graphic(), SLOT(setPaused(bool))); dw->graphic->setConfigVisible(buttonConfigVisible->isChecked()); dw->graphic->graphic()->setLegendVisible(buttonLegendVisible->isChecked()); dw->graphic->graphic()->setBorderInputsVisible(buttonBorderInputsVisible->isChecked()); da->addDockWidget(Qt::RightDockWidgetArea, dw); docks << dw; for (int i = 0; i < docks.size(); ++i) docks[i]->setObjectName(QString("dock_%1").arg(i)); } void CDGraphics::receivedX() { PIMap> data; X.lock(); PIVector> x_list = X.enabledList(); PIVector ch; for (const auto & p: x_list) { CDType & t(X[p]); if (t.xmode_rec() == CDType::X_Current) ch.resize(1).fill(t.toDouble()); else ch = t.history; t.history.clear(); data[CDCore::pathToString(t.path())] = ch; } // piCout << data; X.unlock(); foreach(GDockWidget * d, docks) d->drawX(data); } void CDGraphics::changedGlobal() { foreach(GDockWidget * d, docks) d->changedGlobal(); } void CDGraphics::removeGraphic() { GDockWidget * d = qobject_cast(sender()); if (!d) return; docks.removeAll(d); d->deleteLater(); for (int i = 0; i < docks.size(); ++i) docks[i]->setObjectName(QString("dock_%1").arg(i)); } void CDGraphics::on_buttonAdd_clicked() { addGraphic(); } void CDGraphics::on_buttonClear_clicked() { foreach(GDockWidget * d, docks) d->graphic->graphic()->clear(); } void CDGraphics::on_buttonRemoveAll_clicked() { qDeleteAll(docks); docks.clear(); }