From 9e1a99b598d0fd5f29f078574980dc0281eca185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Wed, 28 Sep 2016 12:24:52 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/libs@127 a8b55f48-bf90-11e4-a774-851b48703e85 --- cd_utils/cdutils_core.cpp | 8 +- cd_utils/cdutils_core.h | 1 + cd_utils/cdutils_k.cpp | 5 ++ cd_utils/cdutils_k.h | 1 + cd_utils/cdutils_types.cpp | 159 ++++++++++++++++++++++++++++++++++-- cd_utils/cdutils_types.h | 16 +++- cd_utils/pult/cd_kmodel.cpp | 14 +++- cd_utils/pult/cdkview.cpp | 5 ++ cd_utils/pult/cdkview.h | 1 + cd_utils/pult/form.cpp | 14 +++- cd_utils/pult/form.h | 3 +- cd_utils/pult/form.ui | 9 +- qad_widgets/icons/f1.png | Bin 0 -> 1046 bytes qad_widgets/qad_widgets.qrc | 1 + qad_widgets/qcodeedit.cpp | 40 +++++---- qad_widgets/qcodeedit.h | 3 +- 16 files changed, 249 insertions(+), 31 deletions(-) create mode 100644 qad_widgets/icons/f1.png diff --git a/cd_utils/cdutils_core.cpp b/cd_utils/cdutils_core.cpp index 7e95195..139f2c8 100644 --- a/cd_utils/cdutils_core.cpp +++ b/cd_utils/cdutils_core.cpp @@ -128,6 +128,12 @@ void CDCore::k_update(PIIODevice * d) { k_ = uk; } + +void CDCore::k_calculate() { + k_.calculate(); +} + + void CDCore::reinitConnection(const PIString &configuration) { PIString c = configuration; connection.stop(); @@ -248,7 +254,7 @@ void CDCore::dtReceiveFinished(bool ok) { K_Send(); break; case CD_KSend: { - piCoutObj << "K received"; + piCoutObj << "K received"; PIByteArray k; ba >> k; k << uchar(0); diff --git a/cd_utils/cdutils_core.h b/cd_utils/cdutils_core.h index 07f89fd..d7e9d1e 100644 --- a/cd_utils/cdutils_core.h +++ b/cd_utils/cdutils_core.h @@ -42,6 +42,7 @@ public: void k_read(PIIODevice * d); void k_parse(PIIODevice * d); void k_update(PIIODevice * d); + void k_calculate(); PIString pultConfig() {return PIString(pult_config);} PIString appConfig() {return PIString(app_config);} void reinitConnection(const PIString & configuration); diff --git a/cd_utils/cdutils_k.cpp b/cd_utils/cdutils_k.cpp index 1c5d07f..c93d62e 100644 --- a/cd_utils/cdutils_k.cpp +++ b/cd_utils/cdutils_k.cpp @@ -118,6 +118,11 @@ void KInterface::update(PIIODevice * d) { } +void KInterface::calculate() { + core->k_calculate(); +} + + PIString KInterface::appConfig() { return core->appConfig(); } diff --git a/cd_utils/cdutils_k.h b/cd_utils/cdutils_k.h index 54de25a..f2d2f5f 100644 --- a/cd_utils/cdutils_k.h +++ b/cd_utils/cdutils_k.h @@ -44,6 +44,7 @@ public: void read(PIIODevice * d); void parse(PIIODevice * d); void update(PIIODevice * d); + void calculate(); PIString appConfig(); PIString pultConfig(); diff --git a/cd_utils/cdutils_types.cpp b/cd_utils/cdutils_types.cpp index c3269ce..29e3733 100644 --- a/cd_utils/cdutils_types.cpp +++ b/cd_utils/cdutils_types.cpp @@ -1,6 +1,8 @@ #include "cdutils_types.h" #include "piconfig.h" #include "pifile.h" +#include "pievaluator.h" +#include "cdutils_core.h" using namespace CDUtils; @@ -10,8 +12,9 @@ CDType::CDType() { index_ = -1; value_d = 0.; value_i = 0; - value_b = false; + value_b = calculated = false; cd_type_ = cdNull; + parent = 0; // debug_cnt = cdtype_debug_cnt; // cdtype_debug_cnt++; // piCout << "[CDType]" << "create Null" << debug_cnt; @@ -31,6 +34,8 @@ CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v value_i = v.toInt(); value_b = v.toBool(); cd_type_ = cd_t; + calculated = false; + parent = 0; if (type_ == "e") { enum_values << comment_.inBrackets('{', '}').split(","); piForeach(PIString &s, enum_values) s.trim(); @@ -58,20 +63,85 @@ PIString CDType::value() const { } -void CDType::setFormula(const PIString &f) { +void CDType::setFormula(const PIString & f) { formula_ = f; - calculate(); + calculated = false; + //PIEvaluator e; + //calculate(&e); } -void CDType::calculate() { - value_s = formula_.trimmed(); +void CDType::setValue(const PIString & value_) { + formula_ = value_; value_d = formula_.toDouble(); value_i = formula_.toInt(); value_b = formula_.toBool(); } +bool CDType::calculate(PIEvaluator * e, PIVector stack) { + if (stack.contains(this)) { + error_ = "Circular dependencies: "; + piForeachC (CDType * k, stack) + error_ << k->name() << " -> "; + error_ << name(); + //piCout << error_; + return false; + } + stack << this; + if (calculated) return true; + calculated = true; + error_.clear(); + if (!parent) return true; + //piCout << "calc" << name_ << (parent ? parent->alias : "root"); + value_s = formula_.trimmed(); + for (;;) { + int ki = value_s.find("K["); + if (ki < 0) break; + int ke = value_s.find("]", ki + 2); + if (ke < 0) break; + PIString kp = value_s.mid(ki + 2, ke - ki - 2); + //piCout << kp; + CDType & k((*parent)[kp]); + k.calculate(e, stack); + value_s.replace(ki, ke - ki + 1, PIString::fromNumber(k.value_d)); + } + value_d = formula_.toDouble(); + value_i = formula_.toInt(); + value_b = formula_.toBool(); + double ev = 0.; + if (!e->check(value_s) && value_d == 0. && value_i == 0 && !value_b) { + PIString f = formula_.trimmed().toLowerCase(); + if (f != "off" && f != "false" && f != "no" && !value_b) { + error_ = e->error(); + return false; + } + } else + if (e->isCorrect()) + ev = e->evaluate().real(); + //piCout << value_s << value_i << value_d << ev; + //if ((value_d == 0.) || (piAbsd(value_d) < piAbsd(ev))) value_d = ev; + //if ((value_i == 0) || (piAbsd(value_i) < piAbsd(ev))) value_i = int(ev); + if ((value_d == 0.) || (ev != 0.)) value_d = ev; + if ((value_i == 0) || (ev != 0.)) value_i = int(ev); + value_b = value_b || (ev > 0.); + if (value_i != 0) { + if (value_d == 0.) value_d = value_i; + value_b = value_i > 0; + } + if (value_d != 0.) { + if (value_i == 0) value_i = value_d; + value_b = value_d > 0.; + } + if (value_b) { + if (value_d == 0.) value_d = 1.; + if (value_i == 0) value_i = 1; + } + value_s = PIString::fromNumber(value_d); + return true; +} + + //CDType::CDType(const CDType &cdt) { // index_ = cdt.index_; // name_ = cdt.name_; @@ -111,6 +181,56 @@ void CDType::calculate() { //} +CDType & CDSection::operator [](const PIString & name_) { + PIStringList np = name_.split("."); + if (np.isEmpty()) return null; + //piCout << np; + CDSection * cs = this, * ns = 0; + if (np.front().isEmpty()) { + if (np.size_s() < 2) return null; + cs = &(CDCore::instance()->k_); + np.pop_front(); + } + for (int i = 0; i < np.size_s() - 1; ++i) { + if (np[i].isEmpty()) return null; + bool isd = np[i][0].isDigit() || (np[i][0] == '-'); + int dv = 0; + if (isd) dv = np[i].toInt(); + ns = 0; + PIMap::iterator it; + //piCout << np[i] << isd << dv; + for (it = cs->s.begin(); it != cs->s.end(); ++it) { + bool f = false; + if (isd) f = (dv == it.key()); + else f = (np[i] == it.value().alias); + //piCout << "s..." << it.key() << it.value().alias << f; + if (f) { + ns = &(it.value()); + break; + } + } + //piCout << ns; + if (!ns) return null; + cs = ns; + } + PIMap::iterator it; + if (np.back().isEmpty()) return null; + bool isd = np.back()[0].isDigit() || (np.back()[0] == '-'); + int dv = 0; + if (isd) dv = np.back().toInt(); + //piCout << np.back() << isd << dv; + for (it = cs->k.begin(); it != cs->k.end(); ++it) { + bool f = false; + if (isd) f = (dv == it.key()); + else f = (np.back() == it.value().name()); + //piCout << "k..." << it.key() << it.value().name() << f; + if (f) + return cs->k[it.key()]; + } + return null; +} + + int CDSection::count(bool recursive) const { int ret = k.size_s(); if (recursive) { @@ -136,6 +256,13 @@ PIStringList CDSection::index_names() const { } +void CDSection::calculate() { + CDCore::instance()->k_.prepareCalculate(); + PIEvaluator e; + calculateRecursive(&e); +} + + void CDSection::write(PIIODevice * d, const PIString & prefix) { if (!d) return; if (k.isEmpty() && s.isEmpty()) return; @@ -266,3 +393,25 @@ bool CDSection::isSameStructure(CDSection & v) { } +void CDSection::prepareCalculate() { + PIMap::iterator i; + for (i = k.begin(); i != k.end(); ++i) { + i.value().parent = this; + i.value().calculated = false; + } + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().prepareCalculate(); +} + + +void CDSection::calculateRecursive(PIEvaluator * e) { + PIMap::iterator i; + for (i = k.begin(); i != k.end(); ++i) + i.value().calculate(e); + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().calculateRecursive(e); +} + + diff --git a/cd_utils/cdutils_types.h b/cd_utils/cdutils_types.h index 6894b73..21d3660 100644 --- a/cd_utils/cdutils_types.h +++ b/cd_utils/cdutils_types.h @@ -5,6 +5,7 @@ #include "pimap.h" class PIIODevice; +class PIEvaluator; class CD_Pult; class CDKItem; class CDKItemModel; @@ -30,19 +31,22 @@ public: bool toBool() const {return value_b;} cdT cd_type() const {return cd_type_;} void setFormula(const PIString & formula); - void calculate(); + void setValue(const PIString & value_); operator double() const {return value_d;} const PIStringList & enumValues() const {return enum_values;} + const PIString & errorString() const {return error_;} protected: + bool calculate(PIEvaluator * e, PIVector stack = PIVector()); cdT cd_type_; int index_; PIString name_, type_; - PIString value_s, formula_, comment_; + PIString value_s, formula_, comment_, error_; PIStringList enum_values; + CDSection * parent; double value_d; int value_i; - bool value_b; + bool value_b, calculated; }; @@ -60,6 +64,8 @@ public: // CDType & operator [](int v) {if (!k.contains(v)) k[v].index_ = v; return k[v];} CDType & operator [](int v) {return k[v];} const CDType operator [](int v) const {return k[v];} + CDType & operator [](const PIString & name_); + const CDType operator [](const PIString & name_) const {return (*this)[name_];} CDSection & section(int v) {return s[v];} const CDSection section(int v) const {return s[v];} @@ -68,6 +74,7 @@ public: int sectionsCount() const; PIVector indexes() const {return k.keys();} PIStringList index_names() const; + void calculate(); PIString name; PIString alias; @@ -81,9 +88,12 @@ protected: void read(const void * ep); void update(CDSection & v, bool keep_names); bool isSameStructure(CDSection & v); + void prepareCalculate(); + void calculateRecursive(PIEvaluator * e); PIMap k; PIMap s; + CDType null; }; diff --git a/cd_utils/pult/cd_kmodel.cpp b/cd_utils/pult/cd_kmodel.cpp index de6d877..5d39d6f 100644 --- a/cd_utils/pult/cd_kmodel.cpp +++ b/cd_utils/pult/cd_kmodel.cpp @@ -128,7 +128,7 @@ void CDKItemModel::buildItem(CDKItem *it, CDSection & r) { void CDKItemModel::internalRebuild() { - qDebug() << "[CDKItemModel]" << "internalRebuild()"; + //qDebug() << "[CDKItemModel]" << "internalRebuild()"; if (root) delete root; root = new CDKItem(0, CDKItem::ItemCDSection, 0); CDSection & r = K.root(); @@ -162,7 +162,11 @@ CDKItem::~CDKItem() { QVariant CDKItem::data(int column, int role) const { if (role == Qt::BackgroundRole) { switch (type_) { - case ItemCDType: return QBrush(QColor(255, 250, 230)); + case ItemCDType: { + CDType & t = K.section(buildPath())[index_]; + if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230)); + else return QBrush(QColor(255, 128, 128)); + } case ItemCDSection: return QBrush(QColor(230, 250, 230)); } } @@ -171,6 +175,10 @@ QVariant CDKItem::data(int column, int role) const { if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked; else QVariant(); } + if (role == Qt::ToolTipRole && type_ == ItemCDType) { + CDType & t = K.section(buildPath())[index_]; + return PI2QString(t.errorString()); + } if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); PIDeque path = buildPath(); CDSection & rs = K.section(path); @@ -221,7 +229,7 @@ QVariant CDKItem::value(CDType t, int role) const { bool CDKItem::setData(int column, const QVariant &value) { if ((column == 3 || column == 4) && type_ == ItemCDType) { - K.section(buildPath())[index_].setFormula(Q2PIString(value.toString())); + K.section(buildPath())[index_].setValue(Q2PIString(value.toString())); return true; } return false; diff --git a/cd_utils/pult/cdkview.cpp b/cd_utils/pult/cdkview.cpp index 7b7a6f3..25e58ff 100644 --- a/cd_utils/pult/cdkview.cpp +++ b/cd_utils/pult/cdkview.cpp @@ -87,6 +87,11 @@ void CDKView::buildFromHeader(const QString &kdescription) { } +void CDKView::calculateK() { + K.calculate(); +} + + void CDKView::k_sendFailed() { bisyStatusChanged(false); emit messageStatus("send failed"); diff --git a/cd_utils/pult/cdkview.h b/cd_utils/pult/cdkview.h index 8405102..3f2edfd 100644 --- a/cd_utils/pult/cdkview.h +++ b/cd_utils/pult/cdkview.h @@ -26,6 +26,7 @@ public slots: void loadK(); void clearK(); void buildFromHeader(const QString & kdescription); + void calculateK(); private slots: void k_sendFailed(); diff --git a/cd_utils/pult/form.cpp b/cd_utils/pult/form.cpp index 7b1ebb0..12576df 100644 --- a/cd_utils/pult/form.cpp +++ b/cd_utils/pult/form.cpp @@ -1,12 +1,14 @@ #include "form.h" #include "ui_form.h" #include "QFileDialog" +#include "cdutils_k.h" +using namespace CDUtils; Form::Form(QWidget *parent) : QWidget(parent), ui(new Ui::Form) { ui->setupUi(this); ui->treeView->setKFile(""); ui->treeView->refresh(); - ui->treeView->startPing(); + } @@ -31,4 +33,14 @@ void Form::on_pushButton_4_clicked() { void Form::on_pushButton_6_clicked() { ui->treeView->buildFromHeader(QFileDialog::getOpenFileName(this, trUtf8("Select *.h file with K description"), "k_description.h", "C/C++ header files(*.h *.hpp);;All files(*)")); + /*piCout << K.root()["Radar_WaveFreqTune"]; + piCout << K.root()["11.NVA_PulseGenFineTune"]; + piCout << K.root()[".NVA.NVA_PulseGenFineTune"]; + piCout << K.root()["NVA_A.1.NVA_Clk"];*/ +} + + +void Form::on_buttonCalc_clicked() { + ui->treeView->calculateK(); + ui->treeView->refresh(); } diff --git a/cd_utils/pult/form.h b/cd_utils/pult/form.h index 47fcc0b..ae334c5 100644 --- a/cd_utils/pult/form.h +++ b/cd_utils/pult/form.h @@ -17,10 +17,9 @@ public: private slots: void on_pushButton_3_clicked(); - void on_pushButton_4_clicked(); - void on_pushButton_6_clicked(); + void on_buttonCalc_clicked(); private: Ui::Form *ui; diff --git a/cd_utils/pult/form.ui b/cd_utils/pult/form.ui index 827887b..47ab476 100644 --- a/cd_utils/pult/form.ui +++ b/cd_utils/pult/form.ui @@ -14,7 +14,7 @@ Form - + @@ -59,6 +59,13 @@ + + + + Calculate + + + diff --git a/qad_widgets/icons/f1.png b/qad_widgets/icons/f1.png new file mode 100644 index 0000000000000000000000000000000000000000..fc3aeae27e73532c9a03efe67139ad19c825e4cd GIT binary patch literal 1046 zcmV+x1nK*UP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv000ApNkl`xtEs8!-T3(Um)Y6bukqB#$jGPq`uaByw)Zb7eqLK! zyWQH_;vlrVy!@lDug|Kv+<9naW#x8rbCaRn-Cf?_-&Y+R9Hb~+1VMN zpP%#Pw{br}Gl)zwvoK#76z0&sGE z^6OhOG&Dr=OacXfAEW?-gM+lVxTuAo0N}T@w8RY!4b}_{43I1cEd~Lwy}gYE$O{V# z_W=F<{WLc>r$sM-;^Jb?%*^DhtSrvX&Q|5*Fw>M>FH@L_yPRx5ujFE zTN?v=3IG`ZKS;(~)7{-olarHL_!EHq{Cpjko}TUtfE<7yqySxAT_im~3mE)T0NlN- zCmrJlfB=Hu#KZ*G)YMqh+1W{BV`EzI14u|nh$%5KQH5X4YZv$dNY7#TLDkjO)^v1q z(CFx>7W@E`lao~`DJdKZg;ZF$F9CobR8>`FO?!Jg4G#}%!4Kd$Ip7C?#DyOejYh3$ zZEYnG zr>92?UI2M{dCvw&O-D$QlAXYk2Y~^=4=O1su}1QkWFfNb zhS;EZ0wBJfpPV(Ukvt|@hzy}2#S;LhAv}BMrvQ>h-((@;bfS_|vaVDl7Ge|GjShx3 z3Zb9lP=U!DEZ(E$&i(G_jcYLn=92%4)cmnmVPRp0k(Kyf9>X2lX^@gebR#+NS~A8M zNu-Dr?&NWxMaEs?^;2&Aqnf){QBlzcDSnr&5sjxLe8Q1P3l?TG{MHuy Q6#xJL07*qoM6N<$f|wNH8~^|S literal 0 HcmV?d00001 diff --git a/qad_widgets/qad_widgets.qrc b/qad_widgets/qad_widgets.qrc index cca0bcf..18d2ce6 100644 --- a/qad_widgets/qad_widgets.qrc +++ b/qad_widgets/qad_widgets.qrc @@ -35,5 +35,6 @@ icons/qcodeedit.png icons/qvariantedit.png icons/code-word.png + icons/f1.png diff --git a/qad_widgets/qcodeedit.cpp b/qad_widgets/qcodeedit.cpp index d78dd0d..6e9ea5e 100644 --- a/qad_widgets/qcodeedit.cpp +++ b/qad_widgets/qcodeedit.cpp @@ -22,12 +22,22 @@ QCodeEdit::QCodeEdit(QWidget * parent): QWidget(parent) { es_line.format.setBackground(QColor(240, 245, 240)); es_line.format.setProperty(QTextFormat::FullWidthSelection, true); es_cursor.format.setBackground(QColor(220, 255, 200)); - lbl_help = new IconedLabel(); - lbl_help->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); - lbl_help->setFocusPolicy(Qt::NoFocus); - lbl_help->setFrameShadow(QFrame::Sunken); - lbl_help->setFrameShape(QFrame::StyledPanel); - lbl_help->setDirection(IconedLabel::RightToLeft); + widget_help = new QFrame(); + widget_help->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); + widget_help->setFocusPolicy(Qt::NoFocus); + widget_help->setFrameShadow(QFrame::Sunken); + widget_help->setFrameShape(QFrame::StyledPanel); + widget_help->setLayout(new QBoxLayout(QBoxLayout::TopToBottom)); + widget_help->layout()->setContentsMargins(0, 0, 0, 0); + for (int i = 0; i < 2; ++i) { + lbl_help[i] = new IconedLabel(); + lbl_help[i]->setFrameShadow(QFrame::Plain); + lbl_help[i]->setFrameShape(QFrame::NoFrame); + lbl_help[i]->setDirection(IconedLabel::RightToLeft); + widget_help->layout()->addWidget(lbl_help[i]); + } + lbl_help[1]->setIcon(QIcon(":/icons/f1.png")); + lbl_help[1]->setText(trUtf8("Press F1 for details")); completer = new QTreeWidget(); completer->setWindowFlags(Qt::Tool | Qt::FramelessWindowHint); completer->setFocusPolicy(Qt::NoFocus); @@ -107,7 +117,9 @@ QCodeEdit::~QCodeEdit() { delete textCode; delete textLines; delete completer; - delete lbl_help; + //for (int i = 0; i < 2; ++i) + // delete lbl_help[i]; + delete widget_help; } @@ -706,8 +718,8 @@ void QCodeEdit::raiseHelp(QTextCursor tc, int arg) { } //qDebug() << s.second << st; ACClass acc = ac_classes.value(i.first); - lbl_help->setIcon(acc.icon); - lbl_help->setText(QString("[%1] %2 %3").arg(acc.name, s.first, selectArg(s.second, arg))); + lbl_help[0]->setIcon(acc.icon); + lbl_help[0]->setText(QString("[%1] %2 %3").arg(acc.name, s.first, selectArg(s.second, arg))); ok = true; break; } @@ -720,10 +732,10 @@ void QCodeEdit::raiseHelp(QTextCursor tc, int arg) { es_cursor.cursor = tc; applyExtraSelection(); tc.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, st.size()); - lbl_help->setFont(font()); - lbl_help->resize(lbl_help->sizeHint()); - lbl_help->move(textCode->mapToGlobal(textCode->cursorRect(tc).topLeft() - QPoint(0, lbl_help->height() + 8))); - lbl_help->show(); + lbl_help[0]->setFont(font()); + widget_help->resize(widget_help->sizeHint()); + widget_help->move(textCode->mapToGlobal(textCode->cursorRect(tc).topLeft() - QPoint(0, widget_help->height() + 8))); + widget_help->show(); cursor_scope = scope.first; cursor_scope << scope.second; //qDebug() << "tooltip" << st; @@ -731,7 +743,7 @@ void QCodeEdit::raiseHelp(QTextCursor tc, int arg) { void QCodeEdit::hideHelp() { - lbl_help->hide(); + widget_help->hide(); es_cursor.cursor = QTextCursor(); cursor_scope.clear(); applyExtraSelection(); diff --git a/qad_widgets/qcodeedit.h b/qad_widgets/qcodeedit.h index d183e04..f477180 100644 --- a/qad_widgets/qcodeedit.h +++ b/qad_widgets/qcodeedit.h @@ -75,7 +75,8 @@ private: QPlainTextEdit * textCode, * textLines; QTreeWidget * completer; - IconedLabel * lbl_help; + IconedLabel * lbl_help[2]; + QFrame * widget_help; QTextEdit::ExtraSelection es_line, es_cursor; QList es_selected, es_custom; QMap ac_classes;