diff --git a/vlsisapd/src/configuration/src/Configuration.cpp b/vlsisapd/src/configuration/src/Configuration.cpp index 8b951d50..e10a9263 100644 --- a/vlsisapd/src/configuration/src/Configuration.cpp +++ b/vlsisapd/src/configuration/src/Configuration.cpp @@ -164,7 +164,10 @@ namespace { , _getAttributeValue("value") ); } else { - _parameter->setString ( _getAttributeValue("value"), false ); + _parameter->setString ( _getAttributeValue("value") + , (Parameter::AllRequirements | Parameter::FromString) + & ~Parameter::TypeCheck + ); } if ( not attrRestart.empty() ) _parameter->setFlags ( Parameter::NeedRestart ); @@ -389,11 +392,7 @@ namespace Cfg { , _layout (this) , _flags (0) , _logSets () - { - _logSets.reserve ( LogTypeSize ); - for ( size_t ilog=0 ; ilog() ); - } + { } ConfigurationWidget* Configuration::buildWidget ( unsigned int flags ) @@ -443,15 +442,31 @@ namespace Cfg { } - void Configuration::addLog ( unsigned int type, const string& id ) + const set& Configuration::getLogs ( unsigned int mask ) const { - _logSets[ (type _failsafe; + + map< unsigned int, set >::const_iterator ilog = _logSets.find(mask); + if ( ilog != _logSets.end() ) return (*ilog).second; + + return _failsafe; + } + + void Configuration::addLog ( unsigned int mask, const string& id ) + { + map< unsigned int, set >::iterator ilog = _logSets.find(mask); + if ( ilog == _logSets.end() ) { + _logSets.insert ( make_pair(mask,set()) ); + ilog = _logSets.find(mask); + } + (*ilog).second.insert ( LogEntry(id) ); } - void Configuration::removeLog ( unsigned int type, const string& id ) + void Configuration::removeLog ( unsigned int mask, const string& id ) { - _logSets[ (type >::iterator ilog = _logSets.find(mask); + if ( ilog != _logSets.end() ) (*ilog).second.erase ( id ); } diff --git a/vlsisapd/src/configuration/src/ConfigurationWidget.cpp b/vlsisapd/src/configuration/src/ConfigurationWidget.cpp index c1b5b132..8b9bea55 100644 --- a/vlsisapd/src/configuration/src/ConfigurationWidget.cpp +++ b/vlsisapd/src/configuration/src/ConfigurationWidget.cpp @@ -194,21 +194,29 @@ namespace Cfg { void ConfigurationWidget::applyClicked () { emit updateParameters(); - checkConfiguration (); + if ( checkConfiguration(Configuration::LogNeedExist) == QDialog::Accepted ) { + if ( checkConfiguration(Configuration::LogRestart) == QDialog::Accepted ) { + emit confOk(); + } else { + Configuration* configuration = Configuration::get(); + configuration->restoreFromLogs(Configuration::LogRestart); + configuration->clearLogs (Configuration::LogRestart); + } + } } - void ConfigurationWidget::checkConfiguration () + int ConfigurationWidget::checkConfiguration ( unsigned int mask ) { Configuration* configuration = Configuration::get(); - if ( configuration->hasLogs() ) { + if ( configuration->hasLogs(mask) ) { if ( _log == NULL ) _log = new LogWidget(this); - _log->updateLogs (); - _log->exec (); - } else { - emit checkOk(); + _log->updateLogs (mask); + return _log->exec (); } + + return QDialog::Accepted; } diff --git a/vlsisapd/src/configuration/src/LogWidget.cpp b/vlsisapd/src/configuration/src/LogWidget.cpp index 7fd3d1d6..da6964fa 100644 --- a/vlsisapd/src/configuration/src/LogWidget.cpp +++ b/vlsisapd/src/configuration/src/LogWidget.cpp @@ -45,16 +45,17 @@ namespace Cfg { LogWidget::LogWidget ( QWidget* parent ) - : QDialog (parent) - , _restartMessage (new QLabel()) - , _needExistMessage(new QLabel()) + : QDialog (parent) + , _message (new QLabel()) + , _contButton (new QPushButton()) + , _cancelButton(new QPushButton()) { setModal ( true ); setWindowTitle( tr("") ); setToolTip ( tr("You should better follow these instructions...") ); - _restartMessage->setTextFormat ( Qt::RichText ); - _restartMessage->setText ( "Oups! I did it again!" ); + _message->setTextFormat ( Qt::RichText ); + _message->setText ( "Oups! I did it again!" ); QLabel* ok = new QLabel (); ok->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding ); @@ -62,20 +63,23 @@ namespace Cfg { ok->setStyleSheet ( "QLabel { background-color: #FF9999;" " padding: 5px }" ); - QPushButton* okButton = new QPushButton (); - okButton->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); - okButton->setText ( tr("Continue") ); + _contButton->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); + _contButton->setText ( tr("Continue") ); + + _cancelButton->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); + _cancelButton->setText ( tr("Cancel") ); QHBoxLayout* hLayout2 = new QHBoxLayout (); hLayout2->addStretch ( 1 ); - hLayout2->addWidget ( okButton, Qt::AlignCenter ); + hLayout2->addWidget ( _contButton, Qt::AlignCenter ); + hLayout2->addStretch ( 1 ); + hLayout2->addWidget ( _cancelButton, Qt::AlignCenter ); hLayout2->addStretch ( 1 ); QVBoxLayout* vLayout1 = new QVBoxLayout (); vLayout1->setContentsMargins ( 10, 10, 10, 10 ); vLayout1->setSpacing ( 0 ); - vLayout1->addWidget ( _restartMessage , Qt::AlignCenter ); - vLayout1->addWidget ( _needExistMessage, Qt::AlignCenter ); + vLayout1->addWidget ( _message, Qt::AlignCenter ); vLayout1->addSpacing ( 10 ); vLayout1->addLayout ( hLayout2, Qt::AlignCenter ); @@ -87,7 +91,8 @@ namespace Cfg { setLayout ( hLayout1 ); - connect ( okButton, SIGNAL(clicked()), this, SLOT(accept()) ); + connect ( _contButton , SIGNAL(clicked()), this, SLOT(accept()) ); + connect ( _cancelButton, SIGNAL(clicked()), this, SLOT(reject()) ); } @@ -97,34 +102,41 @@ namespace Cfg { } - void LogWidget::updateLogs () + void LogWidget::updateLogs ( unsigned int mask ) { Configuration* configuration = Configuration::get(); + QString contents; + bool enableCont = true; - for ( size_t ilog=0 ; ilog& logs = configuration->getLogs(ilog); - QLabel* messageLabel = NULL; - QString contents; - const char* header = NULL; + for ( size_t ibit=0 ; ibit < 32 ; ++ibit ) { + unsigned int bit = 1 << ibit; + const char* header = NULL; - switch ( ilog ) { + switch ( bit ) { case Configuration::LogRestart: - messageLabel = _restartMessage; - header = "Program needs restart for these parameters to take effect:
"; + header = "Program needs restart for these parameters to take effect:
"; break; case Configuration::LogNeedExist: - messageLabel = _needExistMessage; - header = "Those parameters needs file/path to exists:
"; + header = "Those parameters needs file/path to exists:
"; break; } - if ( messageLabel == NULL ) continue; + + if ( (header == NULL) or not (mask & bit) ) continue; + mask &= ~bit; + + const set& logs = configuration->getLogs(bit); if ( not logs.empty() ) { + switch ( bit ) { + case Configuration::LogRestart: break; + case Configuration::LogNeedExist: enableCont = false; break; + } + contents += header; - set::const_iterator iid = logs.begin(); - for ( ; iid != logs.end() ; ++iid ) { - Parameter* p = configuration->getParameter((*iid)); + set::const_iterator ientry = logs.begin(); + for ( ; ientry != logs.end() ; ++ientry ) { + Parameter* p = configuration->getParameter((*ientry).getId()); if ( p != NULL ) { WidgetDescription* desc = configuration->getLayout().getWidget ( p->getId() ); @@ -142,9 +154,9 @@ namespace Cfg { } } } - - messageLabel->setText ( contents ); } + _message->setText ( contents ); + _contButton->setEnabled ( enableCont ); } diff --git a/vlsisapd/src/configuration/src/Parameter.cpp b/vlsisapd/src/configuration/src/Parameter.cpp index 8d68da84..08bdae3d 100644 --- a/vlsisapd/src/configuration/src/Parameter.cpp +++ b/vlsisapd/src/configuration/src/Parameter.cpp @@ -36,6 +36,9 @@ namespace Cfg { using std::cerr; using std::endl; using std::string; + using std::ostringstream; + using std::boolalpha; + using std::hex; string Parameter::typeToString ( Parameter::Type type ) @@ -131,20 +134,14 @@ namespace Cfg { } - bool Parameter::setString ( const std::string& s, bool check ) + bool Parameter::setString ( const std::string& s, unsigned int flags ) { - if ( check and (_type != String) ) + if ( (flags & TypeCheck) and (_type != String) ) cerr << "[ERROR] Parameter::setString(): Setting " << Parameter::typeToString(_type) << " parameter <" << _id << "> as " << Parameter::typeToString(String)<< " (type mismatch)." << endl; - if ( _value == s ) return true; - - _value = s; - _onValueChanged(); - _checkRequirements(); - - return true; + return _doChange ( flags, s, false, 0, 0.0 ); } @@ -155,14 +152,7 @@ namespace Cfg { << " parameter <" << _id << "> as " << Parameter::typeToString(Bool)<< " (type mismatch)." << endl; - std::ostringstream s; s << std::boolalpha << b; - if ( _value == s.str() ) return true; - - _value = s.str(); - _onValueChanged(); - _checkRequirements(); - - return true; + return _doChange ( AllRequirements, "", b, 0, 0.0 ); } @@ -173,17 +163,7 @@ namespace Cfg { << " parameter <" << _id << "> as " << Parameter::typeToString(Int)<< " (type mismatch)." << endl; - bool success = checkValue(i); - if ( success ) { - std::ostringstream s; s << i; - if ( _value == s.str() ) return true; - - _value = s.str(); - _onValueChanged(); - _checkRequirements(); - } - - return success; + return _doChange ( AllRequirements, "", false, i, 0.0 ); } @@ -194,17 +174,7 @@ namespace Cfg { << " parameter <" << _id << "> as " << Parameter::typeToString(Double)<< " (type mismatch)." << endl; - bool success = checkValue(d); - if ( success ) { - std::ostringstream s; s << d; - if ( _value == s.str() ) return true; - - _value = s.str(); - _onValueChanged(); - _checkRequirements(); - } - - return success; + return _doChange ( AllRequirements, "", false, 0, d ); } @@ -215,37 +185,72 @@ namespace Cfg { << " parameter <" << _id << "> as " << Parameter::typeToString(Double)<< " (type mismatch)." << endl; - bool success = checkValue(d/100.0); - if ( success ) { - std::ostringstream s; s << (d/100.0); - if ( _value == s.str() ) return true; - - _value = s.str(); - _onValueChanged(); - _checkRequirements(); - } - - return success; + return _doChange ( AllRequirements, "", false, 0, d ); } - void Parameter::_checkRequirements () const + bool Parameter::_doChange ( unsigned int flags, const string& s, bool b, int i, double d ) { - Configuration* configuration = Configuration::get(); + //cerr << "_doChange: " << _id << ":" << _value << " -> \"" << s << "\"|" << b << "|" << i << "|" << d; - if ( hasFlags(NeedRestart) ) { + Configuration* configuration = Configuration::get(); + ostringstream svalue; + bool success = true; + unsigned int type = (flags & FromString) ? String : _type; + + switch ( type ) { + case Unknown: + break; + case String: + svalue << s; + break; + case Bool: + svalue << boolalpha << b; + break; + case Enumerate: + case Int: + svalue << i; + if ( flags & TypeCheck ) success = checkValue(i); + break; + case Double: + svalue << d; + if ( flags & TypeCheck ) success = checkValue(d); + break; + case Percentage: + svalue << (d/100.0); + if ( flags & TypeCheck ) success = checkValue(d/100.0); + break; + } + + if ( not success ) { + //cerr << " (" << _flags << "," << _minInt << ") check failed." << endl; + return false; + } + if ( svalue.str() == _value ) { + //cerr << " no change." << endl; + return true; + } + + if ( (flags & NeedRestart) and hasFlags(NeedRestart) ) { configuration->addLog ( Configuration::LogRestart, _id ); } - if ( hasFlags(MustExist) ) { + if ( (flags & MustExist) and hasFlags(MustExist) ) { if ( _type == String ) { - bfs::path filePath = ( asString() ); + bfs::path filePath = ( svalue.str() ); if ( not bfs::exists(filePath) ) configuration->addLog ( Configuration::LogNeedExist, _id ); else configuration->removeLog ( Configuration::LogNeedExist, _id ); } } + + //cerr << " updated" << endl; + + _value = svalue.str(); + _onValueChanged(); + + return true; } diff --git a/vlsisapd/src/configuration/src/ParameterWidget.cpp b/vlsisapd/src/configuration/src/ParameterWidget.cpp index c0fbfc76..af670fdc 100644 --- a/vlsisapd/src/configuration/src/ParameterWidget.cpp +++ b/vlsisapd/src/configuration/src/ParameterWidget.cpp @@ -237,6 +237,8 @@ namespace Cfg { void ParameterWidget::onUpdateValueCb ( Parameter* ) { + //cerr << "onUpdateValue: " << _parameter->getId() << " -> " << _parameter->asString() << endl; + if ( _parameter->getType() == Parameter::String ) { QLineEdit* lineEdit = qobject_cast(_valueWidget); diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h index 8cd0200a..d5f87e02 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h @@ -43,41 +43,53 @@ namespace Cfg { class Configuration { public: enum Flags { DriveValues=0x1, DriveLayout=0x2 }; - enum LogType { LogRestart=0, LogNeedExist, LogTypeSize }; + enum LogType { LogRestart=0x1, LogNeedExist=0x2, AllLogs=0xFFFF }; public: - static Configuration* get (); + class LogEntry { + public: + inline LogEntry ( const std::string& id ); + inline const std::string& getId () const; + inline const std::string& getValid () const; + inline void restore () const; + private: + std::string _id; + std::string _valid; + }; + + public: + static Configuration* get (); public: // Methods. - ConfigurationWidget* buildWidget ( unsigned int flags ); - ConfigurationDialog* buildDialog (); + ConfigurationWidget* buildWidget ( unsigned int flags ); + ConfigurationDialog* buildDialog (); inline const std::map& - getParameters () const; - inline const std::set& - getLogs ( unsigned int type ) const; - inline unsigned int getFlags () const; - inline const LayoutDescription& getLayout () const; - inline LayoutDescription& getLayout (); - Parameter* getParameter ( const std::string& id - , Parameter::Type type=Parameter::Unknown ) const; - Parameter* addParameter ( const std::string& id - , Parameter::Type type - , const std::string& value ); - inline void setFlags ( unsigned int mask ); - inline bool hasLogs () const; - void addLog ( unsigned int type, const std::string& id ); - void removeLog ( unsigned int type, const std::string& id ); - inline void clearLogs (); - void print ( std::ostream& ) const; - bool readFromFile ( const std::string& ); - bool writeToFile ( const std::string&, unsigned int flags, const std::string& tabs="" ) const; - void writeToStream ( std::ostream&, unsigned int flags, const std::string& tabs="" ) const; + getParameters () const; + const std::set& getLogs ( unsigned int ilog ) const; + inline unsigned int getFlags () const; + inline const LayoutDescription& getLayout () const; + inline LayoutDescription& getLayout (); + Parameter* getParameter ( const std::string& id + , Parameter::Type type=Parameter::Unknown ) const; + Parameter* addParameter ( const std::string& id + , Parameter::Type type + , const std::string& value ); + inline void setFlags ( unsigned int mask ); + inline bool hasLogs ( unsigned int mask ) const; + void addLog ( unsigned int mask, const std::string& id ); + void removeLog ( unsigned int mask, const std::string& id ); + inline void restoreFromLogs ( unsigned int mask ); + inline void clearLogs ( unsigned int mask ); + void print ( std::ostream& ) const; + bool readFromFile ( const std::string& ); + bool writeToFile ( const std::string&, unsigned int flags, const std::string& tabs="" ) const; + void writeToStream ( std::ostream&, unsigned int flags, const std::string& tabs="" ) const; private: // Attributes. - static Configuration* _singleton; - std::map _parameters; - LayoutDescription _layout; - unsigned int _flags; - std::vector< std::set > _logSets; + static Configuration* _singleton; + std::map _parameters; + LayoutDescription _layout; + unsigned int _flags; + std::map< unsigned int, std::set > _logSets; private: Configuration (); }; @@ -87,25 +99,42 @@ namespace Cfg { inline const std::map& Configuration::getParameters () const { return _parameters; } - inline const std::set& Configuration::getLogs ( unsigned int type ) const - { return _logSets[(type >::const_iterator ilog = _logSets.begin(); + for ( ; ilog != _logSets.end() ; ++ilog ) + if ( (mask & (*ilog).first) and not (*ilog).second.empty () ) return true; return false; } - inline void Configuration::clearLogs () + + inline void Configuration::restoreFromLogs ( unsigned int mask ) { - for ( size_t ilog=0 ; ilog<_logSets.size() ; ++ilog ) - _logSets[ilog].clear (); + std::map< unsigned int, std::set >::iterator ilog = _logSets.begin(); + for ( ; ilog != _logSets.end() ; ++ilog ) { + if ( mask & (*ilog).first ) { + std::set::iterator ientry = (*ilog).second.begin(); + for ( ; ientry != (*ilog).second.end() ; ++ientry ) { + //std::cerr << "Restoring " << (*ientry).getId() << " -> " << (*ientry).getValid() << std::endl; + (*ientry).restore (); + } + } + } + } + + + inline void Configuration::clearLogs ( unsigned int mask ) + { + std::map< unsigned int, std::set >::iterator ilog = _logSets.begin(); + for ( ; ilog != _logSets.end() ; ++ilog ) { + if ( mask & (*ilog).first ) (*ilog).second.clear(); + } } @@ -174,6 +203,29 @@ namespace Cfg { } + inline Configuration::LogEntry::LogEntry ( const std::string& id ) + : _id (id) + , _valid("") + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter != NULL ) _valid = parameter->asString(); + } + + + inline const std::string& Configuration::LogEntry::getId () const { return _id; } + inline const std::string& Configuration::LogEntry::getValid () const { return _valid; } + + + inline void Configuration::LogEntry::restore () const + { + Parameter* parameter = Configuration::get()->getParameter(_id); + if ( parameter != NULL ) parameter->setString(_valid,false); + } + + inline bool operator< ( const Configuration::LogEntry& lhs, const Configuration::LogEntry& rhs ) + { return lhs.getId() < rhs.getId(); } + + } // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h index 7fef8b7a..5ad36f68 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h @@ -73,13 +73,13 @@ namespace Cfg { , int span =1 , int flags =0 ); void syncSlaves (); - void checkConfiguration (); + int checkConfiguration ( unsigned int mask ); void selectTab ( const std::string& ); public slots: void applyClicked (); signals: void updateParameters (); - void checkOk (); + void confOk (); private: unsigned int _flags; QFont _boldFont; diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/LogWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/LogWidget.h index 355a5a74..75d8e508 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/LogWidget.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/LogWidget.h @@ -29,6 +29,7 @@ #include class QLabel; +class QPushButton; namespace Cfg { @@ -38,12 +39,13 @@ namespace Cfg { Q_OBJECT; public: LogWidget ( QWidget* parent=NULL); - void updateLogs (); + void updateLogs ( unsigned int mask ); private: - QLabel* _restartMessage; - QLabel* _needExistMessage; - protected: virtual void closeEvent ( QCloseEvent* ); + private: + QLabel* _message; + QPushButton* _contButton; + QPushButton* _cancelButton; }; diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h index 5e47fa8e..e842acb0 100644 --- a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h @@ -38,20 +38,23 @@ namespace Cfg { class Parameter { public: - enum Type { Unknown = 0 - , String = 1 - , Bool = 2 - , Int = 3 - , Enumerate = 4 - , Double = 5 - , Percentage = 6 + enum Type { Unknown = 0 + , String = 1 + , Bool = 2 + , Int = 3 + , Enumerate = 4 + , Double = 5 + , Percentage = 6 }; - enum Flags { HasMin = 0x01 - , HasMax = 0x02 - , IsFile = 0x04 - , IsPath = 0x08 - , NeedRestart = 0x10 - , MustExist = 0x20 + enum Flags { HasMin = 0x01 + , HasMax = 0x02 + , IsFile = 0x04 + , IsPath = 0x08 + , NeedRestart = 0x10 + , MustExist = 0x20 + , TypeCheck = 0x40 + , FromString = 0x80 + , AllRequirements = HasMin|HasMax|IsFile|IsPath|NeedRestart|MustExist|TypeCheck }; typedef boost::function< void(Parameter*) > ParameterChangedCb_t; public: @@ -98,7 +101,7 @@ namespace Cfg { inline void addSlave ( const std::string& ); inline void setFlags ( int mask ); inline void unsetFlags ( int mask ); - bool setString ( const std::string&, bool check=true ); + bool setString ( const std::string&, unsigned int flags=AllRequirements ); bool setBool ( bool ); bool setInt ( int ); bool setDouble ( double ); @@ -110,7 +113,7 @@ namespace Cfg { inline void registerCb ( ParameterChangedCb_t ); private: inline void _onValueChanged (); - void _checkRequirements () const; + bool _doChange ( unsigned int flags, const std::string&, bool, int, double ); private: // Attributes. std::string _id; @@ -150,12 +153,15 @@ namespace Cfg { // std::cerr << "flags:" << _flags << " " // << _minInt << " < " << value << " < " << _maxInt // << " : " << std::boolalpha << ok << std::endl; + // std::cerr << " " << std::boolalpha << ok; return ok; } inline bool Parameter::checkValue ( double value ) const { + // std::cerr << " (double) " << _minDouble << "<" << value << "<" << _maxDouble; bool ok = not ( ( (_flags&HasMin) and (value < _minDouble) ) or ( (_flags&HasMax) and (value > _maxDouble) ) ); + // std::cerr << " " << std::boolalpha << ok; return ok; }