tree changes

This commit is contained in:
2020-08-19 16:22:10 +03:00
parent 76d9604282
commit d0148bf460
356 changed files with 5334 additions and 6298 deletions

View File

@@ -1,49 +1,50 @@
cmake_minimum_required(VERSION 3.0)
project(piqt)
if(NOT LIBPROJECT)
find_package(PIP REQUIRED)
option(LIB "System install" 0)
option(DEBUG "Build with -g3" 0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall")
if(DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
endif()
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
set(_PIQt_MAJOR 1)
set(_PIQt_MINOR 0)
set(_PIQt_REVISION 0)
set(_PIQt_SUFFIX )
set(_PIQt_COMPANY SHS)
set(_PIQt_DOMAIN org.SHS)
if(NOT DEFINED BUILD_NUMBER)
set(BUILD_NUMBER 9999)
endif()
find_package(QAD REQUIRED)
list(APPEND QT_MULTILIB_LIST ${PROJECT_NAME})
set(PIQt_LIB_TYPE SHARED)
set(QAD_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/piqt_version.h")
set_version(PIQt
MAJOR "${_PIQt_MAJOR}"
MINOR "${_PIQt_MINOR}"
REVISION "${_PIQt_REVISION}"
BUILD "${BUILD_NUMBER}"
SUFFIX "${_PIQt_SUFFIX}"
OUTPUT "${PIQt_VERSION_FILE}")
set_deploy_property(PIQt ${_PIQt_LIB_TYPE}
FULLNAME "${_PIQt_DOMAIN}.*"
COMPANY "${_PIQt_COMPANY}")
include(QADMacros)
macro(piqt_library NAME _MODULES _LIBS)
_qt_project(${NAME} FALSE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN})
_qt_install(${NAME} FALSE "pip" "out_HDR" "out_QM")
endmacro()
macro(piqt_application NAME _MODULES _LIBS)
_qt_project(${NAME} TRUE "PIQt" "${_MODULES}" "pip;${_LIBS}" ${ARGN})
_qt_install(${NAME} TRUE "pip" "" "out_QM")
endmacro()
include_directories(${PIP_INCLUDES})
add_subdirectory(libs)
if (UTILS)
add_subdirectory(utils)
endif()
set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE)
include_directories(${PIP_INCLUDES} ${QAD_INCLUDES})
file(GLOB SRC "*.h" "*.cpp" "*.ui" "*.qrc" "lang/*.ts")
find_qt(${QtVersions} Core Gui Positioning)
qt_wrap(${SRC} HDRS out_HDR CPPS out_CPP QMS out_QM)
qt_add_library(${PROJECT_NAME} SHARED out_CPP)
qt_target_link_libraries(${PROJECT_NAME} pip qad_utils qad_widgets)
message(STATUS "Building ${PROJECT_NAME}")
if(LIBPROJECT)
sdk_install("pip" "${PROJECT_NAME}" "${out_HDR}" "${out_QM}")
else()
if(LIB)
if(WIN32)
install(FILES ${out_HDR} DESTINATION ${MINGW_INCLUDE}/pip)
if(NOT "x${out_QM}" STREQUAL "x")
qt_install(FILES ${out_QM} DESTINATION QtLang)
endif()
qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${MINGW_LIB})
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${MINGW_BIN})
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION QtBin)
else()
install(FILES ${out_HDR} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
qt_install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
else()
if(WIN32)
qt_install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
qt_install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib)
else()
qt_install(TARGETS ${PROJECT_NAME} DESTINATION lib)
endif()
install(FILES ${out_HDR} DESTINATION include/pip)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"")
endif()
set(piqt_includes ${piqt_includes} PARENT_SCOPE)
if (LIB)
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
endif()

1
piqt/libs/CMakeLists.txt Normal file
View File

@@ -0,0 +1 @@
add_directories_with_include("piqt_")

View File

@@ -0,0 +1 @@
piqt_library(piqt "Gui;Positioning" "qad_utils;qad_widgets")

View File

@@ -0,0 +1 @@
piqt_library(qcd_utils "Gui" "pip;qad_utils;qad_widgets;qad_graphic;cd_utils;piqt")

297
piqt/libs/qcd/qcd_core.cpp Normal file
View File

@@ -0,0 +1,297 @@
#include "qcd_core.h"
#include "cdutils_k.h"
#include "cdutils_core.h"
#include "piqt.h"
#include <QWidget>
#include <QCheckBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QSlider>
#include <QScrollBar>
#include <QDoubleSpinBox>
#include <QLineEdit>
#include <spinslider.h>
#include <clineedit.h>
#include <evalspinbox.h>
#include <qvariantedit.h>
#include <qcd_view.h>
using namespace CDUtils;
int __QCore_Initializer__::count_(0);
QCDCore * __QCore_Initializer__::__instance__(0);
__QCore_Initializer__::__QCore_Initializer__() {
count_++;
if (count_ > 1) return;
__instance__ = new QCDCore();
}
__QCore_Initializer__::~__QCore_Initializer__() {
count_--;
if (count_ > 0) return;
if (__instance__ != 0) {
delete __instance__;
__instance__ = 0;
}
}
QCDCore::QCDCore() {
setObjectName("QCDCore");
setName("QCDCore");
CONNECTU(&K, changedGlobal, this, K_ChangedGlobal);
updating = direct_on = false;
}
QCDCore::~QCDCore() {
}
void QCDCore::K_ChangedGlobal() {
QMetaObject::invokeMethod(this, "updateBindedWidgets", Qt::QueuedConnection);
}
void QCDCore::slotBool(bool v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromBool(v));
K.calculate();
emit updateViewRequest();
}
void QCDCore::slotInt(int v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotDouble(double v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(PIString::fromNumber(v));
finishEdit(pathes);
}
void QCDCore::slotText(QString v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setValue(Q2PIString(v));
finishEdit(pathes);
}
void QCDCore::slotVariant(QVariant v) {
QWidget * w = (QWidget*)sender();
if (!w || updating) return;
QList<PIDeque<int> > pathes = binded_widgets.values(w);
foreach (const PIDeque<int> & path, pathes)
K[path].setVariantValue(Q2PIVariant(v));
finishEdit(pathes);
}
void QCDCore::slotDestroyed(QObject * o) {
if (!o) return;
if (!binded_widgets.contains((QWidget*)o)) return;
binded_widgets.remove((QWidget*)o);
}
int QCDCore::bindWindow(QWidget * wnd) {
if (!wnd) return 0;
//K.root().makePath();
return bindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::bindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (bindWidget(w)) ++ret;
return ret;
}
bool QCDCore::bindWidget(QWidget * w) {
if (!w) return false;
QString on = w->objectName();
QString cn = w->metaObject()->className();
if (cn == "CDView") {
bindView(w);
return false;
}
PIVector<CDType * > ak = K.root().children();
piForeachC (CDType * k, ak) {
if (!on.endsWith(PI2QString(k->pathString().join("_")))) continue;
if (bindWidget(w, *k)) return true;
}
return false;
}
bool QCDCore::bindWidget(QWidget * w, const CDType & k) {
if (!w) return false;
//piCout << "bind..." << k.name() << k.path();
QString cn = w->metaObject()->className();
bool ok = false;
if (cn == "QCheckBox" || cn == "QGroupBox") {
connect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar") {
connect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox") {
connect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QLineEdit" || cn == "CLineEdit") {
connect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)), Qt::UniqueConnection);
ok = true;
}
if (cn == "QVariantEdit") {
connect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)), Qt::UniqueConnection);
ok = true;
}
if (cn == "CDView") {
bindView(w);
}
connect(w, SIGNAL(destroyed(QObject*)), this, SLOT(slotDestroyed(QObject*)), Qt::UniqueConnection);
setWidgetValue(w, k);
if (!ok) return false;
//piCout << k.name() << k.path() << "ok";
binded_widgets.insert(w, k.path());
return true;
}
void QCDCore::updateBindedWidgets() {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
QWidgetList to_remove;
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
if (!K.exists(it.value()))
to_remove << w;
else
setWidgetValue(w, K[it.value()]);
}
foreach (QWidget * w, to_remove)
unbindWidget(w);
updating = false;
}
void QCDCore::bindView(QWidget * v) {
CDView * w = qobject_cast<CDView * >(v);
if (!w) return;
connect(this, SIGNAL(updateViewRequest()), w, SLOT(refreshValues()), Qt::UniqueConnection);
}
void QCDCore::setWidgetValue(QWidget * w, const CDType & k) {
if (!w) return;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox") qobject_cast<QCheckBox*>(w)->setChecked(k.toBool());
if (cn == "QGroupBox") qobject_cast<QGroupBox*>(w)->setChecked(k.toBool());
if (cn == "QSpinBox") qobject_cast<QSpinBox*>(w)->setValue(k.toInt());
if (cn == "QSlider") qobject_cast<QSlider*>(w)->setValue(k.toInt());
if (cn == "QScrollBar") qobject_cast<QScrollBar*>(w)->setValue(k.toInt());
if (cn == "QDoubleSpinBox") qobject_cast<QDoubleSpinBox*>(w)->setValue(k.toDouble());
if (cn == "SpinSlider") qobject_cast<SpinSlider*>(w)->setValue(k.toDouble());
if (cn == "QLineEdit") qobject_cast<QLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "CLineEdit") qobject_cast<CLineEdit*>(w)->setText(PI2QString(k.value()));
if (cn == "EvalSpinBox") qobject_cast<EvalSpinBox*>(w)->setValue(k.toDouble());
if (cn == "QVariantEdit") qobject_cast<QVariantEdit*>(w)->setValue(PI2QVariant(k.variantValue()));
}
void QCDCore::finishEdit(const QList<PIDeque<int> > & pathes) {
K.calculate();
if (direct_on) {
foreach (const PIDeque<int> & path, pathes)
K.directChange(K[path]);
}
emit updateViewRequest();
}
int QCDCore::unbindWindow(QWidget * wnd) {
if (!wnd) return 0;
return unbindWidgets(wnd->findChildren<QWidget * >());
}
int QCDCore::unbindWidgets(QList<QWidget * > wl) {
int ret = 0;
foreach (QWidget * w, wl)
if (unbindWidget(w)) ++ret;
return ret;
}
bool QCDCore::unbindWidget(QWidget * w) {
if (!w) return false;
//qDebug() << "unbind" << w;
if (!binded_widgets.contains(w)) return false;
QString cn = w->metaObject()->className();
if (cn == "QCheckBox" || cn == "QGroupBox")
disconnect(w, SIGNAL(toggled(bool)), this, SLOT(slotBool(bool)));
if (cn == "QSpinBox" || cn == "QSlider" || cn == "QScrollBar")
disconnect(w, SIGNAL(valueChanged(int)), this, SLOT(slotInt(int)));
if (cn == "QDoubleSpinBox" || cn == "SpinSlider" || cn == "EvalSpinBox")
disconnect(w, SIGNAL(valueChanged(double)), this, SLOT(slotDouble(double)));
if (cn == "QLineEdit" || cn == "CLineEdit")
disconnect(w, SIGNAL(textChanged(QString)), this, SLOT(slotText(QString)));
if (cn == "QVariantEdit")
disconnect(w, SIGNAL(valueChanged(QVariant)), this, SLOT(slotVariant(QVariant)));
//qDebug() << "remove b" << binded_widgets.size();
binded_widgets.remove(w);
//qDebug() << "remove a" << binded_widgets.size();
return true;
}
void QCDCore::unbindAllWidgets() {
QMap<QWidget * , PIDeque<int> > bwm = binded_widgets;
QMapIterator<QWidget * , PIDeque<int> > it(bwm);
while (it.hasNext()) {
QWidget * w = it.next().key();
unbindWidget(w);
}
binded_widgets.clear();
}
void QCDCore::updateBindedWidget(const CDType & k_) {
QMapIterator<QWidget * , PIDeque<int> > it(binded_widgets);
updating = true;
while (it.hasNext()) {
QWidget * w = it.next().key();
const CDType & k(K[it.value()]);
if (k.path() != k_.path()) continue;
setWidgetValue(w, k);
}
updating = false;
}

96
piqt/libs/qcd/qcd_core.h Normal file
View File

@@ -0,0 +1,96 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_CORE_H
#define QCD_CORE_H
#include <QObject>
#include <QMultiMap>
#include <QVariant>
#include "piobject.h"
#include "cdutils_types.h"
class QCDCore;
class __QCore_Initializer__ {
public:
__QCore_Initializer__();
~__QCore_Initializer__();
static int count_;
static QCDCore * __instance__;
};
class QCDCore: public QObject, public PIObject
{
Q_OBJECT
PIOBJECT(QCDCore)
friend class __QCore_Initializer__;
public:
static QCDCore * instance() {return __QCore_Initializer__::__instance__;}
int bindWindow(QWidget * wnd);
int bindWidgets(QList<QWidget * > wl);
bool bindWidget(QWidget * w);
bool bindWidget(QWidget * w, const CDUtils::CDType & k);
int unbindWindow(QWidget * wnd);
int unbindWidgets(QList<QWidget * > wl);
bool unbindWidget(QWidget * w);
void unbindAllWidgets();
void updateBindedWidget(const CDUtils::CDType & k_);
void setDirectKEnabled(bool yes) {direct_on = yes;}
bool isDirectKEnabled() const {return direct_on;}
private:
QCDCore();
~QCDCore();
void bindView(QWidget * v);
void setWidgetValue(QWidget * w, const CDUtils::CDType & k);
void finishEdit(const QList<PIDeque<int> > & pathes);
EVENT_HANDLER(void, K_ChangedGlobal);
QMultiMap<QWidget * , PIDeque<int> > binded_widgets;
bool updating, direct_on;
private slots:
void slotBool(bool v);
void slotInt(int v);
void slotDouble(double v);
void slotText(QString v);
void slotVariant(QVariant v);
void slotDestroyed(QObject * );
public slots:
void updateBindedWidgets();
signals:
void updateViewRequest();
};
static __QCore_Initializer__ __QCore_initializer__;
#endif // QCD_CORE_H

View File

