Files
cd/utils/pult/cdgraphics.cpp

344 lines
9.0 KiB
C++

#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 <QDockWidget>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QInputDialog>
#include <QMainWindow>
#include <QMimeData>
using namespace CDUtils;
QStringList CDUtils::getList(const PIVector<PIDeque<int>> & x_list) {
QStringList ret;
for (const auto & p: x_list)
ret << PI2QString(CDCore::pathToString(p));
return ret;
}
PIVector<PIDeque<int>> CDUtils::setList(const QStringList & l) {
PIVector<PIDeque<int>> 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<int> 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<PIString, PIVector<double>> & data) {
for (int i = 0; i < x_list.size_s(); ++i) {
PIString sp = CDCore::pathToString(x_list[i]);
PIVector<double> 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<QString>()); break;
case 2: x_list = setList(cs.getData<QStringList>()); break;
case 3: graphic->graphic()->load(cs.getData<QByteArray>()); break;
case 4: graphic->evalSpinBoxHistory()->setExpression(cs.getData<QString>()); break;
case 5: graphic->evalSpinBoxVisible()->setExpression(cs.getData<QString>()); 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<CDGraphicWidget *>(o) && o)
o = o->parent();
return qobject_cast<CDGraphicWidget *>(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<QAction *>(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<QByteArray> 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<int>();
piForTimes(s) addGraphic();
} break;
case 2: {
QVector<QByteArray> dstates = cs.getData<QVector<QByteArray>>();
for (int i = 0; i < piMini(dstates.size(), docks.size()); ++i)
docks[i]->load(dstates[i]);
} break;
case 3: da->restoreState(cs.getData<QByteArray>()); break;
case 4:
X.lock();
X.setEnabledList(setList(cs.getData<QStringList>()));
X.unlock();
break;
case 5: buttonConfigVisible->setChecked(cs.getData<bool>()); 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<PIString, PIVector<double>> data;
X.lock();
PIVector<PIDeque<int>> x_list = X.enabledList();
PIVector<double> 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<GDockWidget *>(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();
}