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();
}

View File

@@ -0,0 +1,75 @@
#ifndef CDDIRECTK_H
#define CDDIRECTK_H
#include "cdgraphics.h"
#include "ui_cddirectk.h"
#include "cddirectk_type_dialog.h"
class QFormLayout;
class KDockWidget: public QDockWidget {
Q_OBJECT
public:
KDockWidget(QString title = QString(), QMainWindow * p = 0);
void addK(const CDUtils::CDType & t, CDDirectKTypeDialog::TypeInfo ti);
QByteArray save() const;
void load(QByteArray ba);
void clear();
QFormLayout * lay;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
void removeRow(int r);
QMenu * menu, * menu_k;
QList<QAction*> dactions;
QMainWindow * da;
CDDirectKTypeDialog * type_dialog;
PIVector<PIDeque<int> > k_list;
QVector<CDDirectKTypeDialog::TypeInfo> info_list;
private slots:
void rename();
void removeK();
signals:
void removeRequest();
};
class CDDirectK: public QWidget, public Ui::CDDirectK
{
Q_OBJECT
public:
explicit CDDirectK(QWidget *parent = 0);
~CDDirectK();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
void addArea();
QList<KDockWidget * > docks;
QMainWindow * da;
public slots:
private slots:
void removeArea();
void on_buttonAdd_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDDIRECTK_H

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectK</class>
<widget class="QWidget" name="CDDirectK">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain" stretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonAdd">
<property name="toolTip">
<string>Add new</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonRemoveAll">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,76 @@
#include "cddirectk_type_dialog.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "piqt.h"
#include "spinslider.h"
#include "qvariantedit.h"
CDDirectKTypeDialog::CDDirectKTypeDialog(QWidget * parent) : QDialog(parent), Ui::CDDirectKTypeDialog() {
setupUi(this);
}
CDDirectKTypeDialog::~CDDirectKTypeDialog() {
}
CDDirectKTypeDialog::TypeInfo CDDirectKTypeDialog::getType() const {
if (!groupBox->isChecked()) return TypeInfo();
TypeInfo ret;
ret.type = comboType->currentIndex();
ret.params_d[0] = evalMin->value();
ret.params_d[1] = evalMax->value();
ret.params_d[2] = spinDecimals->value();
ret.params_d[3] = evalStep->value();
ret.params_s[0] = linePrefix->text();
ret.params_s[1] = lineSuffix->text();
return ret;
}
CDDirectKTypeDialog::TypeInfo::TypeInfo(int type_) {
type = type_;
params_d.resize(4);
params_s.resize(2);
}
QWidget * CDDirectKTypeDialog::TypeInfo::create() {
params_d.resize(4);
params_s.resize(2);
switch (type) {
case 0: {
QDoubleSpinBox * ret = new QDoubleSpinBox();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
case 1: {
QSlider * ret = new QSlider(Qt::Horizontal);
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setSingleStep(params_d[3]);
return ret;
} break;
case 2: {
SpinSlider * ret = new SpinSlider();
ret->setMinimum(params_d[0]);
ret->setMaximum(params_d[1]);
ret->setDecimals(params_d[2]);
ret->setSingleStep(params_d[3]);
ret->setPrefix(params_s[0]);
ret->setSuffix(params_s[1]);
return ret;
} break;
default: break;
}
return new QVariantEdit();
}

View File

@@ -0,0 +1,44 @@
#ifndef CDDIRECTK_TYPE_DIALOG_H
#define CDDIRECTK_TYPE_DIALOG_H
#include <QDialog>
#include "ui_cddirectk_type_dialog.h"
class CDDirectKTypeDialog: public QDialog, public Ui::CDDirectKTypeDialog
{
Q_OBJECT
public:
explicit CDDirectKTypeDialog(QWidget * parent = 0);
~CDDirectKTypeDialog();
struct TypeInfo {
TypeInfo(int type_ = -1);
QWidget * create();
int type;
QVector<double> params_d;
QVector<QString> params_s;
};
TypeInfo getType() const;
private:
public slots:
private slots:
signals:
};
inline QDataStream & operator <<(QDataStream & s, const CDDirectKTypeDialog::TypeInfo & v) {
s << v.type << v.params_d << v.params_s;
return s;
}
inline QDataStream & operator >>(QDataStream & s, CDDirectKTypeDialog::TypeInfo & v) {
s >> v.type >> v.params_d >> v.params_s;
return s;
}
#endif // CDDIRECTK_TYPE_DIALOG_H

View File

@@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDDirectKTypeDialog</class>
<widget class="QDialog" name="CDDirectKTypeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>275</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Custom</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboType">
<item>
<property name="text">
<string>Spin</string>
</property>
</item>
<item>
<property name="text">
<string>Slider</string>
</property>
</item>
<item>
<property name="text">
<string>SpinSlider</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Min:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EvalSpinBox" name="evalMin"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Max:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="EvalSpinBox" name="evalMax">
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Decimals:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinDecimals"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Single step:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="EvalSpinBox" name="evalStep">
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Prefix:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="CLineEdit" name="linePrefix"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Suffix:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="CLineEdit" name="lineSuffix"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>groupBox</sender>
<signal>toggled(bool)</signal>
<receiver>widget</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>86</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>94</x>
<y>91</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>297</x>
<y>285</y>
</hint>
<hint type="destinationlabel">
<x>315</x>
<y>280</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>CDDirectKTypeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>281</x>
<y>290</y>
</hint>
<hint type="destinationlabel">
<x>283</x>
<y>307</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -110,7 +110,7 @@ bool GDockWidget::eventFilter(QObject * o, QEvent * e) {
const QMimeData * mime = de->mimeData();
//qDebug() << "enter" << mime;
if (!mime) break;
if (mime->text().isEmpty()) break;
if (!mime->text().startsWith("x")) break;
de->setDropAction(Qt::CopyAction);
de->accept();
return true;
@@ -120,8 +120,8 @@ bool GDockWidget::eventFilter(QObject * o, QEvent * 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()))]);
if (!mime->text().startsWith("x")) break;
addX(X[CDCore::stringToPath(Q2PIString(mime->text().mid(1)))]);
de->accept();
return true;
} break;

