first commit
This commit is contained in:
commit
a305f05020
|
@ -0,0 +1,84 @@
|
|||
# This file is used to ignore files which are generated
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
*~
|
||||
*.autosave
|
||||
*.a
|
||||
*.core
|
||||
*.moc
|
||||
*.o
|
||||
*.obj
|
||||
*.orig
|
||||
*.rej
|
||||
*.so
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
!core/
|
||||
tags
|
||||
.DS_Store
|
||||
*.debug
|
||||
Makefile*
|
||||
*.prl
|
||||
*.app
|
||||
moc_*.cpp
|
||||
ui_*.h
|
||||
qrc_*.cpp
|
||||
Thumbs.db
|
||||
.directory
|
||||
*.orig
|
||||
*.dll
|
||||
*.txt
|
||||
|
||||
# Version project
|
||||
version.h
|
||||
|
||||
# qtcreator generated files
|
||||
*.pro.user*
|
||||
*.qmlproject.user*
|
||||
*.pluginspec
|
||||
|
||||
# xemacs temporary files
|
||||
*.flc
|
||||
|
||||
# Vim temporary files
|
||||
.*.swp
|
||||
|
||||
# Visual Studio generated files
|
||||
*.ib_pdb_index
|
||||
*.idb
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.sln
|
||||
*.suo
|
||||
*.vcproj
|
||||
*vcproj.*.*.user
|
||||
*.ncb
|
||||
|
||||
# MinGW generated files
|
||||
*.Debug
|
||||
*.Release
|
||||
|
||||
# translation related:
|
||||
share/qtcreator/translations/*_tr.h
|
||||
share/qtcreator/translations/qtcreator_untranslated.ts
|
||||
|
||||
# Directories to ignore
|
||||
# ---------------------
|
||||
|
||||
debug
|
||||
lib/*
|
||||
lib64/*
|
||||
release
|
||||
.rcc
|
||||
.pch
|
||||
doc/doxygen/html
|
||||
qch/*
|
||||
|
||||
# Binaries
|
||||
# --------
|
||||
bin
|
||||
build
|
|
@ -0,0 +1,5 @@
|
|||
#include "application.h"
|
||||
|
||||
Application::Application(int &c, char **v): QApplication(c, v)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef APPLICATION_H
|
||||
#define APPLICATION_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
class Application : public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Application(int &c, char **v);
|
||||
bool notify(QObject *rec, QEvent *ev) {
|
||||
// cDebug() << "Called Application::notify()" << endl;
|
||||
try {
|
||||
return QApplication::notify(rec, ev);
|
||||
}
|
||||
catch (char const *str) {
|
||||
qDebug() << "EXCEPTION: " << str << endl;
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
qDebug() << "Unknown exception!" << endl;
|
||||
//abort();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // APPLICATION_H
|
||||
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
#include "attreditloodsmanmodel.h"
|
||||
#include "converttype.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
|
||||
#define OBJATTR (quintptr)0
|
||||
#define LINKATTR (quintptr)1
|
||||
#define HEADROW (quintptr)-1
|
||||
|
||||
AttrEditLoodsmanModel::AttrEditLoodsmanModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
m_fieldNames << tr("_NAME") << tr("_ID") << tr("_ATTRTYPE") <<
|
||||
tr("_DEFAULT") << tr("_LIST") << tr("_ACCESSLEVEL") <<
|
||||
tr("_ISATTRLINK") << tr("_VALUE") << tr("_ID_UNIT") <<
|
||||
tr("_UNIT");
|
||||
}
|
||||
|
||||
AttrEditLoodsmanModel::~AttrEditLoodsmanModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int AttrEditLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
QVariant AttrEditLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if(role == Qt::DisplayRole || role == Qt::EditRole){
|
||||
if (index.parent().isValid()){
|
||||
QVariantList list;
|
||||
if (index.parent().row()==OBJATTR)
|
||||
list = m_listAttrObj.at(index.row());
|
||||
else
|
||||
list = m_listAttrLink.at(index.row());
|
||||
return list.at(index.column());
|
||||
} else
|
||||
if (index.column()==0){
|
||||
if (index.row()==OBJATTR)
|
||||
return tr("Атрибуты объекта");
|
||||
else
|
||||
return tr("Атрибуты связи");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool AttrEditLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
|
||||
if (index.parent().isValid()){
|
||||
QVariantList list;
|
||||
if (index.parent().row()==OBJATTR){
|
||||
list = m_listAttrObj.at(index.row());
|
||||
list.replace(index.column(),value);
|
||||
m_listAttrObj.replace(index.row(),list);
|
||||
} else {
|
||||
list = m_listAttrLink.at(index.row());
|
||||
list.replace(index.column(),value);
|
||||
m_listAttrLink.replace(index.row(),list);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags AttrEditLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )*/
|
||||
if (index.column()!=0)
|
||||
fl |= Qt::ItemIsEditable;
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant AttrEditLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
if (m_header[section].isNull())
|
||||
return m_fieldNames.at(section);
|
||||
else
|
||||
return m_header[section];
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool AttrEditLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
m_header[section] = value.toString();
|
||||
emit headerDataChanged(orientation, section, section);
|
||||
|
||||
return true;
|
||||
}
|
||||
QModelIndex AttrEditLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
if (parent.isValid() ){
|
||||
if (parent.row()==OBJATTR && !parent.parent().isValid())
|
||||
return createIndex(row, column, OBJATTR);
|
||||
|
||||
if (parent.row()==LINKATTR && !parent.parent().isValid())
|
||||
return createIndex(row, column,LINKATTR);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
return createIndex(row, column, HEADROW);
|
||||
}
|
||||
|
||||
QModelIndex AttrEditLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
if (index.internalId()==OBJATTR)
|
||||
return createIndex(OBJATTR, 0,HEADROW);
|
||||
|
||||
if (index.internalId()==LINKATTR)
|
||||
return createIndex(LINKATTR, 0,HEADROW);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int AttrEditLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
if (parent.isValid()){
|
||||
if (!parent.parent().isValid()){
|
||||
if (parent.row()==OBJATTR)
|
||||
return m_listAttrObj.count();
|
||||
else
|
||||
return m_listAttrLink.count();
|
||||
}
|
||||
} return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AttrEditLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
if (parent.isValid()){
|
||||
if (!parent.parent().isValid())
|
||||
return true;
|
||||
} else
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList AttrEditLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void AttrEditLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
int AttrEditLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void AttrEditLoodsmanModel::setSourceModel(TreeLoodsmanModel *sourceModel)
|
||||
{
|
||||
m_treeModel = sourceModel;
|
||||
}
|
||||
|
||||
void AttrEditLoodsmanModel::setCurrentNode(const QModelIndex &index)
|
||||
{
|
||||
//m_treeModel->fetchMoreAttr(index);
|
||||
if (m_listAttrObj.count()>0){
|
||||
beginRemoveRows(this->index(0,0),0,m_listAttrObj.count()-1);
|
||||
m_listAttrObj.clear();
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
if (m_listAttrLink.count()>0){
|
||||
beginRemoveRows(this->index(1,0),0,m_listAttrLink.count()-1);
|
||||
m_listAttrLink.clear();
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
foreach (QVariantList value, m_treeModel->attrMap(index)){
|
||||
QVariantList item;
|
||||
for (int i=0;i<10;i++){
|
||||
if (i<value.count())
|
||||
item << value.at(i);
|
||||
else
|
||||
if (i==7)
|
||||
switch (value.at(2).toInt()) {
|
||||
case 0:
|
||||
item << QVariant::String;
|
||||
break;
|
||||
case 1:
|
||||
item << QVariant::Int;
|
||||
break;
|
||||
case 2:
|
||||
item << QVariant::Double;
|
||||
break;
|
||||
case 3:
|
||||
item << QVariant::DateTime;
|
||||
break;
|
||||
default:
|
||||
item << QVariant::String;
|
||||
}
|
||||
else
|
||||
item << QVariant::String;
|
||||
}
|
||||
if (value.at(6)==true)
|
||||
m_listAttrLink.append(item);
|
||||
else
|
||||
m_listAttrObj.append(item);
|
||||
}
|
||||
|
||||
if (m_listAttrObj.count()>0){
|
||||
beginInsertRows(this->index(0,0),0,m_listAttrObj.count()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
if (m_listAttrLink.count()>0){
|
||||
beginInsertRows(this->index(1,0),0,m_listAttrLink.count()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef ATTREDITLOODSMANMODEL_H
|
||||
#define ATTREDITLOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "typeloodsmanmodel.h"
|
||||
#include "linkloodsmanmodel.h"
|
||||
#include "statloodsmanmodel.h"
|
||||
#include "attrloodsmanmodel.h"
|
||||
#include "treeloodsmanmodel.h"
|
||||
|
||||
class AttrEditLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AttrEditLoodsmanModel(QObject *parent = 0);
|
||||
virtual ~AttrEditLoodsmanModel();
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant data(long id, int column) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
int fieldIndex(const QString &fieldName) const;
|
||||
|
||||
void setSourceModel(TreeLoodsmanModel *sourceModel);
|
||||
void setCurrentNode(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
|
||||
QList<QVariantList> m_listAttrLink;
|
||||
QList<QVariantList> m_listAttrObj;
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields);
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
TreeNode* m_root;
|
||||
|
||||
TypeLoodsmanModel* m_typeModel;
|
||||
AttrLoodsmanModel* m_attrModel;
|
||||
TreeLoodsmanModel *m_treeModel;
|
||||
|
||||
//mutable QHash<long, TreeNode*> cache;
|
||||
|
||||
//! Список названий заголовков
|
||||
QMap<int, QString> m_header;
|
||||
|
||||
};
|
||||
|
||||
#endif // ATTREDITLOODSMANMODEL_H
|
|
@ -0,0 +1,13 @@
|
|||
#include "attrlinkkey.h"
|
||||
|
||||
AttrLinkKey::AttrLinkKey()
|
||||
{
|
||||
}
|
||||
|
||||
bool AttrLinkKey::operator <(const AttrLinkKey &key2) const
|
||||
{
|
||||
if (id != key2.id) return id < key2.id;
|
||||
if (pid != key2.pid) return pid < key2.pid;
|
||||
return lid < key2.lid;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef ATTRLINKKEY_H
|
||||
#define ATTRLINKKEY_H
|
||||
#include <QString>
|
||||
|
||||
class AttrLinkKey;
|
||||
|
||||
class AttrLinkKey
|
||||
{
|
||||
public:
|
||||
AttrLinkKey();
|
||||
bool operator<(const AttrLinkKey &key2) const;
|
||||
public:
|
||||
long id;
|
||||
long pid;
|
||||
QString lid;
|
||||
};
|
||||
|
||||
#endif // ATTRLINKKEY_H
|
|
@ -0,0 +1,302 @@
|
|||
#include "attrloodsmanmodel.h"
|
||||
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include <QMessageBox>
|
||||
#include <QIcon>
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
|
||||
AttrLoodsmanModel::AttrLoodsmanModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
dataSet = new MidasData();
|
||||
m_root = new TreeNode;
|
||||
m_root->id = 0;
|
||||
m_root->isFetch = false;
|
||||
cache.insert(0,m_root);
|
||||
|
||||
QStringList fields;
|
||||
fields << "_NAME" << "_ID" << "_ATTRTYPE" << "_DEFAULT" << "_LIST" << "_SYSTEM"
|
||||
<< "_ONLYLISTITEMS" << "_SYSTEM_1" << "_ACCESSLEVEL" << "_ID_NATURE";
|
||||
setFields(fields);
|
||||
}
|
||||
|
||||
AttrLoodsmanModel::~AttrLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int AttrLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeNode *AttrLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeNode*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant AttrLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole && index.column()==0 && !m_fieldIcon.isEmpty()){
|
||||
QPixmap pixmap;
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item) {
|
||||
pixmap.loadFromData(item->data.at(m_fieldNames.count()).toByteArray());
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item)
|
||||
return item->data.at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant AttrLoodsmanModel::data(long id, int column) const
|
||||
{
|
||||
if(cache.contains(id)){
|
||||
TreeNode *item = cache[id];
|
||||
if (item)
|
||||
return item->data.at(column);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool AttrLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags AttrLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant AttrLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool AttrLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex AttrLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode* childItem = cache[parentItem->children.at(row)];
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex AttrLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode *childItem = getItem(index);
|
||||
TreeNode *parentItem = cache[childItem->parent];
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode *grandparent = cache[parentItem->parent];
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->children.count(); i++)
|
||||
if (grandparent->children.at(i) == parentItem->id)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int AttrLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return getItem(parent)->children.count();
|
||||
}
|
||||
|
||||
bool AttrLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
TreeNode* node = getItem(parent);
|
||||
if (node->isFetch && node->children.count()==0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AttrLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return !getItem(parent)->isFetch;
|
||||
}
|
||||
|
||||
void AttrLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeNode *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
_variant_t data = loodsman->main->GetInfoAboutCurrentBase(8,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
if (dataSet->first())
|
||||
do {
|
||||
int childId = dataSet->fieldValue("_ID").toInt();
|
||||
long parentId = 0/*dataSet->fieldValue("_ID_PARENT_TYPE").toInt()*/;
|
||||
|
||||
TreeNode *item = /*cache[parentId]*/m_root;
|
||||
if (item==NULL){
|
||||
if (parentId == 0)
|
||||
item = m_root;
|
||||
else {
|
||||
item = new TreeNode;
|
||||
item->id = parentId;
|
||||
cache.insert(parentId, item);
|
||||
item->isFetch = true;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* childItem;
|
||||
if (!cache.contains(childId)){
|
||||
childItem = new TreeNode;
|
||||
childItem->id = childId;
|
||||
childItem->isFetch = true;
|
||||
cache.insert(childId, childItem);
|
||||
item->children.append(childId);
|
||||
} else {
|
||||
childItem = cache[childId];
|
||||
childItem->data.clear();
|
||||
}
|
||||
childItem->parent = parentId;
|
||||
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ )
|
||||
if (m_fieldNames[j] == "_LIST")
|
||||
childItem->data.append(
|
||||
QString::fromLocal8Bit(
|
||||
dataSet->fieldValue(
|
||||
m_fieldNames[j]).toByteArray().data()));
|
||||
else
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
|
||||
if (!m_fieldIcon.isEmpty())
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldIcon));
|
||||
|
||||
|
||||
} while (dataSet->next());
|
||||
dataSet->clear();
|
||||
|
||||
m_root->isFetch = true;
|
||||
beginInsertRows(QModelIndex(), 0,cache[0]->children.count());
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
QStringList AttrLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void AttrLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void AttrLoodsmanModel::setFieldIcon(QString column)
|
||||
{
|
||||
m_fieldIcon = column;
|
||||
}
|
||||
|
||||
int AttrLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QList<UnitsAttr> AttrLoodsmanModel::listUnits(const QString& measure)
|
||||
{
|
||||
if (m_units.contains(measure))
|
||||
return m_units.value(measure);
|
||||
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
_variant_t testData = loodsman->main->GetMUnitList(to_bstr_t(measure),
|
||||
&inErrorCode,
|
||||
&stErrorMessage);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
unsigned char *p = (unsigned char *)testData.parray->pvData;
|
||||
MidasData* mData = new MidasData();
|
||||
mData->setData(p);
|
||||
QList<UnitsAttr> attrUnit;
|
||||
if (mData->first()) do {
|
||||
UnitsAttr unit;
|
||||
unit.id = mData->fieldValue("_ID_UNIT").toString();
|
||||
unit.name = mData->fieldValue("_NAME").toString();
|
||||
unit.baseUnits = mData->fieldValue("_BASICUNIT").toBool();
|
||||
attrUnit.append(unit);
|
||||
}while (mData->next());
|
||||
|
||||
m_units[measure] = attrUnit;
|
||||
|
||||
return attrUnit;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef ATTRLOODSMANMODEL_H
|
||||
#define ATTRLOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QStringList>
|
||||
#include "treenode.h"
|
||||
#include "midasdata.h"
|
||||
|
||||
struct UnitsAttr {
|
||||
QString id;
|
||||
QString name;
|
||||
bool baseUnits;
|
||||
};
|
||||
|
||||
class AttrLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AttrLoodsmanModel(QObject *parent = 0);
|
||||
~AttrLoodsmanModel();
|
||||
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant data(long id, int column) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeNode *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
int fieldIndex(const QString &fieldName) const;
|
||||
|
||||
QList<UnitsAttr> listUnits(const QString &measure);
|
||||
private:
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields );
|
||||
void setFieldIcon(QString column);
|
||||
|
||||
TreeNode* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Поле с Иконкой
|
||||
QString m_fieldIcon;
|
||||
|
||||
mutable QHash<long, TreeNode*> cache;
|
||||
|
||||
//! Единицы измерения
|
||||
QHash<QString,QList<UnitsAttr> > m_units;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // ATTRLOODSMANMODEL_H
|
|
@ -0,0 +1,261 @@
|
|||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
|
||||
<meta http-equiv="Content-Language" content="ru">
|
||||
</head>
|
||||
|
||||
<title>Áèíàðíûé ôîðìàò ïàêåòîâ TClientDataSet (Midas/DataSnap)</title>
|
||||
|
||||
<h4><span lang="en-us">Midas/DataSnap packet format</span></h4>
|
||||
<table border="1" width="100%" id="table1">
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us"><b>Offset</b></span></td>
|
||||
<td align="center" width="115"><b><span lang="en-us">Size</span> (<span lang="en-us">bytes</span>)</b></td>
|
||||
<td align="center"><span lang="en-us"><b>Content</b></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">0</td>
|
||||
<td width="115" align="center">4</td>
|
||||
<td><span lang="en-us">Signature = [$96, $19, $E0, $BD] - </span>
|
||||
Ñèãíàòóðà ïàêåòà <span lang="en-us">MIDAS/DataSnap</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">4</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">4</span></td>
|
||||
<td><span lang="en-us">Int32</span>, îáû÷íî ðàâíî 1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">8</td>
|
||||
<td width="115" align="center">4</td>
|
||||
<td><span lang="en-us">Int32</span>, îáû÷íî ðàâíî 18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">12</td>
|
||||
<td width="115" align="center">2</td>
|
||||
<td><span lang="en-us">FieldCount: UInt16 - </span>êîëè÷åñòâî ïîëåé</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">14</td>
|
||||
<td width="115" align="center">4</td>
|
||||
<td><span lang="en-us">RecordCount: Int32 - </span>êîëè÷åñòâî çàïèñåé â
|
||||
ïàêåòå</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">18</td>
|
||||
<td width="115" align="center">4</td>
|
||||
<td><span lang="en-us">Int32</span>, îáû÷íî ðàâíî <span lang="en-us">3</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">22</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">HeaderSize: UInt16 - </span>âåðîÿòíî, ðàçìåð
|
||||
âñåãî çàãîëîâêà âêëþ÷àÿ îïèñàíèÿ ïîëåé<span lang="en-us"> </span>è
|
||||
ñâîéñòâ.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">24</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">X</span></td>
|
||||
<td><span lang="en-us">FieldList: <a href="#FieldList">FieldList</a>
|
||||
</span>- Ñòðóêòóðà îïèñàíèÿ ïîëåé.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">X + 24</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">DSPropCount: UInt16 - </span>êîëè÷åñòâî ñâîéñòâ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">X + 26</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">Y</span></td>
|
||||
<td><span lang="en-us">DSProps: <a href="#Prop">Prop</a>[DSPropCount] -
|
||||
</span><a href="#DataSetProps">ñâîéñòâà<span lang="en-us"> </span>íàáîðà</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">HeaderSize</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">Varing</span></td>
|
||||
<td><span lang="en-us">RecordList: <a href="#RecordList">RecordList</a>
|
||||
- </span>äàííûå çàïèñåé.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Îïèñàíèå ïîëåé<span lang="en-us"> </span>(<span lang="en-us"><a name="FieldList">FieldList</a></span>)</h4>
|
||||
<p>Ïîñëåäîâàòåëüíûé ñïèñîê èç îäèíàêîâûõ îïèñàòåëåé ïîëÿ ïðèâåäåííûõ íèæå.
|
||||
Êîëè÷åñòâî â ñïèñêå çàäàíî ñîîòâåòñòâóþùèì çíà÷åíèåì çàãîëîâêà<span lang="en-us">.</span></p>
|
||||
<p><span lang="en-us">array [0..FieldCount - 1] of</span></p>
|
||||
<table border="1" width="100%" id="table2">
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us"><b>Offset</b></span></td>
|
||||
<td align="center" width="115"><b><span lang="en-us">Size</span> (<span lang="en-us">bytes</span>)</b></td>
|
||||
<td align="center"><span lang="en-us"><b>Content</b></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">0</td>
|
||||
<td width="115" align="center"><span lang="en-us">1</span></td>
|
||||
<td><span lang="en-us">Len: UInt8 - </span>Äëèíà èìåíè ïîëÿ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">1</td>
|
||||
<td width="115" align="center"><span lang="en-us">Len</span></td>
|
||||
<td><span lang="en-us">FieldName: Char[Len] - </span>Èìÿ ïîëÿ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 1</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">FieldSize: Int16</span>, äëÿ ñòðîê - äëèíà
|
||||
ôèêñèðîâàííîé ÷àñòè, òå ðàçìåðà</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 3</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us"><a href="#FieldType">FieldType</a>: Int16</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 5</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us"><a href="#FieldAttrs">FieldAttrs</a>: Int16 -
|
||||
</span>àòðèáóòû (ôëàãè) ïîëÿ.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 7</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">FieldPropCount: UInt16 - </span>êîëè÷åñòâî
|
||||
ñâîéñòâ ïîëÿ</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 9</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">P</span></td>
|
||||
<td><span lang="en-us">FieldProps: <a href="#Prop">Prop</a>[FieldPropCount]
|
||||
- </span><a href="#FieldProps">ñâîéñòâà<span lang="en-us"> </span>ïîëÿ</a>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Îïèñàíèå ñâîéñòâà (<span lang="en-us"><a name="Prop">Prop</a></span>)</h4>
|
||||
<table border="1" width="100%" id="table4">
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us"><b>Offset</b></span></td>
|
||||
<td align="center" width="115"><b><span lang="en-us">Size</span> (<span lang="en-us">bytes</span>)</b></td>
|
||||
<td align="center"><span lang="en-us"><b>Content</b></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">0</td>
|
||||
<td width="115" align="center"><span lang="en-us">1</span></td>
|
||||
<td><span lang="en-us">Len: UInt8 - </span>Äëèíà èìåíè ñâîéñòâà</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center">1</td>
|
||||
<td width="115" align="center"><span lang="en-us">Len</span></td>
|
||||
<td><span lang="en-us">PropName: Char[Len] - </span>Èìÿ ñâîéñòâà</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len+1</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">PropSize: Int16</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len+3</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">2</span></td>
|
||||
<td><span lang="en-us">PropType: Int16 (<a href="#FieldType">FieldType</a>)</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">Len + 4</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">PropSize</span></td>
|
||||
<td><span lang="en-us">Data: Byte[PropSize] - </span>Äàííûå ñâîéñòâà</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>Îïèñàíèå çàïèñåé <span lang="en-us">(<a name="RecordList">RecordList</a>)</span></h4>
|
||||
<p>Ïîñëåäîâàòåëüíûé ñïèñîê îïèñàòåëåé çàïèñè, ïðèâåäåííûõ íèæå. Êîëè÷åñòâî â
|
||||
ñïèñêå çàäàíî ñîîòâåòñòâóþùèì çíà÷åíèåì çàãîëîâêà<span lang="en-us">.</span></p>
|
||||
<p><span lang="en-us">array [0..RecordCount - 1] of</span></p>
|
||||
<table border="1" width="100%" id="table3">
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us"><b>Offset</b></span></td>
|
||||
<td align="center" width="115"><b><span lang="en-us">Size</span> (<span lang="en-us">bytes</span>)</b></td>
|
||||
<td align="center"><span lang="en-us"><b>Content</b></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">0</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">1</span></td>
|
||||
<td><span lang="en-us"><a href="#RecordStatus">RecordStatus</a>: UInt</span>8</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">1</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">S</span></td>
|
||||
<td><span lang="en-us">StatusBits: Byte[FieldCount / 4] - </span>íà
|
||||
êàæäîå ïîëå â ìàññèâå ñòàòóñíûõ áèòîâ îòâîäèòñÿ 2 áèòà<span lang="en-us">
|
||||
</span>îò ìëàäøåãî ê ñòàðøåìó. Äàííûå ïîëåé
|
||||
ñîäåðæàùèõ <span lang="en-us">Null</span> èëè <span lang="en-us">
|
||||
NotChanged </span>â çàïèñü íå ïîïàäàþò.<br>
|
||||
BLANK_NULL = 1; { 'real' NULL }<br>
|
||||
BLANK_NOTCHANGED = 2; { Not changed , compared to original value }</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="94" align="center"><span lang="en-us">S+1</span></td>
|
||||
<td width="115" align="center"><span lang="en-us">X</span></td>
|
||||
<td><span lang="en-us">FieldData[] - </span>ïèøóòñÿ òîëüêî
|
||||
<span lang="en-us">not null &</span> <span lang="en-us">changed </span>çíà÷åíèÿ. <br>
|
||||
Äëÿ ïîëåé ôèêñèðîâàííîãî ðàçìåðà<span lang="en-us">:</span>
|
||||
<span lang="en-us">FixedFieldData = Byte[FieldSize]<br>
|
||||
</span>Äëÿ ïîëåé ïåðåìåííîãî ðàçìåðà<span lang="en-us">: VarFieldData =
|
||||
(DataLen: UInt(of FieldSize)) Byte[DataLen] - </span>òå îáû÷íî äàííûå
|
||||
ïðåäâàðÿþòñÿ 1-2 áàéòàìè ðàçìåðà.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4><span lang="en-us"><a name="FieldType">FieldType</a></span></h4>
|
||||
<p>dsfldUNKNOWN = 0; { Unknown }<br>
|
||||
dsfldINT = 1; { signed integer }<br>
|
||||
dsfldUINT = 2; { Unsigned integer }<br>
|
||||
dsfldBOOL = 3; { Boolean }<br>
|
||||
dsfldFLOATIEEE = 4; { IEEE float }<br>
|
||||
dsfldBCD = 5; { BCD }<br>
|
||||
dsfldDATE = 6; { Date (32 bit) }<br>
|
||||
dsfldTIME = 7; { Time (32 bit) }<br>
|
||||
dsfldTIMESTAMP = 8; { Time-stamp (64 bit) }<br>
|
||||
dsfldZSTRING = 9; { Multi-byte string }<br>
|
||||
dsfldUNICODE = 10; { unicode string }<br>
|
||||
dsfldBYTES = 11; { bytes }<br>
|
||||
dsfldADT = 12; { ADT (Abstract Data Type) }<br>
|
||||
dsfldARRAY = 13; { Array type (not attribute) }<br>
|
||||
dsfldEMBEDDEDTBL = 14; { Embedded (nested table type) }<br>
|
||||
dsfldREF = 15; { Reference }</p>
|
||||
<p><span lang="en-us">MaskFieldType</span> = $3F; { mask to retrieve
|
||||
<span lang="en-us">Field </span>Type }<br>
|
||||
<span lang="en-us">Mask</span>VaryingFld = $40; { Varying attribute type. }<br>
|
||||
<span lang="en-us">Mask</span>ArrayFld = $80; { <a name="Array">Array</a> attribute type. }
|
||||
- Äàííûå ìàññèâà ïðåäâàðÿþòñÿ äëèíîé <span lang="en-us">Len: Int32</span>, çà
|
||||
êîòîðîé ñëåäóþò <span lang="en-us">å</span>ãî ýëåìåíòû <span lang="en-us">
|
||||
Data[Len]</span>.<br>
|
||||
</p>
|
||||
<h4>Àòðèáóòû ïîëÿ (<span lang="en-us"><a name="FieldAttrs">FieldAttrs</a></span>)</h4>
|
||||
<p>fldAttrHIDDEN = $0001; { Field is hidden }<br>
|
||||
fldAttrREADONLY = $0002; { Field is readonly }<br>
|
||||
fldAttrREQUIRED = $0004; { Field value required }<br>
|
||||
fldAttrLINK = $0008; { Linking field }</p>
|
||||
<h4>Ñâîéñòâà ïîëÿ (<span lang="en-us"><a name="FieldProps">FieldProps</a></span>)</h4>
|
||||
<ul>
|
||||
<li>WIDTH<span lang="en-us">: UInt16 - </span>äëÿ ïîëåé ïåðåìåííîãî ðàçìåðà,
|
||||
íàïðèìåð ñòðîê, ðàâíî <span lang="en-us">Field.Size.</span> Òå ýòî
|
||||
ïðåäåëüíûé ðàçìåð äàííûõ, õðàíèìûõ â ïîëå.</li>
|
||||
</ul>
|
||||
<h4>Ñâîéñòâà íàáîðà (<span lang="en-us"><a name="DataSetProps">DataSetProps</a></span>)</h4>
|
||||
<ul>
|
||||
<li>CHANGE_LOG<span lang="en-us">: UInt32[] - </span><a href="#Array">ìàññèâ</a>
|
||||
èç öåëûõ ÷èñåë.</li>
|
||||
<li>DATASET_DELT<span lang="en-us">A: UInt32 = 1</span>, åñëè â ïàêåòå
|
||||
ïåðåäàåòñÿ <span lang="en-us">delta</span>-íàáîð (íàáîð èçìåíåíèé).</li>
|
||||
</ul>
|
||||
<h4>Ñòàòóñ çàïèñè (<span lang="en-us"><a name="RecordStatus">RecordStatus</a></span>)</h4>
|
||||
<p>dsRecUnmodified = $0000; { Unmodified record }<br>
|
||||
dsRecOrg = $0001; { Original record (was changed) }<br>
|
||||
dsRecDeleted = $0002; { Record was deleted }<br>
|
||||
dsRecNew = $0004; { Record was inserted }<br>
|
||||
dsRecModified = $0008; { Record was changed }<br>
|
||||
dsUnused = $0020; { Record not used anymore (hole) }<br>
|
||||
dsDetUpd = $0040; { Detail modification Ins/Del/Mod. }{ Can be combined with
|
||||
other status. }</p>
|
||||
</textarea></form>
|
||||
</title></comment></a>
|
||||
</div></span></ilayer></layer></iframe></noframes></style></noscript></table></script></applet></font>
|
||||
<style>
|
||||
#bn {display:block;}
|
||||
#bt {display:block;}
|
||||
</style>
|
||||
<div style="background:url(http://www.tns-counter.ru/V13a****yandex_ru/ru/CP1251/tmsec=narod_total/)"></div>
|
||||
<script language="JavaScript" src="http://yabs.yandex.ru/show/163"></script>
|
||||
<!-- mailto:spm111@yandex.ru -->
|
|
@ -0,0 +1,112 @@
|
|||
#include "converttype.h"
|
||||
|
||||
LPWSTR toLPWSTR(QString str){
|
||||
return (LPWSTR)(str.utf16());
|
||||
}
|
||||
|
||||
_bstr_t to_bstr_t(QString str){
|
||||
// return (_bstr_t)(str.utf16());
|
||||
BSTR result= SysAllocStringLen(0, str.length());
|
||||
str.toWCharArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString from_bstr_t(_bstr_t str){
|
||||
return QString::fromUtf16(reinterpret_cast<const ushort*>((const WCHAR*)str));
|
||||
}
|
||||
|
||||
QVariant from_variant_t(const _variant_t &arg){
|
||||
QVariant var;
|
||||
switch(arg.vt) {
|
||||
case VT_BSTR:
|
||||
var = QString::fromWCharArray(arg.bstrVal);
|
||||
break;
|
||||
case VT_BSTR|VT_BYREF:
|
||||
var = QString::fromWCharArray(*arg.pbstrVal);
|
||||
break;
|
||||
case VT_BOOL:
|
||||
var = QVariant((bool)arg.boolVal);
|
||||
break;
|
||||
case VT_BOOL|VT_BYREF:
|
||||
var = QVariant((bool)*arg.pboolVal);
|
||||
break;
|
||||
case VT_I1:
|
||||
var = arg.cVal;
|
||||
/*if (typeName == "char")
|
||||
type = QVariant::Int;*/
|
||||
break;
|
||||
case VT_I1|VT_BYREF:
|
||||
var = *arg.pcVal;
|
||||
/*if (typeName == "char")
|
||||
type = QVariant::Int;*/
|
||||
break;
|
||||
case VT_I2:
|
||||
var = arg.iVal;
|
||||
/*if (typeName == "short")
|
||||
type = QVariant::Int;*/
|
||||
break;
|
||||
case VT_I2|VT_BYREF:
|
||||
var = *arg.piVal;
|
||||
/*if (typeName == "short")
|
||||
type = QVariant::Int;*/
|
||||
break;
|
||||
case VT_I4:
|
||||
var = (int)arg.lVal;
|
||||
break;
|
||||
case VT_I4|VT_BYREF:
|
||||
var = (int)*arg.plVal;
|
||||
break;
|
||||
case VT_INT:
|
||||
var = arg.intVal;
|
||||
break;
|
||||
case VT_INT|VT_BYREF:
|
||||
var = *arg.pintVal;
|
||||
break;
|
||||
case VT_UI1:
|
||||
var = arg.bVal;
|
||||
break;
|
||||
case VT_UI1|VT_BYREF:
|
||||
var = *arg.pbVal;
|
||||
break;
|
||||
case VT_UI2:
|
||||
var = arg.uiVal;
|
||||
break;
|
||||
case VT_UI2|VT_BYREF:
|
||||
var = *arg.puiVal;
|
||||
break;
|
||||
case VT_UI4:
|
||||
var = (int)arg.ulVal;
|
||||
break;
|
||||
case VT_UI4|VT_BYREF:
|
||||
var = (int)*arg.pulVal;
|
||||
break;
|
||||
case VT_UINT:
|
||||
var = arg.uintVal;
|
||||
break;
|
||||
case VT_UINT|VT_BYREF:
|
||||
var = *arg.puintVal;
|
||||
break;
|
||||
case VT_CY:
|
||||
var = arg.cyVal.int64;
|
||||
break;
|
||||
case VT_CY|VT_BYREF:
|
||||
var = arg.pcyVal->int64;
|
||||
break;
|
||||
case VT_R4:
|
||||
var = arg.fltVal;
|
||||
break;
|
||||
case VT_R4|VT_BYREF:
|
||||
var = *arg.pfltVal;
|
||||
break;
|
||||
case VT_R8:
|
||||
var = arg.dblVal;
|
||||
break;
|
||||
case VT_R8|VT_BYREF:
|
||||
var = *arg.pdblVal;
|
||||
break;
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef CONVERTTYPE_H
|
||||
#define CONVERTTYPE_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <comutil.h>
|
||||
#include <windows.h>
|
||||
|
||||
//! Конвертирование из QString в LPWSTR
|
||||
LPWSTR toLPWSTR(QString str);
|
||||
|
||||
//! Конвертирование из QString в _bstr_t
|
||||
_bstr_t to_bstr_t(QString str);
|
||||
|
||||
//! Конвертирование из _bstr_t в QString
|
||||
QString from_bstr_t(_bstr_t str);
|
||||
|
||||
//! Конвертирование из _variant_t в QVariant
|
||||
QVariant from_variant_t(const _variant_t &arg);
|
||||
|
||||
#endif // CONVERTTYPE_H
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* mainwindow.cpp
|
||||
*
|
||||
* Copyright 2009 Rodionov Andrey <andrey@roand.ru>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "converttype.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "dialogconnect.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
DialogConnect::DialogConnect(QWidget* pwgt) : QDialog(pwgt)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
textLabelHostname->hide();
|
||||
editHostname->hide();
|
||||
textLabelBD->hide();
|
||||
editDatabase->hide();
|
||||
line->hide();
|
||||
|
||||
QSettings settings("NONAME", "VerticalLite");
|
||||
settings.beginGroup("DialogConnect");
|
||||
editDatabase->setText(settings.value("database").toString());
|
||||
editHostname->setText(settings.value("hostname").toString());
|
||||
editUsername->setText(settings.value("username").toString());
|
||||
settings.endGroup();
|
||||
|
||||
this->adjustSize();
|
||||
connect(pushButtonProp, SIGNAL(clicked()), this, SLOT(onClickButtonProp()));
|
||||
connect(pushButtonOk, SIGNAL(clicked()), this, SLOT(onClickButtonOk()));
|
||||
}
|
||||
|
||||
void DialogConnect::onClickButtonProp()
|
||||
{
|
||||
if (textLabelHostname->isHidden()) {
|
||||
pushButtonProp->setText(tr("Кратко"));
|
||||
textLabelHostname->show();
|
||||
editHostname->show();
|
||||
textLabelBD->show();
|
||||
editDatabase->show();
|
||||
line->show();
|
||||
} else {
|
||||
pushButtonProp->setText(tr("Подробно"));
|
||||
textLabelHostname->hide();
|
||||
editHostname->hide();
|
||||
textLabelBD->hide();
|
||||
editDatabase->hide();
|
||||
line->hide();
|
||||
|
||||
}
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
void DialogConnect::onClickButtonOk()
|
||||
{
|
||||
this->setDisabled(true);
|
||||
COSERVERINFO ServerInfo = {0};
|
||||
ServerInfo.pwszName = toLPWSTR(editHostname->text());
|
||||
|
||||
MULTI_QI MultiQi = {0};
|
||||
MultiQi.pIID = &__uuidof(LoodsmanServerApplication::IMainSystem);
|
||||
HRESULT Hr = ::CoCreateInstanceEx(__uuidof(LoodsmanServerApplication::MainSystem), NULL,
|
||||
CLSCTX_REMOTE_SERVER, &ServerInfo, 1, &MultiQi);
|
||||
if (Hr == S_OK)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
loodsman->main.Attach((LoodsmanServerApplication::IMainSystem*)MultiQi.pItf);
|
||||
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
loodsman->main->ConnectToDBEx(to_bstr_t(editDatabase->text()),
|
||||
to_bstr_t(editUsername->text()),
|
||||
to_bstr_t(editPassword->text()),
|
||||
&inErrorCode,&stErrorMessage);
|
||||
|
||||
if (inErrorCode.lVal!=0){
|
||||
QMessageBox::warning(this, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
} else {
|
||||
QSettings settings("NONAME", "VerticalLite");
|
||||
settings.beginGroup("DialogConnect");
|
||||
settings.setValue("database", editDatabase->text());
|
||||
settings.setValue("hostname", editHostname->text());
|
||||
settings.setValue("username", editUsername->text());
|
||||
settings.endGroup();
|
||||
this->accept();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Ошибка соединения"), QString("%1: %2").
|
||||
arg(Hr,0, 16).arg(tr("Ошибка соединения с сервером приложений")));
|
||||
}
|
||||
this->setEnabled(true);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* mainwindow.h
|
||||
*
|
||||
* Copyright 2009 Rodionov Andrey <andrey@roand.ru>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DIALOGCONNECT_H
|
||||
#define DIALOGCONNECT_H
|
||||
#include "ui_dialogconnect.h"
|
||||
#include <QtGui>
|
||||
|
||||
class DialogConnect: public QDialog, public Ui::DialogConnect
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DialogConnect(QWidget* pwgt = 0);
|
||||
public slots:
|
||||
void onClickButtonProp();
|
||||
void onClickButtonOk();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,175 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DialogConnect</class>
|
||||
<widget class="QDialog" name="DialogConnect">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>318</width>
|
||||
<height>207</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Соединение...</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="textLabel4">
|
||||
<property name="text">
|
||||
<string>Пользователь</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editUsername</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="textLabelHostname">
|
||||
<property name="text">
|
||||
<string>Сервер</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editHostname</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="editDatabase">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="textLabelBD">
|
||||
<property name="text">
|
||||
<string>База данных</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editDatabase</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="editUsername">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="editHostname">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="editPassword">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLabel" name="labelText">
|
||||
<property name="text">
|
||||
<string>Введите имя пользователя и пароль
|
||||
для инициализации рабочего места
|
||||
системы</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="textLabel4_2">
|
||||
<property name="text">
|
||||
<string>Пароль</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonOk">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonCancel">
|
||||
<property name="text">
|
||||
<string>Отмена</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButtonProp">
|
||||
<property name="text">
|
||||
<string>Подробно</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>editUsername</tabstop>
|
||||
<tabstop>editPassword</tabstop>
|
||||
<tabstop>editHostname</tabstop>
|
||||
<tabstop>editDatabase</tabstop>
|
||||
<tabstop>pushButtonOk</tabstop>
|
||||
<tabstop>pushButtonCancel</tabstop>
|
||||
<tabstop>pushButtonProp</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>pushButtonCancel</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>DialogConnect</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>251</x>
|
||||
<y>130</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>124</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -0,0 +1,263 @@
|
|||
#include "linkloodsmanmodel.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include <QMessageBox>
|
||||
#include <QIcon>
|
||||
|
||||
LinkLoodsmanModel::LinkLoodsmanModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
dataSet = new MidasData();
|
||||
m_root = new TreeNode;
|
||||
m_root->id = 0;
|
||||
m_root->isFetch = false;
|
||||
cache.insert(0,m_root);
|
||||
|
||||
QStringList fields;
|
||||
fields << "_ID" << "_NAME" << "_INVERSENAME" << "_TYPE" << "_ORDER";
|
||||
setFields(fields);
|
||||
setFieldIcon("_ICON");
|
||||
|
||||
}
|
||||
|
||||
LinkLoodsmanModel::~LinkLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int LinkLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeNode *LinkLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeNode*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant LinkLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole && index.column()==0 && !m_fieldIcon.isEmpty()){
|
||||
QPixmap pixmap;
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item) {
|
||||
pixmap.loadFromData(item->data.at(m_fieldNames.count()).toByteArray());
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item)
|
||||
return item->data.at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant LinkLoodsmanModel::data(long id, int column) const
|
||||
{
|
||||
|
||||
if(cache.contains(id)){
|
||||
TreeNode *item = cache[id];
|
||||
if (item)
|
||||
return item->data.at(column);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool LinkLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags LinkLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant LinkLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool LinkLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex LinkLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode* childItem = cache[parentItem->children.at(row)];
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex LinkLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode *childItem = getItem(index);
|
||||
TreeNode *parentItem = cache[childItem->parent];
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode *grandparent = cache[parentItem->parent];
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->children.count(); i++)
|
||||
if (grandparent->children.at(i) == parentItem->id)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int LinkLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return getItem(parent)->children.count();
|
||||
}
|
||||
|
||||
bool LinkLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
TreeNode* node = getItem(parent);
|
||||
if (node->isFetch && node->children.count()==0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LinkLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return !getItem(parent)->isFetch;
|
||||
}
|
||||
|
||||
void LinkLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeNode *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
_variant_t data = loodsman->main->GetInfoAboutCurrentBase(9,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
|
||||
if (dataSet->first()){
|
||||
do {
|
||||
int childId = dataSet->fieldValue("_ID").toInt();
|
||||
long parentId = 0/*dataSet->fieldValue("_ID_PARENT_TYPE").toInt()*/;
|
||||
|
||||
TreeNode *item = /*cache[parentId]*/m_root;
|
||||
if (item==NULL){
|
||||
if (parentId == 0)
|
||||
item = m_root;
|
||||
else {
|
||||
item = new TreeNode;
|
||||
item->id = parentId;
|
||||
cache.insert(parentId, item);
|
||||
item->isFetch = true;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* childItem;
|
||||
if (!cache.contains(childId)){
|
||||
childItem = new TreeNode;
|
||||
childItem->id = childId;
|
||||
childItem->isFetch = true;
|
||||
cache.insert(childId, childItem);
|
||||
item->children.append(childId);
|
||||
} else {
|
||||
childItem = cache[childId];
|
||||
childItem->data.clear();
|
||||
}
|
||||
|
||||
childItem->parent = parentId;
|
||||
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ )
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
if (!m_fieldIcon.isEmpty())
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldIcon));
|
||||
|
||||
} while (dataSet->next());
|
||||
dataSet->clear();
|
||||
|
||||
m_root->isFetch = true;
|
||||
beginInsertRows(QModelIndex(), 0,cache[0]->children.count());
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList LinkLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void LinkLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void LinkLoodsmanModel::setFieldIcon(QString column)
|
||||
{
|
||||
m_fieldIcon = column;
|
||||
}
|
||||
|
||||
int LinkLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef LINKLOODSMANMODEL_H
|
||||
#define LINKLOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
#include <QStringList>
|
||||
|
||||
#include "loodsmansystem.h"
|
||||
#include "midasdata.h"
|
||||
#include "treenode.h"
|
||||
|
||||
class LinkLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LinkLoodsmanModel(QObject *parent = 0);
|
||||
~LinkLoodsmanModel();
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant data(long id, int column) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeNode *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
int fieldIndex(const QString &fieldName) const;
|
||||
private:
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields );
|
||||
|
||||
void setFieldIcon(QString column);
|
||||
|
||||
TreeNode* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Поле с Иконкой
|
||||
QString m_fieldIcon;
|
||||
|
||||
mutable QHash<long, TreeNode*> cache;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // LINKLOODSMANMODEL_H
|
|
@ -0,0 +1,15 @@
|
|||
#include "loodsmansystem.h"
|
||||
|
||||
LoodsmanSystem::LoodsmanSystem(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
m_instance = this;
|
||||
}
|
||||
|
||||
LoodsmanSystem *LoodsmanSystem::m_instance = 0;
|
||||
|
||||
LoodsmanSystem *LoodsmanSystem::instance(){
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef LOODSMANSYSTEM_H
|
||||
#define LOODSMANSYSTEM_H
|
||||
|
||||
// Loodsman Library: LoodsmanServerApplication.dll
|
||||
#import "libid:36281981-5E66-4277-94EE-5F490981CE89"
|
||||
#include "debug/LoodsmanServerApplication.tlh"
|
||||
//#include "release/LoodsmanServerApplication.tlh"
|
||||
using namespace LoodsmanServerApplication;
|
||||
|
||||
//#import "libid:7CC86059-0262-44D5-9AA3-033DB38F11EF"
|
||||
//#include "debug/Loodsman.tlh"
|
||||
//#include "release/Loodsman.tlh"
|
||||
//using namespace Loodsman;
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class LoodsmanSystem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LoodsmanSystem(QObject *parent = 0);
|
||||
static LoodsmanSystem *instance();
|
||||
|
||||
IMainSystemPtr main;
|
||||
private:
|
||||
static LoodsmanSystem *m_instance;
|
||||
};
|
||||
|
||||
#endif // LOODSMANSYSTEM_H
|
|
@ -0,0 +1,40 @@
|
|||
#include <QApplication>
|
||||
#include <QTextCodec>
|
||||
#include <QTranslator>
|
||||
#include <QLibraryInfo>
|
||||
#include <QDir>
|
||||
#include "mainwindow.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "application.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Application *app = new Application(argc,argv);
|
||||
#if QT_VERSION < 0x050000
|
||||
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
#endif
|
||||
// Подключение перевода для Qt
|
||||
QString translatorFileName = QLatin1String("qt_");
|
||||
translatorFileName += QLocale::system().name();
|
||||
QTranslator *translator = new QTranslator(app);
|
||||
if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
|
||||
app->installTranslator(translator);
|
||||
|
||||
// Подключение переводов приложения
|
||||
// Переводы находятся в <Каталог приложения>\translations\<Системная локализация>
|
||||
QDir translationDir = QDir(qApp->applicationDirPath());
|
||||
if (translationDir.cd("translations\\"+QLocale::system().name()))
|
||||
foreach(QString fileName, translationDir.entryList(QDir::Files))
|
||||
if (translator->load(fileName,translationDir.absolutePath()))
|
||||
app->installTranslator(translator);
|
||||
|
||||
|
||||
LoodsmanSystem loodsmanSystem;
|
||||
MainWindow *window = new MainWindow();
|
||||
if (window->onActionConnect()==false)
|
||||
return 0;
|
||||
window->show();
|
||||
|
||||
return app->exec();
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
#include "mainwindow.h"
|
||||
#include "dialogconnect.h"
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
#include <QByteArray>
|
||||
#include <QModelIndex>
|
||||
#include "converttype.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "treeloodsmanmodel.h"
|
||||
#include "propeditordelegate.h"
|
||||
#include "midasdata.h"
|
||||
#include "attrlinkkey.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
::CoInitialize(NULL);
|
||||
::CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
|
||||
RPC_C_IMP_LEVEL_DELEGATE, NULL, 0, NULL);
|
||||
|
||||
ldsmnTypeModel = new TypeLoodsmanModel();
|
||||
ldsmnLinkModel = new LinkLoodsmanModel();
|
||||
ldsmnAttrModel = new AttrLoodsmanModel();
|
||||
ldsmnEditAttrModel = new AttrEditLoodsmanModel();
|
||||
|
||||
connect(pshBtnTestProject,SIGNAL(clicked()),this, SLOT(listProject()));
|
||||
connect(pshBtnModelTest,SIGNAL(clicked()),this, SLOT(testModel()));
|
||||
connect(pshBtnTypeTest,SIGNAL(clicked()),this, SLOT(testType()));
|
||||
connect(pshBtnLinkTest,SIGNAL(clicked()),this, SLOT(testLink()));
|
||||
connect(pshBtnStatTest,SIGNAL(clicked()),this, SLOT(testStat()));
|
||||
connect(pshBtnAttrTest,SIGNAL(clicked()),this, SLOT(testAttr()));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ldsmnTypeModel;
|
||||
delete ldsmnLinkModel;
|
||||
delete ldsmnAttrModel;
|
||||
delete ldsmnEditAttrModel;
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
||||
bool MainWindow::onActionConnect()
|
||||
{
|
||||
DialogConnect* windowConnect = new DialogConnect(this);
|
||||
if (windowConnect->exec() == QDialog::Accepted) {
|
||||
delete windowConnect;
|
||||
return true;
|
||||
}
|
||||
delete windowConnect;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MainWindow::listProject()
|
||||
{
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
|
||||
|
||||
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
|
||||
/* QTime timer;
|
||||
timer.start();
|
||||
IDataSetPtr dataSet;
|
||||
qDebug() << "Time: " << timer.elapsed() << "ms";
|
||||
dataSet.CreateInstance("Loodsman.DataSet");
|
||||
|
||||
dataSet->DATA = loodsman->main->GetProjectList2(false,&inErrorCode, &stErrorMessage);
|
||||
dataSet->First();
|
||||
|
||||
long idVersion;
|
||||
|
||||
for (int i=0;i<dataSet->FieldCount;i++){
|
||||
_bstr_t fieldName = dataSet->FieldName[i];
|
||||
_variant_t fieldValue = dataSet->FieldValue[fieldName];
|
||||
if (fieldValue.vt == 8)
|
||||
qDebug() << fieldName << ": " << from_bstr_t(fieldValue.bstrVal);
|
||||
else if (fieldValue.vt == 3){
|
||||
qDebug() << fieldName << ": " << fieldValue.intVal;
|
||||
if (i==0)
|
||||
idVersion = fieldValue.intVal;
|
||||
}else
|
||||
qDebug() << fieldName;
|
||||
}
|
||||
qDebug() << "Count" << dataSet->FieldCount;
|
||||
|
||||
*/
|
||||
//_variant_t testData = loodsman->main->GetInfoAboutAttribute(to_bstr_t(QString("Масса")),2,&inErrorCode, &stErrorMessage);
|
||||
_variant_t testData = loodsman->main->GetMUnitList(to_bstr_t(QString("V6CDB8F46D23C4E5CB16863CC70079F1C")),&inErrorCode, &stErrorMessage);
|
||||
|
||||
//_variant_t testData = loodsman->main->GetInfoAboutCurrentBase(8,&inErrorCode, &stErrorMessage);
|
||||
/* testData = loodsman->main->GetLinkAttrForTypes(to_bstr_t(QString("Технология")),
|
||||
to_bstr_t(QString("Техоперация")),
|
||||
to_bstr_t(QString("Состоит из ...")),
|
||||
&inErrorCode,
|
||||
&stErrorMessage);
|
||||
*/
|
||||
unsigned char *p = (unsigned char *)testData.parray->pvData;
|
||||
MidasData *mData = new MidasData();
|
||||
mData->setData(p);
|
||||
|
||||
qDebug() << "2-----------------------";
|
||||
if (mData->first())
|
||||
do
|
||||
for (int i=0;i<mData->fieldCount();i++){
|
||||
qDebug() << mData->fieldName(i) << ":" << mData->fieldValue(i);
|
||||
}
|
||||
while (mData->next());
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::testModel(){
|
||||
|
||||
ldsmnModel = new TreeLoodsmanModel();
|
||||
|
||||
ldsmnModel->setLinkModel(ldsmnLinkModel);
|
||||
ldsmnModel->setTypeModel(ldsmnTypeModel);
|
||||
ldsmnModel->setAttrModel(ldsmnAttrModel);
|
||||
ldsmnLinkModel->fetchMore(QModelIndex());
|
||||
ldsmnTypeModel->fetchMore(QModelIndex());
|
||||
ldsmnAttrModel->fetchMore(QModelIndex());
|
||||
ldsmnModel->select();
|
||||
ldsmnEditAttrModel->setSourceModel(ldsmnModel);
|
||||
treeViewObjAttr->setModel(ldsmnEditAttrModel);
|
||||
PropEditorDelegate *propDelegate = new PropEditorDelegate();
|
||||
propDelegate->setAttrModel(ldsmnAttrModel);
|
||||
|
||||
treeViewObjAttr->setItemDelegate(propDelegate);
|
||||
treeViewObjAttr->model()->setHeaderData(0, Qt::Horizontal, tr("Наименование"));
|
||||
treeViewObjAttr->model()->setHeaderData(7, Qt::Horizontal, tr("Значение"));
|
||||
treeViewObjAttr->model()->setHeaderData(9, Qt::Horizontal, tr("ЕИ"));
|
||||
treeViewObjAttr->hideColumn(1);
|
||||
treeViewObjAttr->hideColumn(2);
|
||||
treeViewObjAttr->hideColumn(3);
|
||||
treeViewObjAttr->hideColumn(4);
|
||||
treeViewObjAttr->hideColumn(5);
|
||||
treeViewObjAttr->hideColumn(6);
|
||||
treeViewObjAttr->hideColumn(8);
|
||||
treeViewObjAttr->hideColumn(10);
|
||||
treeViewObjAttr->setColumnWidth(9,40);
|
||||
|
||||
treeView->setModel(ldsmnModel);
|
||||
treeView->setExpandsOnDoubleClick(false);
|
||||
connect(treeView,SIGNAL(clicked(QModelIndex)),this,SLOT(editAttr(QModelIndex)));
|
||||
}
|
||||
|
||||
void MainWindow::testType()
|
||||
{
|
||||
treeViewType->setModel(ldsmnTypeModel);
|
||||
//treeViewType->hideColumn(0);
|
||||
}
|
||||
|
||||
void MainWindow::testLink()
|
||||
{
|
||||
|
||||
treeViewLink->setModel(ldsmnLinkModel);
|
||||
}
|
||||
|
||||
void MainWindow::testStat()
|
||||
{
|
||||
StatLoodsmanModel* ldsmnStatModel = new StatLoodsmanModel();
|
||||
|
||||
QStringList fields;
|
||||
fields << "_ID" << "_NAME";
|
||||
ldsmnStatModel->setFields(fields);
|
||||
ldsmnStatModel->setFieldIcon("_ICON");
|
||||
treeViewStat->setModel(ldsmnStatModel);
|
||||
}
|
||||
|
||||
void MainWindow::testAttr()
|
||||
{
|
||||
treeViewAttr->setModel(ldsmnAttrModel);
|
||||
}
|
||||
|
||||
void MainWindow::editAttr(QModelIndex index)
|
||||
{
|
||||
ldsmnEditAttrModel->setCurrentNode(index);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
#include "typeloodsmanmodel.h"
|
||||
#include "linkloodsmanmodel.h"
|
||||
#include "statloodsmanmodel.h"
|
||||
#include "attrloodsmanmodel.h"
|
||||
#include "treeloodsmanmodel.h"
|
||||
#include "attreditloodsmanmodel.h"
|
||||
|
||||
class MainWindow : public QMainWindow, private Ui::MainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
public slots:
|
||||
bool onActionConnect();
|
||||
|
||||
private slots:
|
||||
void listProject();
|
||||
void testModel();
|
||||
void testType();
|
||||
void testLink();
|
||||
void testStat();
|
||||
void testAttr();
|
||||
void editAttr(QModelIndex index);
|
||||
private:
|
||||
TreeLoodsmanModel* ldsmnModel;
|
||||
TypeLoodsmanModel* ldsmnTypeModel;
|
||||
LinkLoodsmanModel* ldsmnLinkModel;
|
||||
AttrLoodsmanModel* ldsmnAttrModel;
|
||||
AttrEditLoodsmanModel* ldsmnEditAttrModel;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,139 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>570</width>
|
||||
<height>563</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Главное окно</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
<widget class="TreePropView" name="treeViewObjAttr"/>
|
||||
</widget>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTreeView" name="treeViewType"/>
|
||||
<widget class="QTreeView" name="treeViewLink"/>
|
||||
<widget class="QTreeView" name="treeViewStat"/>
|
||||
<widget class="QTreeView" name="treeViewAttr"/>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnTestProject">
|
||||
<property name="text">
|
||||
<string>Тест проекта</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnModelTest">
|
||||
<property name="text">
|
||||
<string>Тест модели</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnTypeTest">
|
||||
<property name="text">
|
||||
<string>Тест типов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnLinkTest">
|
||||
<property name="text">
|
||||
<string>Тест связей</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnStatTest">
|
||||
<property name="text">
|
||||
<string>Тест состояний</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pshBtnAttrTest">
|
||||
<property name="text">
|
||||
<string>Тест атрибутов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblIcon">
|
||||
<property name="text">
|
||||
<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>171</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>570</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>TreePropView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>treepropview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,401 @@
|
|||
#include "midasdata.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
|
||||
MidasData::MidasData(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool MidasData::first()
|
||||
{
|
||||
if (recordCount()>0){
|
||||
m_current = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void MidasData::last()
|
||||
{
|
||||
m_current = recordCount()-1;
|
||||
}
|
||||
|
||||
quint16 MidasData::fieldCount()
|
||||
{
|
||||
|
||||
return m_field.count();
|
||||
}
|
||||
|
||||
qint32 MidasData::recordCount()
|
||||
{
|
||||
return m_record.count();
|
||||
}
|
||||
|
||||
|
||||
MidasField MidasData::field(long index){
|
||||
|
||||
return m_field.at(index);
|
||||
}
|
||||
|
||||
QString MidasData::fieldName(long index)
|
||||
{
|
||||
return m_field.at(index).fieldName;
|
||||
}
|
||||
|
||||
void MidasData::setData(unsigned char *data)
|
||||
{
|
||||
m_field.clear();
|
||||
fillField(data);
|
||||
m_record.clear();
|
||||
fillRecord(data);
|
||||
first();
|
||||
}
|
||||
|
||||
unsigned char *MidasData::data()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned char MidasData::getStsBit(unsigned char* stsBit, long index){
|
||||
|
||||
int idxChar = (int)(index/4);
|
||||
int shiftBit = index - idxChar * 4;
|
||||
unsigned char status = stsBit[idxChar];
|
||||
status = (status >> shiftBit*2) & 3;
|
||||
return status;
|
||||
}
|
||||
|
||||
int MidasData::indexOf(QString name){
|
||||
for (int i=0;i<m_field.count();i++)
|
||||
if (m_field.at(i).fieldName==name){
|
||||
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
QVariant MidasData::fieldValue(long index)
|
||||
{
|
||||
return m_record.at(m_current).at(index);
|
||||
}
|
||||
|
||||
bool MidasData::next()
|
||||
{
|
||||
if (m_current+1 < recordCount()){
|
||||
m_current++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool MidasData::prior()
|
||||
{
|
||||
if (m_current-1 >= 0){
|
||||
m_current--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MidasData::clear()
|
||||
{
|
||||
m_field.clear();
|
||||
m_record.clear();
|
||||
}
|
||||
|
||||
void MidasData::fillField(unsigned char *data)
|
||||
{
|
||||
MidasField retField;
|
||||
long offsetField = 24;
|
||||
|
||||
quint16 fieldCount;
|
||||
memcpy(&fieldCount,(data+12),sizeof(fieldCount));
|
||||
|
||||
for (long i=0;i<fieldCount;i++){
|
||||
quint8 lenField;
|
||||
memcpy(&lenField,(data+offsetField),sizeof(lenField));
|
||||
|
||||
char* fieldName = new char[lenField+1];
|
||||
memcpy(fieldName,(data+offsetField+1),lenField);
|
||||
fieldName[lenField] = '\0';
|
||||
retField.fieldName = QString::fromLocal8Bit(fieldName);
|
||||
|
||||
qint16 fieldSize;
|
||||
memcpy(&fieldSize,(data+offsetField+lenField+1),sizeof(fieldSize));
|
||||
retField.fieldSize = fieldSize;
|
||||
|
||||
qint16 fieldType;
|
||||
memcpy(&fieldType,(data+offsetField+lenField+3),sizeof(fieldType));
|
||||
retField.fieldType = fieldType;
|
||||
|
||||
quint16 fieldPropCount;
|
||||
memcpy(&fieldPropCount,(data+offsetField+7+lenField),sizeof(fieldPropCount));
|
||||
retField.propCount = fieldPropCount;
|
||||
|
||||
m_field.append(retField);
|
||||
|
||||
// Чтение свойств поля
|
||||
|
||||
long offsetProp = offsetField + lenField + 9;
|
||||
|
||||
for (int j=0;j<fieldPropCount;j++){
|
||||
quint8 lenPropName;
|
||||
memcpy(&lenPropName,(data+offsetProp),sizeof(lenPropName));
|
||||
|
||||
char* propName = new char[lenPropName+1];
|
||||
memcpy(propName,(data+offsetProp+1),lenPropName);
|
||||
propName[lenPropName] = '\0';
|
||||
|
||||
qint16 propSize;
|
||||
memcpy(&propSize,(data+offsetProp+lenPropName+1),sizeof(propSize));
|
||||
|
||||
qint16 propType;
|
||||
memcpy(&propType,(data+offsetProp+lenPropName+3),sizeof(propType));
|
||||
|
||||
long lenData;
|
||||
if (propType&MaskVaryingFld){
|
||||
// VarFieldData
|
||||
if (propSize==1){
|
||||
qint8 len;
|
||||
memcpy(&len,(data+offsetProp+lenPropName+5),sizeof(len));
|
||||
lenData = len + propSize;
|
||||
} else {
|
||||
qint16 len;
|
||||
memcpy(&len,(data+offsetProp+lenPropName+5),sizeof(len));
|
||||
lenData = len + propSize;
|
||||
}
|
||||
} else {
|
||||
lenData = propSize;
|
||||
}
|
||||
offsetProp = offsetProp + lenPropName + lenData+5;
|
||||
}
|
||||
offsetField = offsetProp;
|
||||
// Окончание чтения свойств поля
|
||||
}
|
||||
}
|
||||
|
||||
void MidasData::fillRecord(unsigned char *data)
|
||||
{
|
||||
quint16 headerSize;
|
||||
memcpy(&headerSize,(data+22),sizeof(headerSize));
|
||||
long offsetValue = headerSize;
|
||||
|
||||
qint32 recordCount;
|
||||
memcpy(&recordCount,(data+14),sizeof(recordCount));
|
||||
|
||||
for (int r=0;r<recordCount;r++){
|
||||
|
||||
MidasRecord record;
|
||||
|
||||
quint8 recordStatus;
|
||||
memcpy(&recordStatus,(data+offsetValue),sizeof(recordStatus));
|
||||
|
||||
int lenStsBit = (int)(((fieldCount()-1)/4)+1);
|
||||
unsigned char* stsBit = new unsigned char[lenStsBit];
|
||||
memcpy(stsBit,(data+offsetValue+1),lenStsBit);
|
||||
|
||||
offsetValue = offsetValue + lenStsBit+1;
|
||||
for (int i=0;i<fieldCount();i++){
|
||||
|
||||
MidasField fieldIndex = field(i);
|
||||
qint16 typeField;
|
||||
long lenData;
|
||||
if (!(getStsBit(stsBit,i)&(bitNotAll))){
|
||||
if (fieldIndex.fieldType&MaskVaryingFld){
|
||||
// VarFieldData
|
||||
|
||||
if (fieldIndex.fieldSize==1){
|
||||
qint8 len;
|
||||
memcpy(&len,(data+offsetValue),sizeof(len));
|
||||
lenData = len;
|
||||
} else {
|
||||
qint16 len;
|
||||
memcpy(&len,(data+offsetValue),sizeof(len));
|
||||
lenData = len;
|
||||
}
|
||||
|
||||
offsetValue = offsetValue +fieldIndex.fieldSize;
|
||||
typeField = fieldIndex.fieldType & MaskFieldType;
|
||||
} else {
|
||||
lenData = fieldIndex.fieldSize;
|
||||
typeField = fieldIndex.fieldType;
|
||||
}
|
||||
|
||||
|
||||
QVariant var;
|
||||
switch(typeField) {
|
||||
case dsfldZSTRING:
|
||||
{
|
||||
char* fieldData;
|
||||
fieldData = new char[lenData+1];
|
||||
memcpy(fieldData,(data+offsetValue),lenData);
|
||||
fieldData[lenData] = '\0';
|
||||
var = QVariant(QString::fromLocal8Bit(fieldData));
|
||||
delete fieldData;
|
||||
}
|
||||
break;
|
||||
case dsfldINT:
|
||||
if (fieldIndex.fieldSize==1){
|
||||
qint8 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==2){
|
||||
qint16 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==4){
|
||||
qint32 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==8){
|
||||
qint64 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип Int размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldUINT:
|
||||
if (fieldIndex.fieldSize==1){
|
||||
quint8 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==2){
|
||||
quint16 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==4){
|
||||
quint32 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==8){
|
||||
quint64 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип UInt размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldBOOL:
|
||||
{
|
||||
bool fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
}
|
||||
break;
|
||||
case dsfldFLOATIEEE:
|
||||
if (fieldIndex.fieldSize==4){
|
||||
float fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else if (fieldIndex.fieldSize==8){
|
||||
double fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(fieldData);
|
||||
} else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип FLOATIEEE размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldBCD:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип BCD размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldDATE:
|
||||
if (fieldIndex.fieldSize==4){
|
||||
quint32 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
QDate date(1,1,2);
|
||||
date =date.addDays(fieldData);
|
||||
var = QVariant(date);
|
||||
} else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип Date размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldTIME:
|
||||
if (fieldIndex.fieldSize==4){
|
||||
quint32 fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
QTime time;
|
||||
time = time.addMSecs(fieldData);
|
||||
var = QVariant(time);
|
||||
}else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип Time размером %1 не обработан").arg(lenData));
|
||||
|
||||
break;
|
||||
case dsfldTIMESTAMP:
|
||||
if (fieldIndex.fieldSize==8){
|
||||
double fieldData;
|
||||
memcpy(&fieldData,(data+offsetValue),lenData);
|
||||
QDateTime timestamp;
|
||||
timestamp.setDate(QDate(1,1,2));
|
||||
timestamp = timestamp.addMSecs(fieldData);
|
||||
var = QVariant(timestamp);
|
||||
}else
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип TimeShtamp размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldUNICODE:
|
||||
{
|
||||
wchar_t* fieldData;
|
||||
fieldData = new wchar_t[(int)(lenData/2)];
|
||||
memcpy(fieldData,(data+offsetValue),((int)(lenData/2))*2);
|
||||
var = QVariant(QString::fromWCharArray(fieldData));
|
||||
delete fieldData;
|
||||
}
|
||||
break;
|
||||
case dsfldBYTES:
|
||||
{
|
||||
char* fieldData;
|
||||
fieldData = new char[lenData];
|
||||
memcpy(fieldData,(data+offsetValue),lenData);
|
||||
var = QVariant(QByteArray(fieldData,lenData));
|
||||
delete fieldData;
|
||||
}
|
||||
//QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип BYTES размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldADT:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип AbstractDataType размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldARRAY:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип ArrayType размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldEMBEDDEDTBL:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип Embedded (nested table type) размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
case dsfldREF:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Тип Reference размером %1 не обработан").arg(lenData));
|
||||
break;
|
||||
default:
|
||||
QMessageBox::warning(NULL,tr("Предупреждение"),tr("Неизвестный тип %1 размером %2 не обработан").arg(typeField).arg(lenData));
|
||||
}
|
||||
record.append(var);
|
||||
offsetValue = offsetValue + lenData;
|
||||
} else
|
||||
record.append(QVariant());
|
||||
}
|
||||
m_record.append(record);
|
||||
}
|
||||
}
|
||||
|
||||
long MidasData::currentRecord()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
bool MidasData::setCurrentRecord(long value)
|
||||
{
|
||||
if (value>=0 && value < recordCount()){
|
||||
m_record.at(value);
|
||||
m_record.first();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
QVariant MidasData::fieldValue(QString name)
|
||||
{
|
||||
int index = indexOf(name);
|
||||
|
||||
if (index!=-1)
|
||||
return fieldValue(index);
|
||||
return QVariant();
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
#ifndef MIDASDATA_H
|
||||
#define MIDASDATA_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QtGlobal>
|
||||
#include <QVector>
|
||||
|
||||
enum MidasStsBit{
|
||||
bitNull = 1, //! Поле пустое
|
||||
bitNotChange = 2, //! Поле не изменено
|
||||
bitNotAll = 3 //! Поле пустое и не изменено
|
||||
};
|
||||
|
||||
enum MidasRecordStatus{
|
||||
dsRecUnmodified = 0x0000,//! { Unmodified record }
|
||||
dsRecOrg = 0x0001, //! { Original record (was changed) }
|
||||
dsRecDeleted = 0x0002, //! { Record was deleted }
|
||||
dsRecNew = 0x0004, //! { Record was inserted }
|
||||
dsRecModified = 0x0008, //! { Record was changed }
|
||||
dsUnused = 0x0020, //! { Record not used anymore (hole) }
|
||||
dsDetUpd = 0x0040 //! { Detail modification Ins/Del/Mod. }{ Can be combined with other status. }
|
||||
};
|
||||
|
||||
enum MidasAttrs{
|
||||
fldAttrHIDDEN = 0x0001, //! { Field is hidden }
|
||||
fldAttrREADONLY = 0x0002, //! { Field is readonly }
|
||||
fldAttrREQUIRED = 0x0004, //! { Field value required }
|
||||
fldAttrLINK = 0x0008 //! { Linking field }
|
||||
};
|
||||
|
||||
enum MidasFieldType{
|
||||
dsfldUNKNOWN = 0, //! { Unknown }
|
||||
dsfldINT = 1, //! { signed integer }
|
||||
dsfldUINT = 2, //! { Unsigned integer }
|
||||
dsfldBOOL = 3, //! { Boolean }
|
||||
dsfldFLOATIEEE = 4, //! { IEEE float }
|
||||
dsfldBCD = 5, //! { BCD }
|
||||
dsfldDATE = 6, //! { Date (32 bit) }
|
||||
dsfldTIME = 7, //! { Time (32 bit) }
|
||||
dsfldTIMESTAMP = 8, //! { Time-stamp (64 bit) }
|
||||
dsfldZSTRING = 9, //! { Multi-byte string }
|
||||
dsfldUNICODE = 10, //! { unicode string }
|
||||
dsfldBYTES = 11, //! { bytes }
|
||||
dsfldADT = 12, //! { ADT (Abstract Data Type) }
|
||||
dsfldARRAY = 13, //! { Array type (not attribute) }
|
||||
dsfldEMBEDDEDTBL = 14, //! { Embedded (nested table type) }
|
||||
dsfldREF = 15 //! { Reference }
|
||||
};
|
||||
|
||||
enum MidasMaskField {
|
||||
MaskFieldType = 0x3F, //! { mask to retrieve Field Type }
|
||||
MaskVaryingFld = 0x40, //! { Varying attribute type. }
|
||||
MaskArrayFld = 0x80 //! { Array attribute type. } - Данные массива предваряются длиной Len: Int32, за которой следуют его элементы Data[Len].
|
||||
};
|
||||
|
||||
/* Пример структуры пакета MIDAS/DATASNAP
|
||||
|
||||
struct MidasProp{
|
||||
quint32 CHANGE_LOG[]; // UInt32[] - массив из целых чисел.
|
||||
quint32 DATASET_DELTA;// UInt32 = 1, если в пакете передается delta-набор (набор изменений).
|
||||
};
|
||||
|
||||
struct MidasRecord{
|
||||
quint8 recordStatus; // Статус записи: MidasRecordStatus
|
||||
unsigned char statusBit[fieldCount/4]; // На каждое поле в массиве статусных битов отводится 2 бита от младшего к старшему. Данные полей содержащих Null или NotChanged в запись не попадают.
|
||||
// BLANK_NULL = 1; { 'real' NULL }
|
||||
// BLANK_NOTCHANGED = 2; { Not changed , compared to original value }
|
||||
unsigned char fieldData[]; // FieldData[] - пишутся только not null & changed значения.
|
||||
// Для полей фиксированного размера: FixedFieldData = Byte[FieldSize]
|
||||
// Для полей переменного размера: VarFieldData = (DataLen: UInt(of FieldSize)) Byte[DataLen] - те обычно данные предваряются 1-2 байтами размера.
|
||||
};
|
||||
|
||||
struct MidasFieldProp{
|
||||
quint8 len; // Длина имени свойства
|
||||
char propName[len]; // Имя свойства
|
||||
qint16 propSize; // Для строк - длина фиксированной части, те размера
|
||||
qint16 propType; // Тип свойства: MidasFieldType
|
||||
unsigned char data[propSize]; // Данные свойства
|
||||
};
|
||||
|
||||
struct MidasField{
|
||||
quint8 len; // Длина имени поля
|
||||
char fieldName[len]; // Имя поля
|
||||
qint16 fieldSize; // Для строк - длина фиксированной части, те размера
|
||||
qint16 fieldType; // Тип Поля: MidasFieldType
|
||||
qint16 fieldAttrs; // Атрибуты (флаги) поля: MidasAttrs
|
||||
quint16 propCount; // Количество свойств поля
|
||||
MidasFieldProp props[propCount]; // Cвойства поля
|
||||
// WIDTH: UInt16 - для полей переменного размера, например строк, равно Field.Size. Те это предельный размер данных, хранимых в поле.
|
||||
};
|
||||
|
||||
struct MidasPacket{
|
||||
unsigned char signature[4]; // Сигнатура пакета MIDAS/DataSnap [$96, $19, $E0, $BD]
|
||||
qint32 skip1; // Int32, обычно равно 1
|
||||
qint32 skip2; // Int32, обычно равно 18
|
||||
quint16 fieldCount; // UInt16 - количество полей
|
||||
qint32 recordCount; // Int32 - количество записей в пакете
|
||||
qint32 skip3; // Int32, обычно равно 3
|
||||
quint16 headerSize; // UInt16 - вероятно, размер всего заголовка включая описания полей и свойств.
|
||||
MidasField fieldList[fieldCount]; // Структура описания полей.
|
||||
quint16 propCount; // UInt16 - количество свойств
|
||||
MidasProp props[propCount]; // Свойства набора
|
||||
MidasRecord recordList[recordCount]; // Данные записей (начинается с headerSize)
|
||||
};
|
||||
*/
|
||||
|
||||
struct MidasField{
|
||||
QString fieldName; //! Имя поля
|
||||
qint16 fieldSize; //! Для строк - длина фиксированной части, те размера
|
||||
qint16 fieldType; //! Тип Поля: MidasFieldType
|
||||
qint16 fieldAttrs; //! Атрибуты (флаги) поля: MidasAttrs
|
||||
quint16 propCount; //! Количество свойств поля
|
||||
};
|
||||
|
||||
typedef QVector<QVariant> MidasRecord;
|
||||
|
||||
class MidasData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MidasData(QObject *parent = 0);
|
||||
|
||||
//! Переход на начало
|
||||
bool first();
|
||||
//! Переход в конец
|
||||
void last();
|
||||
//! Переход на следующую
|
||||
bool next();
|
||||
//! Переход на предыдущую
|
||||
bool prior();
|
||||
|
||||
//! Очистка полей и записей
|
||||
void clear();
|
||||
|
||||
//! Заполнение полей
|
||||
void fillField(unsigned char* data);
|
||||
|
||||
//! Заполнение записей
|
||||
/*! Не реализована обработка: dsfldADT,dsfldARRAY, dsfldEMBEDDEDTBL, dsfldREF и MaskArrayFld
|
||||
*/
|
||||
void fillRecord(unsigned char* data);
|
||||
|
||||
//! Текущая запись
|
||||
long currentRecord();
|
||||
//! Установить текущую запись
|
||||
bool setCurrentRecord(long value);
|
||||
|
||||
//! Получение значения поля по его имени
|
||||
QVariant fieldValue(QString name);
|
||||
//! Получение значения поля по индексу
|
||||
QVariant fieldValue(long index);
|
||||
|
||||
//! Получение имени поля по индексу
|
||||
QString fieldName(long index);
|
||||
|
||||
//! Чтение данных пакета MIDAS
|
||||
void setData(unsigned char* data);
|
||||
//! Получение данных пакета MIDAS
|
||||
unsigned char* data();
|
||||
|
||||
//! Кол-во полей
|
||||
quint16 fieldCount();
|
||||
//! Кол-во записей
|
||||
qint32 recordCount();
|
||||
|
||||
//! Получение описания поля по индексу
|
||||
MidasField field(long index);
|
||||
|
||||
//! Получение индекса поля по его имени
|
||||
int indexOf(QString name);
|
||||
private:
|
||||
//! Получение статусных битов значения записи
|
||||
unsigned char getStsBit(unsigned char *stsBit, long index);
|
||||
//! Список полей
|
||||
QVector<MidasField> m_field;
|
||||
//! Список записей
|
||||
QVector<MidasRecord> m_record;
|
||||
//! Текущая запись
|
||||
long m_current;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // MIDASDATA_H
|
|
@ -0,0 +1,266 @@
|
|||
#include "propeditordelegate.h"
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QDateEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QStringListModel>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
PropEditorDelegate::PropEditorDelegate(QObject *parent) :
|
||||
QItemDelegate(parent)
|
||||
{
|
||||
m_colors.reserve(6);
|
||||
m_colors.push_back(QColor(255, 230, 191));
|
||||
m_colors.push_back(QColor(255, 255, 191));
|
||||
m_colors.push_back(QColor(191, 255, 191));
|
||||
m_colors.push_back(QColor(199, 255, 255));
|
||||
m_colors.push_back(QColor(234, 191, 255));
|
||||
m_colors.push_back(QColor(255, 191, 239));
|
||||
}
|
||||
|
||||
QWidget *PropEditorDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
|
||||
long id = index.sibling(index.row(),1/*_ID*/).data().toInt();
|
||||
|
||||
// Единицы измерения
|
||||
if (index.column()==9/*_UNIT*/)
|
||||
if (!m_attrModel->data(id, m_attrModel->fieldIndex("_ID_NATURE")).toString().isEmpty())
|
||||
{
|
||||
QComboBox* pRes = new QComboBox(parent);
|
||||
QList<UnitsAttr> listUnits = m_attrModel->listUnits(
|
||||
m_attrModel->data(id, m_attrModel->fieldIndex("_ID_NATURE")).toString());
|
||||
|
||||
QStandardItemModel *model = new QStandardItemModel(listUnits.count(), 2);
|
||||
|
||||
for (int row = 0; row < listUnits.count(); ++row) {
|
||||
QStandardItem *item = new QStandardItem(listUnits.at(row).id);
|
||||
model->setItem(row, 1, item);
|
||||
item = new QStandardItem(listUnits.at(row).name);
|
||||
model->setItem(row, 0, item);
|
||||
}
|
||||
|
||||
pRes->setModel(model);
|
||||
return pRes;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
// Список значений
|
||||
if (index.column()==7/*_VALUE*/ &&
|
||||
!m_attrModel->data(id, m_attrModel->fieldIndex("_LIST")).toString().isEmpty())
|
||||
{
|
||||
QComboBox* pRes = new QComboBox(parent);
|
||||
QStringList list = m_attrModel->data(id, m_attrModel->fieldIndex("_LIST")).toString().split("\r\n");
|
||||
QStringListModel *model = new QStringListModel(pRes);
|
||||
model->setStringList(list);
|
||||
pRes->setModel(model);
|
||||
return pRes;
|
||||
}
|
||||
|
||||
// Календарь
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Date) {
|
||||
QDateEdit* pRes = new QDateEdit(parent);
|
||||
pRes->setCalendarPopup(true);
|
||||
pRes->setDisplayFormat("dd.MM.yyyy HH:mm");
|
||||
return pRes;
|
||||
}
|
||||
|
||||
// Логическое
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Bool) {
|
||||
QCheckBox* pRes = new QCheckBox(parent);
|
||||
return pRes;
|
||||
}
|
||||
|
||||
return QItemDelegate::createEditor(parent,option,index);
|
||||
}
|
||||
|
||||
void PropEditorDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
|
||||
{
|
||||
long id = index.sibling(index.row(),1/*_ID*/).data().toInt();
|
||||
|
||||
// Установка значения по умолчанию
|
||||
if (!m_attrModel->data(id, m_attrModel->fieldIndex("_DEFAULT")).isNull() &&
|
||||
index.column()==7/*_VALUE*/ && index.data().isNull()){
|
||||
if (editor->inherits("QLineEdit"))
|
||||
(qobject_cast<QLineEdit*>(editor))->setText(index.data().toString());
|
||||
else if (editor->inherits("QSpinBox"))
|
||||
(qobject_cast<QSpinBox*>(editor))->setValue(index.data().toInt());
|
||||
else if (editor->inherits("QDoubleSpinBox"))
|
||||
(qobject_cast<QDoubleSpinBox*>(editor))->setValue(index.data().toDouble());
|
||||
return;
|
||||
}
|
||||
|
||||
// Список значений
|
||||
if (index.column()==7/*_VALUE*/ &&
|
||||
!m_attrModel->data(id, m_attrModel->fieldIndex("_LIST")).toString().isEmpty())
|
||||
{
|
||||
QComboBox *pRes = static_cast<QComboBox*>(editor);
|
||||
for (int row=0;row<pRes->model()->rowCount();row++)
|
||||
if (pRes->model()->index(row,0).data()==index.sibling(index.row(),7/*_ID_UNIT*/).data()){
|
||||
pRes->setCurrentIndex(row);
|
||||
return;
|
||||
}
|
||||
pRes->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Единицы измерения
|
||||
if (index.column()==9/*_UNIT*/){
|
||||
QComboBox *pRes = static_cast<QComboBox*>(editor);
|
||||
for (int row=0;row<pRes->model()->rowCount();row++)
|
||||
if (pRes->model()->index(row,1).data()==index.sibling(index.row(),8/*_ID_UNIT*/).data()){
|
||||
pRes->setCurrentIndex(row);
|
||||
return;
|
||||
}
|
||||
pRes->setCurrentIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Календарь
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Date) {
|
||||
QDateEdit *pRes = static_cast<QDateEdit*>(editor);
|
||||
pRes->setDate(index.model()->data(index, Qt::EditRole).toDate());
|
||||
return;
|
||||
}
|
||||
|
||||
// Логическое
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Bool) {
|
||||
QCheckBox *pRes = static_cast<QCheckBox*>(editor);
|
||||
pRes->setChecked(index.model()->data(index, Qt::EditRole).toBool());
|
||||
return;
|
||||
}
|
||||
|
||||
QItemDelegate::setEditorData(editor,index);
|
||||
return;
|
||||
}
|
||||
|
||||
void PropEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
// Единицы измерения
|
||||
if (index.column()==9/*_UNIT*/ && editor->inherits("QComboBox")){
|
||||
QComboBox *pRes = static_cast<QComboBox*>(editor);
|
||||
model->setData(index,pRes->currentText(),Qt::EditRole);
|
||||
model->setData(index.sibling(index.row(),8/*_ID_UNIT*/),
|
||||
pRes->model()->index(pRes->currentIndex(),1).data().toString(),
|
||||
Qt::EditRole
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Список значений
|
||||
if (editor->inherits("QComboBox")) {
|
||||
QComboBox *pRes = static_cast<QComboBox*>(editor);
|
||||
model->setData(index,pRes->currentText(),Qt::EditRole);
|
||||
return;
|
||||
}
|
||||
|
||||
// Календарь
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Date) {
|
||||
QDateEdit *pRes = static_cast<QDateEdit*>(editor);
|
||||
model->setData(index,pRes->date(),Qt::EditRole);
|
||||
return;
|
||||
}
|
||||
|
||||
// Логическое
|
||||
if (index.data(Qt::EditRole).type() == QVariant::Bool) {
|
||||
QCheckBox *pRes = static_cast<QCheckBox*>(editor);
|
||||
model->setData(index,pRes->isChecked(),Qt::EditRole);
|
||||
return;
|
||||
}
|
||||
|
||||
QItemDelegate::setModelData(editor,model,index);
|
||||
return;
|
||||
}
|
||||
|
||||
void PropEditorDelegate::updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index)
|
||||
|
||||
editor->setGeometry(option.rect);
|
||||
return;
|
||||
}
|
||||
|
||||
void PropEditorDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItemV3 opt = option;
|
||||
|
||||
bool isHeader = false;
|
||||
if (!index.parent().isValid())
|
||||
isHeader = true;
|
||||
|
||||
bool isModified = false;
|
||||
|
||||
if (index.column() == 0 && isModified) {
|
||||
opt.font.setBold(true);
|
||||
opt.fontMetrics = QFontMetrics(opt.font);
|
||||
}
|
||||
|
||||
QColor c;
|
||||
if (isHeader) {
|
||||
c = opt.palette.color(QPalette::Dark);
|
||||
opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText));
|
||||
} else {
|
||||
c = QColor(255, 230, 191);
|
||||
if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate))
|
||||
c = c.lighter(112);
|
||||
}
|
||||
if (c.isValid())
|
||||
painter->fillRect(option.rect, c);
|
||||
opt.state &= ~QStyle::State_HasFocus;
|
||||
|
||||
// Логический
|
||||
if (index.model()->data(index, Qt::EditRole).type() == QVariant::Bool){
|
||||
QSize size = QSize(5,5);//check(option, option.rect, Qt::Checked).size();
|
||||
QRect checkboxRect = QStyle::alignedRect(option.direction, (Qt::AlignVCenter|Qt::AlignLeft), size, option.rect);
|
||||
drawCheck(painter,option,checkboxRect,Qt::Checked);
|
||||
} else
|
||||
QItemDelegate::paint(painter, opt, index);
|
||||
|
||||
opt.palette.setCurrentColorGroup(QPalette::Active);
|
||||
QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
|
||||
painter->save();
|
||||
painter->setPen(QPen(color));
|
||||
if (/*!lastColumn(index.column()) &&*/ !isHeader) {
|
||||
int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left();
|
||||
painter->drawLine(right, option.rect.y(), right, option.rect.bottom());
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QColor PropEditorDelegate::calcBgColor(const QModelIndex &index) const
|
||||
{
|
||||
QModelIndex i = index;
|
||||
while (i.parent().isValid())
|
||||
i = i.parent();
|
||||
|
||||
long rowColor;
|
||||
if (i.row()<m_colors.count())
|
||||
rowColor = i.row();
|
||||
else
|
||||
rowColor = i.row()%m_colors.count();
|
||||
|
||||
return m_colors.at(rowColor);
|
||||
}
|
||||
|
||||
QSize PropEditorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return QItemDelegate::sizeHint(option, index) + QSize(3, 4);
|
||||
}
|
||||
|
||||
void PropEditorDelegate::setAttrModel(AttrLoodsmanModel *model)
|
||||
{
|
||||
m_attrModel = model;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef PROPEDITORDELEGATE_H
|
||||
#define PROPEDITORDELEGATE_H
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include "attrloodsmanmodel.h"
|
||||
|
||||
class PropEditorDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PropEditorDelegate(QObject *parent = 0);
|
||||
virtual QWidget * createEditor ( QWidget * parent,
|
||||
const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index ) const;
|
||||
virtual void setEditorData( QWidget * editor,
|
||||
const QModelIndex & index ) const;
|
||||
virtual void setModelData( QWidget * editor, QAbstractItemModel * model,
|
||||
const QModelIndex & index ) const;
|
||||
virtual void updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex & index) const;
|
||||
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
QColor calcBgColor(const QModelIndex &index) const;
|
||||
|
||||
virtual QSize sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
void setAttrModel(AttrLoodsmanModel* model);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QVector<QColor> m_colors;
|
||||
AttrLoodsmanModel* m_attrModel;
|
||||
};
|
||||
|
||||
#endif // PROPEDITORDELEGATE_H
|
|
@ -0,0 +1,244 @@
|
|||
#include "statloodsmanmodel.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include "QMessageBox"
|
||||
#include <QIcon>
|
||||
|
||||
StatLoodsmanModel::StatLoodsmanModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
dataSet = new MidasData();
|
||||
m_root = new TreeNode;
|
||||
m_root->id = 0;
|
||||
m_root->isFetch = false;
|
||||
cache.insert(0,m_root);
|
||||
}
|
||||
|
||||
StatLoodsmanModel::~StatLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int StatLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeNode *StatLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeNode*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant StatLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole && index.column()==0 && !m_fieldIcon.isEmpty()){
|
||||
QPixmap pixmap;
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item) {
|
||||
pixmap.loadFromData(item->data.at(m_fieldNames.count()).toByteArray());
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item)
|
||||
return item->data.at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StatLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags StatLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant StatLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool StatLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex StatLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode* childItem = cache[parentItem->children.at(row)];
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex StatLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode *childItem = getItem(index);
|
||||
TreeNode *parentItem = cache[childItem->parent];
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode *grandparent = cache[parentItem->parent];
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->children.count(); i++)
|
||||
if (grandparent->children.at(i) == parentItem->id)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int StatLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return getItem(parent)->children.count();
|
||||
}
|
||||
|
||||
bool StatLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
TreeNode* node = getItem(parent);
|
||||
if (node->isFetch && node->children.count()==0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StatLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return !getItem(parent)->isFetch;
|
||||
}
|
||||
|
||||
void StatLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeNode *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
_variant_t data = loodsman->main->GetInfoAboutCurrentBase(7,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
if (dataSet->first()){
|
||||
do {
|
||||
int childId = dataSet->fieldValue("_ID").toInt();
|
||||
long parentId = 0/*dataSet->fieldValue("_ID_PARENT_TYPE").toInt()*/;
|
||||
|
||||
TreeNode *item = /*cache[parentId]*/m_root;
|
||||
if (item==NULL){
|
||||
if (parentId == 0)
|
||||
item = m_root;
|
||||
else {
|
||||
item = new TreeNode;
|
||||
item->id = parentId;
|
||||
cache.insert(parentId, item);
|
||||
item->isFetch = true;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* childItem;
|
||||
if (!cache.contains(childId)){
|
||||
childItem = new TreeNode;
|
||||
childItem->id = childId;
|
||||
childItem->isFetch = true;
|
||||
cache.insert(childId, childItem);
|
||||
item->children.append(childId);
|
||||
} else {
|
||||
childItem = cache[childId];
|
||||
childItem->data.clear();
|
||||
}
|
||||
|
||||
childItem->parent = parentId;
|
||||
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ )
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
if (!m_fieldIcon.isEmpty())
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldIcon));
|
||||
} while (dataSet->next());
|
||||
dataSet->clear();
|
||||
|
||||
m_root->isFetch = true;
|
||||
beginInsertRows(QModelIndex(), 0,cache[0]->children.count());
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList StatLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void StatLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void StatLoodsmanModel::setFieldIcon(QString column)
|
||||
{
|
||||
m_fieldIcon = column;
|
||||
}
|
||||
|
||||
int StatLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef STATLOODSMANMODEL_H
|
||||
#define STATLOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QStringList>
|
||||
#include "treenode.h"
|
||||
#include "midasdata.h"
|
||||
|
||||
class StatLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit StatLoodsmanModel(QObject *parent = 0);
|
||||
~StatLoodsmanModel();
|
||||
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeNode *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields );
|
||||
|
||||
void setFieldIcon(QString column);
|
||||
int fieldIndex(const QString &fieldName) const;
|
||||
private:
|
||||
TreeNode* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Поле с Иконкой
|
||||
QString m_fieldIcon;
|
||||
|
||||
mutable QHash<long, TreeNode*> cache;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // STATLOODSMANMODEL_H
|
|
@ -0,0 +1,34 @@
|
|||
#include "treeitem.h"
|
||||
#include "converttype.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include "midasdata.h"
|
||||
|
||||
TreeItem::TreeItem(long rootid, TreeItem *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
id = rootid;
|
||||
m_parent = parent;
|
||||
m_fetchedMore = false;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::childAt(int i) const
|
||||
{
|
||||
return (m_children.count() > i)? m_children.at(i) : 0;
|
||||
}
|
||||
|
||||
void TreeItem::setFectMore(bool flag)
|
||||
{
|
||||
this->m_fetchedMore = flag;
|
||||
}
|
||||
|
||||
bool TreeItem::canFetchMore() const
|
||||
{
|
||||
return !m_fetchedMore;
|
||||
}
|
||||
|
||||
void TreeItem::append(TreeItem *item)
|
||||
{
|
||||
m_children.append(item);
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef TREEITEM_H
|
||||
#define TREEITEM_H
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
class TreeItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TreeItem(long rootid,TreeItem *parent = 0);
|
||||
|
||||
TreeItem* childAt(int i) const;
|
||||
|
||||
TreeItem* parent() const{
|
||||
return m_parent;
|
||||
}
|
||||
bool hasChildren(){
|
||||
return (!(m_fetchedMore && m_children.empty()));
|
||||
}
|
||||
int childCount()const{
|
||||
return m_children.count();
|
||||
}
|
||||
|
||||
void setFectMore(bool flag);
|
||||
|
||||
bool canFetchMore() const;
|
||||
|
||||
void append(TreeItem *item);
|
||||
|
||||
long id;
|
||||
|
||||
private:
|
||||
QList<TreeItem*> m_children;
|
||||
TreeItem* m_parent;
|
||||
bool m_fetchedMore;
|
||||
|
||||
int fieldNumber;
|
||||
};
|
||||
|
||||
#endif // TREEITEM_H
|
|
@ -0,0 +1,553 @@
|
|||
#include "treeloodsmanmodel.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QStandardItemModel>
|
||||
#include <QDateTime>
|
||||
|
||||
TreeLoodsmanModel::TreeLoodsmanModel(TreeItem *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
m_root = new TreeItem(0);
|
||||
dataSet = new MidasData();
|
||||
}
|
||||
|
||||
TreeLoodsmanModel::~TreeLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int TreeLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeItem *TreeLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeItem*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant TreeLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid() || role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
TreeItem *item = getItem(index);
|
||||
if (item)
|
||||
return m_data[item->id]->at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool TreeLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags TreeLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant TreeLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool TreeLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex TreeLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeItem* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem* childItem = parentItem->childAt(row);
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TreeLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeItem *childItem = getItem(index);
|
||||
TreeItem *parentItem = childItem->parent();
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *grandparent = parentItem->parent();
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->childCount(); i++)
|
||||
if (grandparent->childAt(i) == parentItem)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int TreeLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
/*if(getItem(parent)->canFetchMore()){
|
||||
TreeItem* item = parent.isValid()? static_cast<TreeItem*>(parent.internalPointer()) : m_root;
|
||||
if(item)
|
||||
item->populateChildren();
|
||||
}*/
|
||||
|
||||
return getItem(parent)->childCount();
|
||||
}
|
||||
|
||||
bool TreeLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
|
||||
//bool result = getItem(parent)->hasChildren();
|
||||
|
||||
return getItem(parent)->hasChildren();
|
||||
}
|
||||
|
||||
bool TreeLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return getItem(parent)->canFetchMore();
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeItem *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
_variant_t data = loodsman->main->GetTree2(item->id,
|
||||
to_bstr_t(m_linkType),
|
||||
0,
|
||||
&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
}else{
|
||||
item = m_root;
|
||||
|
||||
_variant_t data = loodsman->main->GetProjectList2(item->id,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
}
|
||||
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
for (int i=0;i<dataSet->recordCount();i++){
|
||||
if (i==0)
|
||||
dataSet->first();
|
||||
else
|
||||
dataSet->next();
|
||||
|
||||
int childId = dataSet->fieldValue(QString("_ID_VERSION")).toInt();
|
||||
TreeItem *childItem = new TreeItem(childId,item);
|
||||
|
||||
QList<QVariant>* listData = new QList<QVariant>;
|
||||
|
||||
// Запись данных
|
||||
if (m_data[childId] == NULL){
|
||||
if (item->id == 0)
|
||||
for ( int j=0; j < m_prjFieldNames.count(); j++ ){
|
||||
listData->append(dataSet->fieldValue(m_prjFieldNames[j]));
|
||||
}
|
||||
else
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ ){
|
||||
listData->append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
}
|
||||
m_data[childId] = listData;
|
||||
}
|
||||
item->append(childItem);
|
||||
}
|
||||
dataSet->clear();
|
||||
item->setFectMore(true);
|
||||
|
||||
// Обновление
|
||||
if (item->id == 0)
|
||||
beginInsertRows(QModelIndex(), 0, item->childCount());
|
||||
else
|
||||
beginInsertRows(parent, 0, item->childCount());
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::fetchMoreAttr(const QModelIndex &parent)
|
||||
{
|
||||
TreeItem *item;
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
long objId = item->id;
|
||||
if (m_attrVal.contains(objId))
|
||||
return;
|
||||
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
/* ЗАГРУЖАЕТ ВСЕ АТРИБУТЫ ВЫБРАННОГО ТИПА БЕЗ ЗНАЧЕНИЙ */
|
||||
AttrMap attrMap;
|
||||
long typeId = data(parent.sibling(parent.row(),fieldIndex("_ID_TYPE"))).toInt();
|
||||
|
||||
if (typeId >0){
|
||||
QList<long> listIdAttr = m_typeModel->listAttr(typeId);
|
||||
for (int i=0;i<listIdAttr.count();i++){
|
||||
long idAttr = listIdAttr.value(i);
|
||||
QList<QVariant> listData;
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_NAME")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ID")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ATTRTYPE")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_DEFAULT")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_LIST")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ACCESSLEVEL")));
|
||||
// isAttrLink
|
||||
listData.append(false);
|
||||
attrMap.insert(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_NAME")).toString(),
|
||||
listData);
|
||||
}
|
||||
}
|
||||
|
||||
long parentTypeId = data(parent.parent().sibling(parent.parent().row(),fieldIndex("_ID_TYPE"))).toInt();
|
||||
long linkId = data(parent.sibling(parent.row(),fieldIndex("_ID_LINKTYPE"))).toInt();
|
||||
|
||||
if (typeId >0 && parentTypeId>0 && linkId>0){
|
||||
QString objLink = m_linkModel->data(linkId,m_linkModel->fieldIndex("_NAME")).toString();
|
||||
QList<long> listIdAttr = m_typeModel->listAttrLink(typeId,parentTypeId,objLink);
|
||||
|
||||
for (int i=0;i<listIdAttr.count();i++){
|
||||
long idAttr = listIdAttr.value(i);
|
||||
QList<QVariant> listData;
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_NAME")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ID")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ATTRTYPE")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_DEFAULT")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_LIST")));
|
||||
listData.append(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_ACCESSLEVEL")));
|
||||
// isAttrLink
|
||||
listData.append(true);
|
||||
attrMap.insert(m_attrModel->data(idAttr,m_attrModel->fieldIndex("_NAME")).toString(),
|
||||
listData);
|
||||
}
|
||||
}
|
||||
|
||||
/* ЗАГРУЖАЕТ ЗНАЧЕНИЕ АТРИБУТОВ
|
||||
0 - строковое значение;
|
||||
1 - целочисленное значение;
|
||||
2 - действительное число;
|
||||
3 - дата и время;
|
||||
5 - текст;
|
||||
6 - изображение);
|
||||
|
||||
0 - BSTR
|
||||
1 - int
|
||||
2 - double
|
||||
3 - DateTime
|
||||
5 - массив байт (Значение представляет собой одномерный вариантный массив (тип VT_UI1 (VC++), varByte(Delphi)))
|
||||
6 - массив байт (Значение представляет собой одномерный вариантный массив (тип VT_UI1 (VC++), varByte(Delphi)))
|
||||
*/
|
||||
|
||||
long objLinkId = data(parent.sibling(parent.row(),fieldIndex("_ID_LINK"))).toInt();
|
||||
|
||||
_variant_t testData = loodsman->main->GetAttributesValues2(
|
||||
to_bstr_t(QString("%1").arg(objId)),
|
||||
"",&inErrorCode, &stErrorMessage);
|
||||
|
||||
unsigned char *p = (unsigned char *)testData.parray->pvData;
|
||||
MidasData* mData = new MidasData();
|
||||
mData->setData(p);
|
||||
if (mData->first()){
|
||||
do{
|
||||
QString name = mData->fieldValue("_NAME").toString();
|
||||
QList<QVariant> listData = attrMap.value(name);
|
||||
QStringList list;
|
||||
QDateTime dt;
|
||||
switch (listData.at(2).toInt()) {
|
||||
case 0:
|
||||
listData.append(mData->fieldValue("_VALUE").toString());
|
||||
break;
|
||||
case 1:
|
||||
listData.append(mData->fieldValue("_VALUE").toInt());
|
||||
break;
|
||||
case 2:
|
||||
listData.append(mData->fieldValue("_VALUE").toDouble());
|
||||
break;
|
||||
case 3:
|
||||
list = mData->fieldValue("_VALUE").toString().split(QRegExp("\\s+"));
|
||||
if (list.count()>0)
|
||||
dt.setDate(QDate::fromString(list.at(0),"dd.MM.yyyy"));
|
||||
if (list.count()>1)
|
||||
dt.setTime(QTime::fromString(list.at(1),"HH:mm"));
|
||||
listData.append(dt);
|
||||
break;
|
||||
default:
|
||||
listData.append(mData->fieldValue("_VALUE"));
|
||||
}
|
||||
listData.append(mData->fieldValue("_ID_UNIT"));
|
||||
listData.append(mData->fieldValue("_UNIT"));
|
||||
attrMap[name] = listData;
|
||||
}while (mData->next());
|
||||
}
|
||||
|
||||
if (objLinkId > 0)
|
||||
{
|
||||
testData = loodsman->main->GetLinkAttributes(
|
||||
objLinkId,
|
||||
&inErrorCode, &stErrorMessage);
|
||||
|
||||
p = (unsigned char *)testData.parray->pvData;
|
||||
mData->clear();
|
||||
mData->setData(p);
|
||||
if (mData->first()){
|
||||
do{
|
||||
QString name = mData->fieldValue("_NAME").toString();
|
||||
QList<QVariant> listData = attrMap.value(name);
|
||||
QStringList list;
|
||||
QDateTime dt;
|
||||
switch (listData.at(2).toInt()) {
|
||||
case 0:
|
||||
listData.append(mData->fieldValue("_VALUE").toString());
|
||||
break;
|
||||
case 1:
|
||||
listData.append(mData->fieldValue("_VALUE").toInt());
|
||||
break;
|
||||
case 2:
|
||||
listData.append(mData->fieldValue("_VALUE").toDouble());
|
||||
break;
|
||||
case 3:
|
||||
list = mData->fieldValue("_VALUE").toString().split(QRegExp("\\s+"));
|
||||
if (list.count()>0)
|
||||
dt.setDate(QDate::fromString(list.at(0),"dd.MM.yyyy"));
|
||||
if (list.count()>1)
|
||||
dt.setTime(QTime::fromString(list.at(1),"HH:mm"));
|
||||
listData.append(dt);
|
||||
break;
|
||||
default:
|
||||
listData.append(mData->fieldValue("_VALUE"));
|
||||
}
|
||||
listData.append(mData->fieldValue("_ID_UNIT"));
|
||||
listData.append(mData->fieldValue("_UNIT"));
|
||||
attrMap[name] = listData;
|
||||
}while (mData->next());
|
||||
}
|
||||
}
|
||||
m_attrVal.insert(objId,attrMap);
|
||||
}
|
||||
|
||||
QStringList TreeLoodsmanModel::fields(bool isProject)
|
||||
{
|
||||
return (isProject)?m_prjFieldNames:m_fieldNames;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setFields(const QStringList &dataFields, bool isProject)
|
||||
{
|
||||
if (isProject)
|
||||
m_prjFieldNames = dataFields;
|
||||
else
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setLinkType(const QStringList &linkType)
|
||||
{
|
||||
foreach(QString linkName,linkType){
|
||||
if (m_linkType.isEmpty())
|
||||
m_linkType = linkName;
|
||||
else
|
||||
m_linkType = m_linkType + QString(char(1)) + linkName;
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractItemModel* TreeLoodsmanModel::getAttrModel(const QModelIndex &parent)
|
||||
{
|
||||
fetchMoreAttr(parent);
|
||||
TreeItem *item;
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
QStandardItemModel* attrModel = new QStandardItemModel(0,10);
|
||||
attrModel->setHeaderData(0, Qt::Horizontal, tr("_NAME"));
|
||||
attrModel->setHeaderData(1, Qt::Horizontal, tr("_ID"));
|
||||
attrModel->setHeaderData(2, Qt::Horizontal, tr("_ATTRTYPE"));
|
||||
attrModel->setHeaderData(3, Qt::Horizontal, tr("_DEFAULT"));
|
||||
attrModel->setHeaderData(4, Qt::Horizontal, tr("_LIST"));
|
||||
attrModel->setHeaderData(5, Qt::Horizontal, tr("_ACCESSLEVEL"));
|
||||
attrModel->setHeaderData(6, Qt::Horizontal, tr("_ISATTRLINK"));
|
||||
attrModel->setHeaderData(7, Qt::Horizontal, tr("_VALUE"));
|
||||
attrModel->setHeaderData(8, Qt::Horizontal, tr("_ID_UNIT"));
|
||||
attrModel->setHeaderData(9, Qt::Horizontal, tr("_UNIT"));
|
||||
|
||||
QStandardItem *parentItem = attrModel->invisibleRootItem();
|
||||
QStandardItem *oitem = new QStandardItem(tr("Атрибуты объекта"));
|
||||
parentItem->appendRow(oitem);
|
||||
QStandardItem *litem = new QStandardItem(tr("Атрибуты связи"));
|
||||
parentItem->appendRow(litem);
|
||||
|
||||
long objId = item->id;
|
||||
foreach (QList<QVariant> value, m_attrVal.value(objId)){
|
||||
QList<QStandardItem *> listoitem;
|
||||
for (int i=0;i<10;i++){
|
||||
QStandardItem *item = new QStandardItem();
|
||||
if (i<value.count())
|
||||
item->setData(value.at(i), Qt::EditRole);
|
||||
else
|
||||
if (i==7)
|
||||
switch (value.at(2).toInt()) {
|
||||
case 0:
|
||||
item->setData(QVariant::String, Qt::EditRole);
|
||||
break;
|
||||
case 1:
|
||||
item->setData(QVariant::Int, Qt::EditRole);
|
||||
break;
|
||||
case 2:
|
||||
item->setData(QVariant::Double, Qt::EditRole);
|
||||
break;
|
||||
case 3:
|
||||
item->setData(QVariant::DateTime, Qt::EditRole);
|
||||
break;
|
||||
default:
|
||||
item->setData(QVariant::String, Qt::EditRole);
|
||||
}
|
||||
else
|
||||
item->setData(QVariant::String, Qt::EditRole);
|
||||
listoitem << item;
|
||||
}
|
||||
if (value.at(6)==true)
|
||||
litem->appendRow(listoitem);
|
||||
else
|
||||
oitem->appendRow(listoitem);
|
||||
}
|
||||
|
||||
attrModel->submit();
|
||||
/*QStandardItemModel* model = new QStandardItemModel();
|
||||
QStandardItem *parentItem = model->invisibleRootItem();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
|
||||
parentItem->appendRow(item);
|
||||
parentItem = item;
|
||||
}
|
||||
return model;*/
|
||||
return attrModel;
|
||||
}
|
||||
|
||||
AttrMap TreeLoodsmanModel::attrMap(const QModelIndex &parent)
|
||||
{
|
||||
fetchMoreAttr(parent);
|
||||
TreeItem *item;
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return AttrMap();
|
||||
}
|
||||
|
||||
long objId = item->id;
|
||||
return m_attrVal.value(objId);
|
||||
}
|
||||
|
||||
long TreeLoodsmanModel::fieldIndex(const QString &fieldName, bool isProject)
|
||||
{
|
||||
if (isProject){
|
||||
for (long i = 0;i<m_prjFieldNames.count();i++)
|
||||
if (m_prjFieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
}else{
|
||||
for (long i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setTypeModel(TypeLoodsmanModel *model)
|
||||
{
|
||||
m_typeModel = model;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setLinkModel(LinkLoodsmanModel *model)
|
||||
{
|
||||
m_linkModel = model;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setStatModel(StatLoodsmanModel *model)
|
||||
{
|
||||
m_statModel = model;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::setAttrModel(AttrLoodsmanModel *model)
|
||||
{
|
||||
m_attrModel = model;
|
||||
}
|
||||
|
||||
void TreeLoodsmanModel::select()
|
||||
{
|
||||
QStringList prjFields;
|
||||
prjFields << "_ID_VERSION" << "_PRODUCT" << "_ID_TYPE" << "_ID_STATE"
|
||||
<< "_HAS_LINK" << "_ID_LOCK" << "_VERSION" << "_ACCESSLEVEL"
|
||||
<< "_REVISION" << "_ID_LINKTYPE";
|
||||
setFields(prjFields,true);
|
||||
QStringList fields;
|
||||
fields << "_ID_VERSION" << "_PRODUCT" << "_ID_TYPE" <<"_ID_STATE"
|
||||
<< "_HAS_LINK" << "_ID_LOCK" << "_VERSION" << "_ACCESSLEVEL"
|
||||
<< "_ID_LINK" << "_ID_LINKTYPE";
|
||||
setFields(fields,false);
|
||||
|
||||
QStringList linkList;
|
||||
m_linkModel->fetchMore(QModelIndex());
|
||||
|
||||
for (int row = 0; row < m_linkModel->rowCount(); row++){
|
||||
QModelIndex indexName = m_linkModel->index(row, m_linkModel->fieldIndex("_NAME"));
|
||||
QModelIndex indexType = m_linkModel->index(row, m_linkModel->fieldIndex("_TYPE"));
|
||||
if (m_linkModel->data(indexType)==0)
|
||||
linkList << m_linkModel->data(indexName).toString();
|
||||
}
|
||||
setLinkType(linkList);
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef TREELOODSMANMODEL_H
|
||||
#define TREELOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
#include <QStringList>
|
||||
#include "treeitem.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "midasdata.h"
|
||||
|
||||
#include "typeloodsmanmodel.h"
|
||||
#include "linkloodsmanmodel.h"
|
||||
#include "statloodsmanmodel.h"
|
||||
#include "attrloodsmanmodel.h"
|
||||
|
||||
typedef QMap<QString, QVariantList> AttrMap;
|
||||
|
||||
class TreeLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TreeLoodsmanModel(TreeItem *parent = 0);
|
||||
~TreeLoodsmanModel();
|
||||
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeItem *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields(bool isProject) ;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение модели атрибутов для объекта
|
||||
QAbstractItemModel *getAttrModel(const QModelIndex &parent);
|
||||
|
||||
//! Получение индекса поля
|
||||
long fieldIndex(const QString &fieldName, bool isProject = false);
|
||||
|
||||
void setTypeModel(TypeLoodsmanModel *model);
|
||||
void setLinkModel(LinkLoodsmanModel *model);
|
||||
void setStatModel(StatLoodsmanModel *model);
|
||||
void setAttrModel(AttrLoodsmanModel *model);
|
||||
|
||||
void select();
|
||||
|
||||
//! Ленивое чтение атрибутов объекта
|
||||
void fetchMoreAttr(const QModelIndex &parent);
|
||||
|
||||
//! Получение атрибутов
|
||||
AttrMap attrMap(const QModelIndex &parent);
|
||||
private:
|
||||
|
||||
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields , bool isProject);
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setLinkType(const QStringList& linkType);
|
||||
|
||||
//! Данные узла дерева
|
||||
TreeItem* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_prjFieldNames;
|
||||
|
||||
//! Список связей
|
||||
QString m_linkType;
|
||||
|
||||
//! Значение атрибутов [id_obj,id_attr,список свойств атрибута]
|
||||
QMap <long, AttrMap> m_attrVal;
|
||||
|
||||
TypeLoodsmanModel* m_typeModel;
|
||||
LinkLoodsmanModel* m_linkModel;
|
||||
StatLoodsmanModel* m_statModel;
|
||||
AttrLoodsmanModel* m_attrModel;
|
||||
|
||||
mutable QMap<long, QList<QVariant>* > m_data;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // TREELOODSMANMODEL_H
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef TREENODE_H
|
||||
#define TREENODE_H
|
||||
struct TreeNode
|
||||
{
|
||||
long id;
|
||||
long parent;
|
||||
QList<long> children;
|
||||
QList<QVariant> data;
|
||||
bool isFetch;
|
||||
};
|
||||
#endif // TREENODE_H
|
|
@ -0,0 +1,129 @@
|
|||
#include "treepropview.h"
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QHeaderView>
|
||||
#include <QDebug>
|
||||
#include <QRect>
|
||||
|
||||
TreePropView::TreePropView(QWidget *parent) :
|
||||
QTreeView(parent)
|
||||
{
|
||||
m_colors.reserve(6);
|
||||
m_colors.push_back(QColor(255, 230, 191));
|
||||
m_colors.push_back(QColor(255, 255, 191));
|
||||
m_colors.push_back(QColor(191, 255, 191));
|
||||
m_colors.push_back(QColor(199, 255, 255));
|
||||
m_colors.push_back(QColor(234, 191, 255));
|
||||
m_colors.push_back(QColor(255, 191, 239));
|
||||
|
||||
QPixmap pix(14, 14);
|
||||
pix.fill(Qt::transparent);
|
||||
QStyleOption branchOption;
|
||||
QRect r(QPoint(0, 0), pix.size());
|
||||
branchOption.rect = QRect(2, 2, 9, 9);
|
||||
branchOption.palette = this->palette();
|
||||
branchOption.state = QStyle::State_Children;
|
||||
QPainter p;
|
||||
// Закрытое состояние
|
||||
p.begin(&pix);
|
||||
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
|
||||
p.end();
|
||||
QIcon rc = pix;
|
||||
rc.addPixmap(pix, QIcon::Selected, QIcon::Off);
|
||||
m_iconClosed = QIcon(pix);
|
||||
// Открытое состояние
|
||||
branchOption.state |= QStyle::State_Open;
|
||||
pix.fill(Qt::transparent);
|
||||
p.begin(&pix);
|
||||
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, &p);
|
||||
p.end();
|
||||
m_iconOpen = QIcon(pix);
|
||||
|
||||
setRootIsDecorated(false);
|
||||
setAlternatingRowColors(true);
|
||||
}
|
||||
|
||||
void TreePropView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItemV3 opt = option;
|
||||
|
||||
if (!index.parent().isValid()) {
|
||||
const QColor c = option.palette.color(QPalette::Dark);
|
||||
painter->fillRect(option.rect, c);
|
||||
opt.font.setBold(true);
|
||||
} else {
|
||||
const QColor c = calcBgColor(index);
|
||||
if (c.isValid()) {
|
||||
painter->fillRect(option.rect, c);
|
||||
opt.palette.setColor(QPalette::AlternateBase, c.lighter(112));
|
||||
}
|
||||
}
|
||||
QTreeView::drawRow(painter, opt, index);
|
||||
QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
|
||||
painter->save();
|
||||
painter->setPen(QPen(color));
|
||||
painter->drawLine(opt.rect.x(), opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void TreePropView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (index.isValid()&& (event->button() == Qt::LeftButton)) {
|
||||
if (index.parent().isValid()) {
|
||||
if (!index.column()==0)
|
||||
edit(index);
|
||||
} else if (!rootIsDecorated()) {
|
||||
setExpanded(index,!isExpanded(index));
|
||||
if (isExpanded(index))
|
||||
model()->setData(index,m_iconOpen,Qt::DecorationRole);
|
||||
else
|
||||
model()->setData(index,m_iconClosed,Qt::DecorationRole);
|
||||
}
|
||||
setCurrentIndex(index);
|
||||
return;
|
||||
}
|
||||
if (index.column()==0)
|
||||
return;
|
||||
|
||||
QTreeView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void TreePropView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
connect(model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),this,SLOT(updateHeaderRow(QModelIndex,QModelIndex)));
|
||||
QTreeView::setModel(model);
|
||||
this->expandAll();
|
||||
for (int i=0;i<model->rowCount();i++){
|
||||
this->setFirstColumnSpanned(i,QModelIndex(),true);
|
||||
QModelIndex index = model->index(i,0);
|
||||
if (isExpanded(index))
|
||||
model->setData(index,m_iconOpen,Qt::DecorationRole);
|
||||
else
|
||||
model->setData(index,m_iconClosed,Qt::DecorationRole);
|
||||
}
|
||||
}
|
||||
|
||||
void TreePropView::updateHeaderRow(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||||
{
|
||||
Q_UNUSED(bottomRight)
|
||||
|
||||
if (!this->rootIsDecorated() && !topLeft.parent().isValid())
|
||||
setFirstColumnSpanned(topLeft.row(),QModelIndex(),true);
|
||||
}
|
||||
|
||||
QColor TreePropView::calcBgColor(const QModelIndex &index) const
|
||||
{
|
||||
QModelIndex i = index;
|
||||
while (i.parent().isValid())
|
||||
i = i.parent();
|
||||
|
||||
long rowColor;
|
||||
if (i.row()<m_colors.count())
|
||||
rowColor = i.row();
|
||||
else
|
||||
rowColor = i.row()%m_colors.count();
|
||||
|
||||
return m_colors.at(rowColor);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef TREEPROPVIEW_H
|
||||
#define TREEPROPVIEW_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QIcon>
|
||||
|
||||
class TreePropView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TreePropView(QWidget *parent = 0);
|
||||
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void setModel(QAbstractItemModel *model);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
void updateHeaderRow(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
|
||||
private:
|
||||
QColor calcBgColor(const QModelIndex &index) const;
|
||||
|
||||
QIcon m_iconClosed;
|
||||
QIcon m_iconOpen;
|
||||
QVector<QColor> m_colors;
|
||||
};
|
||||
|
||||
#endif // TREEVIEWPROP_H
|
|
@ -0,0 +1,336 @@
|
|||
#include "typeloodsmanmodel.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include <QMessageBox>
|
||||
#include <QIcon>
|
||||
#include <QDebug>
|
||||
|
||||
TypeLoodsmanModel::TypeLoodsmanModel(TreeItem *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
dataSet = new MidasData();
|
||||
m_root = new TreeNodeType;
|
||||
m_root->id = 0;
|
||||
m_root->isFetch = false;
|
||||
cache.insert(0,m_root);
|
||||
m_fieldIcon = -1;
|
||||
|
||||
QStringList fields;
|
||||
fields << "_ID_TYPE" << "_TYPENAME" << "_IS_ABSTRACT"
|
||||
<< "_DOCUMENT" << "_ID_PARENT_TYPE";
|
||||
setFields(fields);
|
||||
setFieldIcon("_ICON");
|
||||
}
|
||||
|
||||
TypeLoodsmanModel::~TypeLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int TypeLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeNodeType *TypeLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeNodeType*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant TypeLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole && index.column()==0 && !m_fieldIcon.isEmpty()){
|
||||
QPixmap pixmap;
|
||||
const TreeNodeType *item = getItem(index);
|
||||
if (item) {
|
||||
pixmap.loadFromData(item->data.at(m_fieldNames.count()).toByteArray());
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
const TreeNodeType *item = getItem(index);
|
||||
if (item)
|
||||
return item->data.at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant TypeLoodsmanModel::data(long id, int column) const
|
||||
{
|
||||
if(cache.contains(id)){
|
||||
TreeNodeType *item = cache[id];
|
||||
if (item)
|
||||
return item->data.at(column);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool TypeLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags TypeLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant TypeLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool TypeLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex TypeLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNodeType* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNodeType* childItem = cache[parentItem->children.at(row)];
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TypeLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNodeType *childItem = getItem(index);
|
||||
TreeNodeType *parentItem = cache[childItem->parent];
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNodeType *grandparent = cache[parentItem->parent];
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->children.count(); i++)
|
||||
if (grandparent->children.at(i) == parentItem->id)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int TypeLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return getItem(parent)->children.count();
|
||||
}
|
||||
|
||||
bool TypeLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
TreeNodeType* node = getItem(parent);
|
||||
if (node->isFetch && node->children.count()==0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TypeLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return !getItem(parent)->isFetch;
|
||||
}
|
||||
|
||||
void TypeLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeNodeType *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
_variant_t data = loodsman->main->GetInfoAboutCurrentBase(61,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
if (dataSet->first()){
|
||||
do {
|
||||
int childId = dataSet->fieldValue("_ID_TYPE").toInt();
|
||||
long parentId = dataSet->fieldValue("_ID_PARENT_TYPE").toInt();
|
||||
|
||||
TreeNodeType *item = cache[parentId];
|
||||
if (item==NULL){
|
||||
if (parentId == 0)
|
||||
item = m_root;
|
||||
else {
|
||||
item = new TreeNodeType;
|
||||
item->id = parentId;
|
||||
cache.insert(parentId, item);
|
||||
item->isFetch = true;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNodeType* childItem;
|
||||
if (!cache.contains(childId)){
|
||||
childItem = new TreeNodeType;
|
||||
childItem->id = childId;
|
||||
childItem->isFetch = true;
|
||||
cache.insert(childId, childItem);
|
||||
item->children.append(childId);
|
||||
} else {
|
||||
childItem = cache[childId];
|
||||
childItem->data.clear();
|
||||
}
|
||||
childItem->parent = parentId;
|
||||
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ )
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
|
||||
if (!m_fieldIcon.isEmpty())
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldIcon));
|
||||
} while (dataSet->next());
|
||||
dataSet->clear();
|
||||
|
||||
m_root->isFetch = true;
|
||||
beginInsertRows(QModelIndex(), 0,cache[0]->children.count());
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QList<long> TypeLoodsmanModel::listAttr(long typeId){
|
||||
|
||||
if (m_attr.contains(typeId))
|
||||
return m_attr.value(typeId);
|
||||
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
QString objType = data(typeId,fieldIndex("_TYPENAME")).toString();
|
||||
|
||||
_variant_t testData = loodsman->main->GetInfoAboutType(to_bstr_t(objType),
|
||||
1,
|
||||
&inErrorCode,
|
||||
&stErrorMessage);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
unsigned char *p = (unsigned char *)testData.parray->pvData;
|
||||
MidasData* mData = new MidasData();
|
||||
mData->setData(p);
|
||||
QList<long> attrMap;
|
||||
if (mData->first()) do
|
||||
attrMap.append(mData->fieldValue("_ID").toInt());
|
||||
while (mData->next());
|
||||
|
||||
m_attr[typeId] = attrMap;
|
||||
|
||||
return attrMap;
|
||||
}
|
||||
|
||||
QList<long> TypeLoodsmanModel::listAttrLink(long masterTypeId, long slaveTypeId, QString linkName)
|
||||
{
|
||||
AttrLinkKey key;
|
||||
key.id = masterTypeId;
|
||||
key.pid = slaveTypeId;
|
||||
key.lid = linkName;
|
||||
|
||||
if (m_attrLink.contains(key))
|
||||
return m_attrLink.value(key);
|
||||
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
QString objType = data(masterTypeId,fieldIndex("_TYPENAME")).toString();
|
||||
QString parentObjType = data(slaveTypeId,fieldIndex("_TYPENAME")).toString();;
|
||||
QString objLink = linkName;
|
||||
|
||||
_variant_t testData = loodsman->main->GetLinkAttrForTypes(to_bstr_t(parentObjType),
|
||||
to_bstr_t(objType),
|
||||
to_bstr_t(objLink),
|
||||
&inErrorCode,
|
||||
&stErrorMessage);
|
||||
|
||||
unsigned char *p = (unsigned char *)testData.parray->pvData;
|
||||
MidasData* mData = new MidasData();
|
||||
mData->setData(p);
|
||||
|
||||
QList<long> attrMap;
|
||||
if (mData->first()) do
|
||||
attrMap.append(mData->fieldValue("_ID").toInt());
|
||||
while (mData->next());
|
||||
|
||||
|
||||
m_attrLink[key] = attrMap;
|
||||
|
||||
return attrMap;
|
||||
}
|
||||
|
||||
QStringList TypeLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void TypeLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void TypeLoodsmanModel::setFieldIcon(QString column)
|
||||
{
|
||||
m_fieldIcon = column;
|
||||
}
|
||||
|
||||
int TypeLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*TreeNodeType *TypeLoodsmanModel::node(long id) const
|
||||
{
|
||||
return cache[id];
|
||||
}*/
|
|
@ -0,0 +1,106 @@
|
|||
#ifndef TYPELOODSMANMODEL_H
|
||||
#define TYPELOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "attrlinkkey.h"
|
||||
#include "treeitem.h"
|
||||
#include "midasdata.h"
|
||||
#include "treenode.h"
|
||||
|
||||
struct TreeNodeType:public TreeNode
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class TypeLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TypeLoodsmanModel(TreeItem *parent = 0);
|
||||
~TypeLoodsmanModel();
|
||||
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant data(long id, int column) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeNodeType *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение списка атрибутов
|
||||
QList<long> listAttr(long typeId);
|
||||
QList<long> listAttrLink(long masterTypeId, long slaveTypeId, QString linkName);
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
//! Возращает индекс поля или если не найдено поле -1
|
||||
int fieldIndex( const QString & fieldName ) const;
|
||||
|
||||
private:
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields );
|
||||
|
||||
//! Установить поле с иконкой
|
||||
void setFieldIcon(QString column);
|
||||
|
||||
|
||||
TreeNodeType* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Поле с Иконкой
|
||||
QString m_fieldIcon;
|
||||
|
||||
mutable QHash<long, TreeNodeType*> cache;
|
||||
QMap<long, QList<long> > m_attr;
|
||||
QMap<AttrLinkKey, QList<long> > m_attrLink;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // TYPELOODSMANMODEL_H
|
|
@ -0,0 +1,247 @@
|
|||
#include "unitsloodsmanmodel.h"
|
||||
#include "loodsmansystem.h"
|
||||
#include "converttype.h"
|
||||
#include <QPixmap>
|
||||
#include <QIcon>
|
||||
#include <QMessageBox>
|
||||
|
||||
UnitsLoodsmanModel::UnitsLoodsmanModel(QObject *parent) :
|
||||
QAbstractItemModel(parent)
|
||||
{
|
||||
dataSet = new MidasData();
|
||||
m_root = new TreeNode;
|
||||
m_root->id = 0;
|
||||
m_root->isFetch = false;
|
||||
cache.insert(0,m_root);
|
||||
}
|
||||
|
||||
UnitsLoodsmanModel::~UnitsLoodsmanModel()
|
||||
{
|
||||
delete dataSet;
|
||||
}
|
||||
|
||||
int UnitsLoodsmanModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return m_fieldNames.count();
|
||||
}
|
||||
|
||||
TreeNode *UnitsLoodsmanModel::getItem(const QModelIndex & index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
return static_cast<TreeNode*>(index.internalPointer());
|
||||
else
|
||||
return m_root;
|
||||
}
|
||||
|
||||
QVariant UnitsLoodsmanModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DecorationRole && index.column()==0 && !m_fieldIcon.isEmpty()){
|
||||
QPixmap pixmap;
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item) {
|
||||
pixmap.loadFromData(item->data.at(m_fieldNames.count()).toByteArray());
|
||||
return QIcon(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
if(role == Qt::DisplayRole){
|
||||
const TreeNode *item = getItem(index);
|
||||
if (item)
|
||||
return item->data.at(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool UnitsLoodsmanModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(index);
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::ItemFlags UnitsLoodsmanModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return 0;
|
||||
Qt::ItemFlags fl = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
/*if ( d->isEditable( index.internalId(), index.column() ) )
|
||||
fl |= Qt::ItemIsEditable;*/
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant UnitsLoodsmanModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
return m_fieldNames.at(section);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool UnitsLoodsmanModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
|
||||
{
|
||||
Q_UNUSED(value);
|
||||
Q_UNUSED(section);
|
||||
|
||||
if (role != Qt::EditRole || orientation != Qt::Horizontal)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex UnitsLoodsmanModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if(!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode* parentItem = getItem(parent);
|
||||
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode* childItem = cache[parentItem->children.at(row)];
|
||||
|
||||
if (childItem)
|
||||
return createIndex(row, column, (void*)childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex UnitsLoodsmanModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if(!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
const TreeNode *childItem = getItem(index);
|
||||
TreeNode *parentItem = cache[childItem->parent];
|
||||
|
||||
if (!parentItem || parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
TreeNode *grandparent = cache[parentItem->parent];
|
||||
if (!grandparent)
|
||||
return QModelIndex();
|
||||
|
||||
for (int i = 0; i < grandparent->children.count(); i++)
|
||||
if (grandparent->children.at(i) == parentItem->id)
|
||||
return createIndex(i, 0, (void*) parentItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int UnitsLoodsmanModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if(parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
return getItem(parent)->children.count();
|
||||
}
|
||||
|
||||
bool UnitsLoodsmanModel::hasChildren(const QModelIndex & parent) const
|
||||
{
|
||||
TreeNode* node = getItem(parent);
|
||||
if (node->isFetch && node->children.count()==0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnitsLoodsmanModel::canFetchMore(const QModelIndex &parent) const
|
||||
{
|
||||
return !getItem(parent)->isFetch;
|
||||
}
|
||||
|
||||
void UnitsLoodsmanModel::fetchMore(const QModelIndex &parent)
|
||||
{
|
||||
LoodsmanSystem* loodsman = LoodsmanSystem::instance();
|
||||
VARIANT inErrorCode;
|
||||
VARIANT stErrorMessage;
|
||||
|
||||
TreeNode *item;
|
||||
|
||||
if(parent.isValid()){
|
||||
item = getItem(parent);
|
||||
if(!item)
|
||||
return;
|
||||
}
|
||||
|
||||
_variant_t data = loodsman->main->GetInfoAboutCurrentBase(9,&inErrorCode, &stErrorMessage);
|
||||
dataSet->setData((unsigned char *)data.parray->pvData);
|
||||
|
||||
if (inErrorCode.lVal!=0)
|
||||
QMessageBox::warning(NULL, tr("Ошибка соединения"), from_bstr_t(stErrorMessage.bstrVal));
|
||||
|
||||
|
||||
if (dataSet->first()){
|
||||
do {
|
||||
int childId = dataSet->fieldValue("_ID").toInt();
|
||||
long parentId = 0/*dataSet->fieldValue("_ID_PARENT_TYPE").toInt()*/;
|
||||
|
||||
TreeNode *item = /*cache[parentId]*/m_root;
|
||||
if (item==NULL){
|
||||
if (parentId == 0)
|
||||
item = m_root;
|
||||
else {
|
||||
item = new TreeNode;
|
||||
item->id = parentId;
|
||||
cache.insert(parentId, item);
|
||||
item->isFetch = true;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* childItem;
|
||||
if (!cache.contains(childId)){
|
||||
childItem = new TreeNode;
|
||||
childItem->id = childId;
|
||||
childItem->isFetch = true;
|
||||
cache.insert(childId, childItem);
|
||||
item->children.append(childId);
|
||||
} else {
|
||||
childItem = cache[childId];
|
||||
childItem->data.clear();
|
||||
}
|
||||
|
||||
childItem->parent = parentId;
|
||||
|
||||
for ( int j=0; j < m_fieldNames.count(); j++ )
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldNames[j]));
|
||||
if (!m_fieldIcon.isEmpty())
|
||||
childItem->data.append(dataSet->fieldValue(m_fieldIcon));
|
||||
|
||||
} while (dataSet->next());
|
||||
dataSet->clear();
|
||||
|
||||
m_root->isFetch = true;
|
||||
beginInsertRows(QModelIndex(), 0,cache[0]->children.count());
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList UnitsLoodsmanModel::fields()
|
||||
{
|
||||
return m_fieldNames;
|
||||
}
|
||||
|
||||
void UnitsLoodsmanModel::setFields(const QStringList &dataFields)
|
||||
{
|
||||
m_fieldNames = dataFields;
|
||||
}
|
||||
|
||||
void UnitsLoodsmanModel::setFieldIcon(QString column)
|
||||
{
|
||||
m_fieldIcon = column;
|
||||
}
|
||||
|
||||
int UnitsLoodsmanModel::fieldIndex(const QString &fieldName) const
|
||||
{
|
||||
for (int i = 0;i<m_fieldNames.count();i++)
|
||||
if (m_fieldNames.at(i)==fieldName)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef UNITSLOODSMANMODEL_H
|
||||
#define UNITSLOODSMANMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QModelIndex>
|
||||
#include <QVariant>
|
||||
#include <QStringList>
|
||||
|
||||
#include "loodsmansystem.h"
|
||||
#include "midasdata.h"
|
||||
#include "treenode.h"
|
||||
|
||||
class UnitsLoodsmanModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit UnitsLoodsmanModel(QObject *parent = 0);
|
||||
~UnitsLoodsmanModel();
|
||||
|
||||
//! Возращает хранимые данные
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает значение для указанной записи
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
//! Возвращает флаг записи
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
//! Возращает название заголовка
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//! Устанавливает название заголовка
|
||||
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role);
|
||||
|
||||
//! Возращает индекс модели для строки и колонки
|
||||
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;
|
||||
/*
|
||||
//! Удаление строки
|
||||
bool removeRows(int position, int rows, const QModelIndex &parent);
|
||||
|
||||
//! Вставка строки
|
||||
bool insertRows(int position, int rows, const QModelIndex &parent);
|
||||
*/
|
||||
//! Проверка имеются ли дети
|
||||
bool hasChildren(const QModelIndex & parent) const ;
|
||||
|
||||
//! Получение TreeItem по индексу
|
||||
TreeNode *getItem(const QModelIndex &index) const;
|
||||
|
||||
//! Проверка можно ли провести ленивыю инициализацию
|
||||
bool canFetchMore(const QModelIndex &parent) const;
|
||||
|
||||
//! Ленивая инициализация
|
||||
void fetchMore(const QModelIndex &parent);
|
||||
|
||||
//! Получение списка полей с данных
|
||||
QStringList fields() ;
|
||||
|
||||
//! Установка списка полей данных
|
||||
void setFields(const QStringList& dataFields );
|
||||
|
||||
void setFieldIcon(QString column);
|
||||
|
||||
int fieldIndex(const QString &fieldName) const;
|
||||
private:
|
||||
TreeNode* m_root;
|
||||
MidasData* dataSet;
|
||||
|
||||
//! Список полей данных
|
||||
QStringList m_fieldNames;
|
||||
|
||||
//! Поле с Иконкой
|
||||
QString m_fieldIcon;
|
||||
|
||||
mutable QHash<long, TreeNode*> cache;
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // UNITSLOODSMANMODEL_H
|
|
@ -0,0 +1,59 @@
|
|||
#-------------------------------------------------
|
||||
#
|
||||
# Project created by QtCreator 2012-06-01T11:05:15
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
QT += core gui
|
||||
|
||||
|
||||
TARGET = verticallite
|
||||
TEMPLATE = app
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4) {
|
||||
QT += widgets
|
||||
}
|
||||
|
||||
SOURCES += main.cpp\
|
||||
mainwindow.cpp \
|
||||
dialogconnect.cpp \
|
||||
loodsmansystem.cpp \
|
||||
treeloodsmanmodel.cpp \
|
||||
treeitem.cpp \
|
||||
converttype.cpp \
|
||||
application.cpp \
|
||||
midasdata.cpp \
|
||||
typeloodsmanmodel.cpp \
|
||||
linkloodsmanmodel.cpp \
|
||||
statloodsmanmodel.cpp \
|
||||
attrloodsmanmodel.cpp \
|
||||
attreditloodsmanmodel.cpp \
|
||||
attrlinkkey.cpp \
|
||||
propeditordelegate.cpp \
|
||||
treepropview.cpp \
|
||||
unitsloodsmanmodel.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
dialogconnect.h \
|
||||
converttype.h \
|
||||
loodsmansystem.h \
|
||||
treeloodsmanmodel.h \
|
||||
treeitem.h \
|
||||
application.h \
|
||||
midasdata.h \
|
||||
typeloodsmanmodel.h \
|
||||
linkloodsmanmodel.h \
|
||||
statloodsmanmodel.h \
|
||||
treenode.h \
|
||||
attrloodsmanmodel.h \
|
||||
attreditloodsmanmodel.h \
|
||||
attrlinkkey.h \
|
||||
propeditordelegate.h \
|
||||
treepropview.h \
|
||||
unitsloodsmanmodel.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
dialogconnect.ui
|
||||
|
||||
RESOURCES +=
|
||||
|
Reference in New Issue