@@ -0,0 +1,40 @@
#include "qcd_graphic.h"
#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "graphic.h"
#include "piqt.h"
using namespace CDUtils;
CDGraphicWidget::CDGraphicWidget(QWidget * p): QWidget(p) {
ui = new Ui::CDGraphicWidget();
ui->setupUi(this);
ui->graphic->setGraphicsCount(0);
}
Graphic * CDGraphicWidget::graphic() const {
return ui->graphic;
}
void CDGraphicWidget::setConfigVisible(bool on) {
ui->widgetConfig->setVisible(on);
}
bool CDGraphicWidget::isConfigVisible() const {
return ui->widgetConfig->isVisible();
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxHistory() {
return ui->evalHistory;
}
EvalSpinBox * CDGraphicWidget::evalSpinBoxVisible() {
return ui->evalVisible;
}

View File

@@ -0,0 +1,66 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_GRAPHIC_H
#define QCD_GRAPHIC_H
#include <QWidget>
#include <evalspinbox.h>
#include <pistring.h>
namespace CDUtils {
class CDType;
class CDSection;
}
namespace Ui {
class CDGraphicWidget;
}
class Graphic;
class Graphic;
class CDGraphicWidget: public QWidget {
Q_OBJECT
friend class CDGraphics;
friend class GDockWidget;
public:
CDGraphicWidget(QWidget * p = 0);
Graphic * graphic() const;
bool isConfigVisible() const;
EvalSpinBox * evalSpinBoxHistory();
EvalSpinBox * evalSpinBoxVisible();
public slots:
void setConfigVisible(bool on);
private:
Ui::CDGraphicWidget * ui;
private slots:
signals:
};
#endif // QCD_GRAPHIC_H

View File

@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphicWidget</class>
<widget class="QWidget" name="CDGraphicWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>470</width>
<height>380</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="layoutMain">
<property name="spacing">
<number>0</number>
</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>
<widget class="Graphic" name="graphic">
<property name="buttons">
<set>Graphic::Autofit|Graphic::BorderInputs|Graphic::Clear|Graphic::Configure|Graphic::CursorAxis|Graphic::Fullscreen|Graphic::Legend|Graphic::OnlyExpandY|Graphic::Pause|Graphic::Save</set>
</property>
<property name="borderInputsVisible">
<bool>false</bool>
</property>
<property name="statusVisible">
<bool>false</bool>
</property>
<property name="historySize">
<double>100.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetConfig" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<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="QLabel" name="label">
<property name="text">
<string>History:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalHistory">
<property name="value">
<double>100.000000000000000</double>
</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>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Visible:</string>
</property>
</widget>
</item>
<item>
<widget class="EvalSpinBox" name="evalVisible">
<property name="value">
<double>-1.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
<customwidgets>
<customwidget>
<class>Graphic</class>
<extends>QFrame</extends>
<header>graphic.h</header>
</customwidget>
<customwidget>
<class>EvalSpinBox</class>
<extends>QWidget</extends>
<header>evalspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>evalHistory</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setHistorySize(double)</slot>
<hints>
<hint type="sourcelabel">
<x>148</x>
<y>363</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>297</y>
</hint>
</hints>
</connection>
<connection>
<sender>evalVisible</sender>
<signal>valueChanged(double)</signal>
<receiver>graphic</receiver>
<slot>setMaxVisibleTime(double)</slot>
<hints>
<hint type="sourcelabel">
<x>345</x>
<y>361</y>
</hint>
<hint type="destinationlabel">
<x>342</x>
<y>337</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,46 @@
#include "qcd_modedialog.h"
#include "ui_qcd_modedialog.h"
QCDModeDialog::QCDModeDialog(QWidget * parent): QDialog(parent) {
ui = new Ui::QCDModeDialog();
ui->setupUi(this);
}
QCDModeDialog::~QCDModeDialog() {
delete ui;
}
CDUtils::UpdateModeFlags QCDModeDialog::mode() const {
CDUtils::UpdateModeFlags ret = 0;
if (ui->checkSaveIndex->isChecked()) ret |= CDUtils::SaveByIndex;
if (ui->checkSaveName->isChecked()) ret |= CDUtils::SaveByName;
if (ui->checkMerge->isChecked()) ret |= CDUtils::Merge;
return ret;
}
void QCDModeDialog::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void QCDModeDialog::on_checkSaveIndex_clicked(bool checked) {
if (!checked) return;
ui->checkSaveName->setChecked(false);
}
void QCDModeDialog::on_checkSaveName_clicked(bool checked) {
if (!checked) return;
ui->checkSaveIndex->setChecked(false);
}

View File

@@ -0,0 +1,50 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEDIALOG_H
#define QCD_MODEDIALOG_H
#include <QDialog>
#include <cdutils_types.h>
namespace Ui {
class QCDModeDialog;
}
class QCDModeDialog: public QDialog
{
Q_OBJECT
public:
explicit QCDModeDialog(QWidget * parent = 0);
~QCDModeDialog();
CDUtils::UpdateModeFlags mode() const;
protected:
void changeEvent(QEvent *e);
Ui::QCDModeDialog * ui;
private slots:
void on_checkSaveIndex_clicked(bool checked);
void on_checkSaveName_clicked(bool checked);
};
#endif // QCD_MODEDIALOG_H

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QCDModeDialog</class>
<widget class="QDialog" name="QCDModeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>251</width>
<height>152</height>
</rect>
</property>
<property name="windowTitle">
<string>Update description mode</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkSaveIndex">
<property name="text">
<string>Save by index</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkSaveName">
<property name="text">
<string>Save by name</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkMerge">
<property name="text">
<string>Merge</string>
</property>
</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="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QCDModeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>106</x>
<y>131</y>
</hint>
<hint type="destinationlabel">
<x>101</x>
<y>146</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QCDModeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>182</x>
<y>127</y>
</hint>
<hint type="destinationlabel">
<x>169</x>
<y>146</y>
</hint>
</hints>
</connection>
</connections>
</ui>

460
piqt/libs/qcd/qcd_model.cpp Normal file
View File

@@ -0,0 +1,460 @@
#include "qcd_model.h"
#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "piqt.h"
#include <QDebug>
#include <QBrush>
#include <QColor>
#include <QMimeData>
#include "qvariantedit.h"
#include "qad_types.h"
using namespace CDUtils;
// CDKItem
CDItem::CDItem(CDUtils::Interface * i, int _index, CDItem::CDItemType type, CDItem *parent) {
interface = i;
index_ = _index;
parent_ = parent;
type_ = type;
item_count = 0;
expanded = true;
}
CDItem::~CDItem() {
qDeleteAll(childs);
}
QVariant CDItem::data(int column, int role) const {
if (role == Qt::BackgroundRole) {
switch (type_) {
case ItemCDType: {
CDType & t(interface->section(buildPath())[index_]);
if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230));
else return QBrush(QColor(255, 128, 128));
}
case ItemCDSection: return QBrush(QColor(230, 250, 230));
}
}
if (role == Qt::CheckStateRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if (column == cValue && t.cd_type() == CDType::cdK) {
if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked;
else QVariant();
}
if (column == cName_Cmd && t.cd_type() == CDType::cdX) {
return t.isSelectedX() ? Qt::Checked : Qt::Unchecked;
}
}
if (role == Qt::ToolTipRole && type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
return PI2QString(t.errorString());
}
if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
PIDeque<int> path = buildPath();
CDSection & rs = interface->section(path);
CDSection s;
switch (type_) {
case ItemCDType:
switch (column) {
case cID: return QString::number(index_);
case cName_Cmd: return PI2QString(rs[index_].name());
case cType: return stringType(rs[index_].type());
case cXMode: return QVariant::fromValue(xModeEnum(rs[index_].xmode()));
case cXAvg: return rs[index_].avg();
case cExpression: return PI2QString(rs[index_].formula());
case cValue: return value(rs[index_], role);
case cComment: return PI2QString(rs[index_].comment());
default: break;
}
break;
case ItemCDSection:
s = rs.section(index_);
// piCout << rs.name << rs.alias << s.name << s.alias;
switch (column) {
case cID: return QString("[") + QString::number(index_) + QString("]");
case cName_Cmd: return PI2QString(s.alias);
case cType: return PI2QString(s.name);
default: break;
}
break;
}
return QVariant();
}
QVariant CDItem::value(CDType & t, int role) const {
if (t.type() == "f") return t.toDouble();
if (t.type() == "n") return t.toInt();
if (t.type() == "b") return t.toBool();
if (t.type() == "e") {
QAD::Enum et = PI2QADEnum(t.enumValues());
et.selectValue(t.toInt());
if (role == Qt::EditRole) return QVariant::fromValue<QAD::Enum>(et);
else return et.selectedName();
}
return PI2QString(t.value());
}
bool CDItem::setData(int column, const QVariant & value) {
if (type_ == ItemCDType) {
CDType & t(interface->section(buildPath())[index_]);
if ((column == cExpression || column == cValue) && (t.cd_type() == CDType::cdK)) {
interface->section(buildPath())[index_].setValue(Q2PIString(value.toString()));
interface->calculate();
return true;
}
if (t.cd_type() == CDType::cdX) {
switch (column) {
case cName_Cmd:
X.setEnabled(t, value.toBool());
return true;
case cXMode:
t.setXMode((CDType::XMode)value.toInt());
return true;
case cXAvg:
t.setAvg(piMax(value.toInt(), 1));
return true;
default: break;
}
}
}
return false;
}
PIDeque<int> CDItem::buildPath() const {
PIDeque<int> path;
CDItem * p = parent_;
while (p) {
path.push_front(p->index_);
p = p->parent_;
}
path.take_front();
return path;
}
QString CDItem::stringType(const PIString & t) const {
QString n = PI2QString(t);
if (n.isEmpty()) return QString("");
switch (n[0].toLatin1()) {
case 'l': return QString("list"); break;
case 'b': return QString("bool"); break;
case 'n': return QString("int"); break;
case 'f': return QString("double"); break;
case 'c': return QString("color"); break;
case 'r': return QString("rect"); break;
case 'a': return QString("rect"); break;
case 'p': return QString("point"); break;
case 'v': return QString("vector"); break;
case 'i': return QString("IP"); break;
case 'e': return QString("enum"); break;
case 'F': return QString("file"); break;
case 'D': return QString("dir"); break;
}
return QString("string");
}
QAD::Enum CDItem::xModeEnum(int v) const {
QAD::Enum ret;
ret << QAD::Enumerator(CDType::X_Current, "Current")
<< QAD::Enumerator(CDType::X_All_Avg, "All, Averaging");
ret.selectValue(v);
return ret;
}
// CDKDelegate
CDDelegate::CDDelegate(QObject *parent) : QStyledItemDelegate(parent) {
}
void CDDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
CDItem * item = ((CDItemModel*)index.model())->getItem(index);
if (item) {
if (item->itemType() == CDItem::ItemCDType && item->interface->cdType() == CDType::cdC) {
QStyleOptionButton bo;
bo.direction = option.direction;
bo.fontMetrics = option.fontMetrics;
bo.palette = option.palette;
bo.rect = option.rect;
bo.state = option.state;// & ~(QStyle::State_HasFocus | QStyle::State_MouseOver);
bo.text = item->data(1, Qt::DisplayRole).toString();
QWidget * v = (QWidget*)(painter->device());
if (v) {
QPoint cp = v->mapFromGlobal(QCursor::pos());
if (bo.rect.contains(cp, true)) {
//bo.state |= QStyle::State_MouseOver;
if (qApp->mouseButtons().testFlag(Qt::LeftButton))
bo.state |= QStyle::State_On;
}
}
qApp->style()->drawControl(QStyle::CE_PushButton, &bo, painter);
return;
}
}
QStyledItemDelegate::paint(painter, option, index);
}
QWidget * CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
return new QVariantEdit(parent);
}
void CDDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
edit->setValue(index.model()->data(index, Qt::EditRole));
}
void CDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
QVariantEdit *edit = static_cast<QVariantEdit*>(editor);
QVariant v = edit->value();
if (v.canConvert<QAD::Enum>()) {
QAD::Enum et = v.value<QAD::Enum>();
model->setData(index, et.selectedValue(), Qt::EditRole);
} else model->setData(index, v, Qt::EditRole);
}
void CDDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
editor->setGeometry(option.rect);
}
QSize CDDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
QSize s = QStyledItemDelegate::sizeHint(option, index);
s.setWidth(s.width() + 20);
return s;
}
// CDItemModel
CDItemModel::CDItemModel(int type_, QObject *parent) : QAbstractItemModel(parent) {
interface = new Interface((CDType::cdT)type_);
root = 0;
internalRebuild();
}
CDItemModel::~CDItemModel() {
delete root;
delete interface;
}
QVariant CDItemModel::data(const QModelIndex &index, int role) const {
if (!index.isValid()) return QVariant();
CDItem * item = getItem(index);
return item->data(index.column(), role);
}
QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case cID: return tr("Index");
case cName_Cmd: return interface->cdType() == CDType::cdC ? tr("Command") : tr("Name");
case cType: return tr("Type");
case cXMode: return tr("Mode");
case cXAvg: return tr("Averaging");
case cExpression: return tr("Expression");
case cValue: return tr("Value");
case cComment: return tr("Comment");
}
}
return QVariant();
}
QModelIndex CDItemModel::index(int row, int column, const QModelIndex &parent) const {
if (parent.isValid() && parent.column() != cID) return QModelIndex();
CDItem * p = getItem(parent);
CDItem * c = p->childs.value(row, 0);
if (c) return createIndex(row, column, c);
else return QModelIndex();
}
QModelIndex CDItemModel::parent(const QModelIndex &index) const {
if (!index.isValid()) return QModelIndex();
CDItem * c = getItem(index);
CDItem * p = c->parent_;
if (p == root) return QModelIndex();
return createIndex(p->parent_->childs.indexOf(p), cID, p);
}
int CDItemModel::rowCount(const QModelIndex &parent) const {
CDItem * p = getItem(parent);
return p->childs.count();
}
int CDItemModel::columnCount(const QModelIndex &parent) const {
return cLastColumn;
}
Qt::ItemFlags CDItemModel::flags(const QModelIndex & index) const {
if (!index.isValid()) return 0;
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
CDItem * item = getItem(index);
if (!item) return 0;
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (t.cd_type() == CDType::cdK) {
if (index.column() == cExpression || index.column() == cValue)
f |= Qt::ItemIsEditable;
if (index.column() == cValue && t.type() == "b")
f |= Qt::ItemIsUserCheckable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsDragEnabled;
}
if (t.cd_type() == CDType::cdX) {
if (index.column() == cXMode || index.column() == cXAvg)
f |= Qt::ItemIsEditable;
if (index.column() == cName_Cmd)
f |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
}
}
return f;
}
bool CDItemModel::setData(const QModelIndex & index, const QVariant & value, int role) {
if (role == Qt::CheckStateRole && (index.column() == cName_Cmd || index.column() == cValue)) {
CDItem * item = getItem(index);
if (item->type_ == CDItem::ItemCDType) {
CDType & t(interface->section(item->buildPath())[item->index_]);
if (index.column() == cValue && (t.cd_type() == CDType::cdK)) {
if (t.type() == "b") {
bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool())));
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
return result;
}
}
if (index.column() == cName_Cmd && (t.cd_type() == CDType::cdX)) {
bool result = item->setData(index.column(), value);
//QModelIndex rin(CDItemModel::index(index.row(), 1, index.parent()));
//emit dataChanged(rin, rin);
return result;
}
}
}
if (role != Qt::EditRole) return false;
CDItem * item = getItem(index);
bool result = item->setData(index.column(), value);
if (result) {
QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent()));
emit dataChanged(rin, rin);
emit dataChanged(index, index);
}
return result;
}
QMimeData * CDItemModel::mimeData(const QModelIndexList & indexes) const {
if (indexes.size() == 1) {
QModelIndex index = indexes[0];
if (index.isValid()/* && interface->cdType() == CDType::cdX*/) {
CDItem * item = getItem(index);
if (item) {
CDType & t(interface->section(item->buildPath())[item->index_]);
QMimeData * mime = new QMimeData();
mime->setText(PI2QString(CDCore::instance()->typeLetter(interface->cdType()) +
CDCore::pathToString(t.path())));
return mime;
}
}
}
return QAbstractItemModel::mimeData(indexes);
}
void CDItemModel::rebuildModel() {
beginResetModel();
internalRebuild();
endResetModel();
}
void CDItemModel::buildItem(CDItem * it, CDSection & r) {
//piCout << "build item" << r.name << r.alias;
auto i = r.cd.makeIterator();
while (i.next()) {
it->childs << new CDItem(interface, i.key(), CDItem::ItemCDType, it);
}
it->item_count = it->childs.size();
auto j = r.s.makeIterator();
while (j.next()) {
it->childs << new CDItem(interface, j.key(), CDItem::ItemCDSection, it);
buildItem(it->childs.back(), j.valueRef());
}
}
void CDItemModel::updateModel() {
beginResetModel();
endResetModel();
}
void CDItemModel::internalRebuild() {
//qDebug() << "[CDKItemModel]" << "internalRebuild()";
if (root) delete root;
root = new CDItem(interface, 0, CDItem::ItemCDSection, 0);
CDSection & r = interface->root();
buildItem(root, r);
}
CDItem * CDItemModel::getItem(const QModelIndex &index) const {
if (index.isValid()) {
CDItem * item = static_cast<CDItem*>(index.internalPointer());
if (item) return item;
}
return root;
}
QModelIndex CDItemModel::indexByPath(const PIDeque<int> & path, int column) const {
if (path.isEmpty()) return QModelIndex();
CDItem * item = root;
//piCout << path << "...";
bool ok = false;
for (int i = 0; i < path.size_s() - 1; ++i) {
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDSection && j->index_ == path[i]) {
item = j;
ok = true;
break;
}
if (!ok) return QModelIndex();
}
ok = false;
foreach (CDItem * j, item->childs)
if (j->type_ == CDItem::ItemCDType && j->index_ == path.back()) {
item = j;
ok = true;
break;
}
if (!ok || !item->parent_) return QModelIndex();
QModelIndex ret = createIndex(item->parent_->childs.indexOf(item), column, item);
//piCout << path << Q2PIString(item->data(cName_Cmd, Qt::DisplayRole).toString()) << getItem(ret)->buildPath();
return ret;
}

132
piqt/libs/qcd/qcd_model.h Normal file
View File

@@ -0,0 +1,132 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_MODEL_H
#define QCD_MODEL_H
#include <QAbstractItemModel>
#include <QItemDelegate>
#include <QStyledItemDelegate>
#include "pistring.h"
namespace CDUtils {
class CDType;
class CDSection;
class Interface;
enum Column {
cID ,
cName_Cmd ,
cType ,
cXMode ,
cXAvg ,
cExpression,
cValue ,
cComment ,
cLastColumn,
};
}
namespace QAD {
struct Enum;
}
class CDItemModel;
class CDItem {
friend class CDItemModel;
friend class CDView;
public:
enum CDItemType{ItemCDType, ItemCDSection};
CDItem(CDUtils::Interface * interface, int _index, CDItemType type, CDItem * parent);
~CDItem();
QVariant data(int column, int role) const;
QVariant value(CDUtils::CDType & t, int role) const;
bool setData(int column, const QVariant & value);
CDItemType itemType() const {return type_;}
PIDeque<int> buildPath() const;
int index() const {return index_;}
CDUtils::Interface * interface;
bool expanded;
private:
QString stringType(const PIString & t) const;
QAD::Enum xModeEnum(int v) const;
CDItem * parent_;
int index_, item_count;
CDItemType type_;
QList<CDItem *> childs;
};
class CDDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CDDelegate(QObject *parent = 0);
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
class CDItemModel : public QAbstractItemModel {
Q_OBJECT
friend class CDView;
public:
explicit CDItemModel(int type_, QObject *parent = 0);
~CDItemModel();
QVariant data(const QModelIndex & index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QMimeData * mimeData(const QModelIndexList & indexes) const;
CDItem * getItem(const QModelIndex & index) const;
QModelIndex indexByPath(const PIDeque<int> & path, int column = CDUtils::cID) const;
void buildItem(CDItem * it, CDUtils::CDSection &r);
public slots:
void rebuildModel();
void updateModel();
private:
void internalRebuild();
CDUtils::Interface * interface;
CDItem * root;
signals:
};
#endif // QCD_MODEL_H

371
piqt/libs/qcd/qcd_view.cpp Normal file
View File

@@ -0,0 +1,371 @@
#include <QDir>
#include <QMouseEvent>
#include <QSortFilterProxyModel>
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_c.h"
#include "cdutils_m.h"
#include "cdutils_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "piqt.h"
#include "pifile.h"
using namespace CDUtils;
CDView::CDView(QWidget * parent) : QTreeView(parent) {
type_ = -1;
model_ = 0;
proxy_ = 0;
connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(indexClicked(QModelIndex)));
connect(this, SIGNAL(_qcd_sendFailed()), this, SLOT(cd_sendFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_sendSucceed()), this, SLOT(cd_sendSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveFailed()), this, SLOT(cd_receiveFailed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receiveSucceed()), this, SLOT(cd_receiveSucceed()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_receivedX()), this, SLOT(cd_receivedX()), Qt::QueuedConnection);
connect(this, SIGNAL(_qcd_changedGlobal()), this, SLOT(cd_changedGlobal()), Qt::QueuedConnection);
}
CDView::~CDView() {
if (model_) {
delete model_;
delete proxy_;
}
model_ = 0;
proxy_ = 0;
}
void CDView::setType(int cdt) {
if (cdt < 0) return;
if (type_ >= 0) return;
type_ = cdt;
switch ((CDType::cdT)type_) {
case CDType::cdK:
CONNECTU(&K, sended, this, pi_cd_sendSucceed);
CONNECTU(&K, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&K, received, this, pi_cd_receiveSucceed);
CONNECTU(&K, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&K, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdX:
CONNECTU(&X, sended, this, pi_cd_sendSucceed);
CONNECTU(&X, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&X, received, this, pi_cd_receiveSucceed);
CONNECTU(&X, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&X, receivedX, this, pi_cd_receivedX);
CONNECTU(&X, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdC:
CONNECTU(&C, sended, this, pi_cd_sendSucceed);
CONNECTU(&C, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&C, received, this, pi_cd_receiveSucceed);
CONNECTU(&C, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&C, changedGlobal, this, pi_cd_changedGlobal);
break;
case CDType::cdM:
CONNECTU(&M, sended, this, pi_cd_sendSucceed);
CONNECTU(&M, sendFailed, this, pi_cd_sendFailed);
CONNECTU(&M, received, this, pi_cd_receiveSucceed);
CONNECTU(&M, receiveFailed, this, pi_cd_receiveFailed);
CONNECTU(&M, changedGlobal, this, pi_cd_changedGlobal);
CONNECTU(&M, messageReceived, this, pi_cd_messageReceived);
break;
default: break;
}
}
void CDView::mousePressEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mousePressEvent(e);
}
void CDView::mouseReleaseEvent(QMouseEvent * e) {
if (type_ == CDType::cdC) {
QModelIndex i = indexAt(e->pos());
if (i.isValid() && i.column() == cName_Cmd)
update(i);
}
QTreeView::mouseReleaseEvent(e);
}
void CDView::currentChanged(const QModelIndex & cur, const QModelIndex & prev) {
if (type_ == CDType::cdC) {
if (prev.isValid() && prev.column() == cName_Cmd)
update(prev);
}
QTreeView::currentChanged(cur, prev);
}
void CDView::refresh() {
if (type_ < 0) return;
if (!model_) {
model_ = new CDItemModel(type_);
proxy_ = new QSortFilterProxyModel();
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
proxy_->setRecursiveFilteringEnabled(true);
#endif
proxy_->setFilterKeyColumn(-1);
proxy_->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy_->setSourceModel(model_);
setModel(proxy_);
setItemDelegateForColumn(type_ == CDType::cdC ? cName_Cmd : cValue, new CDDelegate());
if (type_ == CDType::cdX)
setItemDelegateForColumn(cXMode, new CDDelegate());
}
model_->rebuildModel();
switch ((CDType::cdT)type_) {
case CDType::cdK:
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
break;
case CDType::cdX:
setColumnHidden(cExpression, true);
break;
case CDType::cdC:
case CDType::cdM:
setColumnHidden(cType, true);
setColumnHidden(cXMode, true);
setColumnHidden(cXAvg, true);
setColumnHidden(cExpression, true);
setColumnHidden(cValue, true);
break;
default: break;
}
expandAll();
for (int i = 0; i < model_->columnCount(); i++) resizeColumnToContents(i);
}
void CDView::refreshValues() {
if (!model_) return;
model_->dataChanged(model_->index(0, 0), model_->index(model_->columnCount() - 1, model_->rowCount() - 1));
}
void CDView::setFile(const QString & filename) {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.setFileName(Q2PIString(filename)); break;
case CDType::cdX: X.setFileName(Q2PIString(filename)); break;
case CDType::cdC: C.setFileName(Q2PIString(filename)); break;
case CDType::cdM: M.setFileName(Q2PIString(filename)); break;
default: break;
}
}
bool CDView::inProgress() const {
switch ((CDType::cdT)type_) {
case CDType::cdK: return K.inProgress(); break;
case CDType::cdX: return X.inProgress(); break;
case CDType::cdC: return C.inProgress(); break;
case CDType::cdM: return M.inProgress(); break;
default: break;
}
return false;
}
void CDView::startX(double freq) {
switch ((CDType::cdT)type_) {
case CDType::cdX: X.start(freq); break;
default: break;
}
}
CDSection * CDView::root() {
return CDCore::instance()->root((CDType::cdT)type_);
}
QString CDView::typeLetter() const {
return PI2QString(CDCore::instance()->typeLetter((CDType::cdT)type_));
}
void CDView::send() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.send(); break;
case CDType::cdX: X.send(); break;
case CDType::cdC: C.send(); break;
case CDType::cdM: M.send(); break;
default: break;
}
}
void CDView::receive() {
busyStatusChanged(true);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.request(); break;
case CDType::cdX: X.request(); break;
case CDType::cdC: C.request(); break;
case CDType::cdM: M.request(); break;
default: break;
}
}
void CDView::save() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.writeFile(); break;
case CDType::cdX: X.writeFile(); break;
case CDType::cdC: C.writeFile(); break;
case CDType::cdM: M.writeFile(); break;
default: break;
}
}
void CDView::load() {
switch ((CDType::cdT)type_) {
case CDType::cdK:
K.readFile();
K.calculate();
break;
case CDType::cdX:
X.readFile();
X.calculate();
break;
case CDType::cdC:
C.readFile();
C.calculate();
break;
case CDType::cdM:
M.readFile();
M.calculate();
break;
default: break;
}
refresh();
}
void CDView::clear() {
//piCout << "clearK";
switch ((CDType::cdT)type_) {
case CDType::cdK: K.root() = CDSection(); break;
case CDType::cdX: X.root() = CDSection(); break;
case CDType::cdC: C.root() = CDSection(); break;
case CDType::cdM: M.root() = CDSection(); break;
default: break;
}
refresh();
}
void CDView::buildFromHeader(const QString & description, int mode) {
if (description.isEmpty()) return;
PIString desc_file = Q2PIString(QDir::current().relativeFilePath(description));
PIFile f(desc_file, PIIODevice::ReadOnly);
switch ((CDType::cdT)type_) {
case CDType::cdK: K.update(&f, mode); break;
case CDType::cdX: X.update(&f, mode); break;
case CDType::cdC: C.update(&f, mode); break;
case CDType::cdM: M.update(&f, mode); break;
default: break;
}
refresh();
}
void CDView::calculate() {
switch ((CDType::cdT)type_) {
case CDType::cdK: K.calculate(); break;
case CDType::cdX: X.calculate(); break;
case CDType::cdC: C.calculate(); break;
case CDType::cdM: M.calculate(); break;
default: break;
}
}
void CDView::filter(const QString & f) {
proxy_->setFilterRegExp(QRegExp(f, Qt::CaseInsensitive));
}
void CDView::indexClicked(const QModelIndex & i) {
if (!model_ || !i.isValid() || type_ != CDType::cdC || i.column() != cName_Cmd) return;
CDItem * item = model_->getItem(i);
if (!item) return;
if (item->itemType() != CDItem::ItemCDType) return;
CDType & t(model_->interface->section(item->buildPath())[item->index()]);
C.sendCommand(t);
emit commandSended(PI2QString(t.pathString().join(".")));
//piCout << t;
qDebug() << PI2QString(t.pathString().join("."));
}
void CDView::cd_sendFailed() {
busyStatusChanged(false);
emit messageStatus("send failed");
emit sendFailed();
}
void CDView::cd_sendSucceed() {
busyStatusChanged(false);
emit messageStatus("send success");
emit sendSucceed();
}
void CDView::cd_receiveFailed() {
busyStatusChanged(false);
emit messageStatus("receive failed");
emit receiveFailed();
}
void CDView::cd_receiveSucceed() {
refresh();
busyStatusChanged(false);
emit messageStatus("receive success");
emit receiveSucceed();
}
void CDView::cd_receivedX() {
X.lock();
PIVector<PIDeque<int> > xl = X.enabledList();
//piCout << "X" << xl.size();
piForeachC (PIDeque<int> & x, xl) {
CDType & t(X[x]);
//piCout << t;
//piCout << t.path();
if (t.cd_type() != CDType::cdX) continue;
update(model_->indexByPath(t.path(), cValue));
//piCout << CDCore::pathToString(t.path()) << t.toDouble() << "model";
//qDebug() << "val" << model_->data(model_->indexByPath(t.path(), cValue), Qt::DisplayRole).toDouble();
}
X.unlock();
emit receivedX();
}
void CDView::cd_changedGlobal() {
emit changedGlobal();
}
void CDView::pi_cd_messageReceived(PIDeque<int> path, int type, PIString msg) {
QMetaObject::invokeMethod(this, "messageReceived", Qt::QueuedConnection,
Q_ARG(QString, PI2QString(CDCore::pathToString(path))),
Q_ARG(int, type),
Q_ARG(QString, PI2QString(msg)));
}

