#include "cdgraphics.h" #include "cdutils_core.h" #include "cdutils_x.h" #include "qcd_core.h" #include "qcd_model.h" #include "graphic.h" #include "piqt.h" #include #include #include #include #include #include #include using namespace CDUtils; QStringList CDUtils::getList(const PIVector > & x_list) { QStringList ret; piForeachC (PIDeque & p, x_list) ret << PI2QString(CDCore::pathToString(p)); return ret; } PIVector > CDUtils::setList(const QStringList & l) { PIVector > ret; foreach (QString 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(trUtf8("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]); const PIVector & ch(data[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->evalHistory->expression()) .add(5, graphic->evalVisible->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->evalHistory->setExpression(cs.getData()); break; case 5: graphic->evalVisible->setExpression(cs.getData()); break; default: break; } } } bool GDockWidget::eventFilter(QObject * o, QEvent * e) { //if (o == graphic->viewport()) { switch (e->type()) { case QEvent::DragEnter: { QDragEnterEvent * de = (QDragEnterEvent*)e; const QMimeData * mime = de->mimeData(); //qDebug() << "enter" << mime; if (!mime) break; if (mime->text().isEmpty()) 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().isEmpty()) break; addX(X[CDCore::stringToPath(Q2PIString(mime->text()))]); 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, trUtf8("Rename area"), trUtf8("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(); 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; 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())); 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; piForeachC (PIDeque & 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::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(); }