dataaggregatorwidget.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. = StarPU-Top for StarPU =
  3. Copyright (C) 2011
  4. William Braik
  5. Yann Courtois
  6. Jean-Marie Couteyen
  7. Anthony Roy
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public
  10. License as published by the Free Software Foundation; either
  11. version 2.1 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with this library; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "dataaggregatorwidget.h"
  21. #include "mainwindow.h"
  22. #include "widgetwindowsmanager.h"
  23. #include "datawidget.h"
  24. #include "configurationmanager.h"
  25. #include <qwt_plot_item.h>
  26. #include <qwt_plot_curve.h>
  27. #include <qwt_legend.h>
  28. #include <qwt_plot.h>
  29. #include <QToolBar>
  30. #include <QVBoxLayout>
  31. #include <QCloseEvent>
  32. DataAggregatorWidget::DataAggregatorWidget(
  33. WidgetWindowsManager *widgetWindowsManager, MainWindow *mainWindow,
  34. bool inside, QList<int> dataIds) :
  35. AbstractWidgetWindow(widgetWindowsManager, mainWindow, inside)
  36. {
  37. // Init UI
  38. setWindowTitle(tr("Aggregator"));
  39. setWindowIcon(QIcon(":/images/widget.png"));
  40. // Buttons
  41. QToolBar *buttonsToolBar = new QToolBar();
  42. // In/out button
  43. buttonsToolBar->addWidget(_inOutButton);
  44. // Add data button
  45. _addDataButton = new QToolButton();
  46. _addDataButton->setIcon(QIcon(":/images/add.png"));
  47. _addDataButton->setPopupMode(QToolButton::InstantPopup);
  48. _addDataButton->setToolTip(tr("Add data source"));
  49. buttonsToolBar->addSeparator();
  50. buttonsToolBar->addWidget(_addDataButton);
  51. // Remove data button
  52. _removeDataButton = new QToolButton();
  53. _removeDataButton->setIcon(QIcon(":/images/remove.png"));
  54. _removeDataButton->setPopupMode(QToolButton::InstantPopup);
  55. _removeDataButton->setToolTip(tr("Remove data source"));
  56. buttonsToolBar->addWidget(_removeDataButton);
  57. // Set layout
  58. QVBoxLayout *layout = new QVBoxLayout();
  59. setLayout(layout);
  60. layout->addWidget(buttonsToolBar);
  61. // Init actions
  62. for (int i = 0; i < _mainWindow->dataDescriptions()->count(); i++)
  63. {
  64. if (_mainWindow->dataDescriptions()->at(i)->type != DATA_TYPE_BOOL)
  65. {
  66. QAction *addDataAction = new QAction(
  67. _mainWindow->dataDescriptions()->at(i)->descriptionString,
  68. _addDataButton);
  69. addDataAction->setData(_mainWindow->dataDescriptions()->at(i)->id);
  70. QObject::connect(addDataAction, SIGNAL(triggered()), this,
  71. SLOT(dataAdded()));
  72. if (_mainWindow->dataDescriptions()->at(i)->widget
  73. == DATA_WIDGET_NONE)
  74. {
  75. addDataAction->setEnabled(false);
  76. }
  77. _addDataButton->addAction(addDataAction);
  78. }
  79. }
  80. // Init curve colors
  81. _curveColors.append(Qt::black);
  82. _curveColors.append(Qt::red);
  83. _curveColors.append(Qt::green);
  84. _curveColors.append(Qt::blue);
  85. _curveColors.append(Qt::magenta);
  86. _curveColors.append(Qt::yellow);
  87. _curveColors.append(Qt::gray);
  88. _curveColors.append(Qt::darkRed);
  89. _curveColors.append(Qt::darkGreen);
  90. _curveColors.append(Qt::darkBlue);
  91. _curveColors.append(Qt::darkCyan);
  92. _curveColors.append(Qt::darkMagenta);
  93. _curveColors.append(Qt::darkYellow);
  94. _curveColors.append(Qt::cyan);
  95. _colorIterator = new QListIterator<QColor> (_curveColors);
  96. // Create internal widget
  97. createInternalWidget();
  98. // Know when a data source is disabled / enabled
  99. QObject::connect(_mainWindow, SIGNAL(dataDisabled(int)),
  100. this, SLOT(disableData(int)));
  101. QObject::connect(_mainWindow, SIGNAL(dataEnabled(int)),
  102. this, SLOT(enableData(int)));
  103. // Init data
  104. if (dataIds.empty() == false)
  105. {
  106. for (int i = 0; i < dataIds.count(); i++)
  107. {
  108. addData(dataIds.at(i));
  109. }
  110. }
  111. // Setup automatic cleanup
  112. QObject::connect(this, SIGNAL(destroyed()), _mainWindow,
  113. SLOT(removeDestroyedDataAggregatorWidgets()));
  114. qDebug() << "DataAggregatorWidget" << windowId() << ": initializing";
  115. }
  116. DataAggregatorWidget::~DataAggregatorWidget()
  117. {
  118. delete _colorIterator;
  119. delete _addDataButton;
  120. delete _removeDataButton;
  121. delete _plot;
  122. qDebug() << "DataAggregatorWidget" << windowId() << ": terminating";
  123. }
  124. void DataAggregatorWidget::closeEvent(QCloseEvent *ce)
  125. {
  126. ce->accept();
  127. }
  128. void DataAggregatorWidget::createInternalWidget()
  129. {
  130. _plot = new QwtPlot(QwtText(tr("Aggregator")));
  131. QwtLegend *legend = new QwtLegend;
  132. legend->setItemMode(QwtLegend::CheckableItem);
  133. _plot->insertLegend(legend, QwtPlot::BottomLegend);
  134. _plot->setMinimumSize(300, 200);
  135. _plot->setAttribute(Qt::WA_DeleteOnClose);
  136. layout()->addWidget(_plot);
  137. QObject::connect(_plot, SIGNAL(legendChecked(QwtPlotItem *, bool)),
  138. SLOT(curveChecked(QwtPlotItem *, bool)));
  139. }
  140. void DataAggregatorWidget::addData(int dataId)
  141. {
  142. DataWidget *dataWidget = _mainWindow->dataWidgetFromDataId(dataId);
  143. if (dataWidget != 0)
  144. {
  145. qDebug() << "Aggregator" << _windowId << ": adding new data of id"
  146. << dataId;
  147. switch (dataWidget->description()->type)
  148. {
  149. case DATA_TYPE_INT:
  150. {
  151. QObject::connect(dataWidget, SIGNAL(valueChanged(int,int)),
  152. this, SLOT(update(int,int)));
  153. break;
  154. }
  155. case DATA_TYPE_FLOAT:
  156. {
  157. QObject::connect(dataWidget, SIGNAL(valueChanged(double,int)),
  158. this, SLOT(update(double,int)));
  159. break;
  160. }
  161. default:
  162. qDebug() << "Aggregator" << _windowId
  163. << ": attempt to add data of unsupported type (id :"
  164. << dataId << ")";
  165. }
  166. QwtPlotCurve *curve = new QwtPlotCurve(
  167. _mainWindow->dataDescriptionFromId(dataId)->descriptionString);
  168. if (_mainWindow->configurationManager()->antialiasing() == true)
  169. {
  170. curve->setRenderHint(QwtPlotItem::RenderAntialiased);
  171. }
  172. QColor c;
  173. if (_colorIterator->hasNext())
  174. {
  175. c = _colorIterator->next();
  176. c.setAlpha(150);
  177. curve->setPen(c);
  178. }
  179. _curves.insert(dataId, curve);
  180. CurveData curveData;
  181. curveData.xData = new QVector<double> ();
  182. curveData.yData = new QVector<double> ();
  183. _curvesData.insert(dataId, curveData);
  184. curve->attach(_plot);
  185. }
  186. else
  187. {
  188. qDebug() << "Aggregator" << _windowId << ": failed to add data of id"
  189. << dataId;
  190. }
  191. }
  192. void DataAggregatorWidget::removeData(int dataId)
  193. {
  194. DataWidget *dataWidget = _mainWindow->dataWidgetFromDataId(dataId);
  195. if (dataWidget != 0)
  196. {
  197. qDebug() << "Aggregator" << _windowId << ": removing data of id"
  198. << dataId;
  199. switch (dataWidget->description()->type)
  200. {
  201. case DATA_TYPE_INT:
  202. QObject::disconnect(dataWidget, SIGNAL(valueChanged(int,int)),
  203. this, SLOT(update(int,int)));
  204. break;
  205. case DATA_TYPE_FLOAT:
  206. QObject::disconnect(dataWidget, SIGNAL(valueChanged(double,int)),
  207. this, SLOT(update(double,int)));
  208. break;
  209. default:
  210. ;
  211. }
  212. _curves.value(dataId)->detach();
  213. _curvesData.remove(dataId);
  214. _curves.remove(dataId);
  215. }
  216. else
  217. {
  218. qDebug() << "Aggregator" << _windowId
  219. << ": failed to remove data of id" << dataId;
  220. }
  221. }
  222. void DataAggregatorWidget::update(int value, int dataId)
  223. {
  224. qDebug() << "Aggregator" << _windowId << ": updating data of id" << dataId
  225. << "with value" << value;
  226. _curvesData.value(dataId).xData->append(_mainWindow
  227. ->effectiveRunningTime());
  228. _curvesData.value(dataId).yData->append(value);
  229. #if QWT_VERSION >= 0x060000
  230. _curves.value(dataId)->setRawSamples(
  231. _curvesData.value(dataId).xData->data(),
  232. _curvesData.value(dataId).yData->data(),
  233. _curvesData.value(dataId).xData->size());
  234. #else
  235. # warning Old version of qwt being used, data aggregator will not work.
  236. #endif
  237. _plot->replot();
  238. }
  239. void DataAggregatorWidget::update(double value, int dataId)
  240. {
  241. qDebug() << "Aggregator" << _windowId << ": updating data of id" << dataId
  242. << "with value" << value;
  243. _curvesData.value(dataId).xData->append(_mainWindow
  244. ->effectiveRunningTime());
  245. _curvesData.value(dataId).yData->append(value);
  246. #if QWT_VERSION >= 0x060000
  247. _curves.value(dataId)->setRawSamples(
  248. _curvesData.value(dataId).xData->data(),
  249. _curvesData.value(dataId).yData->data(),
  250. _curvesData.value(dataId).xData->size());
  251. #else
  252. # warning Old version of qwt being used, data aggregator will not work.
  253. #endif
  254. _plot->replot();
  255. }
  256. QSize DataAggregatorWidget::minimumInternalWidgetSize() const
  257. {
  258. return _plot->minimumSize();
  259. }
  260. QList<int> DataAggregatorWidget::aggregatedData() const
  261. {
  262. QList<int> addedData;
  263. for (int i = 0; i < _curves.values().count(); i++)
  264. {
  265. addedData.append(_curves.key(_curves.values().at(i)));
  266. }
  267. return addedData;
  268. }
  269. void DataAggregatorWidget::curveChecked(QwtPlotItem *curve, bool checked)
  270. {
  271. curve->setVisible(!checked);
  272. }
  273. void DataAggregatorWidget::dataAdded()
  274. {
  275. QAction *action = (QAction*) QObject::sender();
  276. int dataId = action->data().toInt();
  277. _addDataButton->removeAction(action);
  278. addData(dataId);
  279. QAction *removeDataAction = new QAction(
  280. _mainWindow->dataDescriptionFromId(dataId)->descriptionString,
  281. _removeDataButton);
  282. removeDataAction->setData(dataId);
  283. QObject::connect(removeDataAction, SIGNAL(triggered()), this,
  284. SLOT(dataRemoved()));
  285. _removeDataButton->addAction(removeDataAction);
  286. }
  287. void DataAggregatorWidget::dataRemoved()
  288. {
  289. QAction *action = (QAction*) QObject::sender();
  290. int dataId = action->data().toInt();
  291. _removeDataButton->removeAction(action);
  292. removeData(dataId);
  293. QAction *addDataAction = new QAction(
  294. _mainWindow->dataDescriptionFromId(dataId)->descriptionString,
  295. _addDataButton);
  296. addDataAction->setData(dataId);
  297. QObject::connect(addDataAction, SIGNAL(triggered()), this,
  298. SLOT(dataAdded()));
  299. _addDataButton->addAction(addDataAction);
  300. }
  301. void DataAggregatorWidget::disableData(int dataId)
  302. {
  303. // Search the action on the add button
  304. for (int i = 0; i < _addDataButton->actions().count(); i++)
  305. {
  306. if (_addDataButton->actions().at(i)->data().toInt() == dataId)
  307. {
  308. _addDataButton->actions().at(i)->setEnabled(false);
  309. return;
  310. }
  311. }
  312. // If not found, it has already been added
  313. for (int i = 0; i < _removeDataButton->actions().count(); i++)
  314. {
  315. if (_removeDataButton->actions().at(i)->data().toInt() == dataId)
  316. {
  317. _removeDataButton->removeAction(_removeDataButton->actions().at(i));
  318. removeData(dataId);
  319. QAction
  320. *action =
  321. new QAction(
  322. _mainWindow->dataDescriptionFromId(dataId)
  323. ->descriptionString,
  324. _addDataButton);
  325. action->setData(dataId);
  326. QObject::connect(action, SIGNAL(triggered()), this,
  327. SLOT(dataAdded()));
  328. action->setEnabled(false);
  329. _addDataButton->addAction(action);
  330. return;
  331. }
  332. }
  333. }
  334. void DataAggregatorWidget::enableData(int dataId)
  335. {
  336. // Search the action on the add button
  337. for (int i = 0; i < _addDataButton->actions().count(); i++)
  338. {
  339. if (_addDataButton->actions().at(i)->data().toInt() == dataId)
  340. {
  341. _addDataButton->actions().at(i)->setEnabled(true);
  342. return;
  343. }
  344. }
  345. }