112
piqt/libs/qcd/qcd_view.h Normal file
View File

@@ -0,0 +1,112 @@
/*
QCD Utils - Qt bindings/utilites for CD Utils
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QCD_VIEW_H
#define QCD_VIEW_H
#include "piobject.h"
#include <QTreeView>
namespace CDUtils {
class CDType;
class CDSection;
}
class CDItemModel;
class QSortFilterProxyModel;
class CDView: public QTreeView, public PIObject
{
Q_OBJECT
PIOBJECT(CDView)
public:
explicit CDView(QWidget *parent = 0);
~CDView();
void setType(int cdt);
void setFile(const QString & filename);
bool inProgress() const;
void startX(double freq = 20.);
CDUtils::CDSection * root();
QString typeLetter() const;
CDItemModel * CDModel() {return model_;}
protected:
void mousePressEvent(QMouseEvent * );
void mouseReleaseEvent(QMouseEvent * );
void currentChanged(const QModelIndex & cur, const QModelIndex & prev);
public slots:
void refresh();
void refreshValues();
void send();
void receive();
void save();
void load();
void clear();
void buildFromHeader(const QString & description, int mode = 2);
void calculate();
void filter(const QString & f);
private slots:
void indexClicked(const QModelIndex & i);
void cd_sendFailed();
void cd_sendSucceed();
void cd_receiveFailed();
void cd_receiveSucceed();
void cd_receivedX();
void cd_changedGlobal();
private:
bool filterTree(const QModelIndex & ti, const QString & filter);
EVENT_HANDLER(void, pi_cd_sendFailed) {emit _qcd_sendFailed();}
EVENT_HANDLER(void, pi_cd_sendSucceed) {emit _qcd_sendSucceed();}
EVENT_HANDLER(void, pi_cd_receiveFailed) {emit _qcd_receiveFailed();}
EVENT_HANDLER(void, pi_cd_receiveSucceed) {emit _qcd_receiveSucceed();}
EVENT_HANDLER(void, pi_cd_receivedX) {emit _qcd_receivedX();}
EVENT_HANDLER(void, pi_cd_changedGlobal) {emit _qcd_changedGlobal();}
EVENT_HANDLER3(void, pi_cd_messageReceived, PIDeque<int>, path, int, type, PIString, msg);
CDItemModel * model_;
QSortFilterProxyModel * proxy_;
int type_;
signals:
void sendFailed();
void sendSucceed();
void receiveFailed();
void receiveSucceed();
void receivedX();
void changedGlobal();
void messageStatus(QString msg);
void commandSended(QString msg);
void messageReceived(QString path, int type, QString msg);
void busyStatusChanged(bool busy);
void _qcd_sendFailed(); // PRIVATE
void _qcd_sendSucceed(); // PRIVATE
void _qcd_receiveFailed(); // PRIVATE
void _qcd_receiveSucceed(); // PRIVATE
void _qcd_receivedX(); // PRIVATE
void _qcd_changedGlobal(); // PRIVATE
};
#endif // QCD_VIEW_H

View File

@@ -0,0 +1,9 @@
include(PIPMacros)
pip_code_model(CCM "${ROOT_DIR}/pip/libs/main/io_devices/piiodevice.h" "${ROOT_DIR}/pip/libs/main/io_utils/pipacketextractor.h" OPTIONS "-DPIP_EXPORT" "-Es")
piqt_library(piqt_utils "Gui" "qad_utils;qad_widgets;qad_blockview;piqt" ${CCM})
foreach(_v ${_QT_VERSIONS_})
if (LOCAL_FOUND${_v})
add_dependencies(piqt_utils${_v} pip_cmg)
endif()
endforeach()

View File

@@ -0,0 +1,493 @@
#include "ui_piqt_connection_edit.h"
#include "piqt_connection_edit.h"
#include "piqt_connection_view.h"
#include "piqt_highlighter.h"
#include "piqt.h"
#include "picodeinfo.h"
#include <QCheckBox>
#include <QMessageBox>
ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
ui = new Ui::ConnectionEdit();
ui->setupUi(this);
new ConfigHighlighter(ui->codeEdit->document());
loading = false;
connect(ui->blockView, SIGNAL(schemeAction(BlockItemBase::Action,QList<QGraphicsItem*>)), this, SLOT(recreateRequest()));
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
conn = 0;
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
}
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
QCheckBox * cb = new QCheckBox();
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
cb->setProperty("__value", e.value);
ui->layoutOptions->addWidget(cb);
}
}
ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
}
udevicenum = 0;
}
ConnectionEdit::~ConnectionEdit() {
if (conn) {
conn->stop();
delete conn;
}
}
void ConnectionEdit::accept() {
//bool ok = false;
QList<BlockItem * > bl = ui->blockView->allDevices();
foreach (BlockItem * i, bl)
foreach (BlockItem * j, bl)
if (i != j)
if (((DeviceItem*)i)->name() == ((DeviceItem*)j)->name()) {
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name()));
return;
}
QDialog::accept();
}
QString ConnectionEdit::configuration() const {
if (!conn) return QString();
return PI2QString(conn->makeConfig());
}
QByteArray ConnectionEdit::model() const {
QByteArray ret;
QDataStream s(&ret, QIODevice::ReadWrite);
QString cn = PI2QString(conn ? conn->name() : PIString());
s << cn;
QList<BlockBusItem*> busl = ui->blockView->buses();
s << busl.size();
foreach (BlockBusItem * b, busl)
s << b->save();
QList<BlockItem*> blockl = ui->blockView->blocks();
s << blockl.size();
foreach (BlockItem * b, blockl) {
int type = b->propertyByName("__type").value.toInt();
s << type;
switch (type) {
case __CV_Device:
case __CV_Filter:
case __CV_Sender:
s << b->save();
break;
}
}
return ret;
}
QString ConnectionEdit::name() const {
if (!conn) return QString();
return PI2QString(conn->name());
}
void ConnectionEdit::setName(const QString & name) {
ui->lineName->setText(name);
recreateConnection();
}
void ConnectionEdit::addDevice(const QString & name, const QString & path) {
ui->blockView->addDevice(name, path);
}
void ConnectionEdit::setModel(const QByteArray & m) {
loading = true;
ui->blockView->removeAll();
QDataStream s(m);
QString cn;
s >> cn;
if (conn) delete conn;
conn = new PIConnection(Q2PIString(cn));
ui->lineName->setText(cn);
int sz;
s >> sz;
for (int i = 0; i < sz; ++i) {
BlockBusItem * b = new BlockBusItem();
QByteArray ba; s >> ba; b->load(ba);
ui->blockView->addItem(b);
}
s >> sz;
for (int i = 0; i < sz; ++i) {
int type(0);
BlockItem * b(0);
QByteArray ba;
s >> type;
switch (type) {
case __CV_Device:
b = new DeviceItem();
s >> ba; b->load(ba);
if (!b->isPropertyExists("bufferSize"))
((DeviceItem*)b)->setBufferSize(4096);
((DeviceItem*)b)->rename();
break;
case __CV_Filter:
b = new FilterItem();
s >> ba; b->load(ba);
if (!b->isPropertyExists("bufferSize"))
((FilterItem*)b)->setBufferSize(65536);
((FilterItem*)b)->rename();
break;
case __CV_Sender:
b = new SenderItem();
s >> ba; b->load(ba);
((SenderItem*)b)->rename();
break;
}
if (b)
ui->blockView->addItem(b);
}
ui->blockView->reconnectAll();
loading = false;
recreateConnection();
}
void ConnectionEdit::selectionChanged() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
ui->buttonRemove->setEnabled(!si.isEmpty());
ui->buttonDeviceModify->setEnabled(false);
ui->buttonFilterModify->setEnabled(false);
ui->buttonSenderModify->setEnabled(false);
if (si.size() != 1) return;
BlockItem * b = qgraphicsitem_cast<BlockItem*>(si[0]);
if (!b) return;
int type = b->propertyByName("__type").value.toInt();
if (type == __CV_Device) {
ui->tabWidget->setCurrentIndex(0);
DeviceItem * di = (DeviceItem*)b;
ui->buttonDeviceModify->setEnabled(true);
for (int i = 0; i < ui->comboMode->count(); ++i)
if (ui->comboMode->itemData(i).toInt() == di->mode()) {
ui->comboMode->setCurrentIndex(i);
break;
}
ui->lineDevice->setText(di->name());
ui->linePath->setEditText(di->path());
ui->spinDeviceDT->setValue(di->disconnectTimeout());
ui->spinDeviceBS->setValue(di->bufferSize());
setOptions(di->options());
}
if (type == __CV_Filter) {
ui->tabWidget->setCurrentIndex(1);
FilterItem * fi = (FilterItem*)b;
ui->buttonFilterModify->setEnabled(true);
for (int i = 0; i < ui->comboSplit->count(); ++i)
if (ui->comboSplit->itemData(i).toInt() == fi->mode()) {
ui->comboSplit->setCurrentIndex(i);
break;
}
ui->lineFilter->setText(fi->name());
ui->lineHeader->setText(fi->header());
ui->lineFooter->setText(fi->footer());
ui->spinTimeout->setValue(fi->timeout());
ui->spinSize->setValue(fi->packetSize());
ui->spinFilterDT->setValue(fi->disconnectTimeout());
ui->spinFilterBS->setValue(fi->bufferSize());
}
if (type == __CV_Sender) {
ui->tabWidget->setCurrentIndex(2);
SenderItem * si = (SenderItem*)b;
ui->buttonSenderModify->setEnabled(true);
ui->lineSender->setText(si->name());
ui->lineData->setText(si->data());
ui->spinFrequency->setValue(si->frequency());
}
}
void ConnectionEdit::applyFilter(FilterItem * b) {
b->setName(ui->lineFilter->text());
b->setMode(PIPacketExtractor::SplitMode(ui->comboSplit->itemData(ui->comboSplit->currentIndex()).toInt()));
b->setHeader(ui->lineHeader->text());
b->setFooter(ui->lineFooter->text());
b->setTimeout(ui->spinTimeout->value());
b->setPacketSize(ui->spinSize->value());
b->setDisconnectTimeout(ui->spinFilterDT->value());
b->setBufferSize(ui->spinFilterBS->value());
recreateConnection();
}
void ConnectionEdit::applyDevice(DeviceItem * b) {
QString n = ui->lineDevice->text();
if (n.isEmpty()) {
n = "device" + QString::number(udevicenum);
}
b->setName(n);
b->setMode(PIIODevice::DeviceMode(ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt()));
b->setOptions(PIIODevice::DeviceOptions(getOptions()));
b->setPath(ui->linePath->currentText());
b->setDisconnectTimeout(ui->spinDeviceDT->value());
b->setBufferSize(ui->spinDeviceBS->value());
recreateConnection();
}
void ConnectionEdit::applySender(SenderItem * b) {
b->setName(ui->lineSender->text());
b->setData(ui->lineData->text());
b->setFrequency(ui->spinFrequency->value());
recreateConnection();
}
int ConnectionEdit::getOptions() const {
int ret(0);
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue;
if (cb->isChecked())
ret |= cb->property("__value").toInt();
}
return ret;
}
void ConnectionEdit::setOptions(int o) {
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue;
int cbf = cb->property("__value").toInt();
//qDebug() << cbf;
cb->setChecked((o & cbf) == cbf);
}
}
void ConnectionEdit::recreateConnection() {
//qDebug() << "recreate";
if (loading) return;
ui->blockView->reconnectAll();
if (conn) delete conn;
PIString cn = Q2PIString(ui->lineName->text());
if (cn.isEmpty()) conn = new PIConnection();
else conn = new PIConnection(cn);
QList<BlockItem*> devs = ui->blockView->allDevices();
foreach (BlockItem * b, devs) {
DeviceItem * di = (DeviceItem*)b;
//qDebug() << di->path();
PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode());
if (!dev) continue;
dev->setOptions(di->options());
dev->setThreadedReadBufferSize(di->bufferSize());
conn->setDeviceName(dev, Q2PIString(di->name()));
PIDiagnostics * diag = conn->diagnostic(dev);
if (diag) diag->setDisconnectTimeout(di->disconnectTimeout());
}
foreach (BlockItem * b, devs) {
DeviceItem * di = (DeviceItem*)b;
PIIODevice * dev = conn->deviceByName(Q2PIString(di->name()));
if (!dev) continue;
BlockItemPin * p = b->pinByText("read");
if (!p) continue;
QList<BlockBusItem*> buses = p->connectedBuses(), nbuses;
QSet<BlockBusItem*> pbuses;
while (!buses.isEmpty()) {
nbuses.clear();
foreach (BlockBusItem * bus, buses) {
QList<BlockItem*> cb = bus->connectedBlocks();
if (cb.size() != 2) continue;
FilterItem * fi_t(0);
BlockItem * bi_f(0);
if (cb[0]->pinAtBus(bus)->text() == "in") {
fi_t = (FilterItem*)(cb[0]);
bi_f = (cb[1]);
} else if (cb[1]->pinAtBus(bus)->text() == "in") {
fi_t = (FilterItem*)(cb[1]);
bi_f = (cb[0]);
}
if (!fi_t || !bi_f) continue;
PIString name_from;
int type = bi_f->propertyByName("__type").value.toInt();
if (type == __CV_Device) name_from = Q2PIString(((DeviceItem*)bi_f)->name());
if (type == __CV_Filter) name_from = Q2PIString(((FilterItem*)bi_f)->name());
if (name_from.isEmpty()) continue;
PIPacketExtractor * pe = conn->addFilter(Q2PIString(fi_t->name()),conn->deviceByName(name_from), fi_t->mode());
if (!pe) continue;
pe->setBufferSize(fi_t->bufferSize());
pe->setHeader(PIByteArray::fromUserInput(Q2PIString(fi_t->header())));
pe->setFooter(PIByteArray::fromUserInput(Q2PIString(fi_t->footer())));
pe->setTimeout(fi_t->timeout());
pe->setPacketSize(fi_t->packetSize());
pe->setPayloadSize(fi_t->packetSize());
PIDiagnostics * diag = conn->diagnostic(pe);
if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout());
QList<BlockBusItem*> nb = fi_t->pinByText("out")->connectedBuses();
foreach (BlockBusItem * b_, nb)
if (!pbuses.contains(b_)) {
pbuses << b_;
nbuses << b_;
}
}
buses = nbuses;
}
}
foreach (BlockItem * b, devs) {
BlockItemPin * p = b->pinByText("write");
if (!p) continue;
QList<BlockBusItem*> buses = p->connectedBuses();
foreach (BlockBusItem * bus, buses) {
QList<BlockItem*> cb = bus->connectedBlocks();
if (cb.size() != 2) continue;
BlockItem * bi_f(0);
DeviceItem * di_t(0);
if (cb[0]->pinAtBus(bus)->text() == "write") {
di_t = (DeviceItem*)(cb[0]);
bi_f = (cb[1]);
} else if (cb[1]->pinAtBus(bus)->text() == "write") {
di_t = (DeviceItem*)(cb[1]);
bi_f = (cb[0]);
}
if (!bi_f || !di_t) continue;
QString name_from;
int type = bi_f->propertyByName("__type").value.toInt();
if (type == __CV_Sender) {
SenderItem * si = ((SenderItem*)bi_f);
si->name();
conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency());
if (!si->data().isEmpty())
conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromUserInput(Q2PIString(si->data())));
} else {
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->name();
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name();
if (name_from.isEmpty()) continue;
conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->name()));
}
}
}
ui->codeEdit->setText(PI2QString(conn->makeConfig()));
}
void ConnectionEdit::on_buttonRemove_clicked() {
ui->blockView->removeSelected();
recreateConnection();
}
void ConnectionEdit::on_buttonClear_clicked() {
ui->blockView->removeAll();
recreateConnection();
}
void ConnectionEdit::on_buttonFilterAdd_clicked() {
if (!conn) return;
applyFilter(ui->blockView->addFilter(ui->lineFilter->text()));
}
void ConnectionEdit::on_buttonFilterModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter)
return;
applyFilter(qgraphicsitem_cast<FilterItem*>(si[0]));
}
void ConnectionEdit::on_buttonDeviceAdd_clicked() {
if (!conn) return;
QString n = ui->lineDevice->text();
if (n.isEmpty()) {
udevicenum++;
n = "device" + QString::number(udevicenum);
}
QString p = ui->linePath->currentText();
if (ui->linePath->findText(p) < 0) ui->linePath->addItem(p);
qDebug() << "add:" << n;
applyDevice(ui->blockView->addDevice(n, ui->linePath->currentText()));
}
void ConnectionEdit::on_buttonDeviceModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device)
return;
applyDevice(qgraphicsitem_cast<DeviceItem*>(si[0]));
}
void ConnectionEdit::on_buttonSenderAdd_clicked() {
if (!conn) return;
applySender(ui->blockView->addSender(ui->lineSender->text()));
}
void ConnectionEdit::on_buttonSenderModify_clicked() {
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
if (si.isEmpty()) return;
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender)
return;
applySender(qgraphicsitem_cast<SenderItem*>(si[0]));
}
void ConnectionEdit::on_comboSplit_currentIndexChanged(int index) {
int mode = ui->comboSplit->itemData(index).toInt();
switch (mode) {
case PIPacketExtractor::None:
ui->widgetHeader->setEnabled(false);
ui->widgetFooter->setEnabled(false);
ui->widgetTimeout->setEnabled(false);
ui->widgetSize->setEnabled(false);
break;
case PIPacketExtractor::Header:
ui->widgetHeader->setEnabled(true);
ui->widgetFooter->setEnabled(false);
ui->widgetTimeout->setEnabled(false);
ui->widgetSize->setEnabled(true);
break;
case PIPacketExtractor::Footer:
ui->widgetHeader->setEnabled(false);
ui->widgetFooter->setEnabled(true);
ui->widgetTimeout->setEnabled(false);
ui->widgetSize->setEnabled(true);
break;
case PIPacketExtractor::HeaderAndFooter:
ui->widgetHeader->setEnabled(true);
ui->widgetFooter->setEnabled(true);
ui->widgetTimeout->setEnabled(false);
ui->widgetSize->setEnabled(false);
break;
case PIPacketExtractor::Timeout:
ui->widgetHeader->setEnabled(false);
ui->widgetFooter->setEnabled(false);
ui->widgetTimeout->setEnabled(true);
ui->widgetSize->setEnabled(false);
break;
case PIPacketExtractor::Size:
ui->widgetHeader->setEnabled(false);
ui->widgetFooter->setEnabled(false);
ui->widgetTimeout->setEnabled(false);
ui->widgetSize->setEnabled(true);
break;
default: break;
}
}

View File

@@ -0,0 +1,80 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONNECTION_EDIT_H
#define CONNECTION_EDIT_H
#include <QDialog>
#include "piconnection.h"
namespace Ui {
class ConnectionEdit;
}
class FilterItem;
class DeviceItem;
class SenderItem;
class ConnectionEdit: public QDialog {
Q_OBJECT
public:
explicit ConnectionEdit(QWidget * parent = 0);
~ConnectionEdit();
QString configuration() const;
QByteArray model() const;
QString name() const;
void setName(const QString & name);
void addDevice(const QString & name, const QString & path);
void setModel(const QByteArray & m);
private:
void accept();
void keyPressEvent(QKeyEvent *) {}
void applyFilter(FilterItem * b);
void applyDevice(DeviceItem * b);
void applySender(SenderItem * b);
int getOptions() const;
void setOptions(int o);
Ui::ConnectionEdit * ui;
PIConnection * conn;
bool loading;
int udevicenum;
private slots:
void recreateRequest() {if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);}
void on_buttonRemove_clicked();
void on_buttonClear_clicked();
void on_buttonFilterAdd_clicked();
void on_buttonFilterModify_clicked();
void on_buttonDeviceAdd_clicked();
void on_buttonDeviceModify_clicked();
void on_buttonSenderAdd_clicked();
void on_buttonSenderModify_clicked();
void on_comboSplit_currentIndexChanged(int index);
void selectionChanged();
public slots:
void recreateConnection();
};
#endif // CONNECTION_EDIT_H

View File

@@ -0,0 +1,898 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectionEdit</class>
<widget class="QDialog" name="ConnectionEdit">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>794</width>
<height>799</height>
</rect>
</property>
<property name="windowTitle">
<string>Connection editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineName"/>
</item>
</layout>
</item>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Device</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelFilter_4">
<property name="text">
<string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="CLineEdit" name="lineDevice"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelFilter_11">
<property name="text">
<string>Path:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="EComboBox" name="linePath">
<property name="editable">
<bool>true</bool>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<item>
<property name="text">
<string>eth://UDP:127.0.0.1:12345:127.0.0.1:12346</string>
</property>
</item>
<item>
<property name="text">
<string>eth://TCP:127.0.0.1:16666</string>
</property>
</item>
<item>
<property name="text">
<string>eth://UDP:192.168.0.5:16666:192.168.0.6:16667:mcast:234.0.2.1:mcast:234.0.2.2</string>
</property>
</item>
<item>
<property name="text">
<string>file://./text.txt</string>
</property>
</item>
<item>
<property name="text">
<string>binlog://./logs/:mylog_:1</string>
</property>
</item>
<item>
<property name="text">
<string>ser:///dev/ttyUSB0:9600:8:N:1</string>
</property>
</item>
<item>
<property name="text">
<string>ser://COM32:115200:8:N:1</string>
</property>
</item>
<item>
<property name="text">
<string>usb://0bb4:0c86:1:1:2</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelFilter_12">
<property name="text">
<string>Mode:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboMode"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelFilter_14">
<property name="text">
<string>Options:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QVBoxLayout" name="layoutOptions">
<property name="spacing">
<number>2</number>
</property>
</layout>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_14">
<item>
<widget class="QLabel" name="labelFilter_13">
<property name="text">
<string>Disconnect timeout:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinDeviceDT">
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<double>9999.000000000000000</double>
</property>
<property name="value">
<double>3.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelFilter_15">
<property name="text">
<string>Buffer size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinDeviceBS">
<property name="suffix">
<string> b</string>
</property>
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
</item>
</layout>
</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>
<layout class="QHBoxLayout" name="horizontalLayout_18">
<item>
<widget class="QPushButton" name="buttonDeviceAdd">
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDeviceModify">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Filter</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelFilter">
<property name="text">
<string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="CLineEdit" name="lineFilter"/>
</item>
<item>
<widget class="QComboBox" name="comboSplit"/>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Parameters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QWidget" name="widgetHeader" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFilter_2">
<property name="text">
<string>Header:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="CLineEdit" name="lineHeader"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widgetFooter" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFilter_3">
<property name="text">
<string>Footer:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="CLineEdit" name="lineFooter"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QWidget" name="widgetTimeout" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFilter_7">
<property name="text">
<string>Timeout:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTimeout">
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widgetSize" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFilter_8">
<property name="text">
<string>Size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinSize">
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>8</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QWidget" name="widgetDT" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelFilter_9">
<property name="text">
<string>Disconnect timeout:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinFilterDT">
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<double>9999.000000000000000</double>
</property>
<property name="value">
<double>3.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetSize_2" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>17</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelFilter_17">
<property name="text">
<string>Buffer size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinFilterBS">
<property name="suffix">
<string> b</string>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="value">
<number>65536</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<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>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="buttonFilterAdd">
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonFilterModify">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Sender</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelFilter_5">
<property name="text">
<string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="CLineEdit" name="lineSender"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelFilter_16">
<property name="text">
<string>Frequency:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="spinFrequency">
<property name="suffix">
<string> Hz</string>
</property>
<property name="maximum">
<double>9999.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelFilter_6">
<property name="text">
<string>Data:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="CLineEdit" name="lineData"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>77</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_19">
<item>
<widget class="QPushButton" name="buttonSenderAdd">
<property name="text">
<string>Add</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSenderModify">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Modify</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="buttonRemove">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Remove</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonClear">
<property name="text">
<string>Clear</string>
</property>
<property name="icon">
<iconset resource="piconnedit/piconnedit.qrc">
<normaloff>:/icons/edit-clear-.png</normaloff>:/icons/edit-clear-.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="ConnectionView" name="blockView">
<property name="traceConsiderBuses">
<bool>false</bool>
</property>
<property name="pinMulticonnect" stdset="0">
<bool>true</bool>
</property>
<property name="miniMap" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QCodeEdit" name="codeEdit"/>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BlockView</class>
<extends>QGraphicsView</extends>
<header>blockview.h</header>
</customwidget>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>EComboBox</class>
<extends>QComboBox</extends>
<header>ecombobox.h</header>
</customwidget>
<customwidget>
<class>QCodeEdit</class>
<extends>QWidget</extends>
<header>qcodeedit.h</header>
</customwidget>
<customwidget>
<class>ConnectionView</class>
<extends>BlockView</extends>
<header>piqt_connection_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="piconnedit/piconnedit.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ConnectionEdit</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>442</x>
<y>738</y>
</hint>
<hint type="destinationlabel">
<x>413</x>
<y>426</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ConnectionEdit</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>669</x>
<y>738</y>
</hint>
<hint type="destinationlabel">
<x>643</x>
<y>428</y>
</hint>
</hints>
</connection>
<connection>
<sender>lineName</sender>
<signal>editingFinished()</signal>
<receiver>ConnectionEdit</receiver>
<slot>recreateConnection()</slot>
<hints>
<hint type="sourcelabel">
<x>644</x>
<y>29</y>
</hint>
<hint type="destinationlabel">
<x>662</x>
<y>-5</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>recreateConnection()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,204 @@
#include "piqt_connection_view.h"
#include "picodeinfo.h"
#include "piqt.h"
#include <alignedtextitem.h>
DeviceItem::DeviceItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Device));
addProperty(BlockItem::Property("bufferSize", "", 4096));
setSize(200, 80);
setColor(QColor(192, 192, 255));
text_name = new AlignedTextItem();
text_path = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.);
addDecor(text_name);
fnt.setBold(false);
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
text_path->setFont(fnt);
text_path->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_path->setPos(0., -size().height() / 2. + 20);
addDecor(text_path);
addPin(Qt::AlignLeft, 0, "write", "");
addPin(Qt::AlignRight, 0, "read", "");
}
void DeviceItem::rename() {
QString ms;
BlockItemPin * pr = pinByText("read"), * pw = pinByText("write");
switch (mode()) {
case PIIODevice::ReadOnly: ms = "ro"; pr->show(); pw->hide(); break;
case PIIODevice::WriteOnly: ms = "wo"; pr->hide(); pw->show(); break;
case PIIODevice::ReadWrite: ms = "rw"; pr->show(); pw->show(); break;
}
text_name->setText(name() + " (" + ms + ")");
text_path->setText(path());
}
FilterItem::FilterItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Filter));
addProperty(BlockItem::Property("bufferSize", "", 65536));
setSize(140, 80);
setPos(200, 0);
setColor(QColor(192, 255, 192));
text_name = new AlignedTextItem();
text_mode = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.);
addDecor(text_name);
fnt.setBold(false);
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
text_mode->setFont(fnt);
text_mode->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_mode->setPos(0., -size().height() / 2. + 20);
addDecor(text_mode);
addPin(Qt::AlignLeft, 0, "in", "");
addPin(Qt::AlignRight, 0, "out", "");
}
void FilterItem::rename() {
text_name->setText(name());
QString ms;
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode", 0);
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & i, ei->members)
if (i.value == mode()) {
ms = PI2QString(i.name);
break;
}
}
text_mode->setText(ms);
}
SenderItem::SenderItem(): BlockItem() {
addProperty(BlockItem::Property("__type", "", __CV_Sender));
setSize(140, 80);
setPos(-200, 0);
setColor(QColor(255, 192, 192));
text_name = new AlignedTextItem();
text_frequency = new AlignedTextItem();
QFont fnt(text_name->font()); fnt.setBold(true);
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_name->setFont(fnt);
text_name->setPos(0., -size().height() / 2.);
addDecor(text_name);
fnt.setBold(false);
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
text_frequency->setFont(fnt);
text_frequency->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
text_frequency->setPos(0., -size().height() / 2. + 20);
addDecor(text_frequency);
addPin(Qt::AlignRight, 0, "out", "");
}
void SenderItem::rename() {
text_name->setText(name());
text_frequency->setText(QString::number(frequency()) + " Hz");
}
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) {
}
ConnectionView::~ConnectionView() {
}
DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) {
DeviceItem * ret = findDevice(name);
if (ret) return ret;
ret = new DeviceItem();
PIString dp;
PIIODevice::DeviceMode dm;
PIIODevice::splitFullPath(Q2PIString(path), &dp, &dm);
ret->setPos(0, 0);
ret->setName(name);
ret->setPath(PI2QString(dp));
ret->setMode(dm);
ret->setDisconnectTimeout(3.);
ret->setBufferSize(4096);
placeBlock(ret, allDevices());
addItem(ret);
return ret;
}
FilterItem * ConnectionView::addFilter(const QString & name) {
FilterItem * ret = new FilterItem();
ret->setDisconnectTimeout(3.);
ret->setBufferSize(65536);
ret->setName(name);
placeBlock(ret, allFilters());
addItem(ret);
return ret;
}
SenderItem * ConnectionView::addSender(const QString & name) {
SenderItem * ret = new SenderItem();
ret->setName(name);
placeBlock(ret, allSenders());
addItem(ret);
return ret;
}
DeviceItem * ConnectionView::findDevice(const QString & name) const {
QList<BlockItem*> blockl = blocks();
foreach (BlockItem * b, blockl)
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device))
return (DeviceItem*)b;
return 0;
}
void ConnectionView::loadBus(BlockBusItem * bus) {
bus->setEndpointsNumber(2);
}
void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) {
if (coll.isEmpty()) return;
QList<QRectF> collr;
foreach (BlockItem * i, coll)
collr << i->sceneBoundingRect();
while (true) {
QRectF br = b->sceneBoundingRect();
bool ok = true;
for (int i = 0; i < collr.size(); ++i)
if (br.intersects(collr[i])) {
ok = false;
break;
}
if (ok) break;
b->moveBy(0., grid_step);
}
b->moveBy(0., grid_step * 2.);
}
QList<BlockItem * > ConnectionView::allByType(int type_) const {
QList<BlockItem*> blockl = blocks(), ret;
foreach (BlockItem * b, blockl)
if (b->propertyByName("__type").value.toInt() == type_)
ret << b;
return ret;
}

View File

@@ -0,0 +1,132 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONNECTION_VIEW_H
#define CONNECTION_VIEW_H
#include "blockview.h"
#include "piconnection.h"
const int __CV_Device = 1;
const int __CV_Filter = 2;
const int __CV_Sender = 3;
class DeviceItem: public BlockItem {
public:
DeviceItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
void setPath(const QString & p) {addProperty(BlockItem::Property("device", "", p)); rename();}
void setMode(PIIODevice::DeviceMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();}
void setOptions(PIIODevice::DeviceOptions o) {addProperty(BlockItem::Property("options", "", int(o))); rename();}
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();}
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();}
QString name() const {return propertyByName("name").value.toString();}
QString path() const {return propertyByName("device").value.toString();}
PIIODevice::DeviceMode mode() const {return PIIODevice::DeviceMode(propertyByName("mode").value.toInt());}
PIIODevice::DeviceOptions options() const {return PIIODevice::DeviceOptions(propertyByName("options").value.toInt());}
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
void rename();
protected:
AlignedTextItem * text_name, * text_path;
};
class FilterItem: public BlockItem {
public:
FilterItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
void setMode(PIPacketExtractor::SplitMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();}
void setHeader(const QString & v) {addProperty(BlockItem::Property("header", "", v)); rename();}
void setFooter(const QString & v) {addProperty(BlockItem::Property("footer", "", v)); rename();}
void setTimeout(double v) {addProperty(BlockItem::Property("timeout", "", v)); rename();}
void setPacketSize(int v) {addProperty(BlockItem::Property("size", "", v)); rename();}
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();}
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();}
QString name() const {return propertyByName("name").value.toString();}
PIPacketExtractor::SplitMode mode() const {return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt());}
QString header() const {return propertyByName("header").value.toString();}
QString footer() const {return propertyByName("footer").value.toString();}
double timeout() const {return propertyByName("timeout").value.toDouble();}
int packetSize() const {return propertyByName("size").value.toInt();}
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
void rename();
protected:
AlignedTextItem * text_name, * text_mode;
};
class SenderItem: public BlockItem {
public:
SenderItem();
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
void setData(const QString & p) {addProperty(BlockItem::Property("data", "", p)); rename();}
void setFrequency(double m) {addProperty(BlockItem::Property("frequency", "", m)); rename();}
QString name() const {return propertyByName("name").value.toString();}
QString data() const {return propertyByName("data").value.toString();}
double frequency() const {return propertyByName("frequency").value.toDouble();}
void rename();
protected:
AlignedTextItem * text_name, * text_frequency;
};
class ConnectionView: public BlockView {
Q_OBJECT
public:
explicit ConnectionView(QWidget * parent = 0);
~ConnectionView();
DeviceItem * addDevice(const QString & name, const QString & path);
FilterItem * addFilter(const QString & name);
SenderItem * addSender(const QString & name);
DeviceItem * findDevice(const QString & name) const;
QList<BlockItem * > allDevices() const {return allByType(__CV_Device);}
QList<BlockItem * > allFilters() const {return allByType(__CV_Filter);}
QList<BlockItem * > allSenders() const {return allByType(__CV_Sender);}
private:
QSize sizeHint() const {return QSize(800, 600);}
void loadBus(BlockBusItem * bus);
void placeBlock(BlockItem * b, QList<BlockItem*> coll);
QList<BlockItem * > allByType(int type_) const;
private slots:
};
#endif // CONNECTION_VIEW_H

View File

@@ -0,0 +1,70 @@
#include "piqt_highlighter.h"
ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter(parent) {
HighlightingRule rule;
valueNameFormat.setForeground(QColor(0, 64, 154));
rule.pattern = QRegExp("[^=]"); //"\\b[A-Za-z0-9_]+(?=\\()");
rule.format = valueNameFormat;
highlightingRules.append(rule);
valueFormat.setForeground(QColor(192, 0, 0));
rule.pattern = QRegExp("=[^\n]*");
rule.format = valueFormat;
highlightingRules.append(rule);
equalFormat.setFontWeight(QFont::Bold);
equalFormat.setForeground(QColor(96, 126, 0));
rule.pattern = QRegExp("=");
rule.format = equalFormat;
highlightingRules.append(rule);
sectionFormat.setFontWeight(QFont::Bold);
sectionFormat.setForeground(QColor(0, 32, 64));
rule.pattern = QRegExp("\\[.*\\]");
rule.format = sectionFormat;
highlightingRules.append(rule);
//substFormat.setFontWeight(QFont::Bold);
substFormat.setForeground(QColor(192, 0, 192));
rule.pattern = QRegExp("\\$\\{.*\\}+");
rule.pattern.setMinimal(true);
rule.format = substFormat;
highlightingRules.append(rule);
rule.pattern = QRegExp("\\$\\{[^\\{]*\\}+");
highlightingRules.append(rule);
singleLineCommentFormat.setFontItalic(true);
singleLineCommentFormat.setForeground(QColor(128, 128, 128));
rule.pattern = QRegExp("#[^\n]*");
rule.format = singleLineCommentFormat;
highlightingRules.append(rule);
spaceFormat.setForeground(QColor(210, 210, 210));
//commentStartExpression = QRegExp("/\\*");
//commentEndExpression = QRegExp("\\*/");
}
void ConfigHighlighter::highlightBlock(const QString & text) {
foreach (const HighlightingRule &rule, highlightingRules) {
QRegExp expression(rule.pattern);
int index = expression.indexIn(text);
while (index >= 0) {
int length = expression.matchedLength();
setFormat(index, length, rule.format);
index = expression.indexIn(text, index + length);
}
}
setCurrentBlockState(0);
QRegExp expression = QRegExp("[ |\t]");
int index = expression.indexIn(text);
while (index >= 0) {
int length = expression.matchedLength();
setFormat(index, length, spaceFormat);
index = expression.indexIn(text, index + length);
}
}