View File

@@ -47,6 +47,9 @@ CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWin
connect(widgetX, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetC, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetX->view, SIGNAL(receivedX()), widgetGraphics, SLOT(receivedX()));
QCDCore::instance()->bindWidget(widgetK->view);
QCDCore::instance()->setDirectKEnabled(true);
X.start();
if (windowState() == Qt::WindowMinimized)
setWindowState(Qt::WindowNoState);
}
@@ -73,6 +76,7 @@ void CDPultWindow::apply(bool sessions) {
widgetX->view->startX();
if (sessions) {
widgetGraphics->load(session_gr);
widgetDirectK->load(session_dk);
if (!session_mw.isEmpty())
restoreState(session_mw);
X.lock();
@@ -127,6 +131,7 @@ bool CDPultWindow::load(const QString & path) {
if (codeConfig->text().isEmpty())
codeConfig->setText(def_config);
session_gr = conf.getValue("session_gr", QByteArray());
session_dk = conf.getValue("session_dk", QByteArray());
session_mw = conf.getValue("session_mw", QByteArray());
setChanged(false);
file_name = path;
@@ -138,6 +143,7 @@ bool CDPultWindow::load(const QString & path) {
bool CDPultWindow::save(const QString & path) {
session_gr = widgetGraphics->save();
session_dk = widgetDirectK->save();
session_mw = saveState();
QPIConfig conf(path, QIODevice::ReadWrite);
conf.clear();
@@ -155,6 +161,7 @@ bool CDPultWindow::save(const QString & path) {
conf.setValue("default_config", checkDefaultConfig->isChecked());
conf.setValue("config", QString2QByteArray(codeConfig->text()));
conf.setValue("session_gr", session_gr);
conf.setValue("session_dk", session_dk);
conf.setValue("session_mw", session_mw);
file_name = path;
return true;

View File

@@ -35,7 +35,7 @@ private:
Ribbon * ribbon;
QMap<CDViewWidget::LogIcon, QIcon> log_icons;
QByteArray session_gr, session_mw;
QByteArray session_gr, session_dk, session_mw;
QString def_config, last_icon;
QImage icon;

View File

@@ -323,6 +323,25 @@ device.cd = eth://udp:${ip.pult}:27002:${ip.app}:27001 #s
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockDirectK">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/tools-wizard.png</normaloff>:/icons/tools-wizard.png</iconset>
</property>
<property name="windowTitle">
<string>Direct K</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_7">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="CDDirectK" name="widgetDirectK" native="true"/>
</item>
</layout>
</widget>
</widget>
<action name="actionOpen">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
@@ -427,6 +446,12 @@ device.cd = eth://udp:${ip.pult}:27002:${ip.app}:27001 #s
<header>cdgraphics.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDDirectK</class>
<extends>QWidget</extends>
<header>cddirectk.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>