From bc24bc779f747eda6d9c49b4ee4d390b34b0bb41 Mon Sep 17 00:00:00 2001 From: "alexander.kovalev" Date: Wed, 12 Feb 2014 13:11:01 +0400 Subject: [PATCH] Implementation of 0022326: [CEA 930] YACS: progression of a loop "ForEach" --- idl/yacsgui.idl | 1 + src/engine/ComposedNode.hxx | 1 + src/engine/ForEachLoop.cxx | 27 +++- src/engine/ForEachLoop.hxx | 3 + src/engine/ForLoop.cxx | 21 +++ src/engine/ForLoop.hxx | 2 + src/engine/Proc.cxx | 12 ++ src/engine/Proc.hxx | 1 + src/genericgui/CMakeLists.txt | 2 + src/genericgui/GenericGui.cxx | 19 ++- src/genericgui/GuiExecutor.cxx | 60 ++++---- src/genericgui/Resource.cxx | 4 + src/genericgui/Resource.hxx | 6 + src/genericgui/SceneComposedNodeItem.cxx | 21 +++ src/genericgui/SceneHeaderNodeItem.cxx | 29 ++-- src/genericgui/SceneHeaderNodeItem.hxx | 1 + src/genericgui/SceneItem.cxx | 5 + src/genericgui/SceneItem.hxx | 3 + src/genericgui/SceneNodeItem.cxx | 21 +++ src/genericgui/SceneNodeItem.hxx | 7 +- src/genericgui/SceneProgressItem.cxx | 167 +++++++++++++++++++++++ src/genericgui/SceneProgressItem.hxx | 60 ++++++++ src/hmi/guiObservers.cxx | 5 + src/hmi/guiObservers.hxx | 6 +- src/salomegui/Yacsgui_Resource.cxx | 22 ++- src/salomegui/resources/SalomeApp.xml.in | 2 + src/yacsorb/YACS.py | 3 + 27 files changed, 462 insertions(+), 49 deletions(-) create mode 100644 src/genericgui/SceneProgressItem.cxx create mode 100644 src/genericgui/SceneProgressItem.hxx diff --git a/idl/yacsgui.idl b/idl/yacsgui.idl index 6ac3beb0e..577538abf 100644 --- a/idl/yacsgui.idl +++ b/idl/yacsgui.idl @@ -41,6 +41,7 @@ module YACS_ORB interface ProcExec { long getNodeState(in long numid); + string getNodeProgress(in long numid); string getXMLState(in long numid); string getInPortValue(in long nodeNumid, in string portName); string setInPortValue(in string nodeName, in string portName, in string value); diff --git a/src/engine/ComposedNode.hxx b/src/engine/ComposedNode.hxx index 9f1780bfc..9b9414ddf 100644 --- a/src/engine/ComposedNode.hxx +++ b/src/engine/ComposedNode.hxx @@ -118,6 +118,7 @@ namespace YACS void connected(); void accept(Visitor *visitor); virtual void cleanNodes(); + virtual std::string getProgress() const {return "0";}; protected: struct SortHierarc { diff --git a/src/engine/ForEachLoop.cxx b/src/engine/ForEachLoop.cxx index 29cf49595..9f277975f 100644 --- a/src/engine/ForEachLoop.cxx +++ b/src/engine/ForEachLoop.cxx @@ -293,13 +293,13 @@ void FakeNodeForForEachLoop::finished() ForEachLoop::ForEachLoop(const std::string& name, TypeCode *typeOfDataSplitted):DynParaLoop(name,typeOfDataSplitted), _splitterNode(NAME_OF_SPLITTERNODE,typeOfDataSplitted,this), - _execCurrentId(0),_nodeForSpecialCases(0) + _execCurrentId(0),_nodeForSpecialCases(0),_currentIndex(0) { } ForEachLoop::ForEachLoop(const ForEachLoop& other, ComposedNode *father, bool editionOnly):DynParaLoop(other,father,editionOnly), _splitterNode(other._splitterNode,this), - _execCurrentId(0),_nodeForSpecialCases(0) + _execCurrentId(0),_nodeForSpecialCases(0),_currentIndex(0) { int i=0; if(!editionOnly) @@ -334,6 +334,8 @@ void ForEachLoop::init(bool start) _splitterNode.init(start); _execCurrentId=0; cleanDynGraph(); + _currentIndex = 0; + exUpdateProgress(); } void ForEachLoop::exUpdateState() @@ -435,6 +437,12 @@ void ForEachLoop::exUpdateState() } } +void ForEachLoop::exUpdateProgress() +{ + // emit notification to all observers registered with the dispatcher on any change of the node's state + sendEvent("progress"); +} + void ForEachLoop::getReadyTasks(std::vector& tasks) { if(!_node) @@ -541,6 +549,8 @@ YACS::Event ForEachLoop::updateStateOnFinishedEventFrom(Node *node) if (_initializingCounter == 0) _initNode->setState(DONE); break; case WORK_NODE: + _currentIndex++; + exUpdateProgress(); storeOutValsInSeqForOutOfScopeUse(_execIds[id],id); if(_execCurrentId==_splitterNode.getNumberOfElements()) {//No more elements of _dataPortToDispatch to treat @@ -618,6 +628,8 @@ YACS::Event ForEachLoop::updateStateOnFinishedEventFrom(Node *node) { DEBTRACE("Finalize node finished on branch " << id); _unfinishedCounter--; + _currentIndex++; + exUpdateProgress(); DEBTRACE(_unfinishedCounter << " finalize nodes still running"); if (_unfinishedCounter == 0) { @@ -826,3 +838,14 @@ void ForEachLoop::resetState(int level) //Note: cleanDynGraph is not a virtual method (must be called from ForEachLoop object) cleanDynGraph(); } + +std::string ForEachLoop::getProgress() const +{ + int nbElems = _splitterNode.getNumberOfElements(); + char* aProgress = new char[]; + if (nbElems > 0) + sprintf(aProgress, "%i/%i", _currentIndex, nbElems); + else + sprintf(aProgress, "0"); + return aProgress; +} diff --git a/src/engine/ForEachLoop.hxx b/src/engine/ForEachLoop.hxx index 6aacd34c6..7648f89e8 100644 --- a/src/engine/ForEachLoop.hxx +++ b/src/engine/ForEachLoop.hxx @@ -133,6 +133,7 @@ namespace YACS protected: static const int NOT_RUNNING_BRANCH_ID; protected: + int _currentIndex; SplitterNode _splitterNode; FakeNodeForForEachLoop *_nodeForSpecialCases; std::vector _outGoingPorts;//! ports linked to node outside the current scope @@ -147,6 +148,7 @@ namespace YACS ~ForEachLoop(); void init(bool start=true); void exUpdateState(); + void exUpdateProgress(); void getReadyTasks(std::vector& tasks); int getNumberOfInputPorts() const; // @@ -166,6 +168,7 @@ namespace YACS void writeDot(std::ostream &os) const; virtual std::string typeName() {return "YACS__ENGINE__ForEachLoop";} virtual void resetState(int level); + std::string getProgress() const; protected: Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; void checkLinkPossibility(OutPort *start, const std::list& pointsOfViewStart, diff --git a/src/engine/ForLoop.cxx b/src/engine/ForLoop.cxx index 36511f266..30fcb66ea 100644 --- a/src/engine/ForLoop.cxx +++ b/src/engine/ForLoop.cxx @@ -91,6 +91,7 @@ void ForLoop::init(bool start) Any* tmp=AtomAny::New(_nbOfTurns); _indexPort.put(tmp); tmp->decrRef(); + exUpdateProgress(); } //! Update the state of the for loop @@ -145,6 +146,7 @@ void ForLoop::exUpdateState() YACS::Event ForLoop::updateStateOnFinishedEventFrom(Node *node) { DEBTRACE("ForLoop::updateStateOnFinishedEventFrom " << node->getName()); + exUpdateProgress(); if((++_nbOfTurns)>=_nbOfTimesPort.getIntValue()) { setState(YACS::DONE); @@ -162,6 +164,12 @@ YACS::Event ForLoop::updateStateOnFinishedEventFrom(Node *node) return YACS::NOEVENT; } +void ForLoop::exUpdateProgress() +{ + // emit notification to all observers registered with the dispatcher on any change of the node's state + sendEvent("progress"); +} + void ForLoop::accept(Visitor *visitor) { visitor->visitForLoop(this); @@ -257,3 +265,16 @@ std::list ForLoop::getSetOfOutputPort() const return ret; } +std::string ForLoop::getProgress() const +{ + char* aProgress = new char[]; + sprintf(aProgress, "0"); + AnyInputPort* aNbStepsPort = (AnyInputPort*)&_nbOfTimesPort; + if (aNbStepsPort && !aNbStepsPort->isEmpty()) { + int nbSteps = aNbStepsPort->getIntValue(); + if (nbSteps > 0 && _nbOfTurns >= 0) { + sprintf(aProgress, "%i/%i", _nbOfTurns, nbSteps); + } + } + return aProgress; +} diff --git a/src/engine/ForLoop.hxx b/src/engine/ForLoop.hxx index 82c1d9f6b..bd580f997 100644 --- a/src/engine/ForLoop.hxx +++ b/src/engine/ForLoop.hxx @@ -40,6 +40,7 @@ namespace YACS ForLoop(const ForLoop& other, ComposedNode *father, bool editionOnly); ForLoop(const std::string& name); void exUpdateState(); + void exUpdateProgress(); void init(bool start=true); InputPort *edGetNbOfTimesInputPort() { return &_nbOfTimesPort; } Node *simpleClone(ComposedNode *father, bool editionOnly=true) const; @@ -53,6 +54,7 @@ namespace YACS InputPort *getDecisionPort() const { return (InputPort *)&_nbOfTimesPort; } OutputPort *edGetIndexPort() { return &_indexPort; } virtual std::string typeName() {return "YACS__ENGINE__ForLoop";} + std::string getProgress() const; protected: YACS::Event updateStateOnFinishedEventFrom(Node *node); void checkCFLinks(const std::list& starts, InputPort *end, unsigned char& alreadyFed, diff --git a/src/engine/Proc.cxx b/src/engine/Proc.cxx index 990b80f8c..584e336a5 100644 --- a/src/engine/Proc.cxx +++ b/src/engine/Proc.cxx @@ -221,6 +221,18 @@ YACS::StatesForNode Proc::getNodeState(int numId) return state; } +std::string Proc::getNodeProgress(int numId) +{ + std::string progress = "0"; + if(YACS::ENGINE::Node::idMap.count(numId) == 0) + { + cerr << "Unknown node id " << numId << endl; + } + else if (YACS::ENGINE::ComposedNode* node = dynamic_cast(YACS::ENGINE::Node::idMap[numId])) + progress = node->getProgress(); + return progress; +} + std::string Proc::getXMLState(int numId) { if(YACS::ENGINE::Node::idMap.count(numId) == 0) diff --git a/src/engine/Proc.hxx b/src/engine/Proc.hxx index 1da58cad3..5300ce684 100644 --- a/src/engine/Proc.hxx +++ b/src/engine/Proc.hxx @@ -65,6 +65,7 @@ namespace YACS virtual const Proc * getProc() const; YACS::StatesForNode getNodeState(int numId); + std::string Proc::getNodeProgress(int numId); std::string getInPortValue(int nodeNumId, std::string portName); std::string setInPortValue(std::string nodeName, std::string portName, std::string value); std::string getOutPortValue(int nodeNumId, std::string portName); diff --git a/src/genericgui/CMakeLists.txt b/src/genericgui/CMakeLists.txt index 1174e762f..466e06b98 100644 --- a/src/genericgui/CMakeLists.txt +++ b/src/genericgui/CMakeLists.txt @@ -308,6 +308,8 @@ SET(GenericGui_SOURCES ScenePortItem.cxx SceneProcItem.hxx SceneProcItem.cxx + SceneProgressItem.hxx + SceneProgressItem.cxx SceneTextItem.hxx SceneTextItem.cxx SchemaComponentItem.hxx diff --git a/src/genericgui/GenericGui.cxx b/src/genericgui/GenericGui.cxx index 11f87b006..92db4a50f 100644 --- a/src/genericgui/GenericGui.cxx +++ b/src/genericgui/GenericGui.cxx @@ -1213,6 +1213,7 @@ void GenericGui::setLoadedPresentation(YACS::ENGINE::Proc* proc) { DEBTRACE("GenericGui::setLoadedPresentation"); QtGuiContext::getQtCurrent()->setLoadingPresentation(true); + map nodesToMove; map presNodes = _loader->getPrsData(proc); if (!presNodes.empty()) { @@ -1233,8 +1234,24 @@ void GenericGui::setLoadedPresentation(YACS::ENGINE::Proc* proc) inode->setExpandedPos(QPointF(pres._expx, pres._expy)); inode->setExpandedWH(pres._expWidth, pres._expHeight); inode->setShownState(shownState(pres._shownState)); + + // collect nodes to correct it's Y-position if this collides with parent's header + if (inode->getParent() && inode->y() < inode->getParent()->getHeaderBottom()) + nodesToMove[inode] = QPointF(inode->x(), inode->getParent()->getHeaderBottom()+1); } } + QtGuiContext::getQtCurrent()->setLoadingPresentation(false); + + //after loading of presentation: + + //move nodes because of progress bar, if any was added + map::iterator it = nodesToMove.begin(); + for (; it!= nodesToMove.end(); ++it) + { + (*it).first->setTopLeft((*it).second); + } + + //update links if (Scene::_autoComputeLinks) _guiEditor->rebuildLinks(); else @@ -1244,8 +1261,6 @@ void GenericGui::setLoadedPresentation(YACS::ENGINE::Proc* proc) SceneComposedNodeItem *proc = dynamic_cast(item); proc->updateLinks(); } - - QtGuiContext::getQtCurrent()->setLoadingPresentation(false); } // ----------------------------------------------------------------------------- diff --git a/src/genericgui/GuiExecutor.cxx b/src/genericgui/GuiExecutor.cxx index 0b857e80f..b1ca2d285 100644 --- a/src/genericgui/GuiExecutor.cxx +++ b/src/genericgui/GuiExecutor.cxx @@ -392,6 +392,7 @@ void GuiExecutor::registerStatusObservers() for ( std::list::iterator it = aNodeSet.begin(); it != aNodeSet.end(); it++ ) { _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "status"); + _procRef->addObserver(_observerRef, _serv->getEngineId((*it)->getNumId()) , "progress"); } _procRef->addObserver(_observerRef, _serv->getEngineId(_proc->getNumId()) , "executor"); } @@ -519,32 +520,39 @@ bool GuiExecutor::event(QEvent *e) SubjectNode *snode = _context->_mapOfExecSubjectNode[iGui]; DEBTRACE("node " << snode->getName() << " state=" << state); - YACS::ENGINE::Node *node = snode->getNode(); - list inports = node->getLocalInputPorts(); - list::iterator iti = inports.begin(); - for ( ; iti != inports.end(); ++iti) - { - string val = _procRef->getInPortValue(numid, (*iti)->getName().c_str()); - DEBTRACE("node " << snode->getName() << " inport " << (*iti)->getName() - << " value " << val); - YASSERT(_context->_mapOfSubjectDataPort.count(*iti)); - SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti]; - port->setExecValue(val); - port->update(YACS::HMI::UPDATEPROGRESS, 0, port); - } - list outports = node->getLocalOutputPorts(); - list::iterator ito = outports.begin(); - for ( ; ito != outports.end(); ++ito) - { - string val = _procRef->getOutPortValue(numid, (*ito)->getName().c_str()); - DEBTRACE("node " << snode->getName() << " outport " << (*ito)->getName() - << " value " << val); - YASSERT(_context->_mapOfSubjectDataPort.count(*ito)); - SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito]; - port->setExecValue(val); - port->update(YACS::HMI::UPDATEPROGRESS, 0, port); - } - snode->update(YACS::HMI::UPDATEPROGRESS, state, snode); + if (event == "progress") { // --- Update progress bar + std::string progress = _procRef->getNodeProgress(numid); + snode->setProgress( progress ); + snode->update(YACS::HMI::PROGRESS, state, snode); + } + else { // --- Update node ports + YACS::ENGINE::Node *node = snode->getNode(); + list inports = node->getLocalInputPorts(); + list::iterator iti = inports.begin(); + for ( ; iti != inports.end(); ++iti) + { + string val = _procRef->getInPortValue(numid, (*iti)->getName().c_str()); + DEBTRACE("node " << snode->getName() << " inport " << (*iti)->getName() + << " value " << val); + YASSERT(_context->_mapOfSubjectDataPort.count(*iti)); + SubjectDataPort* port = _context->_mapOfSubjectDataPort[*iti]; + port->setExecValue(val); + port->update(YACS::HMI::UPDATEPROGRESS, 0, port); + } + list outports = node->getLocalOutputPorts(); + list::iterator ito = outports.begin(); + for ( ; ito != outports.end(); ++ito) + { + string val = _procRef->getOutPortValue(numid, (*ito)->getName().c_str()); + DEBTRACE("node " << snode->getName() << " outport " << (*ito)->getName() + << " value " << val); + YASSERT(_context->_mapOfSubjectDataPort.count(*ito)); + SubjectDataPort* port = _context->_mapOfSubjectDataPort[*ito]; + port->setExecValue(val); + port->update(YACS::HMI::UPDATEPROGRESS, 0, port); + } + snode->update(YACS::HMI::UPDATEPROGRESS, state, snode); + } } return true; diff --git a/src/genericgui/Resource.cxx b/src/genericgui/Resource.cxx index 7ed012185..ae6b06310 100644 --- a/src/genericgui/Resource.cxx +++ b/src/genericgui/Resource.cxx @@ -33,6 +33,8 @@ bool Resource::autoComputeLinks = AUTOCOMPUTELINKS; bool Resource::simplifyLink = SIMPLIFYLINK; bool Resource::ensureVisibleWhenMoved = ENSUREVISIBLEWHENMOVED; int Resource::dockWidgetPriority = DOCKWIDGETPRIORITY; +QColor Resource::progressBarColor = PROGRESSBARCOLOR; +int Resource::progressBarLabel = PROGRESSBARLABEL; QFont Resource::pythonfont = PYTHONFONT; // Statics for color of states @@ -144,6 +146,8 @@ int Resource::Corner_Margin = ( Resource::Border_Margin + Resource::Space_Marg int Resource::Header_Height = ( Resource::Corner_Margin + Resource::CtrlPort_Height + Resource::Line_Space + Resource::Line_Width + Resource::Line_Space ); int Resource::Radius = 3; +int Resource::progressBar_Height = 20; + bool Resource::tabPanelsUp = TABPANELSUP; // Constructor diff --git a/src/genericgui/Resource.hxx b/src/genericgui/Resource.hxx index 25d54916e..623bd6caf 100644 --- a/src/genericgui/Resource.hxx +++ b/src/genericgui/Resource.hxx @@ -112,6 +112,8 @@ #define ENSUREVISIBLEWHENMOVED true #define TABPANELSUP true #define DOCKWIDGETPRIORITY 0 +#define PROGRESSBARCOLOR Qt::darkGreen +#define PROGRESSBARLABEL 2 #define EDITEDNODEBRUSHCOLOR QColor(255, 255, 190) #define NORMALNODEBRUSHCOLOR QColor(230, 235, 255) @@ -210,6 +212,8 @@ namespace YACS { static bool simplifyLink; static bool ensureVisibleWhenMoved; static int dockWidgetPriority; + static QColor progressBarColor; + static int progressBarLabel; // Colors of state of nodes static QColor editedNodeBrushColor; @@ -315,6 +319,8 @@ namespace YACS { static int Header_Height; static int Radius; + static int progressBar_Height; + static bool tabPanelsUp; }; } diff --git a/src/genericgui/SceneComposedNodeItem.cxx b/src/genericgui/SceneComposedNodeItem.cxx index 83f89e5e1..a85b2f4e1 100644 --- a/src/genericgui/SceneComposedNodeItem.cxx +++ b/src/genericgui/SceneComposedNodeItem.cxx @@ -30,6 +30,7 @@ #include "SceneLinkItem.hxx" #include "SceneDSLinkItem.hxx" #include "SceneCtrlLinkItem.hxx" +#include "SceneProgressItem.hxx" #include "LinkMatrix.hxx" #include "LinkAStar.hxx" #include "ItemMimeData.hxx" @@ -144,6 +145,11 @@ void SceneComposedNodeItem::update(GuiEvent event, int type, Subject* son) son->getName().c_str(), son); item->addHeader(); + if ( !QtGuiContext::getQtCurrent()->isEdition() + && (type == YACS::HMI::FORLOOP || type == YACS::HMI::FOREACHLOOP) ) + { + item->addProgressItem(); + } autoPosNewChild(item, _children, true); break; case YACS::HMI::PYTHONNODE: @@ -316,6 +322,15 @@ void SceneComposedNodeItem::update(GuiEvent event, int type, Subject* son) autoPosNewChild(sinode, _children, true); } break; + case PROGRESS: + { + if (dynamic_cast(son) || dynamic_cast(son)) + { + if (SceneProgressItem* spitem = getProgressItem()) + spitem->setProgress(son->getProgress().c_str()); + } + } + break; default: ; // DEBTRACE("SceneComposedNodeItem::update(), event not handled: "<< eventName(event)); @@ -464,6 +479,8 @@ void SceneComposedNodeItem::shrinkExpandRecursive(bool isExpanding, bool fromHer else setPos(_expandedPos); adjustHeader(); + if (_progressItem) + _progressItem->adjustGeometry(); } else { // --- expanding: resize, then show children @@ -500,6 +517,8 @@ void SceneComposedNodeItem::shrinkExpandRecursive(bool isExpanding, bool fromHer } setPos(_expandedPos); adjustHeader(); + if (_progressItem) + _progressItem->adjustGeometry(); } } @@ -538,6 +557,8 @@ void SceneComposedNodeItem::setShownState(shownState ss) show(); } adjustHeader(); + if (_progressItem) + _progressItem->adjustGeometry(); } void SceneComposedNodeItem::collisionResolv(SceneItem* child, QPointF oldPos) diff --git a/src/genericgui/SceneHeaderNodeItem.cxx b/src/genericgui/SceneHeaderNodeItem.cxx index 67c5801d4..a58790d98 100644 --- a/src/genericgui/SceneHeaderNodeItem.cxx +++ b/src/genericgui/SceneHeaderNodeItem.cxx @@ -47,6 +47,7 @@ SceneHeaderNodeItem::SceneHeaderNodeItem(QGraphicsScene *scene, SceneItem *paren QString label) : SceneHeaderItem(scene, parent, label) { + _fatherNode= dynamic_cast(parent); _width = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin; _height = Resource::Header_Height; _maxPorts = 0; @@ -92,6 +93,8 @@ void SceneHeaderNodeItem::paint(QPainter *painter, int x = Resource::Border_Margin + 1; int y = Resource::Header_Height - Resource::Line_Space; + if (_fatherNode && _fatherNode->hasProgressBar()) + y += Resource::progressBar_Height; int w = Resource::Corner_Margin + 2*Resource::DataPort_Width + 2*Resource::Space_Margin; if (_parent->getWidth() > w) w = _parent->getWidth() - Resource::Border_Margin; QPen pen(getPenColor()); @@ -106,8 +109,7 @@ void SceneHeaderNodeItem::paint(QPainter *painter, pen.setWidth(Resource::Thickness); painter->setPen(pen); - SceneNodeItem* father = dynamic_cast(_parent); - bool expanded = (father && father->isExpanded()); + bool expanded = (_fatherNode && _fatherNode->isExpanded()); QColor baseColor = getBrushColor(); if (expanded) painter->setBrush(baseColor); @@ -139,11 +141,13 @@ void SceneHeaderNodeItem::setText(QString label) qreal SceneHeaderNodeItem::getHeaderBottom() const { + qreal res = 0; if (_hasHeader) { - return Resource::Header_Height + _maxPorts * (Resource::DataPort_Height + Resource::Space_Margin); - } else { - return 0; - }; + res += Resource::Header_Height + _maxPorts * (Resource::DataPort_Height + Resource::Space_Margin); + if (_fatherNode && _fatherNode->hasProgressBar()) + res += Resource::progressBar_Height; + } + return res; } void SceneHeaderNodeItem::autoPosControl(AbstractSceneItem *item) @@ -171,6 +175,8 @@ void SceneHeaderNodeItem::autoPosNewPort(AbstractSceneItem *item) _outPorts.push_back(dynamic_cast(item)); }; qreal yTop = Resource::Header_Height; + if (_fatherNode && _fatherNode->hasProgressBar()) + yTop += Resource::progressBar_Height; qreal deltaY = Resource::DataPort_Height + Resource::Space_Margin; yTop += nbPorts * deltaY; if (nbPorts >=_maxPorts) { @@ -188,10 +194,12 @@ void SceneHeaderNodeItem::reorganizePorts(shownState ss) qreal yTop; qreal href = Resource::Header_Height; + if (_fatherNode && _fatherNode->hasProgressBar()) + href += Resource::progressBar_Height; bool isShown = (ss != shrinkHidden); if (!isShown) href = Resource::Corner_Margin; -std::list::iterator iti = _inPorts.begin(); + std::list::iterator iti = _inPorts.begin(); int nbPorts = 0; for (; iti != _inPorts.end(); ++iti) { @@ -238,9 +246,8 @@ void SceneHeaderNodeItem::adjustGeometry() void SceneHeaderNodeItem::adjustPosPorts() { - SceneNodeItem* father = dynamic_cast(_parent); - YASSERT(father); - shownState ss = father->getShownState(); + YASSERT(_fatherNode); + shownState ss = _fatherNode->getShownState(); if (_controlOut) { int x = Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin; @@ -258,6 +265,8 @@ QRectF SceneHeaderNodeItem::getMinimalBoundingRect() const int nbPorts = _inPorts.size(); if (_outPorts.size() > nbPorts) nbPorts = _outPorts.size(); if (nbPorts) height += nbPorts*(Resource::DataPort_Height + Resource::Space_Margin); + if (_fatherNode && _fatherNode->hasProgressBar()) + height += Resource::progressBar_Height; //DEBTRACE(nbPorts << " " << width << " " << height); return QRectF(x(), y(), width, height); } diff --git a/src/genericgui/SceneHeaderNodeItem.hxx b/src/genericgui/SceneHeaderNodeItem.hxx index 99b26db09..a22357da7 100644 --- a/src/genericgui/SceneHeaderNodeItem.hxx +++ b/src/genericgui/SceneHeaderNodeItem.hxx @@ -62,6 +62,7 @@ namespace YACS virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + SceneNodeItem* _fatherNode; SceneHeaderItem *_header; SceneCtrlPortItem *_controlIn; SceneCtrlPortItem *_controlOut; diff --git a/src/genericgui/SceneItem.cxx b/src/genericgui/SceneItem.cxx index e0a6b0a10..80872f39e 100644 --- a/src/genericgui/SceneItem.cxx +++ b/src/genericgui/SceneItem.cxx @@ -141,10 +141,15 @@ void AbstractSceneItem::addHeader() { } +void AbstractSceneItem::addProgressItem() +{ +} + qreal AbstractSceneItem::getHeaderBottom() { return 0; } + qreal AbstractSceneItem::getWidth() { return _width; diff --git a/src/genericgui/SceneItem.hxx b/src/genericgui/SceneItem.hxx index aeedd6995..26f19e796 100644 --- a/src/genericgui/SceneItem.hxx +++ b/src/genericgui/SceneItem.hxx @@ -73,6 +73,7 @@ namespace YACS virtual void reorganize(); virtual QString getLabel(); virtual void addHeader(); + virtual void addProgressItem(); virtual qreal getHeaderBottom(); qreal getWidth(); qreal getHeight(); @@ -132,6 +133,8 @@ namespace YACS virtual void shrinkExpandLink(bool se); virtual void shrinkExpandRecursive(bool isExpanding, bool fromHere); bool isAncestorShrinked() { return _ancestorShrinked; }; + bool _blocX; + bool _blocY; protected: // virtual bool sceneEvent(QEvent *event); diff --git a/src/genericgui/SceneNodeItem.cxx b/src/genericgui/SceneNodeItem.cxx index 844ec6681..0a528615a 100644 --- a/src/genericgui/SceneNodeItem.cxx +++ b/src/genericgui/SceneNodeItem.cxx @@ -21,6 +21,7 @@ #include "SceneComposedNodeItem.hxx" #include "SceneProcItem.hxx" #include "SceneHeaderNodeItem.hxx" +#include "SceneProgressItem.hxx" #include "SceneInPortItem.hxx" #include "SceneOutPortItem.hxx" #include "SceneCtrlInPortItem.hxx" @@ -58,6 +59,7 @@ SceneNodeItem::SceneNodeItem(QGraphicsScene *scene, SceneItem *parent, _inPorts.clear(); _outPorts.clear(); _header = 0; + _progressItem = 0; _brushColor = Resource::Scene_pen; _moving = false; _moved = false; @@ -121,6 +123,20 @@ SceneHeaderItem* SceneNodeItem::getHeader() return _header; } +void SceneNodeItem::addProgressItem() +{ + DEBTRACE("SceneNodeItem::addProgressItem "); + if (!_progressItem) + { + _progressItem = new SceneProgressItem(_scene, + this, + "progress"); + _progressItem->setText("0"); + updateState(); + checkGeometryChange(); + } +} + void SceneNodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -441,3 +457,8 @@ void SceneNodeItem::setShownState(shownState ss) { _shownState = ss; } + +bool SceneNodeItem::hasProgressBar() const +{ + return _progressItem != 0; +} diff --git a/src/genericgui/SceneNodeItem.hxx b/src/genericgui/SceneNodeItem.hxx index 8f3b58e0e..46a76a88a 100644 --- a/src/genericgui/SceneNodeItem.hxx +++ b/src/genericgui/SceneNodeItem.hxx @@ -39,6 +39,7 @@ namespace YACS class SceneHeaderNodeItem; class SceneComposedNodeItem; class ScenePortItem; + class SceneProgressItem; class SceneNodeItem: public SceneObserverItem { @@ -51,6 +52,8 @@ namespace YACS virtual void setHeight(qreal height); virtual void addHeader(); virtual SceneHeaderItem* getHeader(); + virtual void addProgressItem(); + virtual SceneProgressItem* getProgressItem() { return _progressItem; }; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -85,8 +88,7 @@ namespace YACS qreal getExpandedWidth() { return _expandedWidth; }; qreal getExpandedHeight() { return _expandedHeight; }; shownState getShownState() {return _shownState; }; - bool _blocX; - bool _blocY; + bool hasProgressBar() const; protected: virtual QString getMimeFormat(); @@ -102,6 +104,7 @@ namespace YACS std::list _inPorts; std::list _outPorts; SceneHeaderNodeItem *_header; + SceneProgressItem *_progressItem; int _execState; bool _moving; bool _moved; diff --git a/src/genericgui/SceneProgressItem.cxx b/src/genericgui/SceneProgressItem.cxx new file mode 100644 index 000000000..a54054a24 --- /dev/null +++ b/src/genericgui/SceneProgressItem.cxx @@ -0,0 +1,167 @@ +// Copyright (C) 2006-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SceneProgressItem.hxx" +#include "SceneHeaderNodeItem.hxx" +#include "SceneTextItem.hxx" +#include "Scene.hxx" +#include + +#include "Resource.hxx" + +#include + +//#define _DEVDEBUG_ +#include "YacsTrace.hxx" + +using namespace std; +using namespace YACS::ENGINE; +using namespace YACS::HMI; + + +SceneProgressItem::SceneProgressItem(QGraphicsScene *scene, SceneItem *parent, + QString label) + : SceneItem(scene, parent, label) +{ + YASSERT(_parent); + _progress = 0; + _width = Resource::Corner_Margin + 2*Resource::DataPort_Width + 2*Resource::Space_Margin; + _height = Resource::progressBar_Height; + _text=0; + _tooltip = ""; + _brushColor = Resource::Header_brush; + _hiBrushColor = Resource::Header_hiBrush; + _penColor = Resource::Header_pen; + _hiPenColor = Resource::Header_hiPen; + int x = Resource::Border_Margin; + int y = Resource::DataPort_Height + 2*Resource::Space_Margin; + setTopLeft(QPointF(x, y)); +} + +SceneProgressItem::~SceneProgressItem() +{ +} + +QRectF SceneProgressItem::getMinimalBoundingRect() const +{ + return QRectF(x(), y(), _width, _height); +} + +void SceneProgressItem::paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget) +{ +// DEBTRACE("SceneProgressItem::paint"); + painter->save(); + + int w = Resource::Corner_Margin + 2*Resource::DataPort_Width + 2*Resource::Space_Margin; + if (_parent->getWidth() > w) w = _parent->getWidth() - Resource::Corner_Margin - Resource::Space_Margin; + int h = Resource::progressBar_Height; + QPen pen(getPenColor()); + pen.setWidth(Resource::Thickness); + painter->setPen(pen); + QRect boundRect(0, 0, w, h); + painter->drawRect(boundRect); + + painter->setBrush(Resource::progressBarColor); + //correct width according to progress + int corr_w = w * _progress / 100; + painter->drawRect(QRect(0, 0, corr_w, h)); + painter->restore(); +} + +void SceneProgressItem::setProgress(QString newProgress) +{ + QString percentageLabel; + QString nbStepsLabel = "-/-"; + QStringList aSteps = newProgress.split('/'); + if (aSteps.count() == 2) + { //case '5/10' view of progress + _progress = aSteps.at(0).toInt() * 100 / aSteps.at(1).toInt(); + nbStepsLabel = newProgress; + } + else + { //case '50' view of progress + _progress = newProgress.toInt(); //set 0 if the conversion fails. + } + percentageLabel = QString("%1\%").arg(_progress); + QString resultLabel; + switch(Resource::progressBarLabel) + { + case 0: //Percentage: 50% + resultLabel = QString("%1").arg(percentageLabel); + break; + case 1: //Nb.steps: 5/10 + resultLabel = QString("%1").arg(nbStepsLabel); + break; + case 2: //Both: 50% (5/10) + resultLabel = QString("%1 (%2)").arg(percentageLabel).arg(nbStepsLabel); + break; + } + setText(resultLabel); + _tooltip = QString("%1 (%2)").arg(percentageLabel).arg(nbStepsLabel); + update(); +} + +void SceneProgressItem::setText(QString label) +{ + if (!_text) + _text = new SceneTextItem(_scene, this, label, true); + else + _text->setPlainTextTrunc(label); + //QGraphicsItem::update(); +} + +void SceneProgressItem::popupMenu(QWidget *caller, const QPoint &globalPos) +{ + if (_parent) _parent->popupMenu(caller, globalPos); +} + +void SceneProgressItem::adjustGeometry() +{ + prepareGeometryChange(); + _width = _parent->getWidth() - Resource::Corner_Margin - Resource::Space_Margin; + update(); +} + +QColor SceneProgressItem::getPenColor() +{ + return _hiPenColor; +} + +QColor SceneProgressItem::getBrushColor() +{ + QColor color = _brushColor; + if (dynamic_cast(this)) + if (getParent()->isSelected()) + color = _hiBrushColor; + if (_hover) + color = hoverColor(color); + return color; +} + +void SceneProgressItem::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + +QString SceneProgressItem::getToolTip() +{ + return _tooltip;; +} diff --git a/src/genericgui/SceneProgressItem.hxx b/src/genericgui/SceneProgressItem.hxx new file mode 100644 index 000000000..77a42ca1f --- /dev/null +++ b/src/genericgui/SceneProgressItem.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2006-2013 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef _SCENEPROGRESSITEM_HXX_ +#define _SCENEPROGRESSITEM_HXX_ + +#include "SceneItem.hxx" + +namespace YACS +{ + namespace HMI + { + class SceneTextItem; + + class SceneProgressItem: public SceneItem + { + public: + SceneProgressItem(QGraphicsScene *scene, SceneItem *parent, + QString label); + virtual ~SceneProgressItem(); + virtual QRectF getMinimalBoundingRect() const; + virtual void paint(QPainter *painter, + const QStyleOptionGraphicsItem *option, + QWidget *widget); + virtual void setProgress(QString newProgress); + virtual int getProgress() { return _progress; }; + virtual void setText(QString label); + virtual void popupMenu(QWidget *caller, const QPoint &globalPos); + virtual void adjustGeometry(); + + protected: + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual QString getToolTip(); + QColor getPenColor(); + QColor getBrushColor(); + SceneTextItem* _text; + QString _tooltip; + int _progress; + + }; + } +} + +#endif diff --git a/src/hmi/guiObservers.cxx b/src/hmi/guiObservers.cxx index 01709dfac..2a767256d 100644 --- a/src/hmi/guiObservers.cxx +++ b/src/hmi/guiObservers.cxx @@ -325,6 +325,11 @@ void Subject::addSubjectReference(Subject *ref) update(ADDREF, 0, son); } +void Subject::setProgress( std::string newProgress ) +{ + _progress = newProgress; +} + // ---------------------------------------------------------------------------- GuiObserver::GuiObserver() diff --git a/src/hmi/guiObservers.hxx b/src/hmi/guiObservers.hxx index 12e792570..535d29f92 100644 --- a/src/hmi/guiObservers.hxx +++ b/src/hmi/guiObservers.hxx @@ -104,7 +104,8 @@ namespace YACS SETSELECT, GEOMETRY, EMPHASIZE, - SWITCHSHAPE + SWITCHSHAPE, + PROGRESS } GuiEvent; class ProcInvoc; @@ -139,11 +140,14 @@ namespace YACS bool isDestructible() { return _destructible; }; static void erase(Subject* sub, Command *command=0, bool post=false); virtual TypeOfElem getType(){return UNKNOWN;} + virtual void setProgress( std::string newProgress ); + virtual std::string getProgress() { return _progress; }; protected: std::set _setObs; Subject *_parent; bool _destructible; bool _askRegisterUndo; + std::string _progress; }; class HMI_EXPORT GuiObserver diff --git a/src/salomegui/Yacsgui_Resource.cxx b/src/salomegui/Yacsgui_Resource.cxx index e9822d4e5..862a76444 100644 --- a/src/salomegui/Yacsgui_Resource.cxx +++ b/src/salomegui/Yacsgui_Resource.cxx @@ -118,18 +118,26 @@ void Yacsgui_Resource::createPreferences(Yacsgui* swm) swm->addPreference( "Ensure Node Visible When Moved", presentationGroup, LightApp_Preferences::Bool, RESOURCE_YACS, "ensureVisibleWhenMoved" ); swm->addPreference( "Tabified Panels Up", presentationGroup, LightApp_Preferences::Bool, RESOURCE_YACS, "tabPanelsUp" ); int priority = swm->addPreference( "DockWidget priority", presentationGroup, LightApp_Preferences::Selector, RESOURCE_YACS, "dockWidgetPriority" ); + swm->addPreference( "Progress bar color", presentationGroup, LightApp_Preferences::Color, RESOURCE_YACS, "progressBarColor" ); + int progressLabel = swm->addPreference( "Progress bar label", presentationGroup, LightApp_Preferences::Selector, RESOURCE_YACS, "progressBarLabel" ); - QStringList priorityList; - priorityList.append( "Horizontal" ); - priorityList.append( "Vertical" ); - + QStringList stringsList; + stringsList.append( "Horizontal" ); + stringsList.append( "Vertical" ); QList indexesList; indexesList.append(0); indexesList.append(1); - - swm->setPreferenceProperty( priority, "strings", priorityList ); + swm->setPreferenceProperty( priority, "strings", stringsList ); swm->setPreferenceProperty( priority, "indexes", indexesList ); + stringsList.clear(); + indexesList.clear(); + + stringsList << "Percentage: \"50%\"" << "Nb.steps: \"5/10\"" << "Both: \"50% (5/10)\""; + indexesList << 0 << 1 << 2; + swm->setPreferenceProperty( progressLabel, "strings", stringsList ); + swm->setPreferenceProperty( progressLabel, "indexes", indexesList ); + int pythonGroup = swm->addPreference( "Python", genTab ); swm->addPreference( "Python Script Font", pythonGroup, LightApp_Preferences::Font, RESOURCE_YACS, "font" ); @@ -286,6 +294,8 @@ void Yacsgui_Resource::preferencesChanged() Resource::ensureVisibleWhenMoved = booleanValue("ensureVisibleWhenMoved", ENSUREVISIBLEWHENMOVED); Resource::tabPanelsUp = booleanValue("tabPanelsUp", TABPANELSUP); Resource::dockWidgetPriority = integerValue( "dockWidgetPriority" , DOCKWIDGETPRIORITY); + Resource::progressBarColor = colorValue("progressBarColor", PROGRESSBARCOLOR); + Resource::progressBarLabel = integerValue( "progressBarLabel" , PROGRESSBARLABEL); // Color of state of nodes Resource::editedNodeBrushColor = colorValue(_editedNodeBrushColor, EDITEDNODEBRUSHCOLOR); diff --git a/src/salomegui/resources/SalomeApp.xml.in b/src/salomegui/resources/SalomeApp.xml.in index a82603ef9..d18e7c5aa 100644 --- a/src/salomegui/resources/SalomeApp.xml.in +++ b/src/salomegui/resources/SalomeApp.xml.in @@ -45,6 +45,8 @@ + + diff --git a/src/yacsorb/YACS.py b/src/yacsorb/YACS.py index 4d868dca8..488334d7a 100644 --- a/src/yacsorb/YACS.py +++ b/src/yacsorb/YACS.py @@ -46,6 +46,9 @@ class proc_i(YACS_ORB__POA.ProcExec): def getNodeState(self,numid): return self.p.getNodeState(numid) + def getNodeProgress(self,numid): + return self.p.getNodeProgress(numid) + def getXMLState(self, numid): return self.p.getXMLState(numid) -- 2.39.2