View File

@@ -0,0 +1,50 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONF_HIGHLIGHTER_H
#define CONF_HIGHLIGHTER_H
#include <QSyntaxHighlighter>
#include <QTextCursor>
#include <QTextCharFormat>
class QTextDocument;
class ConfigHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
ConfigHighlighter(QTextDocument *parent = 0);
QTextCursor cursor;
private:
void highlightBlock(const QString &text);
struct HighlightingRule {
QRegExp pattern;
QTextCharFormat format;
};
QVector<HighlightingRule> highlightingRules;
QRegExp commentStartExpression, commentEndExpression;
QTextCharFormat singleLineCommentFormat, valueNameFormat, valueFormat, equalFormat, sectionFormat, spaceFormat, substFormat;
};
#endif // CONF_HIGHTLIGHTER_H

View File

@@ -0,0 +1,92 @@
#include "piqt_iodevice_edit.h"
#include "piqt_iodevice_edit_dialog.h"
#include "qvariantedit_custom.h"
#include <QLineEdit>
#include <QToolButton>
#include <QBoxLayout>
#include <piqt.h>
#include <piiodevice.h>
IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) {
dlg = new IODeviceEditDialog();
line = new QLineEdit();
btn = new QToolButton();
setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
layout()->setContentsMargins(0, 0, 0, 0);
layout()->addWidget(line);
layout()->addWidget(btn);
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonDlg_clicked()));
line->setReadOnly(true);
btn->setText(QString());
btn->setIcon(QIcon(":/icons/configure.png"));
btn->setToolTip(tr("Edit ..."));
}
IODeviceEdit::~IODeviceEdit() {
delete dlg;
}
QVariant IODeviceEdit::value() const {
return QVariant::fromValue(dev);
}
bool IODeviceEdit::isReadOnly() const {
return btn->isHidden();
}
void IODeviceEdit::setDevice(const QAD::IODevice & d) {
if (dev.toString() == d.toString()) return;
dev = d;
line->setText(dev.toString());
line->setCursorPosition(0);
emit valueChanged();
}
void IODeviceEdit::setValue(const QVariant & v) {
setDevice(v.value<QAD::IODevice>());
}
void IODeviceEdit::setReadOnly(bool yes) {
btn->setHidden(yes);
}
void IODeviceEdit::buttonDlg_clicked() {
QAD::IODevice d = dlg->getIODevice(dev);
if (!d.isValid()) return;
setDevice(d);
}
class Factory: public QVariantEditorFactoryBase {
public:
Factory() {}
virtual QWidget * createEditor() {return new IODeviceEdit();}
};
__IODeviceEditRegistrator__::__IODeviceEditRegistrator__() {
QVariantEditorFactories::registerEditorFactory(qMetaTypeId<QAD::IODevice>(), new Factory());
__QADTypesRegistrator__::instance()->toString_funcs.insert(qMetaTypeId<QAD::IODevice>(), &QAD_IODevice_toString);
}
void QAD_IODevice_toString(const QVariant & v, QString & r) {
PIVariantTypes::IODevice sd = Q2PIVariant(v).toIODevice();
// piCout << sd;
PIIODevice * rd = PIIODevice::createFromVariant(sd);
if (rd) {
PIString ps = rd->constructFullPath();
r = PI2QString(ps);
} else {
piCout << "error in " << sd;
}
}

View File

@@ -0,0 +1,71 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIQT_IODEVICE_EDIT_H
#define PIQT_IODEVICE_EDIT_H
#include <QWidget>
#include "qad_types.h"
class QLineEdit;
class QToolButton;
class IODeviceEditDialog;
class IODeviceEdit: public QWidget {
Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
public:
explicit IODeviceEdit(QWidget * parent = 0);
~IODeviceEdit();
QVariant value() const;
bool isReadOnly() const;
private:
void setDevice(const QAD::IODevice & d);
QLineEdit * line;
QToolButton * btn;
IODeviceEditDialog * dlg;
QAD::IODevice dev;
public slots:
void setValue(const QVariant & v);
void setReadOnly(bool yes);
private slots:
void buttonDlg_clicked();
signals:
void valueChanged();
};
class __IODeviceEditRegistrator__ {
public:
__IODeviceEditRegistrator__();
};
static __IODeviceEditRegistrator__ __iodeviceeditregistrator__;
void QAD_IODevice_toString(const QVariant & v, QString & r);
#endif // PIQT_IODEVICE_EDIT_H

View File

@@ -0,0 +1,112 @@
#include "ui_piqt_iodevice_edit_dialog.h"
#include "piqt_iodevice_edit_dialog.h"
#include "piqt.h"
#include "picodeinfo.h"
#include "piiodevice.h"
#include <QCheckBox>
IODeviceEditDialog::IODeviceEditDialog(QWidget * parent): QDialog(parent) {
ui = new Ui::IODeviceEditDialog();
ui->setupUi(this);
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
}
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
QCheckBox * cb = new QCheckBox();
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
cb->setProperty("__value", e.value);
ui->layoutOptions->addWidget(cb);
}
}
PIStringList pl = PIIODevice::availablePrefixes();
piForeachC (PIString & p, pl) {
ui->comboType->addItem(PI2QString(p));
}
}
IODeviceEditDialog::~IODeviceEditDialog() {
}
int IODeviceEditDialog::getOptions() const {
int ret = 0;
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue;
if (cb->isChecked())
ret |= cb->property("__value").toInt();
}
return ret;
}
void IODeviceEditDialog::setOptions(int o) {
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
if (!cb) continue;
int cbf = cb->property("__value").toInt();
cb->setChecked((o & cbf) == cbf);
}
}
void IODeviceEditDialog::on_comboType_currentIndexChanged(int index) {
PIString prefix = Q2PIString(ui->comboType->currentText());
PIVector<const PIObject * > rd(PICollection::groupElements("__PIIODevices__"));
piForeachC (PIObject * d, rd) {
const PIIODevice * dev = ((const PIIODevice * )d);
if (prefix != dev->fullPathPrefix())
continue;
ps = PI2QPropertyStorage(dev->constructVariant().get());
ui->widgetProperties->setStorage(&ps);
return;
}
}
QAD::IODevice IODeviceEditDialog::getIODevice(const QAD::IODevice & d) {
setValue(d);
if (QDialog::exec() != QDialog::Accepted)
return QAD::IODevice();
return value();
}
QAD::IODevice IODeviceEditDialog::value() const {
QAD::IODevice d;
ui->widgetProperties->applyProperties();
d.prefix = ui->comboType->currentText();
d.mode = ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt();
d.options = getOptions();
d.props = ps;
return d;
}
void IODeviceEditDialog::setValue(const QAD::IODevice & d) {
#if QT_VERSION >= 0x050000
ui->comboType->setCurrentText(d.prefix);
#else
for (int i = 0; i < ui->comboType->count(); ++i) {
if (ui->comboType->itemText(i) == d.prefix) {
ui->comboType->setCurrentIndex(i);
break;
}
}
#endif
for (int i = 0; i < ui->comboMode->count(); ++i)
if (ui->comboMode->itemData(i).toInt() == d.mode) {
ui->comboMode->setCurrentIndex(i);
break;
}
setOptions(d.options);
ps = d.props;
ui->widgetProperties->setStorage(&ps);
}

