git-svn-id: svn://db.shs.com.ru/libs@397 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2018-06-07 11:50:15 +00:00
parent 771011128a
commit 6967dcc747
23 changed files with 975 additions and 41 deletions

View File

@@ -0,0 +1,265 @@
#include "cddirectk.h"
#include "ui_cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "graphic.h"
#include "piqt.h"
#include "qvariantedit.h"
#include <QFormLayout>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
KDockWidget::KDockWidget(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_k = new QMenu(this);
menu_k->setTitle(trUtf8("Remove K"));
lay = new QFormLayout();
lay->setContentsMargins(0, qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin), 0, 0);
lay->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
QWidget * w = new QWidget();
w->setAcceptDrops(true);
w->installEventFilter(this);
w->setLayout(lay);
setWidget(w);
type_dialog = new CDDirectKTypeDialog();
}
void KDockWidget::addK(const CDType & t, CDDirectKTypeDialog::TypeInfo ti) {
if (t.cd_type() != CDType::cdK) return;
PIDeque<int> xp = t.path();
if (k_list.contains(xp)) return;
k_list << xp;
info_list << ti;
QWidget * ve = ti.create();
lay->addRow(PI2QString(t.pathString().join(".")) + ":", ve);
QCDCore::instance()->bindWidget(ve, t);
//ve->setValue();
}
QByteArray KDockWidget::save() const {
ChunkStream cs;
cs.add(1, windowTitle())
.add(2, getList(k_list))
.add(3, info_list);
return cs.data();
}
void KDockWidget::load(QByteArray ba) {
clear();
if (ba.isEmpty()) return;
ChunkStream cs(ba);
PIVector<PIDeque<int> > list;
QVector<CDDirectKTypeDialog::TypeInfo> ilist;
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: setWindowTitle(cs.getData<QString>()); break;
case 2: list = setList(cs.getData<QStringList>()); break;
case 3: ilist = cs.getData<QVector<CDDirectKTypeDialog::TypeInfo> >(); break;
default: break;
}
}
ilist.resize(list.size());
for (int i = 0; i < list.size_s(); ++i) {
addK(K[list[i]], ilist[i]);
}
}
void KDockWidget::clear() {
while (lay->rowCount() > 0)
removeRow(0);
k_list.clear();
info_list.clear();
}
bool KDockWidget::eventFilter(QObject * o, QEvent * e) {
//if (o == graphic->viewport()) {
switch (e->type()) {
case QEvent::DragEnter: {
QDragEnterEvent * de = (QDragEnterEvent*)e;
const QMimeData * mime = de->mimeData();
if (!mime) break;
if (!mime->text().startsWith("k")) 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("k")) break;
CDDirectKTypeDialog::TypeInfo ti;
CDType & k(K[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
if (k.type().left(1) == "n" || k.type().left(1) == "f") {
if (type_dialog->exec() == QDialog::Accepted)
ti = type_dialog->getType();
}
addK(k, ti);
de->accept();
return true;
} break;
default: break;
}
//}
return QWidget::eventFilter(o, e);
}
void KDockWidget::contextMenuEvent(QContextMenuEvent * e) {
qDeleteAll(menu_k->actions());
menu_k->clear();
for (int i = 0; i < k_list.size_s(); ++i) {
QAction * a = new QAction(PI2QString(K[k_list[i]].pathString().join(".")), this);
a->setData(i);
connect(a, SIGNAL(triggered(bool)), this, SLOT(removeK()));
menu_k->addAction(a);
}
QMenu * mwm = da->createPopupMenu();
menu->clear();
menu->addActions(dactions);
menu->addMenu(menu_k);
menu->addSeparator();
menu->addActions(mwm->actions());
menu->popup(e->globalPos());
mwm->deleteLater();
}
void KDockWidget::removeRow(int r) {
if (r < 0 || r >= lay->rowCount()) return;
QLayoutItem * i = lay->takeAt(r+r);
if (i) {delete i->widget(); delete i;}
i = lay->takeAt(r+r);
if (i) {delete i->widget(); delete i;}
}
void KDockWidget::rename() {
QString nn = QInputDialog::getText(this, trUtf8("Rename area"), trUtf8("New area name:"),
QLineEdit::Normal, windowTitle());
if (nn.isEmpty()) return;
setWindowTitle(nn);
}
void KDockWidget::removeK() {
QAction * a = qobject_cast<QAction * >(sender());
if (!a) return;
int ind = a->data().toInt();
if (ind < 0 || ind >= k_list.size_s()) return;
k_list.remove(ind);
if (ind >= 0 && ind < info_list.size())
info_list.remove(ind);
removeRow(ind);
}
CDDirectK::CDDirectK(QWidget * parent) : QWidget(parent), Ui::CDDirectK() {
setupUi(this);
da = new QMainWindow();
da->setWindowFlags(frame->windowFlags());
da->setDockNestingEnabled(true);
layoutMain->addWidget(da);
}
CDDirectK::~CDDirectK() {
}
void CDDirectK::reset() {
qDeleteAll(docks);
docks.clear();
}
QByteArray CDDirectK::save() const {
ChunkStream cs;
QVector<QByteArray> dstates;
foreach (KDockWidget * d, docks) {
dstates << d->save();
}
cs.add(1, docks.size())
.add(2, dstates)
.add(3, da->saveState());
return cs.data();
}
void CDDirectK::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)
addArea();
} 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;
default: break;
}
}
}
void CDDirectK::addArea() {
KDockWidget * dw = new KDockWidget(QString("area %1").arg(docks.size()), da);
connect(dw, SIGNAL(removeRequest()), this, SLOT(removeArea()));
da->addDockWidget(Qt::RightDockWidgetArea, dw);
docks << dw;
for (int i = 0; i < docks.size(); ++i)
docks[i]->setObjectName(QString("dock_%1").arg(i));
}
void CDDirectK::removeArea() {
KDockWidget * d = qobject_cast<KDockWidget * >(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 CDDirectK::on_buttonAdd_clicked() {
addArea();
}
void CDDirectK::on_buttonRemoveAll_clicked() {
qDeleteAll(docks);
docks.clear();
}