diff --git a/cd_utils/CMakeLists.txt b/cd_utils/CMakeLists.txt index 5769d15..1500c1f 100644 --- a/cd_utils/CMakeLists.txt +++ b/cd_utils/CMakeLists.txt @@ -18,8 +18,8 @@ endif() include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${PIP_INCLUDES}) #file(GLOB HDRS_UTILS "*.h") #file(GLOB CPPS_UTILS "*.cpp") -set(CPPS_UTILS "cdutils_core.cpp" "cdutils_types.cpp" "cdutils_parser.cpp" "cdutils_interface.cpp" "cdutils_k.cpp") -set(HDRS_UTILS "cdutils_core.h" "cdutils_types.h" "cdutils_parser.h" "cdutils_interface.h" "cdutils_k.h" "cdutils_protocol.h") +file(GLOB CPPS_UTILS "cdutils_*.cpp") +file(GLOB HDRS_UTILS "cdutils_*.h") if (DEFINED ENV{QNX_HOST}) add_library(${PROJECT_NAME} STATIC ${CPPS_UTILS} ${HDRS_UTILS}) else() diff --git a/cd_utils/cdutils_c.cpp b/cd_utils/cdutils_c.cpp new file mode 100644 index 0000000..3770e43 --- /dev/null +++ b/cd_utils/cdutils_c.cpp @@ -0,0 +1,55 @@ +#include "cdutils_c.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +CInterface C; + + +CInterface::CInterface(): Interface(CDType::cdC) { + CONNECTU(core, C_Sended, this, sended); + CONNECTU(core, C_SendFail, this, sendFailed); + CONNECTU(core, C_Received, this, received); + CONNECTU(core, C_ReceiveFail, this, receiveFailed); +} + + +void CInterface::send() { + core->C_Send(); +} + + +void CInterface::request() { + core->C_Request(); +} + + +void CInterface::sendCommand(const CDType & c) { + core->sendCommand(c); +} + + +void CInterface::connect(const CDType & c, PIObject * o, Handler eh) { + core->registerCHandler(c, o, eh); +} + + +void CInterface::autoConnect(PIObject * o, const PIString & prefix) { + if (!o) return; + PIString cn = o->className(); + if (!PIObject::__meta_data().contains(cn)) return; + PIMap eh_map; + PIObject::__MetaData & md(PIObject::__meta_data()[cn]); + PIMap::const_iterator it; + for (it = md.eh_func.constBegin(); it != md.eh_func.constEnd(); ++it) { + eh_map[it.value().func_name] = (Handler)it.value().addr; + //piCout << "func" << it.value().func_name; + } + PIVector cl = C.root().children(); + piForeachC (CDType * c, cl) { + PIString cp = prefix + c->pathString().join("_"); + if (cp.isEmpty()) continue; + if (!eh_map.contains(cp)) continue; + connect(*c, o, eh_map[cp]); + } +} diff --git a/cd_utils/cdutils_c.h b/cd_utils/cdutils_c.h new file mode 100644 index 0000000..e09b89d --- /dev/null +++ b/cd_utils/cdutils_c.h @@ -0,0 +1,34 @@ +#ifndef CDUTILS_C_H +#define CDUTILS_C_H + +#include "cdutils_interface.h" + + +namespace CDUtils { + + +class CInterface: public Interface +{ + PIOBJECT(CDUtils::CInterface) +public: + CInterface(); + + EVENT(sended) + EVENT(sendFailed) + EVENT(received) + EVENT(receiveFailed) + EVENT1(keepNamesRequest, bool*, cn) + EVENT_HANDLER(void, send); + EVENT_HANDLER(void, request); + + void sendCommand(const CDType & c); + void connect(const CDType & c, PIObject * o, Handler eh); + void autoConnect(PIObject * o, const PIString & prefix = PIStringAscii("c_")); + +}; + +} + +extern CDUtils::CInterface C; + +#endif // CDUTILS_C_H diff --git a/cd_utils/cdutils_core.cpp b/cd_utils/cdutils_core.cpp index 5a2d2ad..f5fcdf5 100644 --- a/cd_utils/cdutils_core.cpp +++ b/cd_utils/cdutils_core.cpp @@ -64,6 +64,7 @@ CDCore::CDCore() { /*PIString s(app_config); connection.configureFromString(&s); connection.start();*/ + need_rebuild_x = x_pult_side = false; k_.cd_type_ = CDType::cdK; x_.cd_type_ = CDType::cdX; c_.cd_type_ = CDType::cdC; @@ -160,27 +161,44 @@ void CDCore::cd_send(CDSection * cd, CDPacketType pt, bool direct) { void CDCore::initApp() { - init(appConfig()); + init(appConfig(), false); } void CDCore::initPult() { - init(pultConfig()); + init(pultConfig(), true); } -void CDCore::init(const PIString & configuration) { +void CDCore::init(const PIString & configuration, bool pult) { PIString c = configuration; //piCoutObj << "init" << c; connection.stop(); connection.removeAllDevices(); connection.configureFromString(&c); connection.start(); + x_pult_side = pult; } -void CDCore::startPing() { - x_timer.start(1.0); +void CDCore::startX(double freq) { + x_timer.start(1000. / piMaxd(freq, 0.01)); +} + + +void CDCore::sendCommand(const CDType & c) { + piCoutObj << "C_sendCommand" << c; + PIByteArray sba = makeHeader(CD_Command, 0); + sba << c.path(); + sendDirect(sba); +} + + +void CDCore::registerCHandler(const CDType & c, PIObject * o, Handler h) { + PIString sp = pathToString(c.path()); + if (sp.isEmpty() || !h) return; + piCout << "register" << sp; + c_handlers[sp] = OHPair(o, h); } @@ -237,6 +255,32 @@ void CDUtils::CDCore::K_DirectChange(PIDeque path, PIString value) { } +void CDCore::X_Send() { + piCoutObj << "X_Send"; + cd_send(&x_, CD_XSend); +} + + +void CDCore::X_Request() { + piCoutObj << "X_Request"; + PIByteArray sba = makeHeader(CD_XQuery, 0); + sendThreaded(sba); +} + + +void CDCore::C_Send() { + piCoutObj << "C_Send"; + cd_send(&c_, CD_CSend); +} + + +void CDCore::C_Request() { + piCoutObj << "C_Request"; + PIByteArray sba = makeHeader(CD_CQuery, 0); + sendThreaded(sba); +} + + void CDCore::sendThread() { if (send_data.size_s() < 4) return; PacketHeader h; @@ -250,17 +294,43 @@ void CDCore::sendThread() { case CD_KQuery: if (!ok) K_ReceiveFail(); break; + case CD_XSend: + if (ok) X_Sended(); + else X_SendFail(); + break; + case CD_XQuery: + if (!ok) X_ReceiveFail(); + break; + case CD_CSend: + if (ok) C_Sended(); + else C_SendFail(); + break; + case CD_CQuery: + if (!ok) C_ReceiveFail(); + break; default: break; } } void CDCore::xTimerTick() { - PacketHeader ph; - ph.type = CD_Ping; - ph.session_id = 0; + x_mutex.lock(); PIByteArray ba; - ba << ph; + if (x_pult_side) { + ba = makeHeader(CD_XRequest, 0); + if (need_rebuild_x) { + x_selected = x_.collectX(); + need_rebuild_x = false; + } + ba << x_selected; + } else { + ba = makeHeader(CD_XValues, 0); + ba << x_selected; + piForeachC (PIDeque & p, x_selected) { + x_[p].writeX(ba); + } + } + x_mutex.unlock(); connection.writeByName("cd", ba); } @@ -323,11 +393,72 @@ void CDCore::procReceivedPacket(PIByteArray & ba) { ba >> p; k_[p.path].setValue(p.value); } break; + case CD_XRequest: { + x_mutex.lock(); + x_selected.clear(); + ba >> x_selected; + x_.setSelectedX(false); + piForeachC (PIDeque & p, x_selected) { + x_[p].x_enabled = true; + } + x_mutex.unlock(); + } break; + case CD_XValues: { + x_mutex.lock(); + x_selected.clear(); + ba >> x_selected; + piForeachC (PIDeque & p, x_selected) { + x_[p].readX(ba); + } + x_mutex.unlock(); + } break; + case CD_CQuery: + C_Send(); + break; + case CD_CSend: { + piCoutObj << "C received"; + PIByteArray c; + ba >> c; + c << uchar(0); + PIString s = PIString::fromUTF8((const char *)c.data()); + PIIOString ios(&s); + cd_read(&c_, &ios); + C_Received(); + } break; + case CD_Command: { + piCoutObj << "C command"; + PIDeque p; + ba >> p; + if (p.isEmpty()) return; + PIString sp = pathToString(p); + OHPair h = c_handlers.value(sp, OHPair(0, 0)); + //piCoutObj << "found" << sp << h.first; + if (h.first && h.second) h.second(h.first); + } break; default: break; } } +PIString CDCore::pathToString(const PIDeque & p) { + PIString ret; + for (int i = 0; i < p.size_s(); ++i) { + if (!ret.isEmpty()) ret += "."; + ret << p[i]; + } + return ret; +} + + +PIDeque CDCore::stringToPath(const PIString & p) { + PIDeque ret; + PIStringList sl = p.split("."); + piForeachC (PIString & s, sl) + ret << s.toInt(); + return ret; +} + + void CDUtils::CDCore::dataReceived(const PIString & from, const PIByteArray & data) { //piCoutObj << "dataReceived" << from << data.size(); PIIODevice * d = connection.deviceByName("cd"); diff --git a/cd_utils/cdutils_core.h b/cd_utils/cdutils_core.h index b59426c..b541af3 100644 --- a/cd_utils/cdutils_core.h +++ b/cd_utils/cdutils_core.h @@ -27,6 +27,7 @@ class CDCore: public PIObject friend class __Core_Initializer__; friend class CDSection; friend class Interface; + friend class XInterface; public: static CDCore * instance(); @@ -39,6 +40,22 @@ public: EVENT_HANDLER(void, K_Request); EVENT_HANDLER2(void, K_DirectChange, PIDeque, path, PIString, value); + EVENT(X_Sended) + EVENT(X_SendFail) + EVENT(X_Received) + EVENT(X_ReceiveFail) + EVENT(X_ChangedGlobal) + EVENT_HANDLER(void, X_Send); + EVENT_HANDLER(void, X_Request); + + EVENT(C_Sended) + EVENT(C_SendFail) + EVENT(C_Received) + EVENT(C_ReceiveFail) + EVENT(C_ChangedGlobal) + EVENT_HANDLER(void, C_Send); + EVENT_HANDLER(void, C_Request); + void cd_write (CDSection * cd, PIIODevice * d); void cd_read (CDSection * cd, PIIODevice * d); void cd_parse (CDSection * cd, PIIODevice * d); @@ -47,13 +64,17 @@ public: void cd_send (CDSection * cd, CDPacketType pt, bool direct = false); void initApp(); void initPult(); - void init(const PIString & configuration); - void startPing(); + void init(const PIString & configuration, bool pult = false); + void startX(double freq = 20.); + void sendCommand(const CDType & c); + void registerCHandler(const CDType & c, PIObject * o, Handler h); bool inProgress() {return sendt.isRunning();} CDSection & k() {return k_;} CDSection * root(CDType::cdT cdt); PIString typeLetter(CDType::cdT cdt); + static PIString pathToString(const PIDeque & p); + static PIDeque stringToPath(const PIString & p); static PIString pultConfig() {return PIString(pult_config);} static PIString appConfig() {return PIString(app_config);} @@ -72,6 +93,8 @@ private: void sendThreaded(PIByteArray & ba); void procReceivedPacket(PIByteArray & ba); + typedef PIPair OHPair; + static const char app_config[], pult_config[]; PIConnection connection; PIDataTransfer datatr; @@ -79,6 +102,10 @@ private: PIThread sendt; PITimer x_timer; CDSection k_, x_, c_; + PIMutex x_mutex; + PIVector > x_selected; + PIMap c_handlers; + bool need_rebuild_x, x_pult_side; }; diff --git a/cd_utils/cdutils_interface.cpp b/cd_utils/cdutils_interface.cpp index 8cec8ad..d836645 100644 --- a/cd_utils/cdutils_interface.cpp +++ b/cd_utils/cdutils_interface.cpp @@ -9,6 +9,7 @@ using namespace CDUtils; Interface::Interface(CDType::cdT type_) { core = CDCore::instance(); s = core->root(type_); + type = type_; //piCoutObj << (void*)this << core; file_ = core->typeLetter(type_) + PIStringAscii(".dat"); file_size = 0; @@ -108,11 +109,6 @@ void Interface::reinitConnection(const PIString &configuration) { } -void Interface::startPing() { - core->startPing(); -} - - void Interface::write(PIIODevice * d) { core->cd_write(s, d); } diff --git a/cd_utils/cdutils_interface.h b/cd_utils/cdutils_interface.h index d837f0c..ded7fc1 100644 --- a/cd_utils/cdutils_interface.h +++ b/cd_utils/cdutils_interface.h @@ -32,11 +32,11 @@ public: int count(bool recursive = true) const; const PIString file() const {return file_;} int fileSize() const {return file_size;} + CDType::cdT cdType() const {return type;} void setFileName(const PIString & _file); bool configure(const PIString & config); void reinitConnection(const PIString & configuration); - void startPing(); void write(PIIODevice * d); void read(PIIODevice * d); void parse(PIIODevice * d); @@ -63,4 +63,4 @@ protected: } -#endif // CDUTILS_K_H +#endif // CDUTILS_INTERFACE_H diff --git a/cd_utils/cdutils_protocol.h b/cd_utils/cdutils_protocol.h index cc27c5b..df9c91b 100644 --- a/cd_utils/cdutils_protocol.h +++ b/cd_utils/cdutils_protocol.h @@ -14,8 +14,11 @@ enum CDPacketType {CD_Ping, CD_XQuery, CD_XSend, + CD_XRequest, CD_XValues, + CD_CQuery, + CD_CSend, CD_Command, }; diff --git a/cd_utils/cdutils_types.cpp b/cd_utils/cdutils_types.cpp index 18f72a2..8eb4c17 100644 --- a/cd_utils/cdutils_types.cpp +++ b/cd_utils/cdutils_types.cpp @@ -14,9 +14,11 @@ CDType::CDType() { index_ = -1; value_d = 0.; value_i = 0; - value_b = calculated = false; + value_b = calculated = x_enabled = false; cd_type_ = cdNull; parent = 0; + avg_size = 1; + mode_ = X_Current; // debug_cnt = cdtype_debug_cnt; // cdtype_debug_cnt++; // piCout << "[CDType]" << "create Null" << debug_cnt; @@ -36,8 +38,10 @@ 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; + calculated = x_enabled = false; parent = 0; + avg_size = 1; + mode_ = X_Current; if (type_ == "e") { enum_values = parseEnumComment(comment_); // piCout << enum_values.size() << enum_values; @@ -51,17 +55,18 @@ CDType::CDType(int i, const PIString & n, const PIString & t, const PIString & v } -CDType &CDType::operator =(double x) { +CDType & CDType::operator =(double x) { value_d = x; + value_i = x; + value_b = x > 0.; if (mode_ == X_All_Avg) { avg_h << x; double val = 0; if (avg_h.size_s() >= avg_size) { - for (int i=0; iroot(cd_type_); + if (!ps) return ret; + for (int i = 0; i < path_.size_s() - 1; ++i) { + ps = &(ps->section(path_[i])); + if (!ps->alias.isEmpty()) ret << ps->alias; + else ret << PIString::fromNumber(path_[i]); + } + if (!name_.isEmpty()) ret << name_; + else ret << PIString::fromNumber(index_); + return ret; +} + + +void CDType::readX(PIByteArray & ba) { + if (ba.size() < 5) return; + uchar t(0); ba >> t; + switch ((XMode)t) { + case X_Current: + ba >> value_d; + value_i = value_d; + value_b = value_d > 0.; + break; + case X_All_Avg: + ba >> history; + break; + default: break; + } +} + + +void CDType::writeX(PIByteArray & ba) { + ba << uchar(mode_); + switch (mode_) { + case X_Current: + ba << value_d; + break; + case X_All_Avg: + ba << history; + break; + default: break; + } +} + + bool CDType::calculate(PIEvaluator * e, PIVector stack) { if (stack.contains(this)) { error_ = "Circular dependencies: "; @@ -436,8 +487,8 @@ void CDSection::read(const void * ep) { break; case CDType::cdX: c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_); - c.setXMode((CDType::XMode)e->getValue("mode").value().toInt()); - c.setAvg((CDType::XMode)e->getValue("avg").value().toInt()); + c.setXMode((CDType::XMode)e->getValue("mode", int(CDType::X_Current)).value().toInt()); + c.setAvg((CDType::XMode)e->getValue("avg", 1).value().toInt()); break; case CDType::cdC: c = CDType(id, e->getValue("name").value(), PIString(), PIString(), PIString() , e->getValue("name").comment(), cd_type_); @@ -601,6 +652,30 @@ void CDSection::calculateRecursive(PIEvaluator * e) { } +void CDSection::setSelectedX(bool yes) { + PIMap::iterator i; + for (i = cd.begin(); i != cd.end(); ++i) + i.value().x_enabled = yes; + PIMap::iterator j; + for (j = s.begin(); j != s.end(); ++j) + j.value().setSelectedX(yes); +} + + +PIVector > CDSection::collectX() const { + PIVector > ret; + PIMap::const_iterator i; + for (i = cd.begin(); i != cd.end(); ++i) { + if (i.value().x_enabled) + ret << i.value().path(); + } + PIMap::const_iterator j; + for (j = s.constBegin(); j != s.constEnd(); ++j) + ret << j.value().collectX(); + return ret; +} + + void CDSection::makePath(PIDeque p) { PIDeque tp; PIMap::iterator i; diff --git a/cd_utils/cdutils_types.h b/cd_utils/cdutils_types.h index 8c7194d..5a84b6c 100644 --- a/cd_utils/cdutils_types.h +++ b/cd_utils/cdutils_types.h @@ -8,8 +8,8 @@ class PIIODevice; class PIEvaluator; class CD_Pult; -class CDKItem; -class CDKItemModel; +class CDItem; +class CDItemModel; namespace CDUtils { @@ -27,6 +27,7 @@ class CDType { friend class CDSection; friend class CDCore; friend class Interface; + friend class XInterface; public: enum cdT {cdNull, cdK, cdX, cdC}; enum XMode {X_Current, X_All_Avg}; @@ -53,10 +54,15 @@ public: void setEnumValues(const PIVariantTypes::Enum & ev) {enum_values = ev;} const PIString & errorString() const {return error_;} PIDeque path() const {return path_;} + PIStringList pathString() const; + void setXMode(XMode mode) {mode_ = mode;} void setAvg(int avg) {avg_size = avg;} XMode xmode() const {return mode_;} int avg() const {return avg_size;} + bool isSelectedX() const {return x_enabled;} + void readX(PIByteArray & ba); + void writeX(PIByteArray & ba); protected: bool calculate(PIEvaluator * e, PIVector stack = PIVector()); @@ -70,7 +76,7 @@ protected: PIDeque path_; double value_d; int value_i; - bool value_b, calculated; + bool value_b, calculated, x_enabled; PIVector history; PIVector avg_h; int avg_size; @@ -81,9 +87,10 @@ protected: class CDSection { friend class CDCore; friend class Interface; + friend class XInterface; friend class ::CD_Pult; - friend class ::CDKItem; - friend class ::CDKItemModel; + friend class ::CDItem; + friend class ::CDItemModel; public: CDSection(CDType::cdT type_ = CDType::cdNull); @@ -125,6 +132,8 @@ protected: bool isSameStructure(CDSection & v); void prepareCalculate(); void calculateRecursive(PIEvaluator * e); + void setSelectedX(bool yes); + PIVector > collectX() const; PIMap cd; mutable PIMap s; diff --git a/cd_utils/cdutils_x.cpp b/cd_utils/cdutils_x.cpp new file mode 100644 index 0000000..546589f --- /dev/null +++ b/cd_utils/cdutils_x.cpp @@ -0,0 +1,39 @@ +#include "cdutils_x.h" +#include "cdutils_core.h" + +using namespace CDUtils; + +XInterface X; + + +XInterface::XInterface(): Interface(CDType::cdX) { + CONNECTU(core, X_Sended, this, sended); + CONNECTU(core, X_SendFail, this, sendFailed); + CONNECTU(core, X_Received, this, received); + CONNECTU(core, X_ReceiveFail, this, receiveFailed); +} + + +void XInterface::send() { + core->X_Send(); +} + + +void XInterface::request() { + core->X_Request(); +} + + +void XInterface::setEnabled(const CDType & x, bool en) { + CDType & t((*s)[x.path()]); + if (t.cd_type() != CDType::cdX) return; + core->x_mutex.lock(); + t.x_enabled = en; + core->need_rebuild_x = true; + core->x_mutex.unlock(); +} + + +void XInterface::start(double freq) { + core->startX(freq); +} diff --git a/cd_utils/cdutils_x.h b/cd_utils/cdutils_x.h new file mode 100644 index 0000000..00b5c10 --- /dev/null +++ b/cd_utils/cdutils_x.h @@ -0,0 +1,37 @@ +#ifndef CDUTILS_X_H +#define CDUTILS_X_H + +#include "cdutils_interface.h" + + +namespace CDUtils { + + +class XInterface: public Interface +{ + PIOBJECT(CDUtils::XInterface) +public: + XInterface(); + + EVENT(sended) + EVENT(sendFailed) + EVENT(received) + EVENT(receiveFailed) + EVENT1(keepNamesRequest, bool*, xn) + EVENT_HANDLER(void, send); + EVENT_HANDLER(void, request); + + void enable(const CDType & x) {setEnabled(x, true);} + void disable(const CDType & x) {setEnabled(x, false);} + void setEnabled(const CDType & x, bool en); + void setDisabled(const CDType & x, bool dis) {setEnabled(x, !dis);} + + void start(double freq = 20.); + +}; + +} + +extern CDUtils::XInterface X; + +#endif // CDUTILS_X_H diff --git a/cd_utils/cdutilstest.cpp b/cd_utils/cdutilstest.cpp index 9ef166b..939424a 100644 --- a/cd_utils/cdutilstest.cpp +++ b/cd_utils/cdutilstest.cpp @@ -1,7 +1,10 @@ #include "cdutils_k.h" +#include "cdutils_x.h" +#include "cdutils_c.h" #include "cdutils_core.h" #include "cdtest.h" #include "pip.h" +#include using namespace CDUtils; @@ -13,6 +16,7 @@ class Core : public PIObject CDCore::instance()->initApp(); // piCout << "testCore"; CONNECTU(&t, tickEvent, this, timerDone); + CONNECTU(&C, received, this, crecv); t.start(1000); } @@ -44,14 +48,21 @@ class Core : public PIObject } void test() { - piCout << "count" << K.count(); + /*piCout << "count" << K.count(); piCout << K[First]; - piCout << K[Second]; + piCout << K[Second];*/ } EVENT_HANDLER(void, ksend) {piCout << "sended k";} - EVENT_HANDLER(void, krecv) {piCout << "received k";} + EVENT_HANDLER(void, crecv) { + piCout << "received c"; + C.connect(C.section(KD::Logs).section(KD::Spec).section(KD::Formats)[KD::Binary], this, HANDLER(cmd)); + C.autoConnect(this); + } EVENT_HANDLER(void, timerDone) {test();} + EVENT_HANDLER(void, cmd) {piCout << "command cmd";} + EVENT_HANDLER(void, c_Pause) {piCout << "command pause";} + EVENT_HANDLER(void, c_Spectrometer_Connection) {piCout << "command spec_conn";} private: PIFile rf; diff --git a/piqt_utils/piconnedit/piconnedit_main.cpp b/piqt_utils/piconnedit/piconnedit_main.cpp index eef79ac..27c6e65 100644 --- a/piqt_utils/piconnedit/piconnedit_main.cpp +++ b/piqt_utils/piconnedit/piconnedit_main.cpp @@ -10,9 +10,6 @@ int main(int argc, char * argv[]) { #if QT_VERSION >= 0x050000 a.setAttribute(Qt::AA_UseHighDpiPixmaps, true); #endif - EvalSpinBox es; - es.show(); - return a.exec(); ConnectionEdit w; if (a.arguments().size() > 1) { QPIConfig cfg(a.arguments()[1]); @@ -31,5 +28,5 @@ int main(int argc, char * argv[]) { } } } - return 0; + return a.exec(); } diff --git a/qad/widgets/qvariantedit.cpp b/qad/widgets/qvariantedit.cpp index f9a8774..14aa6ae 100644 --- a/qad/widgets/qvariantedit.cpp +++ b/qad/widgets/qvariantedit.cpp @@ -104,7 +104,7 @@ PathEdit::PathEdit(QWidget * parent): QWidget(parent), lay(QBoxLayout::LeftToRig is_dir = is_abs = false; filter = tr("All files(*)"); line = new CLineEdit(this); - line->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + //line->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); butt_select = new QPushButton(this); //butt_select->setIconSize(QSize(16, 16)); butt_select->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); @@ -128,6 +128,12 @@ void PathEdit::changeEvent(QEvent * e) { } +void PathEdit::resizeEvent(QResizeEvent *) { + butt_select->setMaximumHeight(line->height()); + +} + + void PathEdit::select() { QString ret; if (is_dir) ret = QFileDialog::getExistingDirectory(this, tr("Select directory"), value()); @@ -143,6 +149,8 @@ void PathEdit::select() { QVariantEdit::QVariantEdit(QWidget * parent): QWidget(parent) { + setLayout(new QBoxLayout(QBoxLayout::TopToBottom)); + layout()->setContentsMargins(0, 0, 0, 0); _empty = 0; _line = 0; _check = 0; @@ -166,7 +174,7 @@ QVariantEdit::~QVariantEdit() { void QVariantEdit::resizeEvent(QResizeEvent * e) { - _resize(); + //_resize(); QWidget::resizeEvent(e); } @@ -310,7 +318,7 @@ void QVariantEdit::_recreate(const QVariant & new_value) { //qDebug() << _cur_edit; if (_cur_edit) { _resize(); - _cur_edit->show(); + //_cur_edit->show(); } _value = new_value; } @@ -405,6 +413,12 @@ void QVariantEdit::_delete() { } +void QVariantEdit::_resize() { + if (!_cur_edit) return; + layout()->addWidget(_cur_edit); +} + + void QVariantEdit::_newPath() { _delete(); _path = new PathEdit(this); @@ -412,7 +426,7 @@ void QVariantEdit::_newPath() { _value = _value.toString(); connect(_path, SIGNAL(valueChanged()), this, SLOT(_changed())); _resize(); - _cur_edit->show(); + //_cur_edit->show(); } diff --git a/qad/widgets/qvariantedit.h b/qad/widgets/qvariantedit.h index d371050..6dbeda3 100644 --- a/qad/widgets/qvariantedit.h +++ b/qad/widgets/qvariantedit.h @@ -60,7 +60,8 @@ public: private: virtual void changeEvent(QEvent * e); - + virtual void resizeEvent(QResizeEvent * ); + QBoxLayout lay; CLineEdit * line; QPushButton * butt_select; @@ -89,14 +90,14 @@ public: ~QVariantEdit(); QVariant value() const; - QSize sizeHint() const {if (_cur_edit) return _cur_edit->sizeHint(); return QWidget::sizeHint();} - QSize minimumSizeHint() const {if (_cur_edit) return _cur_edit->minimumSizeHint(); return QWidget::minimumSizeHint();} + //QSize sizeHint() const {if (_cur_edit) return _cur_edit->sizeHint(); return QWidget::sizeHint();} + //QSize minimumSizeHint() const {if (_cur_edit) return _cur_edit->minimumSizeHint(); return QWidget::minimumSizeHint();} protected: - void resizeEvent(QResizeEvent * ); + virtual void resizeEvent(QResizeEvent * ); void _recreate(const QVariant & new_value); void _delete(); - void _resize() {if (_cur_edit) _cur_edit->resize(size());} + void _resize(); void _newPath(); void _setEnum(const QAD::Enum & v); void _setFile(const QAD::File & v); diff --git a/qcd_utils/pult/cdgraphics.cpp b/qcd_utils/pult/cdgraphics.cpp index f29d94e..aeedc62 100644 --- a/qcd_utils/pult/cdgraphics.cpp +++ b/qcd_utils/pult/cdgraphics.cpp @@ -1,11 +1,60 @@ #include "cdgraphics.h" #include "cdutils_core.h" +#include "cdutils_x.h" #include "qcd_core.h" #include "qcd_model.h" +#include "graphic.h" +#include "piqt.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace CDUtils; + + +GDockWidget::GDockWidget(QString title, QMainWindow * p): QDockWidget(title, p) { + da = p; + menu = new QMenu(this); + QAction * a = new QAction(QIcon(":/icons/document-edit.png"), "Rename ...", this); + connect(a, SIGNAL(triggered(bool)), this, SLOT(rename())); + dactions << a; + a = new QAction(QIcon(":/icons/edit-delete.png"), "Remove", this); + connect(a, SIGNAL(triggered(bool)), this, SIGNAL(removeRequest())); + dactions << a; +} + + +void GDockWidget::contextMenuEvent(QContextMenuEvent * e) { + QMenu * mwm = da->createPopupMenu(); + menu->clear(); + menu->addActions(dactions); + menu->addSeparator(); + menu->addActions(mwm->actions()); + menu->popup(e->globalPos()); + mwm->deleteLater(); +} + + +void GDockWidget::rename() { + QString nn = QInputDialog::getText(this, trUtf8("Rename area"), trUtf8("New area name:"), + QLineEdit::Normal, windowTitle()); + if (nn.isEmpty()) return; + setWindowTitle(nn); +} + + CDGraphics::CDGraphics(QWidget * parent) : QWidget(parent), Ui::CDGraphics() { setupUi(this); + da = new QMainWindow(); + da->setWindowFlags(frame->windowFlags()); + da->setDockNestingEnabled(true); + layoutMain->addWidget(da); } @@ -15,3 +64,97 @@ CDGraphics::~CDGraphics() { void CDGraphics::reset() { } + + +bool CDGraphics::eventFilter(QObject * o, QEvent * e) { + //if (o == graphic->viewport()) { + switch (e->type()) { + case QEvent::DragEnter: { + QDragEnterEvent * de = (QDragEnterEvent*)e; + const QMimeData * mime = de->mimeData(); + //qDebug() << "enter" << mime; + if (!mime) break; + if (mime->text().isEmpty()) break; + de->setDropAction(Qt::CopyAction); + de->accept(); + return true; + } break; + case QEvent::Drop: { + QDropEvent * de = (QDropEvent*)e; + const QMimeData * mime = de->mimeData(); + if (!mime) break; + //qDebug() << "drop" << mime->text(); + if (mime->text().isEmpty()) break; + addXToGraphic(mime->text(), viewportGraphic(o)); + de->accept(); + return true; + } break; + default: break; + } + //} + return QWidget::eventFilter(o, e); +} + + +Graphic * CDGraphics::viewportGraphic(QObject * o) const { + if (!o) return 0; + while (!qobject_cast(o) && o) + o = o->parent(); + return qobject_cast(o); +} + + +void CDGraphics::addGraphic() { + Graphic * g = new Graphic(); + g->setGraphicsCount(0); + g->setBorderInputsVisible(false); + g->setLegendVisible(true); + g->viewport()->setAcceptDrops(true); + g->viewport()->installEventFilter(this); + GDockWidget * dw = new GDockWidget(QString("graphics %1").arg(graphics.size()), da); + connect(dw, SIGNAL(removeRequest()), this, SLOT(removeGraphic())); + dw->setWidget(g); + da->addDockWidget(Qt::RightDockWidgetArea, dw); + docks << dw; + graphics << g; +} + + +void CDGraphics::removeGraphic() { + GDockWidget * d = qobject_cast(sender()); + if (!d) return; + Graphic * g = qobject_cast(d->widget()); + docks.removeAll(d); + graphics.removeAll(g); + g->deleteLater(); + d->deleteLater(); +} + + +void CDGraphics::addXToGraphic(const QString & xp, Graphic * g) { + qDebug() << "addGraphic" << xp << g; + if (xp.isEmpty() || !g) return; + CDType & t(X[CDCore::stringToPath(Q2PIString(xp))]); + int gind = g->graphicsCount(); + g->setGraphicsCount(gind + 1); + g->setGraphicName(PI2QString(t.pathString().join(".")), gind); +} + + +void CDGraphics::on_buttonAdd_clicked() { + addGraphic(); +} + + +void CDGraphics::on_buttonClear_clicked() { + foreach (Graphic * g, graphics) + g->clear(); +} + + +void CDGraphics::on_buttonRemoveAll_clicked() { + qDeleteAll(graphics); + qDeleteAll(docks); + graphics.clear(); + docks.clear(); +} diff --git a/qcd_utils/pult/cdgraphics.h b/qcd_utils/pult/cdgraphics.h index 9b83bf2..f174c8f 100644 --- a/qcd_utils/pult/cdgraphics.h +++ b/qcd_utils/pult/cdgraphics.h @@ -2,8 +2,28 @@ #define CDGRAPHICS_H #include +#include +#include #include "ui_cdgraphics.h" +class QMainWindow; +class Graphic; + + +class GDockWidget: public QDockWidget { + Q_OBJECT +public: + GDockWidget(QString title = QString(), QMainWindow * p = 0); + void contextMenuEvent(QContextMenuEvent * e); + QMenu * menu; + QList dactions; + QMainWindow * da; +private slots: + void rename(); +signals: + void removeRequest(); +}; + class CDGraphics : public QWidget, public Ui::CDGraphics { @@ -15,8 +35,20 @@ public: void reset(); private: + bool eventFilter(QObject * o, QEvent * e); + Graphic * viewportGraphic(QObject * o) const; + void addXToGraphic(const QString & xp, Graphic * g); + void addGraphic(); + + QList graphics; + QList docks; + QMainWindow * da; private slots: + void removeGraphic(); + void on_buttonAdd_clicked(); + void on_buttonClear_clicked(); + void on_buttonRemoveAll_clicked(); signals: diff --git a/qcd_utils/pult/cdgraphics.ui b/qcd_utils/pult/cdgraphics.ui index ec8c364..e5f7336 100644 --- a/qcd_utils/pult/cdgraphics.ui +++ b/qcd_utils/pult/cdgraphics.ui @@ -6,14 +6,85 @@ 0 0 - 689 - 459 + 624 + 411 CD Pult + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + + + + Add new + + + + :/icons/list-add.png:/icons/list-add.png + + + + + + + Clear all + + + + :/icons/edit-clear.png:/icons/edit-clear.png + + + + + + + Remove all + + + + :/icons/edit-delete.png:/icons/edit-delete.png + + + + + + + Qt::Horizontal + + + + 1 + 20 + + + + + + + + - + + + diff --git a/qcd_utils/pult/cdpult.qrc b/qcd_utils/pult/cdpult.qrc index 59858dc..b3dc107 100644 --- a/qcd_utils/pult/cdpult.qrc +++ b/qcd_utils/pult/cdpult.qrc @@ -10,5 +10,6 @@ icons/document-revert.png icons/flame.png icons/view-refresh.png + icons/format-stroke-color.png diff --git a/qcd_utils/pult/cdpultwindow.cpp b/qcd_utils/pult/cdpultwindow.cpp index f909b72..33dfa8a 100644 --- a/qcd_utils/pult/cdpultwindow.cpp +++ b/qcd_utils/pult/cdpultwindow.cpp @@ -17,6 +17,7 @@ CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWin CDUtils::CDCore::instance()->initPult(); widgetK->setType(CDUtils::CDType::cdK); widgetX->setType(CDUtils::CDType::cdX); + widgetC->setType(CDUtils::CDType::cdC); editFileK->setValue(QVariant::fromValue(QAD::File("", "*.dat"))); editFileX->setValue(QVariant::fromValue(QAD::File("", "*.dat"))); editFileC->setValue(QVariant::fromValue(QAD::File("", "*.dat"))); @@ -32,6 +33,7 @@ CDPultWindow::CDPultWindow(QWidget *parent) : EMainWindow(parent), Ui::CDPultWin reset(); connect(widgetK, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString))); connect(widgetX, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString))); + connect(widgetC, SIGNAL(addToLog(CDViewWidget::LogIcon,QString)), this, SLOT(addToLog(CDViewWidget::LogIcon,QString))); if (windowState() == Qt::WindowMinimized) setWindowState(Qt::WindowNoState); } @@ -154,9 +156,10 @@ void CDPultWindow::on_editFileK_valueChanged(const QVariant & p) { void CDPultWindow::on_buttonSessionApply_clicked() { widgetK->setFile(editFileK->value().value().file); widgetX->setFile(editFileX->value().value().file); + widgetC->setFile(editFileC->value().value().file); dockCDKView->setVisible(checkHasK->isChecked()); dockCDXView->setVisible(checkHasX->isChecked()); - //dockCDCView->setVisible(checkHasC->isChecked()); + dockCDCView->setVisible(checkHasC->isChecked()); } diff --git a/qcd_utils/pult/cdpultwindow.ui b/qcd_utils/pult/cdpultwindow.ui index 666d73a..bacf238 100644 --- a/qcd_utils/pult/cdpultwindow.ui +++ b/qcd_utils/pult/cdpultwindow.ui @@ -90,21 +90,6 @@ - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - @@ -311,6 +296,44 @@ + + + + :/icons/legend.png:/icons/legend.png + + + C + + + 1 + + + + + + + + + + + + + :/icons/format-stroke-color.png:/icons/format-stroke-color.png + + + Graphics + + + 8 + + + + + + + + + @@ -418,6 +441,10 @@ + + + + @@ -448,9 +475,16 @@
cdviewwidget.h
1
+ + CDGraphics + QWidget +
cdgraphics.h
+ 1 +
+ diff --git a/qcd_utils/pult/cdviewwidget.ui b/qcd_utils/pult/cdviewwidget.ui index 9d01778..00e18e6 100644 --- a/qcd_utils/pult/cdviewwidget.ui +++ b/qcd_utils/pult/cdviewwidget.ui @@ -58,7 +58,7 @@ Receive
- + :/icons/document-revert.png:/icons/document-revert.png @@ -69,7 +69,7 @@ Update description ... - + :/icons/view-refresh.png:/icons/view-refresh.png @@ -80,7 +80,7 @@ Send - + :/icons/flame.png:/icons/flame.png @@ -97,6 +97,12 @@ QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + true + + + QAbstractItemView::DragOnly + QAbstractItemView::ScrollPerPixel @@ -116,6 +122,7 @@ + diff --git a/qcd_utils/pult/icons/format-stroke-color.png b/qcd_utils/pult/icons/format-stroke-color.png new file mode 100644 index 0000000..4c4d290 Binary files /dev/null and b/qcd_utils/pult/icons/format-stroke-color.png differ diff --git a/qcd_utils/qcd_model.cpp b/qcd_utils/qcd_model.cpp index 5ead0a2..a0e31ab 100644 --- a/qcd_utils/qcd_model.cpp +++ b/qcd_utils/qcd_model.cpp @@ -1,22 +1,23 @@ #include "qcd_model.h" #include "cdutils_interface.h" #include "cdutils_core.h" +#include "cdutils_x.h" #include "piqt.h" #include #include #include +#include #include "qvariantedit.h" #include "qad_types.h" using namespace CDUtils; - // CDKItem -CDItem::CDItem(CDUtils::Interface * i, int index, CDItem::CDItemType type, CDItem *parent) { +CDItem::CDItem(CDUtils::Interface * i, int _index, CDItem::CDItemType type, CDItem *parent) { interface = i; - index_ = index; + index_ = _index; parent_ = parent; type_ = type; } @@ -31,20 +32,25 @@ QVariant CDItem::data(int column, int role) const { if (role == Qt::BackgroundRole) { switch (type_) { case ItemCDType: { - CDType & t = interface->section(buildPath())[index_]; + CDType & t(interface->section(buildPath())[index_]); if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230)); else return QBrush(QColor(255, 128, 128)); } case ItemCDSection: return QBrush(QColor(230, 250, 230)); } } - if (role == Qt::CheckStateRole && type_ == ItemCDType && column == 4) { - CDType & t = interface->section(buildPath())[index_]; - if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked; - else QVariant(); + if (role == Qt::CheckStateRole && type_ == ItemCDType) { + CDType & t(interface->section(buildPath())[index_]); + if (column == cValue && t.cd_type() == CDType::cdK) { + if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked; + else QVariant(); + } + if (column == cName_Cmd && t.cd_type() == CDType::cdX) { + return t.isSelectedX() ? Qt::Checked : Qt::Unchecked; + } } if (role == Qt::ToolTipRole && type_ == ItemCDType) { - CDType & t = interface->section(buildPath())[index_]; + CDType & t(interface->section(buildPath())[index_]); return PI2QString(t.errorString()); } if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); @@ -54,12 +60,14 @@ QVariant CDItem::data(int column, int role) const { switch (type_) { case ItemCDType: switch (column) { - case 0: return QString::number(index_); - case 1: return PI2QString(rs[index_].name()); - case 2: return stringType(rs[index_].type()); - case 3: return PI2QString(rs[index_].formula()); - case 4: return value(rs[index_], role); - case 5: return PI2QString(rs[index_].comment()); + case cID: return QString::number(index_); + case cName_Cmd: return PI2QString(rs[index_].name()); + case cType: return stringType(rs[index_].type()); + case cXMode: return QVariant::fromValue(xModeEnum(rs[index_].xmode())); + case cXAvg: return rs[index_].avg(); + case cExpression: return PI2QString(rs[index_].formula()); + case cValue: return value(rs[index_], role); + case cComment: return PI2QString(rs[index_].comment()); default: break; } break; @@ -67,9 +75,9 @@ QVariant CDItem::data(int column, int role) const { s = rs.section(index_); // piCout << rs.name << rs.alias << s.name << s.alias; switch (column) { - case 0: return QString("[") + QString::number(index_) + QString("]"); - case 1: return PI2QString(s.alias); - case 2: return PI2QString(s.name); + case cID: return QString("[") + QString::number(index_) + QString("]"); + case cName_Cmd: return PI2QString(s.alias); + case cType: return PI2QString(s.name); default: break; } break; @@ -92,11 +100,28 @@ QVariant CDItem::value(CDType t, int role) const { } -bool CDItem::setData(int column, const QVariant &value) { - if ((column == 3 || column == 4) && type_ == ItemCDType) { - interface->section(buildPath())[index_].setValue(Q2PIString(value.toString())); - interface->calculate(); - return true; +bool CDItem::setData(int column, const QVariant & value) { + if (type_ == ItemCDType) { + CDType & t(interface->section(buildPath())[index_]); + if ((column == cExpression || column == cValue) && (t.cd_type() == CDType::cdK)) { + interface->section(buildPath())[index_].setValue(Q2PIString(value.toString())); + interface->calculate(); + return true; + } + if (t.cd_type() == CDType::cdX) { + switch (column) { + case cName_Cmd: + X.setEnabled(t, value.toBool()); + return true; + case cXMode: + t.setXMode((CDType::XMode)value.toInt()); + return true; + case cXAvg: + t.setAvg(piMax(value.toInt(), 1)); + return true; + default: break; + } + } } return false; } @@ -136,13 +161,51 @@ QString CDItem::stringType(const PIString & t) const { } +QAD::Enum CDItem::xModeEnum(int v) const { + QAD::Enum ret; + ret << QAD::Enumerator(CDType::X_Current, "Current") + << QAD::Enumerator(CDType::X_All_Avg, "All, Averaging"); + ret.selectValue(v); + return ret; +} + + // CDKDelegate CDDelegate::CDDelegate(QObject *parent) : QStyledItemDelegate(parent) { } -QWidget *CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { +void CDDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { + CDItem * item = ((CDItemModel*)index.model())->getItem(index); + if (item) { + if (item->itemType() == CDItem::ItemCDType && item->interface->cdType() == CDType::cdC) { + QStyleOptionButton bo; + bo.direction = option.direction; + bo.fontMetrics = option.fontMetrics; + bo.palette = option.palette; + bo.rect = option.rect; + bo.state = option.state;// & ~(QStyle::State_HasFocus | QStyle::State_MouseOver); + bo.text = item->data(1, Qt::DisplayRole).toString(); + QWidget * v = (QWidget*)(painter->device()); + if (v) { + QPoint cp = v->mapFromGlobal(QCursor::pos()); + if (bo.rect.contains(cp, true)) { + //bo.state |= QStyle::State_MouseOver; + if (qApp->mouseButtons().testFlag(Qt::LeftButton)) + bo.state |= QStyle::State_On; + } + } + qApp->style()->drawControl(QStyle::CE_PushButton, &bo, painter); + return; + } + } + QStyledItemDelegate::paint(painter, option, index); + +} + + +QWidget * CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { return new QVariantEdit(parent); } @@ -192,7 +255,7 @@ CDItemModel::~CDItemModel() { QVariant CDItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); - CDItem *item = getItem(index); + CDItem * item = getItem(index); return item->data(index.column(), role); } @@ -200,12 +263,14 @@ QVariant CDItemModel::data(const QModelIndex &index, int role) const { QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { - case 0: return trUtf8("Index"); - case 1: return trUtf8("Name"); - case 2: return trUtf8("Type"); - case 3: return trUtf8("Expression"); - case 4: return trUtf8("Value"); - case 5: return trUtf8("Comment"); + case cID: return trUtf8("Index"); + case cName_Cmd: return interface->cdType() == CDType::cdC ? trUtf8("Command") : trUtf8("Name"); + case cType: return trUtf8("Type"); + case cXMode: return trUtf8("Mode"); + case cXAvg: return trUtf8("Averaging"); + case cExpression: return trUtf8("Expression"); + case cValue: return trUtf8("Value"); + case cComment: return trUtf8("Comment"); } } return QVariant(); @@ -213,7 +278,7 @@ QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int r QModelIndex CDItemModel::index(int row, int column, const QModelIndex &parent) const { - if (parent.isValid() && parent.column() != 0) return QModelIndex(); + if (parent.isValid() && parent.column() != cID) return QModelIndex(); CDItem * p = getItem(parent); CDItem * c = p->childs.value(row, 0); if (c) return createIndex(row, column, c); @@ -226,18 +291,18 @@ QModelIndex CDItemModel::parent(const QModelIndex &index) const { CDItem * c = getItem(index); CDItem * p = c->parent_; if (p == root) return QModelIndex(); - return createIndex(p->parent_->childs.indexOf(p), 0, p); + return createIndex(p->parent_->childs.indexOf(p), cID, p); } int CDItemModel::rowCount(const QModelIndex &parent) const { - CDItem *p = getItem(parent); + CDItem * p = getItem(parent); return p->childs.count(); } int CDItemModel::columnCount(const QModelIndex &parent) const { - return 6; + return cLastColumn; } @@ -246,30 +311,42 @@ Qt::ItemFlags CDItemModel::flags(const QModelIndex & index) const { Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; CDItem * item = getItem(index); if (!item) return 0; - CDType & t(interface->section(item->buildPath())[item->index_]); - if ((index.column() == 3 || index.column() == 4) && - (item->type_ == CDItem::ItemCDType) && - (t.cd_type() == CDType::cdK)) - f |= Qt::ItemIsEditable; - if (item->type_ == CDItem::ItemCDType && index.column() == 4) { - if (t.type() == "b") { - f |= Qt::ItemIsUserCheckable; -// piCout << "ItemIsUserCheckable"; + if (item->type_ == CDItem::ItemCDType) { + CDType & t(interface->section(item->buildPath())[item->index_]); + if (t.cd_type() == CDType::cdK) { + if (index.column() == cExpression || index.column() == cValue) + f |= Qt::ItemIsEditable; + if (index.column() == cValue && t.type() == "b") + f |= Qt::ItemIsUserCheckable; + } + if (t.cd_type() == CDType::cdX) { + if (index.column() == cXMode || index.column() == cXAvg) + f |= Qt::ItemIsEditable; + if (index.column() == cName_Cmd) + f |= Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled; } } return f; } -bool CDItemModel::setData(const QModelIndex & index, const QVariant &value, int role) { - if (role == Qt::CheckStateRole && index.column() == 4) { +bool CDItemModel::setData(const QModelIndex & index, const QVariant & value, int role) { + if (role == Qt::CheckStateRole && (index.column() == cName_Cmd || index.column() == cValue)) { CDItem * item = getItem(index); if (item->type_ == CDItem::ItemCDType) { - CDType t = interface->section(item->buildPath())[item->index_]; - if (t.type() == "b") { - bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool()))); - QModelIndex rin(CDItemModel::index(index.row(), 3, index.parent())); - emit dataChanged(rin, rin); + CDType & t(interface->section(item->buildPath())[item->index_]); + if (index.column() == cValue && (t.cd_type() == CDType::cdK)) { + if (t.type() == "b") { + bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool()))); + QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent())); + emit dataChanged(rin, rin); + return result; + } + } + if (index.column() == cName_Cmd && (t.cd_type() == CDType::cdX)) { + bool result = item->setData(index.column(), value); + //QModelIndex rin(CDItemModel::index(index.row(), 1, index.parent())); + //emit dataChanged(rin, rin); return result; } } @@ -278,7 +355,7 @@ bool CDItemModel::setData(const QModelIndex & index, const QVariant &value, int CDItem * item = getItem(index); bool result = item->setData(index.column(), value); if (result) { - QModelIndex rin(CDItemModel::index(index.row(), 3, index.parent())); + QModelIndex rin(CDItemModel::index(index.row(), cExpression, index.parent())); emit dataChanged(rin, rin); emit dataChanged(index, index); } @@ -286,6 +363,23 @@ bool CDItemModel::setData(const QModelIndex & index, const QVariant &value, int } +QMimeData * CDItemModel::mimeData(const QModelIndexList & indexes) const { + if (indexes.size() == 1) { + QModelIndex index = indexes[0]; + if (index.isValid() && interface->cdType() == CDType::cdX) { + CDItem * item = getItem(index); + if (item) { + CDType & t(interface->section(item->buildPath())[item->index_]); + QMimeData * mime = new QMimeData(); + mime->setText(PI2QString(CDCore::pathToString(t.path()))); + return mime; + } + } + } + return QAbstractItemModel::mimeData(indexes); +} + + void CDItemModel::rebuildModel() { beginResetModel(); internalRebuild(); diff --git a/qcd_utils/qcd_model.h b/qcd_utils/qcd_model.h index 75a3357..29c9204 100644 --- a/qcd_utils/qcd_model.h +++ b/qcd_utils/qcd_model.h @@ -10,6 +10,18 @@ namespace CDUtils { class CDType; class CDSection; class Interface; + + enum Column { + cID , + cName_Cmd , + cType , + cXMode , + cXAvg , + cExpression, + cValue , + cComment , + cLastColumn, + }; } namespace QAD { @@ -23,17 +35,21 @@ class CDItem { friend class CDItemModel; public: enum CDItemType{ItemCDType, ItemCDSection}; - CDItem(CDUtils::Interface * interface, int index, CDItemType type, CDItem * parent); + CDItem(CDUtils::Interface * interface, int _index, CDItemType type, CDItem * parent); ~CDItem(); QVariant data(int column, int role) const; QVariant value(CDUtils::CDType t, int role) const; bool setData(int column, const QVariant & value); - -private: + CDItemType itemType() const {return type_;} PIDeque buildPath() const; - QString stringType(const PIString & t) const; + int index() const {return index_;} CDUtils::Interface * interface; + +private: + QString stringType(const PIString & t) const; + QAD::Enum xModeEnum(int v) const; + CDItem * parent_; int index_; CDItemType type_; @@ -47,16 +63,19 @@ class CDDelegate : public QStyledItemDelegate public: CDDelegate(QObject *parent = 0); + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + }; class CDItemModel : public QAbstractItemModel { Q_OBJECT + friend class CDView; public: explicit CDItemModel(int type_, QObject *parent = 0); ~CDItemModel(); @@ -69,6 +88,8 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const; Qt::ItemFlags flags(const QModelIndex &index) const; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QMimeData * mimeData(const QModelIndexList & indexes) const; + CDItem * getItem(const QModelIndex & index) const; void buildItem(CDItem * it, CDUtils::CDSection &r); @@ -78,7 +99,6 @@ public slots: private: void internalRebuild(); - CDItem * getItem(const QModelIndex & index) const; CDUtils::Interface * interface; CDItem * root; diff --git a/qcd_utils/qcd_view.cpp b/qcd_utils/qcd_view.cpp index cdc53a4..daae036 100644 --- a/qcd_utils/qcd_view.cpp +++ b/qcd_utils/qcd_view.cpp @@ -1,6 +1,8 @@ #include +#include #include "cdutils_k.h" #include "cdutils_x.h" +#include "cdutils_c.h" #include "cdutils_core.h" #include "qcd_view.h" #include "qcd_model.h" @@ -10,9 +12,10 @@ using namespace CDUtils; -CDView::CDView(QWidget *parent) : QTreeView(parent) { +CDView::CDView(QWidget * parent) : QTreeView(parent) { type_ = -1; model_ = 0; + connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(indexClicked(QModelIndex))); connect(this, SIGNAL(_qcd_sendFailed()), this, SLOT(cd_sendFailed()), Qt::QueuedConnection); connect(this, SIGNAL(_qcd_sendSucceed()), this, SLOT(cd_sendSucceed()), Qt::QueuedConnection); connect(this, SIGNAL(_qcd_receiveFailed()), this, SLOT(cd_receiveFailed()), Qt::QueuedConnection); @@ -43,28 +46,76 @@ void CDView::setType(int cdt) { CONNECTU(&X, received, this, pi_cd_receiveSucceed); CONNECTU(&X, receiveFailed, this, pi_cd_receiveFailed); break; + case CDType::cdC: + CONNECTU(&C, sended, this, pi_cd_sendSucceed); + CONNECTU(&C, sendFailed, this, pi_cd_sendFailed); + CONNECTU(&C, received, this, pi_cd_receiveSucceed); + CONNECTU(&C, receiveFailed, this, pi_cd_receiveFailed); + break; default: break; } } +void CDView::mousePressEvent(QMouseEvent * e) { + if (type_ == CDType::cdC) { + QModelIndex i = indexAt(e->pos()); + if (i.isValid() && i.column() == cName_Cmd) + update(i); + } + QTreeView::mousePressEvent(e); +} + + +void CDView::mouseReleaseEvent(QMouseEvent * e) { + if (type_ == CDType::cdC) { + QModelIndex i = indexAt(e->pos()); + if (i.isValid() && i.column() == cName_Cmd) + update(i); + } + QTreeView::mouseReleaseEvent(e); +} + + +void CDView::currentChanged(const QModelIndex & cur, const QModelIndex & prev) { + if (type_ == CDType::cdC) { + if (prev.isValid() && prev.column() == cName_Cmd) + update(prev); + } + QTreeView::currentChanged(cur, prev); +} + + void CDView::refresh() { if (type_ < 0) return; if (!model_) { model_ = new CDItemModel(type_); setModel(model_); - setItemDelegateForColumn(4, new CDDelegate()); + setItemDelegateForColumn(type_ == CDType::cdC ? cName_Cmd : cValue, new CDDelegate()); + if (type_ == CDType::cdX) + setItemDelegateForColumn(cXMode, new CDDelegate()); } model_->rebuildModel(); switch ((CDType::cdT)type_) { + case CDType::cdK: + setColumnHidden(cXMode, true); + setColumnHidden(cXAvg, true); + break; case CDType::cdX: - setColumnHidden(3, true); + setColumnHidden(cExpression, true); + break; + case CDType::cdC: + setColumnHidden(cType, true); + setColumnHidden(cXMode, true); + setColumnHidden(cXAvg, true); + setColumnHidden(cExpression, true); + setColumnHidden(cValue, true); break; default: break; } expandAll(); - for (int i=0; i<6; i++) resizeColumnToContents(i); + for (int i = 0; i < model_->columnCount(); i++) resizeColumnToContents(i); } @@ -72,6 +123,7 @@ void CDView::setFile(const QString & filename) { switch ((CDType::cdT)type_) { case CDType::cdK: K.setFileName(Q2PIString(filename)); break; case CDType::cdX: X.setFileName(Q2PIString(filename)); break; + case CDType::cdC: C.setFileName(Q2PIString(filename)); break; default: break; } } @@ -81,16 +133,16 @@ bool CDView::inProgress() const { switch ((CDType::cdT)type_) { case CDType::cdK: return K.inProgress(); break; case CDType::cdX: return X.inProgress(); break; + case CDType::cdC: return C.inProgress(); break; default: break; } return false; } -void CDView::startPing() { +void CDView::startX(double freq) { switch ((CDType::cdT)type_) { - case CDType::cdK: K.startPing(); break; - case CDType::cdX: X.startPing(); break; + case CDType::cdX: X.start(freq); break; default: break; } } @@ -111,6 +163,7 @@ void CDView::send() { switch ((CDType::cdT)type_) { case CDType::cdK: K.send(); break; case CDType::cdX: X.send(); break; + case CDType::cdC: C.send(); break; default: break; } } @@ -121,6 +174,7 @@ void CDView::receive() { switch ((CDType::cdT)type_) { case CDType::cdK: K.request(); break; case CDType::cdX: X.request(); break; + case CDType::cdC: C.request(); break; default: break; } } @@ -130,6 +184,7 @@ void CDView::save() { switch ((CDType::cdT)type_) { case CDType::cdK: K.writeFile(); break; case CDType::cdX: X.writeFile(); break; + case CDType::cdC: C.writeFile(); break; default: break; } } @@ -145,6 +200,10 @@ void CDView::load() { X.readFile(); X.calculate(); break; + case CDType::cdC: + C.readFile(); + C.calculate(); + break; default: break; } refresh(); @@ -156,6 +215,7 @@ void CDView::clear() { switch ((CDType::cdT)type_) { case CDType::cdK: K.root() = CDSection(); break; case CDType::cdX: X.root() = CDSection(); break; + case CDType::cdC: C.root() = CDSection(); break; default: break; } refresh(); @@ -169,6 +229,7 @@ void CDView::buildFromHeader(const QString & description, int mode) { switch ((CDType::cdT)type_) { case CDType::cdK: K.update(&f, mode); break; case CDType::cdX: X.update(&f, mode); break; + case CDType::cdC: C.update(&f, mode); break; default: break; } refresh(); @@ -179,11 +240,25 @@ void CDView::calculate() { switch ((CDType::cdT)type_) { case CDType::cdK: K.calculate(); break; case CDType::cdX: X.calculate(); break; + case CDType::cdC: C.calculate(); break; default: break; } } +void CDView::indexClicked(const QModelIndex & i) { + if (!model_ || !i.isValid() || type_ != CDType::cdC || i.column() != cName_Cmd) return; + CDItem * item = model_->getItem(i); + if (!item) return; + if (item->itemType() != CDItem::ItemCDType) return; + CDType & t(model_->interface->section(item->buildPath())[item->index()]); + C.sendCommand(t); + emit commandSended(PI2QString(t.pathString().join("."))); + //piCout << t; + qDebug() << PI2QString(t.pathString().join(".")); +} + + void CDView::cd_sendFailed() { busyStatusChanged(false); emit messageStatus("send failed"); @@ -211,4 +286,3 @@ void CDView::cd_receiveSucceed() { emit messageStatus("receive success"); emit receiveSucceed(); } - diff --git a/qcd_utils/qcd_view.h b/qcd_utils/qcd_view.h index 487da91..815f864 100644 --- a/qcd_utils/qcd_view.h +++ b/qcd_utils/qcd_view.h @@ -22,12 +22,17 @@ public: void setType(int cdt); void setFile(const QString & filename); bool inProgress() const; - void startPing(); + void startX(double freq = 20.); CDUtils::CDSection * root(); QString typeLetter() const; CDItemModel * CDModel() {return model_;} +protected: + void mousePressEvent(QMouseEvent * ); + void mouseReleaseEvent(QMouseEvent * ); + void currentChanged(const QModelIndex & cur, const QModelIndex & prev); + public slots: void refresh(); void send(); @@ -39,6 +44,7 @@ public slots: void calculate(); private slots: + void indexClicked(const QModelIndex & i); void cd_sendFailed(); void cd_sendSucceed(); void cd_receiveFailed(); @@ -59,6 +65,7 @@ signals: void receiveFailed(); void receiveSucceed(); void messageStatus(QString msg); + void commandSended(QString msg); void busyStatusChanged(bool busy); void _qcd_sendFailed(); // PRIVATE