View File

@@ -0,0 +1,53 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIQT_IODEVICE_EDIT_DIALOG_H
#define PIQT_IODEVICE_EDIT_DIALOG_H
#include <QDialog>
#include "qad_types.h"
#include "propertystorage.h"
namespace Ui {
class IODeviceEditDialog;
}
class IODeviceEditDialog: public QDialog {
Q_OBJECT
public:
explicit IODeviceEditDialog(QWidget * parent = 0);
~IODeviceEditDialog();
QAD::IODevice getIODevice(const QAD::IODevice & d);
private:
QAD::IODevice value() const;
void setValue(const QAD::IODevice & d);
int getOptions() const;
void setOptions(int o);
PropertyStorage ps;
Ui::IODeviceEditDialog * ui;
private slots:
void on_comboType_currentIndexChanged(int index);
};
#endif // PIQT_IODEVICE_EDIT_DIALOG_H

View File

@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IODeviceEditDialog</class>
<widget class="QDialog" name="IODeviceEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>387</width>
<height>345</height>
</rect>
</property>
<property name="windowTitle">
<string>IODevice</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="labelAlignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</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>
<item row="1" column="0">
<widget class="QLabel" name="labelFilter_12">
<property name="text">
<string>Mode:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboMode"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelFilter_14">
<property name="text">
<string>Options:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QVBoxLayout" name="layoutOptions">
<property name="spacing">
<number>2</number>
</property>
</layout>
</item>
</layout>
</item>
<item>
<widget class="PropertyStorageEditor" name="widgetProperties" native="true"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</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>PropertyStorageEditor</class>
<extends>QWidget</extends>
<header>propertystorage_editor.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>IODeviceEditDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>227</x>
<y>326</y>
</hint>
<hint type="destinationlabel">
<x>144</x>
<y>302</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>IODeviceEditDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>325</x>
<y>315</y>
</hint>
<hint type="destinationlabel">
<x>304</x>
<y>306</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>recreateConnection()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,30 @@
#include "qpiconnection.h"
QPIConnection::QPIConnection(const QString & name): QObject(), PIConnection(Q2PIString(name)) {
setObjectName(name);
CONNECTU(this, dataReceivedEvent, this, piDataRec);
CONNECTU(this, packetReceivedEvent, this, piPacketRec);
}
bool QPIConnection::loadFromCMFile(const QString & file) {
QPIConfig f(file, QIODevice::ReadOnly);
if (!f.isOpen()) return false;
PIString cs = Q2PIString(QString::fromLatin1(f.getValue("config").toByteArray()));
configureFromString(&cs, Q2PIString(f.getValue("name").toString()));
return true;
}
void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) {
//piCout << from << PICoutManipulators::Hex << data;
QMetaObject::invokeMethod(this, "qDataReceivedEvent", Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
}
void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) {
QMetaObject::invokeMethod(this, "qPacketReceivedEvent", Qt::QueuedConnection,
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
}

View File

@@ -0,0 +1,50 @@
/*
PIQt Utils - Qt utilites for PIP
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QPICONNECTION_H
#define QPICONNECTION_H
#include <QObject>
#include <QMetaObject>
#include "piconnection.h"
#include "qpiconfig.h"
#include "piqt.h"
class QPIConnection: public QObject, public PIConnection {
Q_OBJECT
PIOBJECT_SUBCLASS(QPIConnection, PIConnection)
public:
QPIConnection(const QString & name = QString());
bool loadFromCMFile(const QString & file);
protected:
void propertyChanged(const PIString & ) {setObjectName(PI2QString(name()));}
EVENT_HANDLER2(void, piDataRec, const PIString &, from, const PIByteArray &, data);
EVENT_HANDLER2(void, piPacketRec, const PIString &, from, const PIByteArray &, data);
public slots:
signals:
void qDataReceivedEvent(QString from, QByteArray data);
void qPacketReceivedEvent(QString from, QByteArray data);
};
#endif // QPICONNECTION_H

View File

@@ -0,0 +1 @@
add_directories("piqt_")

View File

@@ -0,0 +1,14 @@
project(cd_pult)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "CD Pult")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_graphic;qad_application;qcd_utils;piqt_utils")
if (Qt5_FOUND)
import_version(${PROJ_NAME}5 ${PROJECT_NAME})
deploy_target(${PROJECT_NAME}5 DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${ROOT_DIR}/release)
endif()

View File

@@ -0,0 +1,312 @@
#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(tr("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::DragMove: {
QDragMoveEvent * de = (QDragMoveEvent*)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::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, tr("Rename area"), tr("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();
}

View File

@@ -0,0 +1,77 @@
#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();
void changedGlobal();
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:
void changedGlobal();
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

@@ -0,0 +1,354 @@
#include "cdgraphics.h"
//#include "ui_qcd_graphic.h"
#include "cdutils_core.h"
#include "cdutils_x.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_graphic.h"
#include "graphic.h"
#include "piqt.h"
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMainWindow>
#include <QDockWidget>
#include <QInputDialog>
using namespace CDUtils;
QStringList CDUtils::getList(const PIVector<PIDeque<int> > & x_list) {
QStringList ret;
piForeachC (PIDeque<int> & p, x_list)
ret << PI2QString(CDCore::pathToString(p));
return ret;
}
PIVector<PIDeque<int> > CDUtils::setList(const QStringList & l) {
PIVector<PIDeque<int> > 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(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]);
const PIVector<double> & 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->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;
piForeachC (PIDeque<int> & 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();
}

View File

@@ -0,0 +1,92 @@
#ifndef CDGRAPHICS_H
#define CDGRAPHICS_H
#include <QWidget>
#include <QDockWidget>
#include <QMenu>
#include "ui_cdgraphics.h"
#include "qcd_graphic.h"
#include <pistring.h>
namespace CDUtils {
class CDType;
class CDSection;
QStringList getList(const PIVector<PIDeque<int> > & x_list);
PIVector<PIDeque<int> > setList(const QStringList & l);
}
class QMainWindow;
class Graphic;
class GDockWidget: public QDockWidget {
Q_OBJECT
public:
GDockWidget(QString title = QString(), QMainWindow * p = 0);
void addX(const CDUtils::CDType & t);
void drawX(const PIMap<PIString, PIVector<double> > & data);
QByteArray save() const;
void load(QByteArray ba);
void changedGlobal();
CDGraphicWidget * graphic;
private:
bool eventFilter(QObject * o, QEvent * e);
void contextMenuEvent(QContextMenuEvent * e);
CDGraphicWidget * viewportGraphic(QObject * o) const;
QMenu * menu, * menu_x;
QList<QAction*> dactions;
QMainWindow * da;
PIVector<PIDeque<int> > x_list;
private slots:
void rename();
void removeX();
signals:
void removeRequest();
};
class CDGraphics : public QWidget, public Ui::CDGraphics
{
Q_OBJECT
public:
explicit CDGraphics(QWidget *parent = 0);
~CDGraphics();
void reset();
QByteArray save() const;
void load(QByteArray ba);
private:
GDockWidget * graphicDock(Graphic * o) const;
void addXToGraphic(const QString & xp, Graphic * g);
void addGraphic();
QList<GDockWidget * > docks;
QMainWindow * da;
public slots:
void receivedX();
void changedGlobal();
private slots:
void removeGraphic();
void on_buttonAdd_clicked();
void on_buttonClear_clicked();
void on_buttonRemoveAll_clicked();
signals:
};
#endif // CDGRAPHICS_H

View File

@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDGraphics</class>
<widget class="QWidget" name="CDGraphics">
<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/utils/qad_utils.qrc">
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonClear">
<property name="toolTip">
<string>Clear all</string>
</property>
<property name="icon">
<iconset resource="../../qad/utils/qad_utils.qrc">
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.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/utils/qad_utils.qrc">
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonConfigVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/layer-visible-off.png</normaloff>
<normalon>:/icons/layer-visible-on.png</normalon>:/icons/layer-visible-off.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonLegendVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonPause">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/graphic/qad_graphic.qrc">
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonBorderInputsVisible">
<property name="toolTip">
<string>Remove all</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</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/utils/qad_utils.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="../../qad/application/qad_application.qrc"/>
<include location="../../qad/graphic/qad_graphic.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,16 @@
<RCC>
<qresource prefix="/">
<file>../../../qad/icons/dialog-information.png</file>
<file>../../../qad/icons/dialog-cancel.png</file>
<file>../../../qad/icons/dialog-ok-apply.png</file>
<file>../../../qad/icons/document-revert.png</file>
<file>../../../qad/icons/view-refresh.png</file>
<file>../../../qad/icons/format-stroke-color.png</file>
<file>icons/db-export.png</file>
<file>icons/db-import.png</file>
<file>icons/timer.png</file>
<file>icons/flame.png</file>
<file>icons/Apps-accessories-calculator-icon.png</file>
<file>icons/accessories-text-editor.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,292 @@
#include "edockwidget.h"
#include "cdpultwindow.h"
#include "cdutils_core.h"
#include "cdutils_k.h"
#include "cdutils_x.h"
#include "cdutils_m.h"
#include "qcd_core.h"
#include "qcd_view.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "chunkstream.h"
#include "qvariantedit.h"
#include "piqt.h"
#include "piqt_highlighter.h"
#include "qcodeedit.h"
#include <QFileDialog>
#include <QScrollBar>
#include <QImageReader>
#include <QMessageBox>
using namespace CDUtils;
CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWindow() {
setupUi(this);
centralWidget()->hide();
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
CDCore::instance()->initPult();
def_config = codeConfig->text();
checkDefaultConfig->setChecked(true);
new ConfigHighlighter(codeConfig->document());
widgetK->setType(CDUtils::CDType::cdK);
widgetX->setType(CDUtils::CDType::cdX);
widgetC->setType(CDUtils::CDType::cdC);
widgetM->setType(CDUtils::CDType::cdM);
editFileK->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileX->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileC->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
editFileM->setValue(QVariant::fromValue(QAD::File("", "*.dat")));
log_icons[CDViewWidget::OKIcon] = QIcon(":/icons/dialog-ok-apply.png");
log_icons[CDViewWidget::FailIcon] = QIcon(":/icons/dialog-cancel.png");
log_icons[CDViewWidget::WaitIcon] = QIcon(":/icons/timer.png");
setRecentMenu(menuOpen_recent);
ribbon = new Ribbon(this);
session.setFile("session_cdpult.conf");
session.addEntry(this);
session.addEntry(ribbon->tabWidget());
session.load();
reset();
connect(widgetK, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
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(widgetM, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString)));
connect(widgetK->view, SIGNAL(changedGlobal()), widgetDirectK, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(changedGlobal()), widgetGraphics, SLOT(changedGlobal()));
connect(widgetX->view, SIGNAL(receivedX()), widgetGraphics, SLOT(receivedX()));
connect(widgetM->view, SIGNAL(messageReceived(QString,int,QString)), this, SLOT(messageReceived(QString,int,QString)));
QCDCore::instance()->bindWidget(widgetK->view);
QCDCore::instance()->setDirectKEnabled(true);
X.start();
if (windowState() == Qt::WindowMinimized)
setWindowState(Qt::WindowNoState);
}
CDPultWindow::~CDPultWindow() {
}
void CDPultWindow::loadFile(const QString & fp) {
load(fp);
}
void CDPultWindow::apply(bool sessions) {
CDCore::instance()->stop();
widgetK->setFile(editFileK->value().value<QAD::File>().file);
widgetX->setFile(editFileX->value().value<QAD::File>().file);
widgetC->setFile(editFileC->value().value<QAD::File>().file);
widgetM->setFile(editFileM->value().value<QAD::File>().file);
if (checkDefaultConfig->isChecked())
CDCore::instance()->initPult();
else
CDCore::instance()->init(Q2PIString(codeConfig->text()), true);
widgetX->view->startX();
if (sessions) {
widgetGraphics->load(session_gr);
widgetDirectK->load(session_dk);
if (!session_mw.isEmpty())
restoreState(session_mw);
X.lock();
PIVector<PIDeque<int> > x_list = X.enabledList();
X.unlock();
piForeachC (PIDeque<int> & p, x_list)
X.enable(X[p]);
((CDItemModel*)widgetX->view->model())->updateModel();
widgetX->view->expandAll();
}
dockCDKView->setVisible(checkHasK->isChecked());
dockCDXView->setVisible(checkHasX->isChecked());
dockCDCView->setVisible(checkHasC->isChecked());
dockCDMView->setVisible(checkHasM->isChecked());
QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection);
}
void CDPultWindow::closeEvent(QCloseEvent *e) {
EMainWindow::closeEvent(e);
if (!e->isAccepted())
return;
QApplication::closeAllWindows();
session.save();
session.setFile(QString());
}
void CDPultWindow::reset(bool full) {
setWindowTitle(QString("CD Pult"));
widgetK->reset();
setChanged(false);
}
bool CDPultWindow::load(const QString & path) {
qApp->setOverrideCursor(Qt::WaitCursor);
QPIConfig conf(path, QIODevice::ReadOnly);
QAD::File f = editFileK->value().value<QAD::File>();
checkSyncFiles->setChecked(false);
editFileK->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_k").toString(), f.filter)));
editFileX->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_x").toString(), f.filter)));
editFileC->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_c").toString(), f.filter)));
editFileM->setValue(QVariant::fromValue(QAD::File(conf.getValue("file_m").toString(), f.filter)));
checkSyncFiles->setChecked(conf.getValue("sync_files").toBool());
lineSessionName->setText(conf.getValue("session_name").toString());
last_icon = conf.getValue("icon_path").toString();
setAppIcon(conf.getValue("icon").toByteArray());
checkHasK->setChecked(conf.getValue("has_k").toBool());
checkHasX->setChecked(conf.getValue("has_x").toBool());
checkHasC->setChecked(conf.getValue("has_c").toBool());
checkHasM->setChecked(conf.getValue("has_m").toBool());
checkDefaultConfig->setChecked(conf.getValue("default_config").toBool());
codeConfig->setText(QByteArray2QString(conf.getValue("config").toByteArray()));
if (codeConfig->text().isEmpty())
codeConfig->setText(def_config);
session_gr = conf.getValue("session_gr").toByteArray();
session_dk = conf.getValue("session_dk").toByteArray();
session_mw = conf.getValue("session_mw").toByteArray();
setChanged(false);
file_name = path;
apply(true);
qApp->restoreOverrideCursor();
return true;
}
bool CDPultWindow::save(const QString & path) {
session_gr = widgetGraphics->save();
session_dk = widgetDirectK->save();
session_mw = saveState();
QPIConfig conf(path, QIODevice::ReadWrite);
conf.clear();
conf.setValue("file_k", editFileK->value().value<QAD::File>().file);
conf.setValue("file_x", editFileX->value().value<QAD::File>().file);
conf.setValue("file_c", editFileC->value().value<QAD::File>().file);
conf.setValue("file_m", editFileM->value().value<QAD::File>().file);
conf.setValue("sync_files", checkSyncFiles->isChecked());
conf.setValue("session_name", lineSessionName->text());
conf.setValue("icon_path", last_icon);
conf.setValue("icon", appIcon());
conf.setValue("has_k", checkHasK->isChecked());
conf.setValue("has_x", checkHasX->isChecked());
conf.setValue("has_c", checkHasC->isChecked());
conf.setValue("has_m", checkHasM->isChecked());
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;
//widgetK->setFile(path);
//widgetK->save();
}
void CDPultWindow::loadingSession(QPIConfig & conf) {
setRecentFiles(conf.getValue("recent files").toStringList());
}
void CDPultWindow::savingSession(QPIConfig & conf) {
conf.setValue("recent files", recentFiles());
}
QByteArray CDPultWindow::appIcon() const {
QByteArray ret;
if (icon.isNull()) return ret;
QBuffer buff(&ret);
buff.open(QIODevice::WriteOnly);
icon.save(&buff, "png");
//qDebug() << "s" << ret.size();
return ret;
}
void CDPultWindow::setAppIcon(QByteArray ba) {
if (ba.isEmpty()) {
icon = QImage();
setWindowIcon(QIcon());
return;
}
//qDebug() << "l" << ba.size();
icon = QImage::fromData(ba);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
//qDebug() << QApplication::windowIcon().availableSizes();
}
void CDPultWindow::addToLog(CDViewWidget::LogIcon icon, const QString & msg) {
QListWidgetItem * ni = new QListWidgetItem(log_icons[icon], "(" + QTime::currentTime().toString() + ") " + msg);
bool s = listLog->verticalScrollBar()->value() == listLog->verticalScrollBar()->maximum();
listLog->addItem(ni);
if (s) listLog->scrollToBottom();
}
void CDPultWindow::messageReceived(QString path, int type, QString msg) {
MessageType mt = (MessageType)type;
const CDType & t(M.root()[CDCore::stringToPath(Q2PIString(path))]);
if (t.cd_type() != CDType::cdM) return;
if (mt == MessageBox)
QMessageBox::information(this, windowTitle(), QString("[%1]\n%2").arg(PI2QString(t.name()), msg));
}
void CDPultWindow::on_editFileK_valueChanged(const QVariant & p) {
if (!checkSyncFiles->isChecked()) return;
QFileInfo fi(p.value<QAD::File>().file);
if (fi.path().isEmpty()) return;
QString n = fi.baseName();
QString xn(n), cn(n), mn(n);
if (n.contains("k")) {
xn.replace(n.indexOf("k"), 1, "x");
cn.replace(n.indexOf("k"), 1, "c");
mn.replace(n.indexOf("k"), 1, "m");
} else {
xn += "_x";
cn += "_c";
mn += "_m";
}
QString ext = fi.suffix(), dot, dir;
QString kfn(fi.filePath());
if (!ext.isEmpty()) {
kfn.chop(ext.size());
if (kfn.endsWith(".")) {
kfn.chop(1);
dot = ".";
}
}
if (!fi.path().isEmpty() && fi.path() != ".") {
dir = fi.path();
if (!dir.endsWith("/"))
dir += "/";
}
QAD::File f = editFileK->value().value<QAD::File>();
f.file = dir + xn + dot + ext; editFileX->setValue(QVariant::fromValue(f));
f.file = dir + cn + dot + ext; editFileC->setValue(QVariant::fromValue(f));
f.file = dir + mn + dot + ext; editFileM->setValue(QVariant::fromValue(f));
}
void CDPultWindow::on_buttonSessionApply_clicked() {
apply(false);
}
void CDPultWindow::on_lineSessionName_textChanged(const QString & t) {
setWindowTitle(QString("CD Pult - %1").arg(t));
}
void CDPultWindow::on_buttonIcon_clicked() {
QList<QByteArray> ifl = QImageReader::supportedImageFormats();
QStringList sfl; foreach (QByteArray s, ifl) sfl << ("*." + QString(s).toLower());
QString f = QFileDialog::getOpenFileName(this, tr("Select icon"), last_icon, tr("Images") + " (" + sfl.join(" ") + ")");
if (f.isEmpty()) return;
last_icon = f;
icon = QImage(last_icon);
setWindowIcon(QIcon(QPixmap::fromImage(icon)));
}

View File

@@ -0,0 +1,53 @@
#ifndef CDPULTWINDOW_H
#define CDPULTWINDOW_H
#include "emainwindow.h"
#include "ui_cdpultwindow.h"
#include "cdviewwidget.h"
#include "ribbon.h"
#include "piobject.h"
class CDPultWindow : public EMainWindow, public Ui::CDPultWindow
{
Q_OBJECT
Q_ENUMS(LogIcon)
public:
explicit CDPultWindow(QWidget *parent = 0);
~CDPultWindow();
void loadFile(const QString & fp);
void apply(bool sessions);
private:
void closeEvent(QCloseEvent *);
void reset(bool full = false);
bool load(const QString & path);
bool save(const QString & path);
QString loadFilter() {return "Pult session(*.conf)";}
QString saveFilter() {return loadFilter();}
void loadingSession(QPIConfig & conf);
void savingSession(QPIConfig & conf);
QByteArray appIcon() const;
void setAppIcon(QByteArray ba);
Ribbon * ribbon;
QMap<CDViewWidget::LogIcon, QIcon> log_icons;
QByteArray session_gr, session_dk, session_mw;
QString def_config, last_icon;
QImage icon;
private slots:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
void messageReceived(QString path, int type, QString msg);
void on_editFileK_valueChanged(const QVariant & p);
void on_buttonSessionApply_clicked();
void on_lineSessionName_textChanged(const QString & t);
void on_buttonIcon_clicked();
};
#endif // CDPULTWINDOW_H

View File

@@ -0,0 +1,612 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDPultWindow</class>
<widget class="EMainWindow" name="CDPultWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>593</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks</set>
</property>
<widget class="QWidget" name="central"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>798</width>
<height>24</height>
</rect>
</property>
<widget class="QMenu" name="menuMain">
<property name="title">
<string>Main</string>
</property>
<widget class="QMenu" name="menuOpen_recent">
<property name="title">
<string>Open recent</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open-recent.png</normaloff>:/icons/document-open-recent.png</iconset>
</property>
</widget>
<addaction name="actionOpen"/>
<addaction name="menuOpen_recent"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
</widget>
<addaction name="menuMain"/>
</widget>
<widget class="EDockWidget" name="dockCDKView">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-edit.png</normaloff>:/icons/document-edit.png</iconset>
</property>
<property name="windowTitle">
<string>K</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="CDViewWidget" name="widgetK" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockLog">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/dialog-information.png</normaloff>:/icons/dialog-information.png</iconset>
</property>
<property name="windowTitle">
<string>Log</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listLog">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDXView">
<property name="windowIcon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/qvariantedit.png</normaloff>:/icons/qvariantedit.png</iconset>
</property>
<property name="windowTitle">
<string>X</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="CDViewWidget" name="widgetX" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockSession">
<property name="windowIcon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
</property>
<property name="windowTitle">
<string>Session</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="buttonSessionApply">
<property name="text">
<string>Apply</string>
</property>
<property name="icon">
<iconset resource="../../qad/widgets/qad_widgets.qrc">
<normaloff>:/icons/dialog-ok-apply.png</normaloff>:/icons/dialog-ok-apply.png</iconset>
</property>
</widget>
</item>
<item>
<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>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="CLineEdit" name="lineSessionName"/>
</item>
<item>
<widget class="QPushButton" name="buttonIcon">
<property name="toolTip">
<string>Select icon...</string>
</property>
<property name="icon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/view-preview.png</normaloff>:/icons/view-preview.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>K file:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QVariantEdit" name="editFileK"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>X file:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QVariantEdit" name="editFileX"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>C file:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QVariantEdit" name="editFileC"/>
</item>
<item row="5" column="0" colspan="2">
<widget class="QCheckBox" name="checkSyncFiles">
<property name="text">
<string>Sync files</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkHasK">
<property name="text">
<string>K</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasX">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasC">
<property name="text">
<string>C</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkHasM">
<property name="text">
<string>M</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0" colspan="2">
<widget class="QCheckBox" name="checkDefaultConfig">
<property name="text">
<string>Default config</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>M file:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QVariantEdit" name="editFileM"/>
</item>
</layout>
</item>
<item>
<widget class="QCodeEdit" name="codeConfig">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>include = ip.conf
[connection]
device.cd = eth://udp:${ip.pult}:27002:${ip.app}:27001 #s
[]
</string>
</property>
<property name="editorFont">
<font>
<family>DejaVu Sans Mono</family>
<pointsize>9</pointsize>
</font>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockCDCView">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
</property>
<property name="windowTitle">
<string>C</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="CDViewWidget" name="widgetC" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="EDockWidget" name="dockGraphics">
<property name="windowIcon">
<iconset resource="../../qad/blockview/qad_blockview.qrc">
<normaloff>:/icons/format-stroke-color.png</normaloff>:/icons/format-stroke-color.png</iconset>
</property>
<property name="windowTitle">
<string>Graphics</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="CDGraphics" name="widgetGraphics" native="true"/>
</item>
</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>
<widget class="EDockWidget" name="dockCDMView">
<property name="windowIcon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/accessories-text-editor.png</normaloff>:/icons/accessories-text-editor.png</iconset>
</property>
<property name="windowTitle">
<string>M</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_8">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="CDViewWidget" name="widgetM" native="true"/>
</item>
</layout>
</widget>
</widget>
<action name="actionOpen">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
<property name="text">
<string>Open...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionSaveAs">
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save-as.png</normaloff>:/icons/document-save-as.png</iconset>
</property>
<property name="text">
<string>Save As...</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
</property>
</action>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="menuMain"/>
<addaction name="menuOpen_recent"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
<addaction name="separator"/>
</widget>
<customwidgets>
<customwidget>
<class>EMainWindow</class>
<extends>QMainWindow</extends>
<header>emainwindow.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CLineEdit</class>
<extends>QLineEdit</extends>
<header>clineedit.h</header>
</customwidget>
<customwidget>
<class>QCodeEdit</class>
<extends>QWidget</extends>
<header>qcodeedit.h</header>
</customwidget>
<customwidget>
<class>QVariantEdit</class>
<extends>QWidget</extends>
<header>qvariantedit.h</header>
</customwidget>
<customwidget>
<class>EDockWidget</class>
<extends>QDockWidget</extends>
<header>edockwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDViewWidget</class>
<extends>QWidget</extends>
<header>cdviewwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CDGraphics</class>
<extends>QWidget</extends>
<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"/>
<include location="../../qad/blockview/qad_blockview.qrc"/>
<include location="../../qad/widgets/qad_widgets.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections>
<connection>
<sender>actionSave</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionSaveAs</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>saveAsFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>actionOpen</sender>
<signal>triggered()</signal>
<receiver>CDPultWindow</receiver>
<slot>openFile()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileX</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>151</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileC</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>786</x>
<y>172</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkDefaultConfig</sender>
<signal>toggled(bool)</signal>
<receiver>codeConfig</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>786</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>581</x>
<y>304</y>
</hint>
</hints>
</connection>
<connection>
<sender>checkSyncFiles</sender>
<signal>toggled(bool)</signal>
<receiver>editFileM</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>767</x>
<y>205</y>
</hint>
<hint type="destinationlabel">
<x>767</x>
<y>187</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,78 @@
#include "cdviewwidget.h"
#include "cdutils_core.h"
#include "qcd_core.h"
#include "qcd_model.h"
#include "qcd_modedialog.h"
#include "qvariantedit.h"
#include <QFileDialog>
CDViewWidget::CDViewWidget(QWidget * parent) : QWidget(parent), Ui::CDViewWidget() {
qRegisterMetaType<CDViewWidget::LogIcon>("CDViewWidget::LogIcon");
setupUi(this);
connect(view, SIGNAL(sendSucceed()), this, SLOT(sended()));
connect(view, SIGNAL(receiveSucceed()), this, SLOT(received()));
connect(view, SIGNAL(sendFailed()), this, SLOT(sendFailed()));
connect(view, SIGNAL(receiveFailed()), this, SLOT(receiveFailed()));
}
CDViewWidget::~CDViewWidget() {
}
void CDViewWidget::reset() {
setFile("");
}
void CDViewWidget::setType(int t) {
view->setType((CDUtils::CDType::cdT)t);
tl_u = view->typeLetter().toUpper();
tl_l = view->typeLetter().toLower();
view->refresh();
}
void CDViewWidget::setFile(const QString & f) {
view->setFile(f);
view->load();
}
void CDViewWidget::on_buttonSend_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Sending " + tl_u + "...");
view->send();
}
void CDViewWidget::on_buttonReceive_clicked() {
if (view->inProgress()) {addToLog(WaitIcon, "processing..."); return;}
addToLog(WaitIcon, "Receiving " + tl_u + "...");
view->receive();
}
void CDViewWidget::on_buttonLoad_clicked() {
view->load();
}
void CDViewWidget::on_buttonSave_clicked() {
view->save();
}
void CDViewWidget::on_buttonParse_clicked() {
QString path = QFileDialog::getOpenFileName(this, "Select header file", "",
QString("%1 Description(%2_description.h);;Headers(*.h)").arg(tl_u, tl_l));
if (path.isEmpty()) return;
CDUtils::UpdateModeFlags mode = CDUtils::SaveByName;
if (!view->root()->isEmpty()) {
QCDModeDialog cdm;
if (cdm.exec() != QDialog::Accepted) return;
mode = cdm.mode();
}
view->buildFromHeader(path, mode);
}

View File

@@ -0,0 +1,41 @@
#ifndef CDVIEWWIDGET_H
#define CDVIEWWIDGET_H
#include <QWidget>
#include "ui_cdviewwidget.h"
class CDViewWidget : public QWidget, public Ui::CDViewWidget
{
Q_OBJECT
public:
explicit CDViewWidget(QWidget *parent = 0);
~CDViewWidget();
enum LogIcon {NoIcon, OKIcon, FailIcon, WaitIcon};
void reset();
void setType(int t);
void setFile(const QString & f);
private:
QString tl_u, tl_l;
private slots:
void sended() {addToLog(OKIcon, tl_u + " " + tr("sended succesfull"));}
void received() {addToLog(OKIcon, tl_u + " " + tr("received succesfull"));}
void sendFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT sended"));}
void receiveFailed() {addToLog(FailIcon, tl_u + " " + tr("NOT received"));}
void on_buttonSend_clicked();
void on_buttonReceive_clicked();
void on_buttonLoad_clicked();
void on_buttonSave_clicked();
void on_buttonParse_clicked();
//void on_buttonCalculate_clicked();
signals:
void addToLog(CDViewWidget::LogIcon icon, const QString & msg);
};
#endif // CDVIEWWIDGET_H

View File

@@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CDViewWidget</class>
<widget class="QWidget" name="CDViewWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>689</width>
<height>459</height>
</rect>
</property>
<property name="windowTitle">
<string>CD Pult</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="buttonSend">
<property name="text">
<string>Send</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/flame.png</normaloff>:/icons/flame.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonReceive">
<property name="text">
<string>Receive</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/document-revert.png</normaloff>:/icons/document-revert.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonLoad">
<property name="text">
<string>Load</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonSave">
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset resource="../../qad/application/qad_application.qrc">
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonParse">
<property name="text">
<string>Update description ...</string>
</property>
<property name="icon">
<iconset resource="cdpult.qrc">
<normaloff>:/icons/view-refresh.png</normaloff>:/icons/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="CDView" name="view">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>CDView</class>
<extends>QTreeView</extends>
<header>qcd_view.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../qad/application/qad_application.qrc"/>
<include location="cdpult.qrc"/>
</resources>
<connections/>
</ui>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

373
piqt/utils/cd_pult/main.cpp Normal file
View File

@@ -0,0 +1,373 @@
#include <QApplication>
#include "cdpultwindow.h"
template <typename Key, typename T>
class PIHash {
//template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIHash<Key1, T1> & v);
//template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIHash<Key1, T1> & v);
public:
PIHash() {;}
PIHash(const PIHash<Key, T> & other) {*this = other;}
virtual ~PIHash() {;}
PIHash<Key, T> & operator =(const PIHash<Key, T> & other) {
if (this == &other) return *this;
clear();
pih_content = other.pih_content;
return *this;
}
typedef T mapped_type;
typedef Key key_type;
typedef PIPair<Key, T> value_type;
/*
class iterator {
friend class PIHash<Key, T>;
private:
iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {++pos;}
void operator ++(int) {++pos;}
void operator --() {--pos;}
void operator --(int) {--pos;}
bool operator ==(const iterator & it) const {return (pos == it.pos);}
bool operator !=(const iterator & it) const {return (pos != it.pos);}
};
class reverse_iterator {
friend class PIHash<Key, T>;
private:
reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
reverse_iterator(): parent(0), pos(0) {}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->_key(pos);}
T & value() const {return const_cast<PIHash<Key, T> * >(parent)->_value(pos);}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const reverse_iterator & it) const {return (pos != it.pos);}
};
*/
class const_iterator {
friend class PIHash<Key, T>;
private:
const_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p), bpos(0) {
if (pos == 0) {
pos = -1;
nextPos();
}
}
void nextPos() {
while (++pos < parent->pih_content.size_s()) {
if (!parent->pih_content[pos].isEmpty())
return;
}
}
const PIHash<Key, T> * parent;
ssize_t pos, bpos;
public:
const_iterator(): parent(0), pos(0) {}
//const value_type operator *() const {return parent->_pair(pos);}
//const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
const Key & key() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].key;}
const T & value() const {return const_cast<PIHash<Key, T> * >(parent)->pih_content[pos][bpos].value;}
void operator ++() {
if (pos < parent->pih_content.size_s()) {
if (bpos >= parent->pih_content[pos].size_s() - 1) {
bpos = 0;
nextPos();
} else
++bpos;
} else {
bpos = 0;
++pos;
}
printf(" ++: %d %d\n", pos, bpos);
}
//void operator ++(int) {++pos;}
void operator --() {
--pos;
}
//void operator --(int) {--pos;}
bool operator ==(const const_iterator & it) const {return (pos == it.pos && bpos == it.bpos);}
bool operator !=(const const_iterator & it) const {return !(*this == it);}
mutable value_type cval;
};
/*
class const_reverse_iterator {
friend class PIHash<Key, T>;
private:
const_reverse_iterator(const PIHash<Key, T> * v, ssize_t p): parent(v), pos(p) {}
const PIHash<Key, T> * parent;
ssize_t pos;
public:
const_reverse_iterator(): parent(0), pos(0) {}
const value_type operator *() const {return parent->_pair(pos);}
const value_type* operator ->() const {cval = parent->_pair(pos); return &cval;}
void operator ++() {--pos;}
void operator ++(int) {--pos;}
void operator --() {++pos;}
void operator --(int) {++pos;}
bool operator ==(const const_reverse_iterator & it) const {return (pos == it.pos);}
bool operator !=(const const_reverse_iterator & it) const {return (pos != it.pos);}
mutable value_type cval;
};
*/
//iterator begin() {return iterator(this, 0);}
//iterator end() {return iterator(this, size());}
const_iterator begin() const {return const_iterator(this, 0);}
const_iterator end() const {return const_iterator(this, size());}
const_iterator constBegin() const {return const_iterator(this, 0);}
const_iterator constEnd() const {return const_iterator(this, size());}
//reverse_iterator rbegin() {return reverse_iterator(this, size() - 1);}
//reverse_iterator rend() {return reverse_iterator(this, -1);}
//const_reverse_iterator rbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator rend() const {return const_reverse_iterator(this, -1);}
//const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);}
//const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);}
size_t size() const {return pih_content.size();}
int size_s() const {return pih_content.size_s();}
size_t length() const {return pih_content.size();}
size_t capacity() const {return pih_content.size();}
bool isEmpty() const {return (pih_content.size() == 0);}
T & operator [](const Key & key) {
if (pih_content.isEmpty()) _rehash(1);
uint k = piHash(key);
int i = _index(k);
if (i < pih_content.size_s()) {
PIVector<HashEntry> & hv(pih_content[i]);
if (hv.size_s() == 1) {
if (hv[0].key == k)
return hv[0].value;
}
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
}
if (pih_content[i].size_s() >= 4)
_rehash(pih_content.size_s() * 2);
i = _index(k);
pih_content[i] << HashEntry(k);
return pih_content[i].back().value;
}
const T operator [](const Key & key) const {return value(key);}
T & at(const Key & key) {return (*this)[key];}
const T at(const Key & key) const {return (*this)[key];}
PIHash<Key, T> & operator <<(const PIHash<Key, T> & other) {
if (other.isEmpty()) return *this;
for (int i = 0; i < other.pih_content.size_s(); ++i)
for (int j = 0; j < other.pih_content[i].size_s(); ++j)
insert(other.pih_content[i][j].key, other.pih_content[i][j].value);
return *this;
}
bool operator ==(const PIHash<Key, T> & t) const {return (pih_content == t.pih_content);}
bool operator !=(const PIHash<Key, T> & t) const {return (pih_content != t.pih_content);}
bool contains(const Key & key) const {
bool f(false);
_find(key, f);
return f;
}
PIHash<Key, T> & reserve(size_t new_size) {_rehash(new_size); return *this;}
PIHash<Key, T> & remove(const Key & key) {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return *this;
PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k) {
hv.remove(j);
--j;
}
return *this;
}
PIHash<Key, T> & erase(const Key & key) {return remove(key);}
PIHash<Key, T> & clear() {pih_content.clear(); return *this;}
void swap(PIHash<Key, T> & other) {
pih_content.swap(other.pih_content);
}
PIHash<Key, T> & insert(const Key & key, const T & value) {
(*this)[key] = value;
return *this;
}
const T value(const Key & key, const T & default_ = T()) const {
uint k = piHash(key);
int i = _index(k);
if (i >= pih_content.size_s()) return default_;
const PIVector<HashEntry> & hv(pih_content[i]);
for (int j = 0; j < hv.size_s(); ++j)
if (hv[j].key == k)
return hv[j].value;
return default_;
}
PIVector<T> values() const {
PIVector<T> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].value;
return ret;
}
/*Key key(const T & value_, const Key & default_ = Key()) const {
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
if (pih_content[i][j].value == value_)
return pih_content[i][j].key;
return default_;
}
PIVector<Key> keys() const {
PIVector<Key> ret;
for (int i = 0; i < pih_content.size_s(); ++i)
for (int j = 0; j < pih_content[i].size_s(); ++j)
ret << pih_content[i][j].key;
return ret;
}*/
/*void dump() {
piCout << "PIHash" << size() << "entries" << PICoutManipulators::NewLine << "content:";
for (size_t i = 0; i < pih_content.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pih_content[i];
piCout << "index:";
for (size_t i = 0; i < pim_index.size(); ++i)
piCout << PICoutManipulators::Tab << i << ":" << pim_index[i].key << "->" << pim_index[i].index;
}*/
protected:
struct HashEntry {
HashEntry(uint k = 0, const T & v = T()): key(k), value(v) {;}
uint key;
T value;
bool operator ==(const HashEntry & s) const {return key == s.key;}
bool operator !=(const HashEntry & s) const {return key != s.key;}
bool operator <(const HashEntry & s) const {return key < s.key;}
bool operator >(const HashEntry & s) const {return key > s.key;}
};
/*template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIDeque<typename PIHash<Key1, T1>::HashEntry> & v);
const value_type _pair(ssize_t index) const {
if (index < 0 || index >= pim_index.size_s())
return value_type();
//piCout << "_pair" << index << pim_index[index].index;
return value_type(pim_index[index].key, pih_content[pim_index[index].index]);
}
Key & _key(ssize_t index) {return pim_index[index].key;}
T & _value(ssize_t index) {return pih_content[pim_index[index].index];}*/
inline size_t asize(size_t s) {
if (s == 0) return 0;
if (pih_content.size() + pih_content.size() >= s && pih_content.size() < s)
return pih_content.size() + pih_content.size();
ssize_t t = 0, s_ = s - 1;
while (s_ >> t) ++t;
return (1 << t);
}
int _index(const uint & k) const {
return k % pih_content.size_s();
}
void _rehash(int ns) {
ns = asize(ns);
if (pih_content.size_s() == ns) return;
PIVector<PIVector<HashEntry> > nhc;
nhc.resize(ns);
for (int i = 0; i < pih_content.size_s(); ++i) {
for (int j = 0; j < pih_content[i].size_s(); ++j) {
HashEntry & e(pih_content[i][j]);
int ni = e.key % ns;
nhc[ni] << e;
}
}
pih_content.swap(nhc);
}
PIVector<PIVector<HashEntry> > pih_content;
};
uint qHash(const PIString & v, uint seed = 0) {return piHash(v);}
#include "logview.h"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
//################################
/*QHash<PIString, PIString> h2;
QMap<PIString, PIString> m2;
PIString prefix = "1234567890";
PITimeMeasurer tm;
double el = 0.;
tm.reset();
for (int i=0; i<10000; ++i) {
h2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
m2[prefix + PIString::fromNumber(i)+"1234567890"] = PIString::fromNumber(randomi());
}
el = tm.elapsed_m(); piCout << el;
piCout << "*********";
PIString _s;
tm.reset();
for (int i=0; i<10000; ++i) {
_s = h2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el << h2.capacity();
tm.reset();
for (int i=0; i<10000; ++i) {
_s = m2.value(prefix + PIString::fromNumber(i)+"1234567890");
}
el = tm.elapsed_m(); piCout << el;
return 0;*/
//################################
//1245hghgfhfdgshrgnhdsgfhjshdszdgsdgnjedghrbnlcvleabjmbassfdggfhbnsjkgnfdvfdsdfojbwasv213443gr2t4sfth
/*LogView lw;
lw.setLogFont(QFont("dejavu sans mono", 9));
lw.registerCategory("Warning", "Warning", QImage(":/icons/flame.png"), Qt::darkYellow);
lw.registerCategory("Error", "Error", QImage(":/icons/dialog-cancel.png"), Qt::darkRed, true);
//lw.setLinesLimit(12);
lw.show();
piForTimes(100)
lw.addText(QString("row %1").arg(_i100));
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/scene_tree.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/view_editor.h");
lw.addText("-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/material_map_editor.h\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/materials_editor\n"
"-- Up-to-date: C:/sdk/MinGW/x32/i686-w64-mingw32/include/qglengine/object_editor.h");
lw.addText("[Warning] sdfkjhdfgj");
lw.addText("[Error] gbflknwed");
QLineEdit * le = new QLineEdit();
QObject::connect(le, &QLineEdit::returnPressed, [&](){lw.addText(le->text());});
le->show();
return a.exec();*/
CDPultWindow w;
w.show();
if (a.arguments().size() > 1)
w.loadFile(a.arguments()[1]);
return a.exec();
}

