ctkErrorLogWidget.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QDebug>
  16. #include <QAbstractItemModel>
  17. #include <QStandardItemModel>
  18. // CTK includes
  19. #include "ctkErrorLogWidget.h"
  20. #include "ui_ctkErrorLogWidget.h"
  21. #include <ctkErrorLogModel.h>
  22. class ctkErrorLogWidgetPrivate : public Ui_ctkErrorLogWidget
  23. {
  24. Q_DECLARE_PUBLIC(ctkErrorLogWidget);
  25. protected:
  26. ctkErrorLogWidget* const q_ptr;
  27. public:
  28. typedef ctkErrorLogWidgetPrivate Self;
  29. ctkErrorLogWidgetPrivate(ctkErrorLogWidget& object);
  30. ctkErrorLogLevel::LogLevels ErrorButtonFilter;
  31. ctkErrorLogLevel::LogLevels WarningButtonFilter;
  32. ctkErrorLogLevel::LogLevels InfoButtonFilter;
  33. void init();
  34. QSharedPointer<QItemSelectionModel> SelectionModel;
  35. };
  36. // --------------------------------------------------------------------------
  37. // ctkErrorLogWidgetPrivate methods
  38. // --------------------------------------------------------------------------
  39. ctkErrorLogWidgetPrivate::ctkErrorLogWidgetPrivate(ctkErrorLogWidget& object)
  40. : q_ptr(&object)
  41. {
  42. this->ErrorButtonFilter = ctkErrorLogLevel::Error | ctkErrorLogLevel::Critical | ctkErrorLogLevel::Fatal;
  43. this->WarningButtonFilter = ctkErrorLogLevel::Warning;
  44. this->InfoButtonFilter = ctkErrorLogLevel::Info | ctkErrorLogLevel::Debug | ctkErrorLogLevel::Trace | ctkErrorLogLevel::Status;
  45. }
  46. // --------------------------------------------------------------------------
  47. void ctkErrorLogWidgetPrivate::init()
  48. {
  49. Q_Q(ctkErrorLogWidget);
  50. // this->ShowAllEntryButton->setIcon();
  51. this->ShowErrorEntryButton->setIcon(q->style()->standardIcon(QStyle::SP_MessageBoxCritical));
  52. this->ShowWarningEntryButton->setIcon(q->style()->standardIcon(QStyle::SP_MessageBoxWarning));
  53. this->ShowInfoEntryButton->setIcon(q->style()->standardIcon(QStyle::SP_MessageBoxInformation));
  54. this->ClearButton->setIcon(q->style()->standardIcon(QStyle::SP_DialogDiscardButton));
  55. QObject::connect(this->ShowAllEntryButton, SIGNAL(clicked()),
  56. q, SLOT(setAllEntriesVisible()));
  57. QObject::connect(this->ShowErrorEntryButton, SIGNAL(clicked(bool)),
  58. q, SLOT(setErrorEntriesVisible(bool)));
  59. QObject::connect(this->ShowWarningEntryButton, SIGNAL(clicked(bool)),
  60. q, SLOT(setWarningEntriesVisible(bool)));
  61. QObject::connect(this->ShowInfoEntryButton, SIGNAL(clicked(bool)),
  62. q, SLOT(setInfoEntriesVisible(bool)));
  63. QObject::connect(this->ClearButton, SIGNAL(clicked()),
  64. q, SLOT(removeEntries()));
  65. }
  66. // --------------------------------------------------------------------------
  67. // ctkErrorLogWidget methods
  68. //------------------------------------------------------------------------------
  69. ctkErrorLogWidget::ctkErrorLogWidget(QWidget * newParent)
  70. : Superclass(newParent)
  71. , d_ptr(new ctkErrorLogWidgetPrivate(*this))
  72. {
  73. Q_D(ctkErrorLogWidget);
  74. d->setupUi(this);
  75. d->init();
  76. this->setErrorLogModel(new ctkErrorLogModel(d->ErrorLogTableView));
  77. }
  78. //------------------------------------------------------------------------------
  79. ctkErrorLogWidget::~ctkErrorLogWidget()
  80. {
  81. }
  82. //------------------------------------------------------------------------------
  83. ctkErrorLogModel* ctkErrorLogWidget::errorLogModel()const
  84. {
  85. Q_D(const ctkErrorLogWidget);
  86. QAbstractItemModel* model = d->ErrorLogTableView->model();
  87. ctkErrorLogModel * errorLogModel = qobject_cast<ctkErrorLogModel*>(model);
  88. Q_ASSERT(model ? errorLogModel != 0 : true);
  89. return errorLogModel;
  90. }
  91. //------------------------------------------------------------------------------
  92. void ctkErrorLogWidget::setErrorLogModel(ctkErrorLogModel * newErrorLogModel)
  93. {
  94. Q_D(ctkErrorLogWidget);
  95. if (newErrorLogModel == this->errorLogModel())
  96. {
  97. return;
  98. }
  99. if (this->errorLogModel())
  100. {
  101. disconnect(this->errorLogModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
  102. this, SLOT(onRowsInserted(QModelIndex,int,int)));
  103. disconnect(this->errorLogModel(), SIGNAL(logLevelFilterChanged()),
  104. this, SLOT(onLogLevelFilterChanged()));
  105. disconnect(d->SelectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
  106. this, SLOT(onSelectionChanged(QItemSelection,QItemSelection)));
  107. d->SelectionModel.clear();
  108. }
  109. d->ErrorLogTableView->setModel(newErrorLogModel);
  110. if (newErrorLogModel)
  111. {
  112. connect(this->errorLogModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
  113. this, SLOT(onRowsInserted(QModelIndex,int,int)));
  114. connect(this->errorLogModel(), SIGNAL(logLevelFilterChanged()),
  115. this, SLOT(onLogLevelFilterChanged()));
  116. ctkErrorLogLevel::LogLevels logLevelFilter = newErrorLogModel->logLevelFilter();
  117. this->setErrorEntriesVisible(logLevelFilter & d->ErrorButtonFilter);
  118. this->setWarningEntriesVisible(logLevelFilter & d->WarningButtonFilter);
  119. this->setInfoEntriesVisible(logLevelFilter & d->InfoButtonFilter);
  120. this->errorLogModel()->filterEntry(logLevelFilter & ctkErrorLogLevel::Unknown);
  121. // Setup selection model
  122. d->SelectionModel = QSharedPointer<QItemSelectionModel>(new QItemSelectionModel(this->errorLogModel()));
  123. d->SelectionModel->reset();
  124. connect(d->SelectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
  125. this, SLOT(onSelectionChanged(QItemSelection,QItemSelection)));
  126. d->ErrorLogTableView->setSelectionModel(d->SelectionModel.data());
  127. // Resize time column only if there are rows
  128. if (this->errorLogModel()->rowCount() > 0)
  129. {
  130. d->ErrorLogTableView->resizeColumnToContents(ctkErrorLogModel::TimeColumn);
  131. }
  132. }
  133. else
  134. {
  135. this->setAllEntriesVisible(0);
  136. }
  137. d->ErrorLogTableView->setColumnHidden(ctkErrorLogModel::ThreadIdColumn, true);
  138. }
  139. // --------------------------------------------------------------------------
  140. void ctkErrorLogWidget::setColumnHidden(int columnId, bool hidden) const
  141. {
  142. Q_D(const ctkErrorLogWidget);
  143. d->ErrorLogTableView->setColumnHidden(columnId, hidden);
  144. }
  145. // --------------------------------------------------------------------------
  146. void ctkErrorLogWidget::setAllEntriesVisible(bool visibility)
  147. {
  148. this->setErrorEntriesVisible(visibility);
  149. this->setWarningEntriesVisible(visibility);
  150. this->setInfoEntriesVisible(visibility);
  151. this->setUnknownEntriesVisible(visibility);
  152. }
  153. // --------------------------------------------------------------------------
  154. void ctkErrorLogWidget::setErrorEntriesVisible(bool visibility)
  155. {
  156. Q_D(ctkErrorLogWidget);
  157. if (!this->errorLogModel())
  158. {
  159. return;
  160. }
  161. this->errorLogModel()->filterEntry(d->ErrorButtonFilter, /* disableFilter= */ !visibility);
  162. }
  163. // --------------------------------------------------------------------------
  164. void ctkErrorLogWidget::setWarningEntriesVisible(bool visibility)
  165. {
  166. Q_D(ctkErrorLogWidget);
  167. if (!this->errorLogModel())
  168. {
  169. return;
  170. }
  171. this->errorLogModel()->filterEntry(d->WarningButtonFilter, /* disableFilter= */ !visibility);
  172. }
  173. // --------------------------------------------------------------------------
  174. void ctkErrorLogWidget::setInfoEntriesVisible(bool visibility)
  175. {
  176. Q_D(ctkErrorLogWidget);
  177. if (!this->errorLogModel())
  178. {
  179. return;
  180. }
  181. this->errorLogModel()->filterEntry(d->InfoButtonFilter, /* disableFilter= */ !visibility);
  182. }
  183. // --------------------------------------------------------------------------
  184. void ctkErrorLogWidget::setUnknownEntriesVisible(bool visibility)
  185. {
  186. if (!this->errorLogModel())
  187. {
  188. return;
  189. }
  190. this->errorLogModel()->filterEntry(ctkErrorLogLevel::Unknown,
  191. /* disableFilter= */ !visibility);
  192. }
  193. // --------------------------------------------------------------------------
  194. void ctkErrorLogWidget::onRowsInserted(const QModelIndex &/*parent*/, int /*first*/, int /*last*/)
  195. {
  196. Q_D(ctkErrorLogWidget);
  197. if (d->ErrorLogTableView->model()->rowCount() == 1)
  198. {
  199. // For performance reason, resize first column only when first entry is added
  200. d->ErrorLogTableView->resizeColumnToContents(ctkErrorLogModel::TimeColumn);
  201. }
  202. }
  203. // --------------------------------------------------------------------------
  204. void ctkErrorLogWidget::onLogLevelFilterChanged()
  205. {
  206. Q_D(ctkErrorLogWidget);
  207. Q_ASSERT(this->errorLogModel());
  208. ctkErrorLogLevel::LogLevels logLevelFilter = this->errorLogModel()->logLevelFilter();
  209. d->ShowErrorEntryButton->setChecked(logLevelFilter & d->ErrorButtonFilter);
  210. d->ShowWarningEntryButton->setChecked(logLevelFilter & d->WarningButtonFilter);
  211. d->ShowInfoEntryButton->setChecked(logLevelFilter & d->InfoButtonFilter);
  212. }
  213. // --------------------------------------------------------------------------
  214. void ctkErrorLogWidget::removeEntries()
  215. {
  216. Q_ASSERT(this->errorLogModel());
  217. this->errorLogModel()->clear();
  218. }
  219. // --------------------------------------------------------------------------
  220. void ctkErrorLogWidget::onSelectionChanged(const QItemSelection & selected,
  221. const QItemSelection & deselected)
  222. {
  223. // QTime start = QTime::currentTime();
  224. Q_D(ctkErrorLogWidget);
  225. Q_UNUSED(selected);
  226. Q_UNUSED(deselected);
  227. QModelIndexList selectedRows =
  228. d->SelectionModel->selectedRows(ctkErrorLogModel::DescriptionColumn);
  229. qSort(selectedRows.begin(), selectedRows.end());
  230. QStringList descriptions;
  231. foreach(const QModelIndex& index, selectedRows)
  232. {
  233. descriptions << index.data(ctkErrorLogModel::DescriptionTextRole).toString();
  234. }
  235. d->ErrorLogDescription->setText(descriptions.join("\n"));
  236. // fprintf(stdout, "onSelectionChanged: %d\n", start.msecsTo(QTime::currentTime()));
  237. }