diff --git a/vlsisapd/CMakeLists.txt b/vlsisapd/CMakeLists.txt index 7481b2f1..bf1573ec 100644 --- a/vlsisapd/CMakeLists.txt +++ b/vlsisapd/CMakeLists.txt @@ -7,7 +7,7 @@ LIST(INSERT CMAKE_MODULE_PATH 0 "${VLSISAPD_SOURCE_DIR}/cmake_modules") FIND_PACKAGE(LibXml2 REQUIRED) FIND_PACKAGE(PythonSitePackages REQUIRED) -FIND_PACKAGE(Boost 1.32.0 COMPONENTS python) +FIND_PACKAGE(Boost 1.32.0 COMPONENTS program_options filesystem python REQUIRED) IF (Boost_FOUND) MESSAGE(STATUS "Found Boost.Python libraries in ${Boost_INCLUDE_DIR} as ${Boost_LIBRARIES}") FIND_PACKAGE(PythonLibs REQUIRED) diff --git a/vlsisapd/cmake_modules/FindVLSISAPD.cmake b/vlsisapd/cmake_modules/FindVLSISAPD.cmake index b4dfd60a..4f19391c 100644 --- a/vlsisapd/cmake_modules/FindVLSISAPD.cmake +++ b/vlsisapd/cmake_modules/FindVLSISAPD.cmake @@ -39,8 +39,8 @@ IF(VLSISAPD_DIR_SEARCH) SET_FOUND (AGDS) # CIF - FIND_PATH (CIF_INCLUDE_DIR NAMES vlsisapd/cif/CifCircuit.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include) - FIND_LIBRARY(CIF_LIBRARY NAMES cif PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX}) + FIND_PATH (CIF_INCLUDE_DIR NAMES vlsisapd/cif/Circuit.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(CIF_LIBRARY NAMES cif PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX}) SET_FOUND (CIF) # OPENCHAMS @@ -52,6 +52,11 @@ IF(VLSISAPD_DIR_SEARCH) FIND_PATH (DTR_INCLUDE_DIR NAMES vlsisapd/dtr/Techno.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include) FIND_LIBRARY(DTR_LIBRARY NAMES dtr PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX}) SET_FOUND (DTR) + + # Configuration + FIND_PATH (CONFIGURATION_INCLUDE_DIR NAMES vlsisapd/configuration/ConfigurationWidget.h PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(CONFIGURATION_LIBRARY NAMES configuration PATHS ${VLSISAPD_DIR_SEARCH} PATH_SUFFIXES lib${LIB_SUFFIX}) + SET_FOUND (CONFIGURATION) IF(AGDS_FOUND OR CIF_FOUND OR OPENCHAMS_FOUND OR DTR_FOUND) SET(VLSISAPD_FOUND TRUE) diff --git a/vlsisapd/src/CMakeLists.txt b/vlsisapd/src/CMakeLists.txt index 549fe170..4b304fc9 100644 --- a/vlsisapd/src/CMakeLists.txt +++ b/vlsisapd/src/CMakeLists.txt @@ -6,3 +6,4 @@ ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/openChams) IF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr) ADD_SUBDIRECTORY(dtr) ENDIF(IS_DIRECTORY ${VLSISAPD_SOURCE_DIR}/src/dtr) +ADD_SUBDIRECTORY(configuration) diff --git a/vlsisapd/src/configuration/CMakeLists.txt b/vlsisapd/src/configuration/CMakeLists.txt new file mode 100644 index 00000000..4920bd53 --- /dev/null +++ b/vlsisapd/src/configuration/CMakeLists.txt @@ -0,0 +1,3 @@ +FIND_PACKAGE(Qt4 REQUIRED) + +ADD_SUBDIRECTORY(src) diff --git a/vlsisapd/src/configuration/src/CMakeLists.txt b/vlsisapd/src/configuration/src/CMakeLists.txt new file mode 100644 index 00000000..068a5ed3 --- /dev/null +++ b/vlsisapd/src/configuration/src/CMakeLists.txt @@ -0,0 +1,46 @@ + + include ( ${QT_USE_FILE} ) + include_directories ( ${VLSISAPD_SOURCE_DIR}/src/configuration/src + ${Boost_INCLUDE_DIRS} + ${LIBXML2_INCLUDE_DIR} + ) + + set ( mocIncludes vlsisapd/configuration/ConfigurationWidget.h + vlsisapd/configuration/ParameterWidget.h + vlsisapd/configuration/ConfTabWidget.h + vlsisapd/configuration/ConfEditorWidget.h + ) + set ( includes vlsisapd/configuration/Parameter.h + vlsisapd/configuration/LayoutDescription.h + vlsisapd/configuration/Configuration.h + ) + set ( cpps Parameter.cpp + LayoutDescription.cpp + Configuration.cpp + ParameterWidget.cpp + ConfTabWidget.cpp + ConfigurationWidget.cpp + ConfEditorWidget.cpp + ) + set ( editorcpp ConfEditorMain.cpp ) + + qt4_wrap_cpp ( mocCpps ${mocIncludes} ) + + add_library ( configuration ${cpps} ${mocCpps} ) + target_link_libraries ( configuration ${QT_LIBRARIES} + ${Boost_LIBRARIES} + ${PYTHON_LIBRARIES} + ${LIBXML2_LIBRARIES} + ) + add_executable ( vlsisapd-conf-editor ${editorcpp} ) + target_link_libraries ( vlsisapd-conf-editor configuration ${QT_LIBRARIES} + ${Boost_LIBRARIES} + ${PYTHON_LIBRARIES} + ${LIBXML2_LIBRARIES} + ) + + install ( TARGETS configuration DESTINATION lib${LIB_SUFFIX} ) + install ( TARGETS vlsisapd-conf-editor DESTINATION bin ) + install ( FILES ${includes} ${mocIncludes} + DESTINATION include/vlsisapd/configuration ) + diff --git a/vlsisapd/src/configuration/src/ConfEditorMain.cpp b/vlsisapd/src/configuration/src/ConfEditorMain.cpp new file mode 100644 index 00000000..afa1c6b3 --- /dev/null +++ b/vlsisapd/src/configuration/src/ConfEditorMain.cpp @@ -0,0 +1,102 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./ConfEditorMain.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +namespace boptions = boost::program_options; + +#include +namespace bfs = boost::filesystem; + +#include +#include +#if (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) and not defined (__APPLE__) +# include +#endif +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" +#include "vlsisapd/configuration/ConfEditorWidget.h" + + +using namespace std; +using namespace Cfg; + + +int main ( int argc, char* argv[] ) +{ + int returnCode = 0; + + try { + boptions::options_description options ("Command line arguments & options"); + options.add_options() + ( "help,h", "Print this help." ) + ( "conf,c", boptions::value() + , "The path of the configuration file." ); + + boptions::variables_map arguments; + boptions::store ( boptions::parse_command_line(argc,argv,options), arguments ); + boptions::notify ( arguments ); + + if ( arguments.count("help") ) { + cout << options << endl; + exit ( 0 ); + } + + auto_ptr qa ( new QApplication(argc,argv) ); +#if (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) and not defined (__APPLE__) + qa->setStyle ( new QGtkStyle() ); +#endif + + bfs::path::default_name_check ( bfs::portable_posix_name ); + + Configuration* conf = Configuration::get (); + bfs::path dotConfPath ( "./.coriolis2.configuration.xml" ); + + if ( bfs::exists(dotConfPath) ) { + cout << "Reading dot configuration: <" << dotConfPath.string() << ">." << endl; + conf->readFromFile ( dotConfPath.string() ); + } + + if ( arguments.count("conf") ) { + bfs::path confPath = ( arguments["conf"].as() ); + if ( bfs::exists(confPath) ) { + cout << "Reading configuration: <" << confPath.string() << ">." << endl; + conf->readFromFile ( confPath.string() ); + } else { + cout << "Configuration file: <" << confPath.string() << "> doesn't exists." << endl; + } + } + + ConfEditorWidget* editor = new ConfEditorWidget (); + editor->show (); + + returnCode = qa->exec (); + } + catch ( exception& e ) { + cerr << "[ERROR] Catched exception:\n " << e.what() << endl; + returnCode = 127; + } + + return returnCode; +} diff --git a/vlsisapd/src/configuration/src/ConfEditorWidget.cpp b/vlsisapd/src/configuration/src/ConfEditorWidget.cpp new file mode 100644 index 00000000..24aa9726 --- /dev/null +++ b/vlsisapd/src/configuration/src/ConfEditorWidget.cpp @@ -0,0 +1,98 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ConfEditorWidget.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" +#include "vlsisapd/configuration/ConfEditorWidget.h" + + +namespace Cfg { + + using namespace std; + + + ConfEditorWidget::ConfEditorWidget ( QWidget* parent ) + : QMainWindow (parent) + , _configurationWidget (Configuration::get()->buildWidget()) + , _fileMenu (NULL) + , _saveAction (NULL) + , _quitAction (NULL) + { + setObjectName("confEditor"); + + createMenus (); + + setCentralWidget ( _configurationWidget ); + } + + + void ConfEditorWidget::createActions () + { + if ( _quitAction != NULL ) return; + + _quitAction = new QAction ( tr("&Quit"), this ); + _quitAction->setObjectName ( "confEditor.menuBar.file.quit" ); + _quitAction->setStatusTip ( tr("Quit the VLSISAPD Configuration Editor") ); + _quitAction->setShortcut ( QKeySequence(tr("CTRL+Q")) ); + connect ( _quitAction, SIGNAL(triggered()), this, SLOT(close()) ); + + _saveAction = new QAction ( tr("&Save"), this ); + _saveAction->setObjectName ( "confEditor.menuBar.file.save" ); + _saveAction->setStatusTip ( tr("Save Settings in ./coriolis2.configuration.xml") ); + _saveAction->setShortcut ( QKeySequence(tr("CTRL+S")) ); + connect ( _saveAction, SIGNAL(triggered()), this, SLOT(save()) ); + } + + + void ConfEditorWidget::createMenus () + { + if ( _fileMenu != NULL ) return; + if ( _quitAction == NULL ) createActions (); + + menuBar()->setObjectName ( tr("confEditor.menuBar") ); + + _fileMenu = menuBar()->addMenu ( tr("File") ); + _fileMenu->addAction ( _saveAction ); + _fileMenu->addAction ( _quitAction ); + } + + + void ConfEditorWidget::save () + { + string dotConfigFile = "./.coriolis2.configuration.xml"; + ofstream file ( dotConfigFile.c_str() ); + + cout << "Saving configuration file: <" << dotConfigFile << ">."<< endl; + + Configuration::get()->writeToStream ( file ); + file.close (); + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/ConfTabWidget.cpp b/vlsisapd/src/configuration/src/ConfTabWidget.cpp new file mode 100644 index 00000000..e1a1f419 --- /dev/null +++ b/vlsisapd/src/configuration/src/ConfTabWidget.cpp @@ -0,0 +1,189 @@ + + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ConfTabWidget.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include +#include +#include + +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ParameterWidget.h" +#include "vlsisapd/configuration/ConfTabWidget.h" + + +namespace Cfg { + + using std::max; + using std::cerr; + using std::endl; + using std::string; + using std::vector; + + +// ------------------------------------------------------------------- +// Class : "Cfg::ConfTabWidget". + + + ConfTabWidget::ConfTabWidget ( const string& name, QWidget* parent ) + : QWidget (parent) + , _gridLayout(new QGridLayout()) + , _columns (2) + , _rowsCount (new int[_columns]) + , _parameters() + { + for ( int i=0 ; i<_columns ; ++i ) _rowsCount[i] = 0; + + setObjectName ( name.c_str() ); + + QVBoxLayout* vLayout = new QVBoxLayout (); + vLayout->addLayout ( _gridLayout ); + + QHBoxLayout* hLayout = new QHBoxLayout (); + hLayout->addStretch (); + + QPushButton* apply = new QPushButton (); + apply->setText ( tr("Apply") ); + hLayout->addWidget ( apply ); + hLayout->addStretch (); + + vLayout->addLayout ( hLayout ); + vLayout->addStretch (); + + setLayout ( vLayout ); + + connect ( apply, SIGNAL(clicked()), this, SIGNAL(updateParameters()) ); + } + + + ConfTabWidget::~ConfTabWidget () + { + delete [] _rowsCount; + + for ( size_t i=0 ; i<_parameters.size() ; ++i ) + _parameters[i]->deleteLater(); + } + + + int ConfTabWidget::_getMaxRowCount () + { + int maxrow = _rowsCount[0]; + for ( int column=1 ; column<_columns ; ++column ) + maxrow = max ( maxrow, _rowsCount[column] ); + + return maxrow; + } + + + int ConfTabWidget::_alignMaxRowCount () + { + int maxrow = _gridLayout->rowCount() + 1; + for ( int column=0 ; column<_columns ; ++column ) + _rowsCount[column] = maxrow; + + return maxrow; + } + + + void ConfTabWidget::addRuler () + { + QFrame* separator = new QFrame (); + separator->setFrameShape ( QFrame::HLine ); + separator->setFrameShadow ( QFrame::Sunken ); + + _gridLayout->addWidget ( separator, _getMaxRowCount(), 0, 1, 4 ); + _alignMaxRowCount (); + } + + + QFont& ConfTabWidget::getParentBoldFont () + { + ConfigurationWidget* cw = rparent ( this ); + return cw->getBoldFont(); + } + + + void ConfTabWidget::addTitle ( const string& title ) + { + QLabel* label = new QLabel(); + label->setText ( title.c_str() ); + label->setFont ( getParentBoldFont() ); + + _gridLayout->addWidget ( label, _getMaxRowCount(), 0, 1, 4, Qt::AlignLeft ); + _alignMaxRowCount (); + } + + + void ConfTabWidget::addSection ( const string& section, int column ) + { + QLabel* label = new QLabel(); + label->setText ( section.c_str() ); + label->setFont ( getParentBoldFont() ); + + int row = _rowsCount[column]; + if ( (column >= _columns) or ( column < 0) ) { + cerr << "[WARNING] Column " << column << " is out of bound (" << _columns << ")." << endl; + if ( column < 0 ) column = 0; + else column = _columns-1; + } + + _gridLayout->addWidget ( label, row, column*2, 1, 2, Qt::AlignLeft ); + _rowsCount[column]++; + } + + + ParameterWidget* ConfTabWidget::addParameter ( Parameter* parameter, const std::string& label, int column, int flags ) + { + ConfigurationWidget* cw = rparent ( this ); + ParameterWidget* pw = cw->find(parameter); + + if ( pw != NULL ) { + cerr << "[ERROR] Parameter <" << parameter->getId() << "> already added." << endl; + return pw; + } + + int row = _rowsCount[column]; + if ( (column >= _columns) or ( column < 0) ) { + cerr << "[WARNING] Column " << column << " is out of bound (" << _columns << ")." << endl; + if ( column < 0 ) column = 0; + else column = _columns-1; + } + + pw = new ParameterWidget ( this, parameter, label, flags ); + _gridLayout->addWidget ( pw->getLabelWidget(), row, column*2, Qt::AlignRight ); + _gridLayout->addWidget ( pw->getValueWidget(), row, 1+column*2, Qt::AlignLeft ); + + connect ( this, SIGNAL(updateParameters()), pw, SLOT(updateValue()) ); + + _rowsCount[column]++; + + return pw; + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/Configuration.cpp b/vlsisapd/src/configuration/src/Configuration.cpp new file mode 100644 index 00000000..9028899a --- /dev/null +++ b/vlsisapd/src/configuration/src/Configuration.cpp @@ -0,0 +1,436 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Configuration.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" +#include "vlsisapd/configuration/ParameterWidget.h" + + +namespace { + + using namespace std; + using namespace Cfg; + + + class XmlParser { + public: + XmlParser ( Configuration*, const string& fileName ); + bool parse (); + private: + void _configurationNode (); + void _parameterNode (); + void _itemNode (); + void _groupNode (); + void _masterNode (); + void _slaveNode (); + void _layoutNode (); + void _tabNode (); + void _widgetNode (); + string _getAttributeValue ( const char* attributeName ); + private: + Configuration* _configuration; + string _fileName; + xmlTextReaderPtr _reader; + int _status; + string _tool; + Parameter* _parameter; + }; + + + XmlParser::XmlParser ( Configuration* conf + , const string& fileName ) + : _configuration (conf) + , _fileName (fileName) + , _reader (NULL) + , _status (1) + , _tool ("") + , _parameter (NULL) + { } + + + bool XmlParser::parse () + { + LIBXML_TEST_VERSION; + + _reader = xmlReaderForFile ( _fileName.c_str(), NULL, 0 ); + if ( _reader != NULL ) { + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + if ( tag == "configuration" ) _configurationNode(); + + _status = xmlTextReaderRead ( _reader ); + } + xmlFreeTextReader ( _reader ); + + if ( _status != 0 ) { + cerr << "[ERROR] Syntax error in \"" << _fileName << "\" configuration file." << endl; + } + xmlCleanupParser (); + } + + return (_status != 0); + } + + + void XmlParser::_configurationNode () + { + if ( xmlTextReaderNodeType(_reader) == XML_READER_TYPE_END_ELEMENT ) return; + + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + + if ( tag == "parameter" ) _parameterNode(); + else if ( tag == "group" ) _groupNode(); + else if ( tag == "layout" ) _layoutNode(); + else if ( tag == "configuration" ) return; + + _status = xmlTextReaderRead ( _reader ); + } + } + + + void XmlParser::_parameterNode () + { + if ( xmlTextReaderNodeType(_reader) == XML_READER_TYPE_END_ELEMENT ) return; + + string attrId = _getAttributeValue("id"); + string attrType = _getAttributeValue("type"); + + Parameter::Type type = Parameter::String; + if ( attrType == "string" ) type = Parameter::String; + else if ( attrType == "bool" ) type = Parameter::Bool; + else if ( attrType == "int" ) type = Parameter::Int; + else if ( attrType == "double" ) type = Parameter::Double; + else if ( attrType == "percentage" ) type = Parameter::Percentage; + else if ( attrType == "enumerate" ) type = Parameter::Enumerate; + + _parameter = _configuration->getParameter ( attrId ); + + if ( _parameter == NULL ) { + _parameter = _configuration->addParameter ( attrId + , type + , _getAttributeValue("value") + ); + + } else { + _parameter->setString ( _getAttributeValue("value") ); + } + + if ( (type == Parameter::Enumerate) + and (xmlTextReaderIsEmptyElement(_reader) == 0) ) { + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + if ( tag == "item" ) _itemNode(); + else if ( tag == "parameter" ) break; + + _status = xmlTextReaderRead ( _reader ); + } + } + + if ( (type == Parameter::Int) + or (type == Parameter::Enumerate) ) { + string attrMin = _getAttributeValue("min"); + string attrMax = _getAttributeValue("max"); + + int i; + if ( not attrMin.empty() ) { + istringstream s ( attrMin ); s >> i; _parameter->setMin ( i ); + } + if ( not attrMax.empty() ) { + istringstream s ( attrMax ); s >> i; _parameter->setMax ( i ); + } + } + + if ( (type == Parameter::Double) + or (type == Parameter::Percentage) ) { + string attrMin = _getAttributeValue("min"); + string attrMax = _getAttributeValue("max"); + + double d; + if ( not attrMin.empty() ) { + istringstream s ( attrMin ); s >> d; _parameter->setMin ( d ); + } + if ( not attrMax.empty() ) { + istringstream s ( attrMax ); s >> d; _parameter->setMax ( d ); + } + } + + _parameter = NULL; + } + + + void XmlParser::_itemNode () + { + string attrLabel = _getAttributeValue("label"); + string attrValue = _getAttributeValue("value"); + int value; + + istringstream s ( attrValue ); + s >> value; + + _parameter->addValue ( attrLabel, value ); + } + + + void XmlParser::_groupNode () + { + if ( xmlTextReaderNodeType(_reader) == XML_READER_TYPE_END_ELEMENT ) return; + + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + + if ( tag == "master" ) _masterNode(); + else if ( tag == "slave" ) _slaveNode(); + else if ( tag == "group" ) { + _parameter = NULL; + return; + } + + _status = xmlTextReaderRead ( _reader ); + } + } + + + void XmlParser::_masterNode () + { _parameter = _configuration->getParameter ( _getAttributeValue("id") ); } + + + void XmlParser::_slaveNode () + { + string attrId = _getAttributeValue("id"); + if ( _parameter != NULL ) _parameter->addSlave ( attrId ); + } + + + void XmlParser::_layoutNode () + { + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + if ( tag == "tab" ) _tabNode(); + else if ( tag == "layout" ) return; + + _status = xmlTextReaderRead ( _reader ); + } + } + + + void XmlParser::_tabNode () + { + string attrName = _getAttributeValue("name"); + + _configuration->getLayout().addTab ( new TabDescription(attrName) ); + + _status = xmlTextReaderRead ( _reader ); + while ( _status == 1 ) { + string tag ( (const char*)xmlTextReaderConstName(_reader) ); + if ( tag == "widget" ) _widgetNode(); + else if ( tag == "tab" ) return; + + _status = xmlTextReaderRead ( _reader ); + } + } + + + void XmlParser::_widgetNode () + { + if ( xmlTextReaderNodeType(_reader) == XML_READER_TYPE_END_ELEMENT ) return; + + string attrId = _getAttributeValue("id"); + string attrType = _getAttributeValue("type"); + string attrLabel = _getAttributeValue("label"); + string attrColumn = _getAttributeValue("column"); + string attrSpinBox = _getAttributeValue("spinbox"); + + if ( attrId.empty() and attrType.empty() ) { + cerr << "[ERROR] In tag, neither \"id\" nor \"type\" attribute." << endl; + return; + } + + int column = 0; + if ( not attrColumn.empty() ) { + istringstream s ( attrColumn ); s >> column; + } + + if ( not attrType.empty() ) { + if ( attrType == "title" ) _configuration->getLayout().getBackTab()->addWidget ( WidgetDescription::title (attrLabel) ); + if ( attrType == "section" ) _configuration->getLayout().getBackTab()->addWidget ( WidgetDescription::section(attrLabel,column) ); + else if ( attrType == "rule" ) _configuration->getLayout().getBackTab()->addWidget ( WidgetDescription::rule () ); + return; + } + + Parameter* parameter = _configuration->getParameter ( attrId ); + if ( parameter == NULL ) { + cerr << "[ERROR] In tag, no parameter of id:" << attrId << "." << endl; + return; + } + + int flags = 0; + if ( attrSpinBox == "true" ) flags |= ParameterWidget::UseSpinBox; + + _configuration->getLayout().getBackTab()->addWidget ( WidgetDescription::parameter(attrId,attrLabel,column,flags) ); + } + + + string XmlParser::_getAttributeValue ( const char* attributeName ) + { + char* attributeValue = (char*)xmlTextReaderGetAttribute(_reader,(const xmlChar*)attributeName); + if ( attributeValue == NULL ) + return string(); + + string value ( attributeValue ); + free ( attributeValue ); + + return value; + } + + +} // End of anonymous namespace. + + +namespace Cfg { + + using std::string; + using std::map; + using std::ostream; + using std::setw; + + + Configuration* Configuration::_singleton = NULL; + + + Configuration* Configuration::get () + { + if ( _singleton == NULL ) _singleton = new Configuration (); + return _singleton; + } + + + Configuration::Configuration () + : _parameters() + , _layout (this) + { } + + + ConfigurationWidget* Configuration::buildWidget () + { return _layout.buildWidget(); } + + + Parameter* Configuration::getParameter ( const string& name ) const + { + map::const_iterator iparameter = _parameters.find(name); + if ( iparameter != _parameters.end() ) return iparameter->second; + + return NULL; + } + + + Parameter* Configuration::addParameter ( const string& id + , Parameter::Type type + , const string& value ) + { + Parameter* p = getParameter ( id ); + if ( p != NULL ) { + // Update values here. + return p; + } + + p = new Parameter ( id, type, value ); + _parameters.insert ( make_pair(id,p) ); + + return p; + } + + + void Configuration::print ( ostream& out ) const + { + map::const_iterator iparameter = _parameters.begin(); + for ( ; iparameter != _parameters.end(); ++iparameter ) { + Parameter* p = iparameter->second; + out << "id:" << iparameter->first + << " id:" << p->getId() + << " type:" << p->getType() + << " asString:" << p->asString(); + + out << " asType:"; + switch ( p->getType() ) { + case Parameter::String: out << ""; break; + case Parameter::Bool: out << boolalpha << p->asBool(); break; + case Parameter::Int: out << p->asInt(); break; + case Parameter::Double: out << p->asDouble(); break; + case Parameter::Percentage: out << p->asPercentage(); break; + case Parameter::Enumerate: + out << endl; + + const vector& values = p->getValues(); + for ( size_t i=0; i != values.size() ; ++i ) { + out << " label:" << values[i]._label << " value:" << values[i]._value << endl; + } + break; + } + + out << endl; + } + } + + + void Configuration::writeToStream ( ostream& out ) const + { + out << "" << endl; + + map::const_iterator iparameter = _parameters.begin(); + for ( ; iparameter != _parameters.end(); ++iparameter ) { + Parameter* p = iparameter->second; + + string id = "\"" + p->getId() + "\""; + string type = "\"" + Parameter::typeToString(p->getType()) + "\""; + + out << " asString() << "\"/>" + << endl; + } + + out << "" << endl; + } + + + void Configuration::readFromFile ( const std::string& fileName ) + { + XmlParser parser ( this, fileName ); + parser.parse (); + } + + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/ConfigurationWidget.cpp b/vlsisapd/src/configuration/src/ConfigurationWidget.cpp new file mode 100644 index 00000000..00340168 --- /dev/null +++ b/vlsisapd/src/configuration/src/ConfigurationWidget.cpp @@ -0,0 +1,139 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ConfigurationWidget.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include + +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ParameterWidget.h" +#include "vlsisapd/configuration/ConfTabWidget.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" + + +namespace Cfg { + + using std::max; + using std::cerr; + using std::endl; + using std::string; + using std::map; + + +// ------------------------------------------------------------------- +// Class : "Cfg::ConfigurationWidget". + + + ConfigurationWidget::ConfigurationWidget ( QWidget* parent ) + : QTabWidget(parent) + , _boldFont (QApplication::font()) + { + _boldFont.setBold ( true ); + + setAttribute ( Qt::WA_QuitOnClose, false ); + } + + + QFont& ConfigurationWidget::getBoldFont () + { return _boldFont; } + + + void ConfigurationWidget::addRuler ( const string& tabName ) + { + ConfTabWidget* tab = findOrCreate ( tabName ); + tab->addRuler (); + } + + + void ConfigurationWidget::addTitle ( const string& tabName, const string& title ) + { + ConfTabWidget* tab = findOrCreate ( tabName ); + tab->addTitle ( title ); + } + + + void ConfigurationWidget::addSection ( const string& tabName, const string& section, int column ) + { + ConfTabWidget* tab = findOrCreate ( tabName ); + tab->addSection ( section, column ); + } + + + ParameterWidget* ConfigurationWidget::addParameter ( const string& tabName + , Parameter* parameter + , const std::string& label + , int column + , int flags ) + { + ParameterWidget* pw = find(parameter); + if ( pw != NULL ) { + cerr << "[ERROR] Parameter <" << parameter->getId() << "> already added." << endl; + return pw; + } + + ConfTabWidget* tab = findOrCreate ( tabName ); + return tab->addParameter ( parameter, label, column, flags ); + } + + + ParameterWidget* ConfigurationWidget::find ( Parameter* parameter ) const + { + if ( parameter == NULL ) return NULL; + return find ( parameter->getId() ); + } + + + ParameterWidget* ConfigurationWidget::find ( const string& id ) const + { return findChild(id.c_str()); } + + + ConfTabWidget* ConfigurationWidget::findOrCreate ( const string& tabName ) + { + ConfTabWidget* tab = findChild(tabName.c_str()); + if ( tab != NULL ) return tab; + + tab = new ConfTabWidget ( tabName ); + addTab ( tab, tabName.c_str() ); + + return tab; + } + + + void ConfigurationWidget::syncSlaves () + { + const map& parameters = Configuration::get()->getParameters (); + map::const_iterator iparam = parameters.begin(); + + for ( ; iparam != parameters.end() ; ++iparam ) { + if ( (*iparam).second->getSlaves().empty() ) continue; + + ParameterWidget* pw = find ( (*iparam).first ); + if ( pw == NULL ) continue; + + pw->enableSlaves ( pw->getParameter()->asBool() ); + } + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/LayoutDescription.cpp b/vlsisapd/src/configuration/src/LayoutDescription.cpp new file mode 100644 index 00000000..19e1a3b8 --- /dev/null +++ b/vlsisapd/src/configuration/src/LayoutDescription.cpp @@ -0,0 +1,78 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./LayoutDescription.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include "vlsisapd/configuration/LayoutDescription.h" +#include "vlsisapd/configuration/Configuration.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" + + +namespace Cfg { + + using std::cerr; + using std::endl; + using std::string; + using std::vector; + + + ConfigurationWidget* LayoutDescription::buildWidget () + { + ConfigurationWidget* cw = new ConfigurationWidget (); + + for ( size_t itab=0 ; itab<_tabs.size() ; ++itab ) { + const vector widgets = _tabs[itab]->getWidgets(); + + for ( size_t iwidget=0 ; iwidgetgetType() ) { + case WidgetDescription::Rule: + cw->addRuler ( _tabs[itab]->getName() ); + break; + case WidgetDescription::Title: + cw->addTitle ( _tabs[itab]->getName() + , widgets[iwidget]->getTitle() ); + break; + case WidgetDescription::Section: + cw->addSection ( _tabs[itab]->getName() + , widgets[iwidget]->getTitle() + , widgets[iwidget]->getColumn() ); + break; + case WidgetDescription::Parameter: + Parameter* parameter = _configuration->getParameter ( widgets[iwidget]->getId() ); + cw->addParameter ( _tabs[itab]->getName() + , parameter + , widgets[iwidget]->getLabel() + , widgets[iwidget]->getColumn() + , widgets[iwidget]->getFlags() ); + break; + } + } + } + + cw->syncSlaves (); + + return cw; + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/Parameter.cpp b/vlsisapd/src/configuration/src/Parameter.cpp new file mode 100644 index 00000000..80c65f1e --- /dev/null +++ b/vlsisapd/src/configuration/src/Parameter.cpp @@ -0,0 +1,69 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Parameter.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include "vlsisapd/configuration/Parameter.h" + + +namespace Cfg { + + using std::cerr; + using std::endl; + using std::string; + + + string Parameter::typeToString ( Parameter::Type type ) + { + switch ( type ) { + case String: return "string"; + case Int: return "int"; + case Double: return "double"; + case Bool: return "bool"; + case Percentage: return "percentage"; + case Enumerate: return "enumerate"; + } + return "unsupported"; + } + + + Parameter::Parameter ( const std::string& id + , Type type + , const std::string& value ) + : _id (id) + , _type (type) + , _value (value) + , _flags (0) + , _minInt (0) + , _maxInt (0) + , _minDouble(0.0) + , _maxDouble(0.0) + { + if ( type == Percentage ) { + setPercentage ( asDouble() ); + } + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/ParameterWidget.cpp b/vlsisapd/src/configuration/src/ParameterWidget.cpp new file mode 100644 index 00000000..c7e39a0f --- /dev/null +++ b/vlsisapd/src/configuration/src/ParameterWidget.cpp @@ -0,0 +1,248 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./ParameterWidget.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include +#include +#include +#include "vlsisapd/configuration/Parameter.h" +#include "vlsisapd/configuration/ParameterWidget.h" +#include "vlsisapd/configuration/ConfigurationWidget.h" + + +namespace Cfg { + + using std::cerr; + using std::endl; + using std::boolalpha; + using std::string; + using std::vector; + using std::ostringstream; + + + ParameterWidget::ParameterWidget ( QObject* parent, Parameter* parameter, const std::string& label, int flags ) + : QObject (parent) + , _parameter (parameter) + , _labelWidget(new QLabel()) + , _valueWidget(NULL) + , _flags (flags) + { + setObjectName ( _parameter->getId().c_str() ); + + _labelWidget->setText ( label.c_str() ); + + switch ( _parameter->getType() ) { + case Parameter::String: + { + QLineEdit* lineEdit = new QLineEdit(); + lineEdit->setText ( QString("%1").arg(_parameter->asString().c_str()) ); + _valueWidget = lineEdit; + } + break; + case Parameter::Bool: + { + QCheckBox* checkBox = new QCheckBox(); + checkBox->setChecked ( _parameter->asBool() ); + _valueWidget = checkBox; + + connect ( checkBox, SIGNAL(stateChanged(int)), this, SLOT(enableSlaves(int)) ); + } + break; + case Parameter::Int: + { + if ( hasFlags(UseSpinBox) ) { + QSpinBox* spinBox = new QSpinBox(); + spinBox->setValue ( _parameter->asInt() ); + _valueWidget = spinBox; + } else { + QLineEdit* lineEdit = new QLineEdit(); + lineEdit->setValidator ( new QIntValidator(this) ); + lineEdit->setText ( QString("%1").arg(_parameter->asString().c_str()) ); + _valueWidget = lineEdit; + } + + int bounds = (int)(_parameter->hasFlags(Parameter::HasMin)) + + 2*(int)(_parameter->hasFlags(Parameter::HasMax)); + + if ( bounds ) { + ostringstream toolTip; + toolTip << "A value in interval "; + switch ( bounds ) { + case 1: + toolTip << "[" << _parameter->getMinInt() << ":]"; + break; + case 2: + toolTip << "[:" << _parameter->getMaxInt() << "]"; + break; + case 3: + toolTip << "[" << _parameter->getMinInt() + << ":" << _parameter->getMaxInt() << "]"; + break; + } + _valueWidget->setToolTip ( toolTip.str().c_str() ); + } + } + break; + case Parameter::Double: + case Parameter::Percentage: + { + double mult = (_parameter->getType() == Parameter::Double) ? 1.0 : 100.0; + + QLineEdit* lineEdit = new QLineEdit(); + lineEdit->setValidator ( new QDoubleValidator(this) ); + lineEdit->setText ( QString("%1").arg(_parameter->asDouble()*mult) ); + //lineEdit->setValue ( _parameter->asPercentage() ); + + int bounds = (int)(_parameter->hasFlags(Parameter::HasMin)) + + 2*(int)(_parameter->hasFlags(Parameter::HasMax)); + + if ( bounds ) { + ostringstream toolTip; + toolTip << "A value in interval "; + + + switch ( bounds ) { + case 1: + toolTip << "[" << (_parameter->getMinDouble()*mult) << ":]"; + break; + case 2: + toolTip << "[:" << (_parameter->getMaxDouble()*mult) << "]"; + break; + case 3: + toolTip << "[" << (_parameter->getMinDouble()*mult) + << ":" << (_parameter->getMaxDouble()*mult) << "]"; + break; + } + lineEdit->setToolTip ( toolTip.str().c_str() ); + } + _valueWidget = lineEdit; + } + break; + case Parameter::Enumerate: + { + int currentValue = _parameter->asInt(); + int currentIndex = 0; + QComboBox* comboBox = new QComboBox(); + const vector& values = _parameter->getValues(); + for ( size_t i=0 ; i != values.size() ; ++i ) { + comboBox->addItem ( values[i]._label.c_str(), values[i]._value ); + if ( values[i]._value == currentValue ) currentIndex = i; + } + comboBox->setCurrentIndex ( currentIndex ); + _valueWidget = comboBox; + } + break; + } + + string valueId = _parameter->getId() + ".edit"; + _valueWidget->setObjectName ( valueId.c_str() ); + } + + + void ParameterWidget::updateValue () + { + if ( _parameter->getType() == Parameter::String ) + { + QLineEdit* lineEdit = qobject_cast(_valueWidget); + _parameter->setString ( lineEdit->displayText().toStdString() ); + } + else if ( _parameter->getType() == Parameter::Bool ) + { + QCheckBox* checkBox = qobject_cast(_valueWidget); + _parameter->setBool ( checkBox->isChecked() ); + } + else if ( _parameter->getType() == Parameter::Int ) + { + if ( hasFlags(UseSpinBox) ) { + QSpinBox* spinBox = qobject_cast(_valueWidget); + int value = spinBox->value(); + + if ( _parameter->checkValue(value) ) _parameter->setInt ( value ); + else spinBox->setValue ( _parameter->asInt() ); + } else { + bool success; + QLineEdit* lineEdit = qobject_cast(_valueWidget); + int value = lineEdit->displayText().toInt ( &success ); + + if ( success ) success = _parameter->checkValue ( value ); + if ( success ) _parameter->setInt ( value ); + else lineEdit->setText ( _parameter->asString().c_str() ); + } + } + else if ( _parameter->getType() == Parameter::Double ) + { + bool success; + QLineEdit* lineEdit = qobject_cast(_valueWidget); + double value = lineEdit->displayText().toFloat ( &success ); + + if ( success ) success = _parameter->checkValue ( value ); + if ( success ) _parameter->setDouble ( value ); + else lineEdit->setText ( _parameter->asString().c_str() ); + } + else if ( _parameter->getType() == Parameter::Percentage ) + { + bool success; + QLineEdit* lineEdit = qobject_cast(_valueWidget); + double value = lineEdit->displayText().toFloat ( &success ); + + if ( success ) success = _parameter->checkValue ( value/100.0 ); + if ( success ) _parameter->setPercentage ( value ); + else lineEdit->setText ( _parameter->asString().c_str() ); + } + else if ( _parameter->getType() == Parameter::Enumerate ) + { + QComboBox* comboBox = qobject_cast(_valueWidget); + + const vector& values = _parameter->getValues(); + _parameter->setInt ( values[comboBox->currentIndex()]._value ); + } + } + + + void ParameterWidget::enableSlaves ( int state ) + { + ConfigurationWidget* cw = rparent ( this ); + if ( cw == NULL ) { + cerr << "[ERROR] ParameterWidget::enableSlaves(): Cannot find parent ConfigurationWidget." << endl; + return; + } + + bool enabled = ( state != Qt::Unchecked ); + + const vector& slaveIds = _parameter->getSlaves(); + for ( int islave=0 ; islavefind(slaveIds[islave]); + if ( slave == NULL ) continue; + + slave->getLabelWidget()->setEnabled ( enabled ); + slave->getValueWidget()->setEnabled ( enabled ); + } + } + + +} // End of Cfg namespace. diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfEditorWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfEditorWidget.h new file mode 100644 index 00000000..a7a034ec --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfEditorWidget.h @@ -0,0 +1,57 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./ConfEditorWidget.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __VLSISAPD_CONF_EDITOR_WIDGET__ +#define __VLSISAPD_CONF_EDITOR_WIDGET__ + +#include +#include +class QMenu; +class QAction; + +namespace Cfg { + + class ConfigurationWidget; + + class ConfEditorWidget : public QMainWindow { + Q_OBJECT; + public: + ConfEditorWidget ( QWidget* parent=NULL ); + void createActions (); + void createMenus (); + public slots: + void save (); + private: + ConfigurationWidget* _configurationWidget; + QMenu* _fileMenu; + QAction* _saveAction; + QAction* _quitAction; + }; + + +} // End of Cfg namespace. + +#endif // __VLSISAPD_CONF_EDITOR_WIDGET__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfTabWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfTabWidget.h new file mode 100644 index 00000000..a9cb8bef --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfTabWidget.h @@ -0,0 +1,72 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./ConfTabWidget.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __CFG_CONF_TAB_WIDGET__ +#define __CFG_CONF_TAB_WIDGET__ + +#include +class QFont; +class QGridLayout; + +#include "vlsisapd/configuration/ConfigurationWidget.h" + +namespace Cfg { + + class ParameterWidget; + + +// ------------------------------------------------------------------- +// Class : "Cfg::ConfTabWidget". + + + class ConfTabWidget : public QWidget { + Q_OBJECT; + public: + ConfTabWidget ( const std::string& name="", QWidget* parent=NULL ); + virtual ~ConfTabWidget (); + public: + QFont& getParentBoldFont (); + void addRuler (); + void addTitle ( const std::string& title ); + void addSection ( const std::string& section, int column=0 ); + ParameterWidget* addParameter ( Parameter*, const std::string& label, int column=0, int flags=0 ); + signals: + void updateParameters (); + private: + int _getMaxRowCount (); + int _alignMaxRowCount (); + private: + QGridLayout* _gridLayout; + int _columns; + int* _rowsCount; + std::vector _parameters; + }; + + +} // End of Cfg namespace. + + +#endif // __CFG_CONF_TAB_WIDGET__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h new file mode 100644 index 00000000..4ab9cafd --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Configuration.h @@ -0,0 +1,150 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Configuration.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __CFG_CONFIGURATION__ +#define __CFG_CONFIGURATION__ + +#include +#include +#include +#include "vlsisapd/configuration/Parameter.h" +#include "vlsisapd/configuration/LayoutDescription.h" + + +namespace Cfg { + + class ConfigurationWidget; + + + class Configuration { + public: + static Configuration* get (); + public: + // Methods. + ConfigurationWidget* buildWidget (); + inline const std::map& + getParameters () const; + inline const LayoutDescription& getLayout () const; + inline LayoutDescription& getLayout (); + Parameter* getParameter ( const std::string& id ) const; + Parameter* addParameter ( const std::string& id + , Parameter::Type type + , const std::string& value ); + void print ( std::ostream& ) const; + void readFromFile ( const std::string& ); + void writeToStream ( std::ostream& ) const; + private: + // Attributes. + static Configuration* _singleton; + std::map _parameters; + LayoutDescription _layout; + private: + Configuration (); + }; + + +// Inline Methods. + inline const std::map& Configuration::getParameters () const + { return _parameters; } + + inline const LayoutDescription& Configuration::getLayout () const { return _layout; } + inline LayoutDescription& Configuration::getLayout () { return _layout; } + + + inline Parameter* getParamString ( const std::string& id, const std::string& value="" ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::String, value ); + } + + return parameter; + } + + + inline Parameter* getParamBool ( const std::string& id, bool value=false ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::Bool, "false" ); + parameter->setBool ( value ); + } + + return parameter; + } + + + inline Parameter* getParamInt ( const std::string& id, int value=0 ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::Int, "0" ); + parameter->setInt ( value ); + } + + return parameter; + } + + + inline Parameter* getParamEnumerate ( const std::string& id, int value=0 ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::Enumerate, "0" ); + parameter->setInt ( value ); + } + + return parameter; + } + + + inline Parameter* getParamDouble ( const std::string& id, double value=0.0 ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::Double, "0.0" ); + parameter->setDouble ( value ); + } + + return parameter; + } + + + inline Parameter* getParamPercentage ( const std::string& id, double value=91.0 ) + { + Parameter* parameter = Configuration::get()->getParameter(id); + if ( parameter == NULL ) { + parameter = Configuration::get()->addParameter ( id, Parameter::Percentage, "0.91" ); + parameter->setPercentage ( value ); + } + + return parameter; + } + + +} // End of Cfg namespace. + + +#endif // __CFG_CONFIGURATION__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h new file mode 100644 index 00000000..a8cf37fb --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ConfigurationWidget.h @@ -0,0 +1,85 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./ConfigurationWidget.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __CFG_CONFIGURATION_WIDGET__ +#define __CFG_CONFIGURATION_WIDGET__ + +//#include +#include +#include + + +namespace Cfg { + + class Configuration; + class Parameter; + class ParameterWidget; + class ConfTabWidget; + + +// ------------------------------------------------------------------- +// Class : "Cfg::ConfigurationWidget". + + + class ConfigurationWidget : public QTabWidget { + Q_OBJECT; + public: + ConfigurationWidget ( QWidget* parent=NULL ); + public: + QFont& getBoldFont (); + ParameterWidget* find ( Parameter* ) const; + ParameterWidget* find ( const std::string& id ) const; + ConfTabWidget* findOrCreate ( const std::string& name ); + void addRuler ( const std::string& tabName ); + void addTitle ( const std::string& tabName, const std::string& title ); + void addSection ( const std::string& tabName, const std::string& section, int column=0 ); + ParameterWidget* addParameter ( const std::string& tabName, Parameter*, const std::string& label, int column=0, int flags=0 ); + void syncSlaves (); + private: + QFont _boldFont; + }; + + +// Functions Templates. + template + QTypeWidget rparent ( QObject* object ) + { + QTypeWidget root = NULL; + + while ( object != NULL ) { + object = object->parent(); + root = qobject_cast(object); + if ( root != NULL ) + return root; + } + return NULL; + } + + +} // End of Cfg namespace. + + +#endif // __CFG_CONFIGURATION_WIDGET__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h new file mode 100644 index 00000000..93f1f3df --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/LayoutDescription.h @@ -0,0 +1,178 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./LayoutDescription.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __CFG_LAYOUT_DESCRIPTION__ +#define __CFG_LAYOUT_DESCRIPTION__ + +#include +#include + + +namespace Cfg { + + class Configuration; + class ConfigurationWidget; + + +// ------------------------------------------------------------------- +// Class : "Cfg::WidgetDescription". + + + class WidgetDescription { + public: + enum Type { Title=1, Section=2, Rule=3, Parameter=4 }; + public: + inline static WidgetDescription* rule (); + inline static WidgetDescription* title ( const std::string& title ); + inline static WidgetDescription* section ( const std::string& title, int column ); + inline static WidgetDescription* parameter ( const std::string& id + , const std::string& label + , int column + , int flags + ); + inline Type getType () const; + inline const std::string& getId () const; + inline const std::string& getLabel () const; + inline const std::string& getTitle () const; + inline int getColumn () const; + inline int getFlags () const; + private: + Type _type; + std::string _id; // Alternate id, title or section. + std::string _label; + int _column; + int _flags; + private: + inline WidgetDescription ( Type type + , const std::string& id ="" + , const std::string& label ="" + , int column=0 + , int flags=0 + ); + }; + + +// Inline Functions. + inline WidgetDescription::WidgetDescription ( Type type + , const std::string& id + , const std::string& label + , int column + , int flags ) + : _type(type), _id(id), _label(label), _column(column), _flags(flags) + { } + + inline WidgetDescription* WidgetDescription::rule () + { return new WidgetDescription(Rule); } + + inline WidgetDescription* WidgetDescription::title ( const std::string& title ) + { return new WidgetDescription(Title,title); } + + inline WidgetDescription* WidgetDescription::section ( const std::string& title, int column ) + { return new WidgetDescription(Section,title,"",column); } + + inline WidgetDescription* WidgetDescription::parameter ( const std::string& id + , const std::string& label + , int column + , int flags + ) + { return new WidgetDescription(Parameter,id,label,column,flags); } + + inline WidgetDescription::Type WidgetDescription::getType () const { return _type; } + inline const std::string& WidgetDescription::getId () const { return _id; } + inline const std::string& WidgetDescription::getLabel () const { return _label; } + inline const std::string& WidgetDescription::getTitle () const { return _id; } + inline int WidgetDescription::getColumn () const { return _column; } + inline int WidgetDescription::getFlags () const { return _flags; } + + +// ------------------------------------------------------------------- +// Class : "Cfg::TabDescription". + + + class TabDescription { + public: + inline TabDescription ( const std::string& name ); + inline void addWidget ( WidgetDescription* ); + inline const std::string& getName () const; + inline const std::vector& getWidgets () const; + private: + std::string _name; + std::vector _widgets; + }; + + +// Inline Methods. + inline TabDescription::TabDescription ( const std::string& name ) + : _name(name), _widgets() + { } + + inline void TabDescription::addWidget ( WidgetDescription* widget ) + { _widgets.push_back(widget); } + + inline const std::string& TabDescription::getName () const + { return _name; } + + inline const std::vector& TabDescription::getWidgets () const + { return _widgets; } + + +// ------------------------------------------------------------------- +// Class : "Cfg::LayoutDescription". + + + class LayoutDescription { + public: + inline LayoutDescription ( Configuration* ); + inline void addTab ( TabDescription* ); + inline TabDescription* getBackTab (); + inline const std::vector& getTabs () const; + ConfigurationWidget* buildWidget (); + private: + Configuration* _configuration; + std::vector _tabs; + }; + + +// Inline Methods. + inline LayoutDescription::LayoutDescription ( Configuration* cfg ) + : _configuration(cfg), _tabs() + { } + + inline void LayoutDescription::addTab ( TabDescription* tab ) + { _tabs.push_back(tab); } + + inline TabDescription* LayoutDescription::getBackTab () + { return _tabs.back(); } + + inline const std::vector& LayoutDescription::getTabs () const + { return _tabs; } + + + +} // End of Cfg namespace. + + +#endif // __CFG_LAYOUT_DESCRIPTION__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h new file mode 100644 index 00000000..2d41feba --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/Parameter.h @@ -0,0 +1,186 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./Parameter.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __CFG_CONFIGURATION_PARAMETER__ +#define __CFG_CONFIGURATION_PARAMETER__ + +#include +#include +#include +#include + + +namespace Cfg { + + + class Parameter { + public: + enum Type { String = 1 + , Int = 2 + , Double = 3 + , Bool = 4 + , Percentage = 5 + , Enumerate = 6 + }; + enum Flags { HasMin = 0x1 + , HasMax = 0x2 + }; + public: + class EnumValue { + public: + inline EnumValue ( const std::string&, int ); + public: + std::string _label; + int _value; + }; + public: + static std::string typeToString ( Type ); + public: + Parameter ( const std::string& id + , Type type + , const std::string& value ); + inline const std::string& getId () const; + inline const Type getType () const; + inline const std::vector& + getValues () const; + inline const std::vector& + getSlaves () const; + inline int getFlags () const; + inline bool hasFlags ( int mask ) const; + inline int getMinInt () const; + inline int getMaxInt () const; + inline double getMinDouble () const; + inline double getMaxDouble () const; + inline bool checkValue ( int ) const; + inline bool checkValue ( double ) const; + inline const std::string& asString () const; + inline bool asBool () const; + inline int asInt () const; + inline double asDouble () const; + inline double asPercentage () const; + inline void addValue ( const std::string&, int ); + inline void addSlave ( const std::string& ); + inline void setString ( const std::string& ); + inline void setFlags ( int mask ); + inline void unsetFlags ( int mask ); + inline void setInt ( int ); + inline void setDouble ( double ); + inline void setBool ( bool ); + inline void setPercentage ( double ); + inline void setMin ( int ); + inline void setMax ( int ); + inline void setMin ( double ); + inline void setMax ( double ); + private: + // Attributes. + std::string _id; + Type _type; + std::string _value; + std::vector _values; + int _flags; + int _minInt; + int _maxInt; + double _minDouble; + double _maxDouble; + std::vector _slaves; + }; + + +// Inline Methods. + inline const std::string& Parameter::getId () const { return _id; } + inline const Parameter::Type Parameter::getType () const { return _type; } + inline int Parameter::getFlags () const { return _flags; } + inline bool Parameter::hasFlags ( int mask ) const { return (_flags & mask); } + inline int Parameter::getMinInt () const { return _minInt; } + inline int Parameter::getMaxInt () const { return _maxInt; } + inline double Parameter::getMinDouble () const { return _minDouble; } + inline double Parameter::getMaxDouble () const { return _maxDouble; } + inline const std::string& Parameter::asString () const { return _value; } + inline void Parameter::setString ( const std::string& s ) { _value = s; } + + inline bool Parameter::checkValue ( int value ) const { + bool ok = not ( ( (_flags&HasMin) and (value < _minInt) ) + or ( (_flags&HasMax) and (value > _maxInt) ) ); + // std::cerr << "flags:" << _flags << " " + // << _minInt << " < " << value << " < " << _maxInt + // << " : " << std::boolalpha << ok << std::endl; + return ok; + } + + inline bool Parameter::checkValue ( double value ) const { + bool ok = not ( ( (_flags&HasMin) and (value < _minDouble) ) + or ( (_flags&HasMax) and (value > _maxDouble) ) ); + return ok; + } + + inline const std::vector& Parameter::getValues () const { return _values; } + inline const std::vector& Parameter::getSlaves () const { return _slaves; } + inline void Parameter::addSlave ( const std::string& id ) { _slaves.push_back ( id ); } + + inline void Parameter::addValue ( const std::string& label, int value ) { + if ( _type != Enumerate ) { + std::cerr << "[ERROR] Cannot add item on parameter <" << _id + << ">, not enumerated." << std::endl; + return; + } + _values.push_back ( EnumValue(label,value) ); + } + + + inline bool Parameter::asBool () const + { std::istringstream s ( _value ); bool b; s >> std::boolalpha >> b; return b; } + + inline int Parameter::asInt () const + { std::istringstream s ( _value ); int i; s >> i; return i; } + + inline double Parameter::asDouble () const + { std::istringstream s ( _value ); double d; s >> d; return d; } + + inline double Parameter::asPercentage () const + { std::istringstream s ( _value ); double r; s >> r; return r*100.0; } + + inline void Parameter::setInt ( int i ) { std::ostringstream s; s << i; _value = s.str(); } + inline void Parameter::setDouble ( double d ) { std::ostringstream s; s << d; _value = s.str(); } + inline void Parameter::setBool ( bool b ) { std::ostringstream s; s << std::boolalpha << b; _value = s.str(); } + inline void Parameter::setPercentage ( double d ) { std::ostringstream s; s << (d/100.0); _value = s.str(); } + inline void Parameter::setFlags ( int mask ) { _flags |= mask; } + inline void Parameter::unsetFlags ( int mask ) { _flags &= ~mask; } + inline void Parameter::setMin ( int min ) { _minInt = min; setFlags(HasMin); } + inline void Parameter::setMax ( int max ) { _maxInt = max; setFlags(HasMax); } + + inline void Parameter::setMin ( double min ) + { _minDouble = min; setFlags(HasMin); if (_type==Percentage) _minDouble/=100.0; } + + inline void Parameter::setMax ( double max ) + { _maxDouble = max; setFlags(HasMax); if (_type==Percentage) _maxDouble/=100.0; } + + inline Parameter::EnumValue::EnumValue ( const std::string& label, int value ) + : _label(label), _value(value) { } + + +} // End of Cfg namespace. + + +#endif // __CFG_CONFIGURATION_PARAMETER__ diff --git a/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h b/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h new file mode 100644 index 00000000..0a1ae878 --- /dev/null +++ b/vlsisapd/src/configuration/src/vlsisapd/configuration/ParameterWidget.h @@ -0,0 +1,80 @@ + +// -*- C++ -*- +// +// This file is part of the VSLSI Stand-Alone Software. +// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | C O R I O L I S | +// | C o n f i g u r a t i o n D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./ParameterWidget.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + + +#ifndef __CFG_PARAMETER_WIDGET__ +#define __CFG_PARAMETER_WIDGET__ + +#include +#include +class QLabel; + + +namespace Cfg { + + class Parameter; + + +// ------------------------------------------------------------------- +// Class : "Cfg::ParameterWidget". + + + class ParameterWidget : public QObject { + Q_OBJECT; + public: + enum Flags { UseSpinBox=0x1 }; + public: + ParameterWidget ( QObject* parent, Parameter*, const std::string& label, int flags ); + inline Parameter* getParameter (); + inline QLabel* getLabelWidget (); + inline QWidget* getValueWidget (); + inline int getFlags () const; + inline bool hasFlags ( int mask ) const; + inline void setFlags ( int mask ); + inline void unsetFlags ( int mask ); + public slots: + void updateValue (); + void enableSlaves ( int ); + public: + Parameter* _parameter; + QLabel* _labelWidget; + QWidget* _valueWidget; + int _flags; + }; + + +// Inline Methods. + inline Parameter* ParameterWidget::getParameter () { return _parameter; } + inline QLabel* ParameterWidget::getLabelWidget () { return _labelWidget; } + inline QWidget* ParameterWidget::getValueWidget () { return _valueWidget; } + inline int ParameterWidget::getFlags () const { return _flags; } + inline bool ParameterWidget::hasFlags ( int mask ) const { return (_flags & mask); } + inline void ParameterWidget::setFlags ( int mask ) { _flags |= mask; } + inline void ParameterWidget::unsetFlags ( int mask ) { _flags &= ~mask; } + + +} // End of Cfg namespace. + +#endif // __CFG_PARAMETER_WIDGET__