/* = StarPU-Top for StarPU = Copyright (C) 2011 William Braik Yann Courtois Jean-Marie Couteyen Anthony Roy 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, or (at your option) any later version. 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "dataaggregatorwidget.h" #include "mainwindow.h" #include "widgetwindowsmanager.h" #include "datawidget.h" #include "configurationmanager.h" #include #include #include #include #include #include #include DataAggregatorWidget::DataAggregatorWidget( WidgetWindowsManager *widgetWindowsManager, MainWindow *mainWindow, bool inside, QList dataIds) : AbstractWidgetWindow(widgetWindowsManager, mainWindow, inside) { // Init UI setWindowTitle(tr("Aggregator")); setWindowIcon(QIcon(":/images/widget.png")); // Buttons QToolBar *buttonsToolBar = new QToolBar(); // In/out button buttonsToolBar->addWidget(_inOutButton); // Add data button _addDataButton = new QToolButton(); _addDataButton->setIcon(QIcon(":/images/add.png")); _addDataButton->setPopupMode(QToolButton::InstantPopup); _addDataButton->setToolTip(tr("Add data source")); buttonsToolBar->addSeparator(); buttonsToolBar->addWidget(_addDataButton); // Remove data button _removeDataButton = new QToolButton(); _removeDataButton->setIcon(QIcon(":/images/remove.png")); _removeDataButton->setPopupMode(QToolButton::InstantPopup); _removeDataButton->setToolTip(tr("Remove data source")); buttonsToolBar->addWidget(_removeDataButton); // Set layout QVBoxLayout *layout = new QVBoxLayout(); setLayout(layout); layout->addWidget(buttonsToolBar); // Init actions for (int i = 0; i < _mainWindow->dataDescriptions()->count(); i++) { if (_mainWindow->dataDescriptions()->at(i)->type != DATA_TYPE_BOOL) { QAction *addDataAction = new QAction( _mainWindow->dataDescriptions()->at(i)->descriptionString, _addDataButton); addDataAction->setData(_mainWindow->dataDescriptions()->at(i)->id); QObject::connect(addDataAction, SIGNAL(triggered()), this, SLOT(dataAdded())); if (_mainWindow->dataDescriptions()->at(i)->widget == DATA_WIDGET_NONE) { addDataAction->setEnabled(false); } _addDataButton->addAction(addDataAction); } } // Init curve colors _curveColors.append(Qt::black); _curveColors.append(Qt::red); _curveColors.append(Qt::green); _curveColors.append(Qt::blue); _curveColors.append(Qt::magenta); _curveColors.append(Qt::yellow); _curveColors.append(Qt::gray); _curveColors.append(Qt::darkRed); _curveColors.append(Qt::darkGreen); _curveColors.append(Qt::darkBlue); _curveColors.append(Qt::darkCyan); _curveColors.append(Qt::darkMagenta); _curveColors.append(Qt::darkYellow); _curveColors.append(Qt::cyan); _colorIterator = new QListIterator (_curveColors); // Create internal widget createInternalWidget(); // Know when a data source is disabled / enabled QObject::connect(_mainWindow, SIGNAL(dataDisabled(int)), this, SLOT(disableData(int))); QObject::connect(_mainWindow, SIGNAL(dataEnabled(int)), this, SLOT(enableData(int))); // Init data if (dataIds.empty() == false) { for (int i = 0; i < dataIds.count(); i++) { addData(dataIds.at(i)); } } // Setup automatic cleanup QObject::connect(this, SIGNAL(destroyed()), _mainWindow, SLOT(removeDestroyedDataAggregatorWidgets())); qDebug() << "DataAggregatorWidget" << windowId() << ": initializing"; } DataAggregatorWidget::~DataAggregatorWidget() { delete _colorIterator; delete _addDataButton; delete _removeDataButton; delete _plot; qDebug() << "DataAggregatorWidget" << windowId() << ": terminating"; } void DataAggregatorWidget::closeEvent(QCloseEvent *ce) { ce->accept(); } void DataAggregatorWidget::createInternalWidget() { _plot = new QwtPlot(QwtText(tr("Aggregator"))); QwtLegend *legend = new QwtLegend; legend->setItemMode(QwtLegend::CheckableItem); _plot->insertLegend(legend, QwtPlot::BottomLegend); _plot->setMinimumSize(300, 200); _plot->setAttribute(Qt::WA_DeleteOnClose); layout()->addWidget(_plot); QObject::connect(_plot, SIGNAL(legendChecked(QwtPlotItem *, bool)), SLOT(curveChecked(QwtPlotItem *, bool))); } void DataAggregatorWidget::addData(int dataId) { DataWidget *dataWidget = _mainWindow->dataWidgetFromDataId(dataId); if (dataWidget != 0) { qDebug() << "Aggregator" << _windowId << ": adding new data of id" << dataId; switch (dataWidget->description()->type) { case DATA_TYPE_INT: { QObject::connect(dataWidget, SIGNAL(valueChanged(int,int)), this, SLOT(update(int,int))); break; } case DATA_TYPE_FLOAT: { QObject::connect(dataWidget, SIGNAL(valueChanged(double,int)), this, SLOT(update(double,int))); break; } default: qDebug() << "Aggregator" << _windowId << ": attempt to add data of unsupported type (id :" << dataId << ")"; } QwtPlotCurve *curve = new QwtPlotCurve( _mainWindow->dataDescriptionFromId(dataId)->descriptionString); if (_mainWindow->configurationManager()->antialiasing() == true) { curve->setRenderHint(QwtPlotItem::RenderAntialiased); } QColor c; if (_colorIterator->hasNext()) { c = _colorIterator->next(); c.setAlpha(150); curve->setPen(c); } _curves.insert(dataId, curve); CurveData curveData; curveData.xData = new QVector (); curveData.yData = new QVector (); _curvesData.insert(dataId, curveData); curve->attach(_plot); } else { qDebug() << "Aggregator" << _windowId << ": failed to add data of id" << dataId; } } void DataAggregatorWidget::removeData(int dataId) { DataWidget *dataWidget = _mainWindow->dataWidgetFromDataId(dataId); if (dataWidget != 0) { qDebug() << "Aggregator" << _windowId << ": removing data of id" << dataId; switch (dataWidget->description()->type) { case DATA_TYPE_INT: QObject::disconnect(dataWidget, SIGNAL(valueChanged(int,int)), this, SLOT(update(int,int))); break; case DATA_TYPE_FLOAT: QObject::disconnect(dataWidget, SIGNAL(valueChanged(double,int)), this, SLOT(update(double,int))); break; default: ; } _curves.value(dataId)->detach(); _curvesData.remove(dataId); _curves.remove(dataId); } else { qDebug() << "Aggregator" << _windowId << ": failed to remove data of id" << dataId; } } void DataAggregatorWidget::update(int value, int dataId) { qDebug() << "Aggregator" << _windowId << ": updating data of id" << dataId << "with value" << value; _curvesData.value(dataId).xData->append(_mainWindow ->effectiveRunningTime()); _curvesData.value(dataId).yData->append(value); #if QWT_VERSION >= 0x060000 _curves.value(dataId)->setRawSamples( _curvesData.value(dataId).xData->data(), _curvesData.value(dataId).yData->data(), _curvesData.value(dataId).xData->size()); #else # warning Old version of qwt being used, data aggregator will not work. #endif _plot->replot(); } void DataAggregatorWidget::update(double value, int dataId) { qDebug() << "Aggregator" << _windowId << ": updating data of id" << dataId << "with value" << value; _curvesData.value(dataId).xData->append(_mainWindow ->effectiveRunningTime()); _curvesData.value(dataId).yData->append(value); #if QWT_VERSION >= 0x060000 _curves.value(dataId)->setRawSamples( _curvesData.value(dataId).xData->data(), _curvesData.value(dataId).yData->data(), _curvesData.value(dataId).xData->size()); #else # warning Old version of qwt being used, data aggregator will not work. #endif _plot->replot(); } QSize DataAggregatorWidget::minimumInternalWidgetSize() const { return _plot->minimumSize(); } QList DataAggregatorWidget::aggregatedData() const { QList addedData; for (int i = 0; i < _curves.values().count(); i++) { addedData.append(_curves.key(_curves.values().at(i))); } return addedData; } void DataAggregatorWidget::curveChecked(QwtPlotItem *curve, bool checked) { curve->setVisible(!checked); } void DataAggregatorWidget::dataAdded() { QAction *action = (QAction*) QObject::sender(); int dataId = action->data().toInt(); _addDataButton->removeAction(action); addData(dataId); QAction *removeDataAction = new QAction( _mainWindow->dataDescriptionFromId(dataId)->descriptionString, _removeDataButton); removeDataAction->setData(dataId); QObject::connect(removeDataAction, SIGNAL(triggered()), this, SLOT(dataRemoved())); _removeDataButton->addAction(removeDataAction); } void DataAggregatorWidget::dataRemoved() { QAction *action = (QAction*) QObject::sender(); int dataId = action->data().toInt(); _removeDataButton->removeAction(action); removeData(dataId); QAction *addDataAction = new QAction( _mainWindow->dataDescriptionFromId(dataId)->descriptionString, _addDataButton); addDataAction->setData(dataId); QObject::connect(addDataAction, SIGNAL(triggered()), this, SLOT(dataAdded())); _addDataButton->addAction(addDataAction); } void DataAggregatorWidget::disableData(int dataId) { // Search the action on the add button for (int i = 0; i < _addDataButton->actions().count(); i++) { if (_addDataButton->actions().at(i)->data().toInt() == dataId) { _addDataButton->actions().at(i)->setEnabled(false); return; } } // If not found, it has already been added for (int i = 0; i < _removeDataButton->actions().count(); i++) { if (_removeDataButton->actions().at(i)->data().toInt() == dataId) { _removeDataButton->removeAction(_removeDataButton->actions().at(i)); removeData(dataId); QAction *action = new QAction( _mainWindow->dataDescriptionFromId(dataId) ->descriptionString, _addDataButton); action->setData(dataId); QObject::connect(action, SIGNAL(triggered()), this, SLOT(dataAdded())); action->setEnabled(false); _addDataButton->addAction(action); return; } } } void DataAggregatorWidget::enableData(int dataId) { // Search the action on the add button for (int i = 0; i < _addDataButton->actions().count(); i++) { if (_addDataButton->actions().at(i)->data().toInt() == dataId) { _addDataButton->actions().at(i)->setEnabled(true); return; } } }