View File

@@ -0,0 +1,10 @@
project(piconnedit)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "PIConnection GUI editor")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_blockview;piqt_utils")

View File

@@ -0,0 +1,4 @@
<RCC>
<qresource prefix="/">
</qresource>
</RCC>

View File

@@ -0,0 +1,34 @@
#include <QApplication>
#include "piqt_connection_edit.h"
#include <QFileDialog>
#include <qpiconfig.h>
#include <evalspinbox.h>
#include <piintrospection_server.h>
int main(int argc, char * argv[]) {
PIINTROSPECTION_START
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
ConnectionEdit w;
if (a.arguments().size() > 1) {
QPIConfig cfg(a.arguments()[1]);
QByteArray model = cfg.getValue("connectionmodel").toByteArray();
if (!model.isEmpty()) w.setModel(model);
}
if (w.exec() == QDialog::Accepted) {
QString c = QFileDialog::getSaveFileName(&w, "Save config to file", a.applicationDirPath(), "*.conf");
if (!c.isEmpty()) {
QFile f(c);
if (f.open(QIODevice::WriteOnly)) {
QTextStream ts(&f);
ts << w.configuration();
ts << "connectionmodel = " << QByteArray2QString(w.model()) << "\n";
f.close();
}
}
}
return a.exec();
}

