304 lines
7.7 KiB
C++
304 lines
7.7 KiB
C++
#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;
|
|
//piCout << "add" << xp;
|
|
QWidget * ve = ti.create();
|
|
//qDebug() << "add" << ve;
|
|
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();
|
|
}
|
|
|
|
|
|
void KDockWidget::changedGlobal() {
|
|
piCout << "changedGlobal ..." << k_list.size_s() << info_list.size() << lay->count() << lay->rowCount();
|
|
for (int i = 0; i < k_list.size_s(); ++i) {
|
|
piCout << "update" << i << "0";
|
|
if (!K.exists(k_list[i])) {
|
|
k_list.remove(i);
|
|
info_list.remove(i);
|
|
removeRow(i);
|
|
--i;
|
|
continue;
|
|
}
|
|
piCout << "update" << i << "1";
|
|
QLabel * lbl = qobject_cast<QLabel*>(lay->itemAt(i, QFormLayout::LabelRole)->widget());
|
|
piCout << "update" << i << "2";
|
|
if (lbl) lbl->setText(PI2QString(K[k_list[i]].pathString().join(".")) + ":");
|
|
piCout << "update" << i << "3";
|
|
}
|
|
piCout << "changedGlobal ok";
|
|
}
|
|
|
|
|
|
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();
|
|
else
|
|
return true;
|
|
}
|
|
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;
|
|
#if QT_VERSION >= 0x050800
|
|
QFormLayout::TakeRowResult rr = lay->takeRow(r);
|
|
if (rr.fieldItem) {delete rr.fieldItem->widget(); delete rr.fieldItem;}
|
|
if (rr.labelItem) {delete rr.labelItem->widget(); delete rr.labelItem;}
|
|
#else
|
|
piForTimes (2) {
|
|
QLayoutItem * i = lay->itemAt(r+r);
|
|
lay->removeItem(i);
|
|
if (i) {delete i->widget(); delete i;}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
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::changedGlobal() {
|
|
foreach (KDockWidget * d, docks)
|
|
d->changedGlobal();
|
|
}
|
|
|
|
|
|
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();
|
|
}
|