ctkErrorLogWidget.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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. this->ErrorLogTableView->setColumnHidden(ctkErrorLogModel::ThreadIdColumn, true);
  66. }
  67. // --------------------------------------------------------------------------
  68. // ctkErrorLogWidget methods
  69. //------------------------------------------------------------------------------
  70. ctkErrorLogWidget::ctkErrorLogWidget(QWidget * newParent)
  71. : Superclass(newParent)
  72. , d_ptr(new ctkErrorLogWidgetPrivate(*this))
  73. {
  74. Q_D(ctkErrorLogWidget);
  75. d->setupUi(this);
  76. d->init();
  77. this->setErrorLogModel(new ctkErrorLogModel(d->ErrorLogTableView));
  78. }
  79. //------------------------------------------------------------------------------
  80. ctkErrorLogWidget::~ctkErrorLogWidget()
  81. {
  82. }
  83. //------------------------------------------------------------------------------
  84. ctkErrorLogModel* ctkErrorLogWidget::errorLogModel()const
  85. {
  86. Q_D(const ctkErrorLogWidget);
  87. QAbstractItemModel* model = d->ErrorLogTableView->model();
  88. ctkErrorLogModel * errorLogModel = qobject_cast<ctkErrorLogModel*>(model);
  89. Q_ASSERT(model ? errorLogModel != 0 : true);
  90. return errorLogModel;
  91. }
  92. //------------------------------------------------------------------------------
  93. void ctkErrorLogWidget::setErrorLogModel(ctkErrorLogModel * newErrorLogModel)
  94. {
  95. Q_D(ctkErrorLogWidget);
  96. if (newErrorLogModel == this->errorLogModel())
  97. {
  98. return;
  99. }
  100. if (this->errorLogModel())
  101. {
  102. disconnect(this->errorLogModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
  103. this, SLOT(onRowsInserted(QModelIndex,int,int)));
  104. disconnect(this->errorLogModel(), SIGNAL(logLevelFilterChanged()),
  105. this, SLOT(onLogLevelFilterChanged()));
  106. disconnect(d->SelectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
  107. this, SLOT(onSelectionChanged(QItemSelection,QItemSelection)));
  108. d->SelectionModel.clear();
  109. }
  110. d->ErrorLogTableView->setModel(newErrorLogModel);
  111. if (newErrorLogModel)
  112. {
  113. connect(this->errorLogModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
  114. this, SLOT(onRowsInserted(QModelIndex,int,int)));
  115. connect(this->errorLogModel(), SIGNAL(logLevelFilterChanged()),
  116. this, SLOT(onLogLevelFilterChanged()));
  117. ctkErrorLogLevel::LogLevels logLevelFilter = newErrorLogModel->logLevelFilter();
  118. this->setErrorEntriesVisible(logLevelFilter & d->ErrorButtonFilter);
  119. this->setWarningEntriesVisible(logLevelFilter & d->WarningButtonFilter);
  120. this->setInfoEntriesVisible(logLevelFilter & d->InfoButtonFilter);
  121. this->errorLogModel()->filterEntry(logLevelFilter & ctkErrorLogLevel::Unknown);
  122. // Setup selection model
  123. d->SelectionModel = QSharedPointer<QItemSelectionModel>(new QItemSelectionModel(this->errorLogModel()));
  124. d->SelectionModel->reset();
  125. connect(d->SelectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
  126. this, SLOT(onSelectionChanged(QItemSelection,QItemSelection)));
  127. d->ErrorLogTableView->setSelectionModel(d->SelectionModel.data());
  128. // Resize time column only if there are rows
  129. if (this->errorLogModel()->rowCount() > 0)
  130. {
  131. d->ErrorLogTableView->resizeColumnToContents(ctkErrorLogModel::TimeColumn);
  132. }
  133. }
  134. else
  135. {
  136. this->setAllEntriesVisible(0);
  137. }
  138. }
  139. // --------------------------------------------------------------------------
  140. void ctkErrorLogWidget::setAllEntriesVisible(bool visibility)
  141. {
  142. this->setErrorEntriesVisible(visibility);
  143. this->setWarningEntriesVisible(visibility);
  144. this->setInfoEntriesVisible(visibility);
  145. this->setUnknownEntriesVisible(visibility);
  146. }
  147. // --------------------------------------------------------------------------
  148. void ctkErrorLogWidget::setErrorEntriesVisible(bool visibility)
  149. {
  150. Q_D(ctkErrorLogWidget);
  151. if (!this->errorLogModel())
  152. {
  153. return;
  154. }
  155. this->errorLogModel()->filterEntry(d->ErrorButtonFilter, /* disableFilter= */ !visibility);
  156. }
  157. // --------------------------------------------------------------------------
  158. void ctkErrorLogWidget::setWarningEntriesVisible(bool visibility)
  159. {
  160. Q_D(ctkErrorLogWidget);
  161. if (!this->errorLogModel())
  162. {
  163. return;
  164. }
  165. this->errorLogModel()->filterEntry(d->WarningButtonFilter, /* disableFilter= */ !visibility);
  166. }
  167. // --------------------------------------------------------------------------
  168. void ctkErrorLogWidget::setInfoEntriesVisible(bool visibility)
  169. {
  170. Q_D(ctkErrorLogWidget);
  171. if (!this->errorLogModel())
  172. {
  173. return;
  174. }
  175. this->errorLogModel()->filterEntry(d->InfoButtonFilter, /* disableFilter= */ !visibility);
  176. }
  177. // --------------------------------------------------------------------------
  178. void ctkErrorLogWidget::setUnknownEntriesVisible(bool visibility)
  179. {
  180. if (!this->errorLogModel())
  181. {
  182. return;
  183. }
  184. this->errorLogModel()->filterEntry(ctkErrorLogLevel::Unknown,
  185. /* disableFilter= */ !visibility);
  186. }
  187. // --------------------------------------------------------------------------
  188. void ctkErrorLogWidget::onRowsInserted(const QModelIndex &/*parent*/, int /*first*/, int /*last*/)
  189. {
  190. Q_D(ctkErrorLogWidget);
  191. if (d->ErrorLogTableView->model()->rowCount() == 1)
  192. {
  193. // For performance reason, resize first column only when first entry is added
  194. d->ErrorLogTableView->resizeColumnToContents(ctkErrorLogModel::TimeColumn);
  195. }
  196. }
  197. // --------------------------------------------------------------------------
  198. void ctkErrorLogWidget::onLogLevelFilterChanged()
  199. {
  200. Q_D(ctkErrorLogWidget);
  201. Q_ASSERT(this->errorLogModel());
  202. ctkErrorLogLevel::LogLevels logLevelFilter = this->errorLogModel()->logLevelFilter();
  203. d->ShowErrorEntryButton->setChecked(logLevelFilter & d->ErrorButtonFilter);
  204. d->ShowWarningEntryButton->setChecked(logLevelFilter & d->WarningButtonFilter);
  205. d->ShowInfoEntryButton->setChecked(logLevelFilter & d->InfoButtonFilter);
  206. }
  207. // --------------------------------------------------------------------------
  208. void ctkErrorLogWidget::removeEntries()
  209. {
  210. Q_ASSERT(this->errorLogModel());
  211. this->errorLogModel()->clear();
  212. }
  213. // --------------------------------------------------------------------------
  214. void ctkErrorLogWidget::onSelectionChanged(const QItemSelection & selected,
  215. const QItemSelection & deselected)
  216. {
  217. // QTime start = QTime::currentTime();
  218. Q_D(ctkErrorLogWidget);
  219. Q_UNUSED(selected);
  220. Q_UNUSED(deselected);
  221. QModelIndexList selectedRows =
  222. d->SelectionModel->selectedRows(ctkErrorLogModel::DescriptionColumn);
  223. qSort(selectedRows.begin(), selectedRows.end());
  224. QStringList descriptions;
  225. foreach(const QModelIndex& index, selectedRows)
  226. {
  227. descriptions << index.data(ctkErrorLogModel::DescriptionTextRole).toString();
  228. }
  229. d->ErrorLogDescription->setText(descriptions.join("\n"));
  230. // fprintf(stdout, "onSelectionChanged: %d\n", start.msecsTo(QTime::currentTime()));
  231. }