View File

@@ -0,0 +1,10 @@
project(pidumper)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "PIConnection GUI editor")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;piqt_utils")

View File

@@ -0,0 +1,146 @@
#include "pidumper.h"
#include "pifile.h"
#include "pitime.h"
#include "pidir.h"
//#include "ccm.h"
#include <QClipboard>
#ifdef CC_GCC
# include <unistd.h>
#endif
PIDumper::PIDumper(QWidget * parent): QMainWindow(parent) {
setupUi(this);
#if QT_VERSION >= 0x050000
treeDump->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#else
treeDump->header()->setResizeMode(QHeaderView::ResizeToContents);
#endif
}
void PIDumper::changeEvent(QEvent * e) {
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void PIDumper::buildDump() {
treeDump->clear();
if (!dump.contains('{')) return;
PIString app = dump.takeWord();
if (app != "application") return;
dump.takeLine();
QTreeWidgetItem * ti;
while (!dump.isEmpty()) {
PIString line = dump.takeLine();
if (line.contains('{')) {
ti = new QTreeWidgetItem();
dump.prepend(line + "\n");
buildDumpSection(ti, dump);
treeDump->addTopLevelItem(ti);
continue;
}
int colon = line.find(":");
if (colon < 0) continue;
PIString name = line.takeLeft(colon).trim();
PIString value = line.cutLeft(1).trim();
if (value.startsWith("\"")) value.cutLeft(1);
if (value.endsWith("\"")) value.cutRight(1);
ti = new QTreeWidgetItem(QStringList() << PI2QString(name) << PI2QString(value));
treeDump->addTopLevelItem(ti);
}
on_checkDumpHideService_toggled(checkDumpHideService->isChecked());
}
void PIDumper::buildDumpSection(QTreeWidgetItem * pi, PIString & str) {
PIString section = str.takeLeft(str.find("{")).trim();
PIString value;
if (section.contains('(')) {
value = section;
section = value.takeLeft(value.find('('));
value = value.takeRange("(", ")");
}
pi->setText(0, piqt(section));
pi->setText(1, piqt(value));
//if (section == "PIObjects")
PIString range = str.takeRange("{", "}");
QTreeWidgetItem * ti;
PIString fs;
if (section == "PIObjects" || section == "properties") fs = ":";
if (section == "methodsEH") fs = " ";
if (section == "connections") fs = "->";
while (!range.isEmpty()) {
PIString line = range.takeLine().trim();
if (line.contains('{')) {
ti = new QTreeWidgetItem(pi);
range.prepend(line + "\n");
buildDumpSection(ti, range);
//treeDump->addTopLevelItem(ti);
continue;
}
if (line.left(line.find(":")).trim() == "count") {
pi->setText(1, "[" + PI2QString(line.right(line.length() - line.find(":") - 1).trim()) + "]");
continue;
}
int colon = line.find(fs);
if (colon < 0) continue;
PIString name = line.takeLeft(colon).trim();
PIString value = line.cutLeft(fs.size_s()).trim();
if (value.startsWith("\"")) value.cutLeft(1);
if (value.endsWith("\"")) value.cutRight(1);
if (name.endsWith(":")) name.cutRight(1);
if (name.isEmpty() && value.isEmpty()) continue;
ti = new QTreeWidgetItem(pi, QStringList() << PI2QString(name) << PI2QString(value));
//treeDump->addTopLevelItem(ti);
}
}
void PIDumper::on_buttonDumpMake_clicked() {
if (radioDumpCurrent->isChecked()) {
PICout::setBufferActive(true, true);
dumpApplication();
dump = PICout::buffer();
PICout::setBufferActive(false);
} else {
int pid = lineDumpCustom->text().toInt();
if (pid == 0) return;
if (system(QString("kill -USR1 %1").arg(pid).toLatin1().constData()) < 0) return;
PIString dp = PIDir::home().path() + "/_PIP_DUMP_" + PIString::fromNumber(pid);
PITimeMeasurer tm;
while (tm.elapsed_s() < 5. && !PIFile::isExists(dp)) {
piMSleep(10);
}
//piSleep(2.);
PIFile f(dp, PIIODevice::ReadOnly);
if (!f.isOpened()) return;
dump = PIString(f.readAll());
f.remove();
}
buildDump();
}
void PIDumper::on_buttonDumpClipboard_clicked() {
dump = Q2PIString(QApplication::clipboard()->text());
buildDump();
}
void PIDumper::on_checkDumpHideService_toggled(bool on) {
QList<QTreeWidgetItem * > il = treeDump->findItems("", Qt::MatchContains | Qt::MatchRecursive);
foreach (QTreeWidgetItem * i, il) {
if (on) {
if (i->text(0).startsWith("class"))
i->setHidden(i->text(1).contains("__S__"));
} else
i->setHidden(false);
}
}

View File

@@ -0,0 +1,36 @@
#ifndef PIDUMPER_H
#define PIDUMPER_H
#include "ui_pidumper.h"
#include <QImage>
#include <QTime>
#include <QDesktopWidget>
#include <qmath.h>
#include <QDebug>
#include "piqt.h"
#include "piconnection.h"
class PIDumper: public QMainWindow, private Ui::PIDumper
{
Q_OBJECT
public:
PIDumper(QWidget * parent = 0);
protected:
void changeEvent(QEvent * e);
void buildDump();
void buildDumpSection(QTreeWidgetItem * pi, PIString & str);
PIString dump;
private slots:
void on_buttonDumpMake_clicked();
void on_buttonDumpClipboard_clicked();
void on_checkDumpHideService_toggled(bool on);
public slots:
};
#endif // PIDUMPER_H

View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PIDumper</class>
<widget class="QMainWindow" name="PIDumper">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1134</width>
<height>854</height>
</rect>
</property>
<property name="windowTitle">
<string>PIP dump viewer</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkDumpHideService">
<property name="text">
<string>Hide service objects</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QPushButton" name="buttonDumpMake">
<property name="text">
<string>Make PIP dump</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonDumpClipboard">
<property name="text">
<string>Take PIP dump from clipboard</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Process</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QRadioButton" name="radioDumpCurrent">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Current</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radioDumpCustom">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Custom:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDumpCustom">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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>
</item>
<item>
<widget class="QTreeWidget" name="treeDump">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<attribute name="headerMinimumSectionSize">
<number>20</number>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<column>
<property name="text">
<string notr="true">2</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>radioDumpCustom</sender>
<signal>toggled(bool)</signal>
<receiver>lineDumpCustom</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>439</x>
<y>91</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>90</y>
</hint>
</hints>
</connection>
<connection>
<sender>radioDumpCustom</sender>
<signal>clicked()</signal>
<receiver>lineDumpCustom</receiver>
<slot>setFocus()</slot>
<hints>
<hint type="sourcelabel">
<x>453</x>
<y>91</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>86</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>configChanged()</slot>
<slot>updateMap()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,13 @@
#include <QApplication>
#include "pidumper.h"
int main(int argc, char * argv[]) {
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
PIDumper w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,13 @@
project(piintrospector)
if(APPLE)
set(APP_ICON "")
elseif(WIN32)
set(APP_ICON "")
else()
set(APP_ICON "")
endif()
set(APP_INFO "PIConnection GUI editor")
include(PIPMacros)
set(PII_ROOT "${ROOT_DIR}/pip/libs/main/introspection")
pip_code_model(CCM "${PII_ROOT}/piintrospection_server_p.h" "${PII_ROOT}/piintrospection_threads_p.h" OPTIONS "-DPIP_EXPORT" "-Es")
piqt_application(${PROJECT_NAME} "Gui;Widgets" "qad_utils;qad_widgets;qad_application;piqt_utils" ${CCM})

View File

@@ -0,0 +1,264 @@
#include "containers_view.h"
#include <QTreeView>
#include <QPainter>
#include <QStyle>
#include <QSortFilterProxyModel>
enum ColumnContainers {
ccType,
ccItemSize,
ccCount,
ccBytesAllocated,
ccBytesUsed,
ccColumnCount,
};
ContainersModel::ContainersModel() {
mode_changes = false;
ls_column = 0;
ls_order = Qt::AscendingOrder;
all.resize(columnCount(), 0L);
prev_all.resize(all.size(), 0L);
}
void ContainersModel::update(const PIVector<PIIntrospectionContainers::TypeInfo> & t) {
prev_data.clear();
all.fill(0U);
piForeachC (PIIntrospectionContainers::TypeInfo & i, cur_data) {
prev_data[i.id] = i;
}
piForeachC (PIIntrospectionContainers::TypeInfo & i, t) {
all[ccCount] += i.count;
all[ccBytesAllocated] += i.allocated * i.item_size;
all[ccBytesUsed] += i.used * i.item_size;
}
int pts = cur_data.size_s();
cur_data = t;
if (t.size_s() > pts) {
beginInsertRows(QModelIndex(), pts, t.size_s() - 1);
endInsertRows();
}
if (t.size_s() < pts) {
beginRemoveRows(QModelIndex(), t.size_s(), pts - 1);
endRemoveRows();
}
sort(ls_column, ls_order);
emit headerDataChanged(Qt::Horizontal, ccCount, columnCount());
}
void ContainersModel::clear() {
beginRemoveRows(QModelIndex(), 0, cur_data.size_s() - 1);
cur_data.clear();
prev_data.clear();
all.fill(0L);
endRemoveRows();
}
int ContainersModel::rowCount(const QModelIndex & parent) const {
return cur_data.size_s();
}
int ContainersModel::columnCount(const QModelIndex & parent) const {
return ccColumnCount;
}
QModelIndex ContainersModel::index(int row, int column, const QModelIndex & parent) const {
if (row >= cur_data.size_s() || row >= cur_data.size_s()) return QModelIndex();
return createIndex(row, column, cur_data[row].id);
}
bool ContainersModel::hasChildren(const QModelIndex & parent) const {
if (!parent.isValid()) return true;
return false;
}
QVariant ContainersModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant();
PIVector<llong> ret = all;
if (mode_changes) {
for (int i = 0; i < all.size_s(); ++i)
ret[i] -= prev_all[i];
}
switch (section) {
case ccType : return tr("Type");
case ccItemSize : return tr("Item size");
case ccCount : return tr("Count (%1)").arg(ret[ccCount]);
case ccBytesAllocated: return tr("Allocated (%1)").arg(PI2QString(PIString::readableSize(ret[ccBytesAllocated])));
case ccBytesUsed : return tr("Used (%1)").arg(PI2QString(PIString::readableSize(ret[ccBytesUsed])));
default: break;
}
return QVariant();
}
QVariant ContainersModel::data(const QModelIndex & index, int role) const {
if (role != Qt::DisplayRole && role != Qt::UserRole && role != (Qt::UserRole+1)) return QVariant();
uint id = uint(index.internalId());
const PIIntrospectionContainers::TypeInfo & t(cur_data[index.row()]);
llong v = 0L;
if (role == Qt::DisplayRole || role == Qt::UserRole) {
switch (index.column()) {
case ccType: return PI2QString(t.name);
case ccItemSize:
if (role == Qt::UserRole) return t.item_size;
return PI2QString(PIString::readableSize(t.item_size));
default: break;
}
if (mode_changes) {
switch (index.column()) {
case ccCount: return int(t.count) - int(prev_data.value(id).count);
case ccBytesAllocated:
v = t.allocated;
v -= prev_data.value(id).allocated;
v *= t.item_size;
if (role == Qt::UserRole) return piAbs(v);
return PI2QString(PIString::readableSize(v));
case ccBytesUsed:
v = t.used;
v -= prev_data.value(id).used;
v *= t.item_size;
if (role == Qt::UserRole) return piAbs(v);
return PI2QString(PIString::readableSize(v));
}
} else {
switch (index.column()) {
case ccCount: return t.count;
case ccBytesAllocated:
v = t.allocated * t.item_size;
if (role == Qt::UserRole) return v;
return PI2QString(PIString::readableSize(v));
case ccBytesUsed:
v = t.used * t.item_size;
if (role == Qt::UserRole) return v;
return PI2QString(PIString::readableSize(v));
}
}
}
if (role == (Qt::UserRole+1) && (index.column() == ccCount)) {
return t.count;
}
return QVariant();
}
Qt::ItemFlags ContainersModel::flags(const QModelIndex & index) const {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
//bool cmp(const PIIntrospectionContainers::TypeInfo & a, const PIIntrospectionContainers::TypeInfo & b);
int cmp_func_name_a(const PIIntrospectionContainers::TypeInfo * t0, const PIIntrospectionContainers::TypeInfo * t1) {
return QString::localeAwareCompare(PI2QString(t0->name), PI2QString(t1->name));
}
int cmp_func_name_d(const PIIntrospectionContainers::TypeInfo * t0, const PIIntrospectionContainers::TypeInfo * t1) {
return -cmp_func_name_a(t0, t1);
}
#define CMP_FUNC(field) \
int cmp_func_##field##_a(const PIIntrospectionContainers::TypeInfo * t0, const PIIntrospectionContainers::TypeInfo * t1) { \
return (t0->field) <= (t1->field) ? -1 : ((t0->field) == (t1->field) ? 0 : 1); \
} \
int cmp_func_##field##_d(const PIIntrospectionContainers::TypeInfo * t0, const PIIntrospectionContainers::TypeInfo * t1) { \
return -cmp_func_##field##_a(t0, t1); \
}
CMP_FUNC(item_size)
CMP_FUNC(count)
CMP_FUNC(allocated)
CMP_FUNC(used)
#undef CMP_FUNC
void ContainersModel::sort(int column, Qt::SortOrder order) {
ls_column = column;
ls_order = order;
if (cur_data.isEmpty()) return;
PIVector<PIIntrospectionContainers::TypeInfo>::CompareFunc cf = 0;
switch (column) {
case ccType : cf = order == Qt::AscendingOrder ? cmp_func_name_a : cmp_func_name_d; break;
case ccItemSize : cf = order == Qt::AscendingOrder ? cmp_func_item_size_a : cmp_func_item_size_d; break;
case ccCount : cf = order == Qt::AscendingOrder ? cmp_func_count_a : cmp_func_count_d; break;
case ccBytesAllocated: cf = order == Qt::AscendingOrder ? cmp_func_allocated_a : cmp_func_allocated_d; break;
case ccBytesUsed : cf = order == Qt::AscendingOrder ? cmp_func_used_a : cmp_func_used_d; break;
default : break;
}
if (cf)
cur_data.sort(cf);
//qDebug() << "sort" << column << order;
dataChanged(index(0, 0), index(cur_data.size_s() - 1, columnCount()));
}
void ContainersModel::setChangesMode(bool yes) {
mode_changes = yes;
if (cur_data.isEmpty()) return;
sort(ls_column, ls_order);
emit headerDataChanged(Qt::Horizontal, ccCount, columnCount());
}
void ContainersDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QStyledItemDelegate::paint(painter, option, index);
if (model->index(index.row(), ccCount).data(Qt::UserRole+1).toInt() == 0) {
QColor col;
if (option.state == QStyle::State_Enabled ||
option.state == QStyle::State_HasFocus)
col = option.palette.color(QPalette::Active, QPalette::WindowText);
else
col = option.palette.color(QPalette::Disabled, QPalette::WindowText);
col.setAlphaF(0.5);
int y = option.rect.center().y() + (option.fontMetrics.height() / 2.5) - option.fontMetrics.strikeOutPos();
painter->setPen(QPen(col, lineThickness()));
painter->drawLine(QPoint(option.rect.left(), y), QPoint(option.rect.right(), y));
}
}
ContainersView::ContainersView(QWidget * parent): QWidget(parent) {
setupUi(this);
model = new ContainersModel();
connect(radioChanges, SIGNAL(toggled(bool)), model, SLOT(setChangesMode(bool)));
QSortFilterProxyModel * proxy = new QSortFilterProxyModel();
proxy->setSourceModel(model);
proxy->setSortRole(Qt::UserRole);
proxy->setDynamicSortFilter(false);
treeContainers->setModel(model);
treeContainers->setItemDelegate(new ContainersDelegate(model));
}
ContainersView::~ContainersView() {
}
void ContainersView::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void ContainersView::showContainers(const PIVector<PIIntrospectionContainers::TypeInfo> & t) {
model->update(t);
}
void ContainersView::clear() {
model->clear();
}

View File

@@ -0,0 +1,76 @@
#ifndef CONTAINERS_VIEW_H
#define CONTAINERS_VIEW_H
#include "ui_containers_view.h"
#include <QDebug>
#include <QWidget>
#include <QAbstractItemModel>
#include <QStyledItemDelegate>
#include "piqt.h"
#include "piintrospection_containers_p.h"
class ContainersModel: public QAbstractItemModel {
Q_OBJECT
public:
ContainersModel();
void update(const PIVector<PIIntrospectionContainers::TypeInfo> & t);
void clear();
int rowCount(const QModelIndex & parent = QModelIndex()) const;
int columnCount(const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex & child) const {return QModelIndex();}
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
bool hasChildren(const QModelIndex & parent = QModelIndex()) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex & index, int role) const;
Qt::ItemFlags flags(const QModelIndex & index) const;
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
protected:
PIVector<PIIntrospectionContainers::TypeInfo> cur_data;
PIMap<uint, PIIntrospectionContainers::TypeInfo> prev_data;
PIVector<llong> all, prev_all;
Qt::SortOrder ls_order;
int ls_column;
bool mode_changes;
public slots:
void setChangesMode(bool yes);
};
class ContainersDelegate: public QStyledItemDelegate {
Q_OBJECT
public:
ContainersDelegate(QAbstractItemModel * m) {model = m;}
void paint(QPainter *painter, const QStyleOptionViewItem & option, const QModelIndex &index) const;
QAbstractItemModel * model;
};
class ContainersView: public QWidget, private Ui::ContainersView
{
Q_OBJECT
public:
ContainersView(QWidget * parent = 0);
~ContainersView();
void showContainers(const PIVector<PIIntrospectionContainers::TypeInfo> & t);
void clear();
protected:
void changeEvent(QEvent * e);
ContainersModel * model;
private slots:
void sessionSave(QByteArray * data) {*data = treeContainers->header()->saveState();}
void sessionLoad(QByteArray * data) {treeContainers->header()->restoreState(*data);}
public slots:
};
#endif // CONTAINERS_VIEW_H

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ContainersView</class>
<widget class="QWidget" name="ContainersView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>406</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="radioOverall">
<property name="text">
<string>Overall</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QRadioButton" name="radioChanges">
<property name="text">
<string>Changes</string>
</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>
</item>
<item>
<widget class="QTreeView" name="treeContainers">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,60 @@
#include "objects_view.h"
#include <QScrollBar>
#include <QTreeWidget>
enum ColumnObjects {
coClassName,
coName,
coParents,
coQueuedEvents,
};
ObjectsView::ObjectsView(QWidget * parent): QWidget(parent) {
setupUi(this);
}
ObjectsView::~ObjectsView() {
}
void ObjectsView::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void ObjectsView::showObjects(const PIVector<PIIntrospection::ObjectInfo> & objects) {
QHash<QString, int> stat;
int vpos = treeObjects->verticalScrollBar()->value();
treeObjects->clear();
piForeachC (PIIntrospection::ObjectInfo & i, objects) {
stat[PI2QString(i.classname)]++;
QTreeWidgetItem * ti = new QTreeWidgetItem();
ti->setText(coClassName, PI2QString(i.classname));
ti->setText(coName, PI2QString(i.name));
ti->setText(coParents, PI2QString(i.parents.join(":")));
ti->setText(coQueuedEvents, QString::number(i.queued_events));
treeObjects->addTopLevelItem(ti);
}
treeObjects->verticalScrollBar()->setValue(vpos);
vpos = treeObjectsStat->verticalScrollBar()->value();
treeObjectsStat->clear();
for (QHash<QString, int>::const_iterator i = stat.constBegin(); i != stat.constEnd(); ++i) {
QTreeWidgetItem * ti = new QTreeWidgetItem();
ti->setText(0, i.key());
ti->setText(1, QString::number(i.value()));
treeObjectsStat->addTopLevelItem(ti);
}
treeObjectsStat->verticalScrollBar()->setValue(vpos);
}

View File

@@ -0,0 +1,28 @@
#ifndef OBJECTS_VIEW_H
#define OBJECTS_VIEW_H
#include "ui_objects_view.h"
#include <QDebug>
#include <QWidget>
#include "piqt.h"
#include "piintrospection_server_p.h"
class ObjectsView: public QWidget, private Ui::ObjectsView
{
Q_OBJECT
public:
ObjectsView(QWidget * parent = 0);
~ObjectsView();
void showObjects(const PIVector<PIIntrospection::ObjectInfo> & objects);
protected:
void changeEvent(QEvent * e);
private slots:
void sessionSave(QByteArray * data) {*data = treeObjects->header()->saveState();}
void sessionLoad(QByteArray * data) {treeObjects->header()->restoreState(*data);}
public slots:
};
#endif // OBJECTS_VIEW_H

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ObjectsView</class>
<widget class="QWidget" name="ObjectsView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>614</width>
<height>413</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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="QTabWidget" name="tabWidgetObjects">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_5">
<attribute name="title">
<string>List</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QTreeWidget" name="treeObjects">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<column>
<property name="text">
<string>class</string>
</property>
</column>
<column>
<property name="text">
<string>name</string>
</property>
</column>
<column>
<property name="text">
<string>parents</string>
</property>
</column>
<column>
<property name="text">
<string>queued_events</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_6">
<attribute name="title">
<string>Statictic</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QTreeWidget" name="treeObjectsStat">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<column>
<property name="text">
<string>class</string>
</property>
</column>
<column>
<property name="text">
<string>count</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,242 @@
#include "piintrospector.h"
#include <QClipboard>
#include <QScrollBar>
#include "pifile.h"
#include "pitime.h"
#include "pidir.h"
#include "pichunkstream.h"
#include "ccm_piintrospector.h"
QPIIntrospector::QPIIntrospector(QWidget * parent): EMainWindow(parent), peer("__introspection_client__") {
setupUi(this);
request_timer = 0;
session.setFile("qpiintrospector_session.conf");
#if QT_VERSION >= 0x050000
//treeContainers->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#else
//treeContainers->header()->setResizeMode(QHeaderView::ResizeToContents);
#endif
CONNECTU_QUEUED(&peer, peerConnectedEvent, this, peersChanged, this);
CONNECTU_QUEUED(&peer, peerDisconnectedEvent, this, peersChanged, this);
CONNECTU_QUEUED(&peer, dataReceivedEvent, this, peerReceived, this);
CONNECTU(&peer, peerConnectedEvent, this, reqProcPIEvents);
CONNECTU(&peer, peerDisconnectedEvent, this, reqProcPIEvents);
CONNECTU(&peer, dataReceivedEvent, this, reqProcPIEvents);
session.addEntry(this);
session.addEntry(tabWidgetMain);
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIntrospection::InfoTypes");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
QCheckBox * cb = new QCheckBox(PI2QString(e.name.mid(2)));
cb->setObjectName(QString("checkRequest%1").arg(e.value));
cb->setProperty("__value__", e.value);
layoutRequestFlags->addWidget(cb);
session.addEntry(cb);
}
}
//startTimer(100);
session.load();
peer.start();
}
QPIIntrospector::~QPIIntrospector() {
session.save();
peer.stop();
}
void QPIIntrospector::changeEvent(QEvent * e) {
EMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default: break;
}
}
void QPIIntrospector::timerEvent(QTimerEvent * e) {
if (e->timerId() == request_timer)
buttonRequest->click();
}
void QPIIntrospector::savingSession(QPIConfig & conf) {
conf.setValue("treeStat_header", treeStat->header()->saveState());
}
void QPIIntrospector::loadingSession(QPIConfig & conf) {
treeStat->header()->restoreState(conf.getValue("treeStat_header").toByteArray());
}
void QPIIntrospector::buildTree(QByteArray d) {
/*PIVector<PIIntrospectionThreads::ThreadInfo> threads;
PIByteArray pd = Q2PIByteArray(d);
pd >> threads;
treeContainers->clear();
piForeachC (PIIntrospectionThreads::ThreadInfo & t, threads) {
QTreeWidgetItem * ti = new QTreeWidgetItem();
ti->setText(0, QString(PI2QString(t.name) + " (%1)").arg(t.id));
treeContainers->addTopLevelItem(ti);
}*/
}
void QPIIntrospector::procRequestTimer() {
if (request_timer != 0) killTimer(request_timer);
request_timer = 0;
if (!checkRequestTimer->isChecked()) return;
request_timer = startTimer(1000 / spinRequestTimerHz->value());
}
void QPIIntrospector::buildDumpSection(QTreeWidgetItem * pi, PIString & str) {
}
void QPIIntrospector::showInfo() {
PIString s;
s << info.execCommand << "\n";
s << info.execDateTime.toString() << "\n";
s << info.OS_name << "(" << info.OS_version << ", " << info.architecture << ")\n";
s << info.user << "\n";
s << info.build_options.join(", ") << "\n";
s << "\n";
s << "load k: " << PIString::fromNumber(stat.proc.cpu_load_system, 'f', 2) << " %\n";
s << "load u: " << PIString::fromNumber(stat.proc.cpu_load_user, 'f', 2) << " %\n";
s << "threads: " << stat.proc.threads << "\n";
s << "memory usage: " << stat.proc.physical_memsize_readable;
labelInfo->setText(PI2QString(s));
int tlic = treeStat->topLevelItemCount();
for (int i = tlic; i < stat.threads.size_s(); ++i)
treeStat->addTopLevelItem(new QTreeWidgetItem());
for (int i = tlic - 1; i >= stat.threads.size_s(); --i)
delete treeStat->topLevelItem(i);
tlic = piMini(treeStat->topLevelItemCount(), stat.threads.size_s());
for (int i = 0; i < tlic; ++i) {
QTreeWidgetItem * ti = treeStat->topLevelItem(i);
PISystemMonitor::ThreadStats & ts(stat.threads[i]);
ti->setText(0, QString::number(i + 1));
ti->setText(1, QString::number(ts.id));
ti->setText(2, PI2QString(ts.name));
ti->setText(3, durationStr(ts.work_time));
ti->setText(4, QString::number(ts.cpu_load_kernel, 'f', 2));
ti->setText(5, QString::number(ts.cpu_load_user, 'f', 2));
}
}
QString QPIIntrospector::durationStr(PISystemTime t) {
QString ret;
double s = t.toSeconds();
int d, h, m;
d = piFloor(s / (24*60*60));
if (d > 0) {
ret += QString::number(d) + " d ";
s -= d * (24*60*60);
}
h = piFloor(s / (60*60));
if (h > 0) {
ret += QString::number(h) + " h ";
s -= h * (60*60);
}
m = piFloor(s / 60);
if (m > 0) {
ret += QString::number(m).rightJustified(2, '0') + " m ";
s -= m * 60;
}
ret += QString::number(piFloor(s)).rightJustified(2, '0') + " s";
return ret;
}
void QPIIntrospector::on_listApp_currentRowChanged(int r) {
PIString cs;
if (r < 0) cs.clear();
else cs = Q2PIString(listApp->item(r)->text());
if (cur_server != cs)
widgetContainers->clear();
cur_server = cs;
}
void QPIIntrospector::peerReceived(const PIString & from, const PIByteArray & data) {
if (from != cur_server) return;
//piCout << "rec" << data.size();
PIByteArray ba(data);
if (ba.size_s() < 4) return;
uint sign(0); ba >> sign;
if (sign != PIIntrospection::sign) return;
PIChunkStream cs(ba);
PIByteArray pba;
while (!cs.atEnd()) {
switch (cs.read()) {
case PIIntrospection::itInfo: {
cs.get(pba);
PIIntrospection::unpackInfo(pba, info);
} break;
case PIIntrospection::itProcStat: {
cs.get(pba);
PIIntrospection::unpackProcStat(pba, stat);
widgetThreads->setStat(stat.threads);
//showInfo(info);
} break;
case PIIntrospection::itContainers: {
cs.get(pba);
PIVector<PIIntrospectionContainers::TypeInfo> data;
PIIntrospection::unpackContainers(pba, data);
widgetContainers->showContainers(data);
} break;
case PIIntrospection::itObjects: {
cs.get(pba);
PIVector<PIIntrospection::ObjectInfo> objects;
PIIntrospection::unpackObjects(pba, objects);
widgetObjects->showObjects(objects);
} break;
case PIIntrospection::itThreads: {
cs.get(pba);
PIVector<PIIntrospectionThreads::ThreadInfo> threads;
PIIntrospection::unpackThreads(pba, threads);
widgetThreads->showThreads(threads);
} break;
default: break;
}
}
showInfo();
}
void QPIIntrospector::peersChanged(const PIString & name) {
listApp->blockSignals(true);
QString cs = listApp->currentItem() ? listApp->currentItem()->text() : "";
listApp->clear();
peer.lock();
piForeachC (PIPeer::PeerInfo & p, peer.allPeers()) {
QString pn = PI2QString(p.name);
listApp->addItem(pn);
if (pn == cs)
listApp->setCurrentRow(listApp->count() - 1);
}
peer.unlock();
listApp->blockSignals(false);
}
void QPIIntrospector::on_buttonRequest_clicked() {
if (cur_server.isEmpty()) return;
PIIntrospection::RequiredInfo info;
for (int i = 0; i < layoutRequestFlags->count(); ++i) {
QCheckBox * cb = qobject_cast<QCheckBox*>(layoutRequestFlags->itemAt(i)->widget());
if (!cb) continue;
if (!cb->isChecked()) continue;
info.types |= cb->property("__value__").toInt();
}
PIByteArray ba;
ba << PIIntrospection::sign << info;
peer.send(cur_server, ba);
}

View File

@@ -0,0 +1,53 @@
#ifndef PIINTROSPECTOR_H
#define PIINTROSPECTOR_H
#include "ui_piintrospector.h"
#include <QImage>
#include <QTime>
#include <QDesktopWidget>
#include <QDebug>
#include <emainwindow.h>
#include "piqt.h"
#include "pipeer.h"
#include "piintrospection_server_p.h"
class QPIIntrospector: public EMainWindow, private Ui::QPIIntrospector, public PIObject
{
Q_OBJECT
PIOBJECT(QPIIntrospector)
public:
QPIIntrospector(QWidget * parent = 0);
~QPIIntrospector();
protected:
void changeEvent(QEvent * e);
void timerEvent(QTimerEvent * );
void savingSession(QPIConfig & conf);
void loadingSession(QPIConfig & conf);
void buildDumpSection(QTreeWidgetItem * pi, PIString & str);
void showInfo();
EVENT_HANDLER(void, reqProcPIEvents) {QMetaObject::invokeMethod(this, "procPIEvents", Qt::QueuedConnection);}
QString durationStr(PISystemTime t);
EVENT_HANDLER2(void, peerReceived, const PIString &, from, const PIByteArray &, data);
EVENT_HANDLER1(void, peersChanged, const PIString &, name);
PIString cur_server;
PIIntrospection::ProcessInfo info;
PIIntrospection::ProcessStat stat;
PIPeer peer;
int request_timer;
private slots:
void procPIEvents() {callQueuedEvents();}
void buildTree(QByteArray d);
void procRequestTimer();
void on_listApp_currentRowChanged(int r);
void on_buttonRequest_clicked();
public slots:
};
#endif // PIINTROSPECTOR_H

View File

@@ -0,0 +1,284 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QPIIntrospector</class>
<widget class="QMainWindow" name="QPIIntrospector">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>824</width>
<height>597</height>
</rect>
</property>
<property name="windowTitle">
<string>PIP introspector</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Select application</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QListWidget" name="listApp">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Request</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QWidget" name="widgetRequestFlags" native="true">
<layout class="QVBoxLayout" name="layoutRequestFlags">
<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>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonRequest">
<property name="text">
<string>Request</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="checkRequestTimer">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Timer</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinRequestTimerHz">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="singleStep">
<double>0.500000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidgetMain">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Info</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="labelInfo">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Threads:</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="treeStat">
<column>
<property name="text">
<string>#</string>
</property>
</column>
<column>
<property name="text">
<string>id</string>
</property>
</column>
<column>
<property name="text">
<string>name</string>
</property>
</column>
<column>
<property name="text">
<string>uptime</string>
</property>
</column>
<column>
<property name="text">
<string>kernel, %</string>
</property>
</column>
<column>
<property name="text">
<string>user, %</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Containers</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="ContainersView" name="widgetContainers" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Objects</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="ObjectsView" name="widgetObjects" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Threads</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="ThreadsView" name="widgetThreads" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>ObjectsView</class>
<extends>QWidget</extends>
<header>objects_view.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ContainersView</class>
<extends>QWidget</extends>
<header>containers_view.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ThreadsView</class>
<extends>QWidget</extends>
<header>threads_view.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>checkRequestTimer</sender>
<signal>toggled(bool)</signal>
<receiver>QPIIntrospector</receiver>
<slot>procRequestTimer()</slot>
<hints>
<hint type="sourcelabel">
<x>65</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>6</x>
<y>546</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinRequestTimerHz</sender>
<signal>valueChanged(double)</signal>
<receiver>QPIIntrospector</receiver>
<slot>procRequestTimer()</slot>
<hints>
<hint type="sourcelabel">
<x>150</x>
<y>552</y>
</hint>
<hint type="destinationlabel">
<x>140</x>
<y>605</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>procRequestTimer()</slot>
</slots>
</ui>

View File

@@ -0,0 +1,13 @@
#include <QApplication>
#include "piintrospector.h"
int main(int argc, char * argv[]) {
QApplication a(argc, argv);
#if QT_VERSION >= 0x050000
a.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#endif
QPIIntrospector w;
w.show();
return a.exec();
}

View File

@@ -0,0 +1,230 @@
#include "threads_view.h"
#include <QTreeView>
#include <QPainter>
#include <QStyle>
#include <QSortFilterProxyModel>
#include "ccm_piintrospector.h"
enum ColumnThreads {
ctClassname,
ctName,
ctID,
ctDelay,
ctState,
ctLoad,
ctRunCost,
ctRunCount,
ctColumnCount,
};
ThreadsModel::ThreadsModel() {
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIntrospectionThreads::ThreadState");
if (ei) {
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
state_names[e.value] = PI2QString(e.name.mid(1));
}
}
state_colors[PIIntrospectionThreads::sStopped] = QColor(Qt::red).lighter(150);
state_colors[PIIntrospectionThreads::sStarting] = QColor(Qt::blue).lighter(150);
state_colors[PIIntrospectionThreads::sRunning] = QColor(Qt::green).lighter(120);
state_colors[PIIntrospectionThreads::sWaiting] = QColor(Qt::yellow).lighter(110);
}
void ThreadsModel::update(const PIVector<PIIntrospectionThreads::ThreadInfo> & t) {
int pts = threads.size_s();
threads = t;
if (t.size_s() > pts) {
beginInsertRows(QModelIndex(), pts, t.size_s() - 1);
endInsertRows();
}
if (t.size_s() < pts) {
beginRemoveRows(QModelIndex(), t.size_s(), pts - 1);
endRemoveRows();
}
dataChanged(index(0, 0), index(threads.size_s() - 1, columnCount()));
//emit headerDataChanged(Qt::Horizontal, ccCount, columnCount());
}
void ThreadsModel::setStat(const PIVector<PISystemMonitor::ThreadStats> & s) {
stat = s;
dataChanged(index(0, ctLoad), index(threads.size_s() - 1, ctLoad));
}
void ThreadsModel::clear() {
beginRemoveRows(QModelIndex(), 0, threads.size_s() - 1);
threads.clear();
endRemoveRows();
}
int ThreadsModel::rowCount(const QModelIndex & parent) const {
return threads.size_s();
}
int ThreadsModel::columnCount(const QModelIndex & parent) const {
return ctColumnCount;
}
QModelIndex ThreadsModel::index(int row, int column, const QModelIndex & parent) const {
if (row >= threads.size_s() || row >= threads.size_s()) return QModelIndex();
return createIndex(row, column, quintptr(0));
}
bool ThreadsModel::hasChildren(const QModelIndex & parent) const {
if (!parent.isValid()) return true;
return false;
}
QVariant ThreadsModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant();
switch (section) {
case ctClassname: return tr("Classname");
case ctName : return tr("Name");
case ctID : return tr("pID (pri)");
case ctDelay : return tr("Delay, ms");
case ctState : return tr("State");
case ctLoad : return tr("CPU, %");
case ctRunCost : return tr("Run cost, avg");
case ctRunCount : return tr("Run counts");
default: break;
}
return QVariant();
}
QVariant ThreadsModel::data(const QModelIndex & index, int role) const {
if (role != Qt::DisplayRole && role != Qt::DecorationRole && role != Qt::UserRole) return QVariant();
const PIIntrospectionThreads::ThreadInfo & ti(threads[index.row()]);
if (role == Qt::DisplayRole) {
switch (index.column()) {
case ctClassname: return PI2QString(ti.classname);
case ctName : return PI2QString(ti.name);
case ctID : return QString("%1 (%2)").arg(ti.id).arg(ti.priority);
case ctDelay : return QString::number(ti.delay);
case ctState : return state_names.value(ti.state);
case ctLoad : {
piForeachC (PISystemMonitor::ThreadStats & s, stat) {
if (s.id == llong(ti.id)) {
return QString::number(s.cpu_load_kernel + s.cpu_load_user, 'f', 2) + " %";
}
}
return "-";
}
case ctRunCost : {
double v = ti.run_us;
QByteArray suff = " us";
if (v > 1000.) {v /= 1000.; suff = " ms";}
if (v > 1000.) {v /= 1000.; suff = " s";}
return QString::number(v, 'f', 1) + suff;
}
case ctRunCount : return QString::number(ti.run_count);
}
}
if (index.column() == ctState) {
if (role == Qt::DecorationRole) {
return state_colors.value(ti.state);
}
if (role == Qt::UserRole) {
return int(ti.state);
}
}
return QVariant();
}
Qt::ItemFlags ThreadsModel::flags(const QModelIndex & index) const {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
/*
void ContainersDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QStyledItemDelegate::paint(painter, option, index);
if (model->index(index.row(), ccCount).data(Qt::UserRole+1).toInt() == 0) {
QColor col;
if (option.state == QStyle::State_Enabled ||
option.state == QStyle::State_HasFocus)
col = option.palette.color(QPalette::Active, QPalette::WindowText);
else
col = option.palette.color(QPalette::Disabled, QPalette::WindowText);
col.setAlphaF(0.5);
int y = option.rect.center().y() + (option.fontMetrics.height() / 2.5) - option.fontMetrics.strikeOutPos();
painter->setPen(QPen(col, lineThickness()));
painter->drawLine(QPoint(option.rect.left(), y), QPoint(option.rect.right(), y));
}
}
*/
ThreadsView::ThreadsView(QWidget * parent): QWidget(parent) {
setupUi(this);
model = new ThreadsModel();
QSortFilterProxyModel * proxy = new QSortFilterProxyModel();
proxy->setSourceModel(model);
proxy->setSortRole(Qt::UserRole);
proxy->setDynamicSortFilter(false);
treeThreads->setModel(model);
connect(checkHideStopped, SIGNAL(toggled(bool)), this, SLOT(updateHidden()));
//treeContainers->setItemDelegate(new ContainersDelegate(model));
}
ThreadsView::~ThreadsView() {
}
void ThreadsView::setStat(const PIVector<PISystemMonitor::ThreadStats> & stat) {
model->setStat(stat);
}
void ThreadsView::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
retranslateUi(this);
break;
default:
break;
}
}
void ThreadsView::updateHidden() {
bool hide_stopped = checkHideStopped->isChecked();
QModelIndex root = treeThreads->rootIndex();
for (int i = 0; i < model->rowCount(); ++i) {
if (!hide_stopped) treeThreads->setRowHidden(i, root, false);
else {
if (model->index(i, ctState).data(Qt::UserRole).toInt() == PIIntrospectionThreads::sStopped)
treeThreads->setRowHidden(i, root, true);
else
treeThreads->setRowHidden(i, root, false);
}
}
}
void ThreadsView::showThreads(const PIVector<PIIntrospectionThreads::ThreadInfo> & threads) {
model->update(threads);
updateHidden();
}
void ThreadsView::clear() {
model->clear();
}

View File

@@ -0,0 +1,81 @@
#ifndef THREADS_VIEW_H
#define THREADS_VIEW_H
#include "ui_threads_view.h"
#include <QDebug>
#include <QWidget>
#include <QHash>
#include <QTreeView>
#include <QAbstractItemModel>
#include <QStyledItemDelegate>
#include "piqt.h"
#include "pisystemmonitor.h"
#include "piintrospection_threads_p.h"
class ThreadsModel: public QAbstractItemModel {
Q_OBJECT
public:
ThreadsModel();
void update(const PIVector<PIIntrospectionThreads::ThreadInfo> & t);
void setStat(const PIVector<PISystemMonitor::ThreadStats> & s);
void clear();
int rowCount(const QModelIndex & parent = QModelIndex()) const;
int columnCount(const QModelIndex & parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex & child) const {return QModelIndex();}
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
bool hasChildren(const QModelIndex & parent = QModelIndex()) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QVariant data(const QModelIndex & index, int role) const;
Qt::ItemFlags flags(const QModelIndex & index) const;
protected:
PIVector<PIIntrospectionThreads::ThreadInfo> threads;
PIVector<PISystemMonitor::ThreadStats> stat;
QHash<int, QString> state_names;
QHash<int, QColor> state_colors;
};
/*
class ContainersDelegate: public QStyledItemDelegate {
Q_OBJECT
public:
ContainersDelegate(QAbstractItemModel * m) {model = m;}
void paint(QPainter *painter, const QStyleOptionViewItem & option, const QModelIndex &index) const override;
QAbstractItemModel * model;
};
*/
class ThreadsView: public QWidget, private Ui::ThreadsView
{
Q_OBJECT
public:
ThreadsView(QWidget * parent = 0);
~ThreadsView();
void setStat(const PIVector<PISystemMonitor::ThreadStats> & stat);
void showThreads(const PIVector<PIIntrospectionThreads::ThreadInfo> & threads);
void clear();
protected:
void changeEvent(QEvent * e);
ThreadsModel * model;
private slots:
void sessionSave(QByteArray * data) {*data = treeThreads->header()->saveState();}
void sessionLoad(QByteArray * data) {treeThreads->header()->restoreState(*data);}
void updateHidden();
public slots:
};
#endif // CONTAINERS_VIEW_H

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ThreadsView</class>
<widget class="QWidget" name="ThreadsView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>513</width>
<height>365</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="checkHideStopped">
<property name="text">
<string>Hide stopped</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="treeThreads">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>