ctkCheckableModelHelper.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  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.commontk.org/LICENSE
  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 <QAbstractItemModel>
  16. #include <QApplication>
  17. #include <QDebug>
  18. #include <QStandardItemModel>
  19. // CTK includes
  20. #include "ctkCheckableModelHelper.h"
  21. //-----------------------------------------------------------------------------
  22. class ctkCheckableModelHelperPrivate
  23. {
  24. Q_DECLARE_PUBLIC(ctkCheckableModelHelper);
  25. protected:
  26. ctkCheckableModelHelper* const q_ptr;
  27. public:
  28. ctkCheckableModelHelperPrivate(ctkCheckableModelHelper& object);
  29. ~ctkCheckableModelHelperPrivate();
  30. void init();
  31. /// Set index checkstate and call propagate
  32. void setIndexCheckState(const QModelIndex& index, Qt::CheckState checkState);
  33. /// Return the depth in the model tree of the index.
  34. /// -1 if the index is the root element a header or a header, 0 if the index
  35. /// is a toplevel index, 1 if its parent is toplevel, 2 if its grandparent is
  36. /// toplevel, etc.
  37. int indexDepth(const QModelIndex& modelIndex)const;
  38. /// Set the checkstate of the index based on its children and grand children
  39. void updateCheckState(const QModelIndex& modelIndex);
  40. /// Set the check state of the index to all its children and grand children
  41. void propagateCheckStateToChildren(const QModelIndex& modelIndex);
  42. Qt::CheckState checkState(const QModelIndex& index, bool *checkable)const;
  43. void setCheckState(const QModelIndex& index, Qt::CheckState newCheckState);
  44. void forceCheckability(const QModelIndex& index);
  45. QAbstractItemModel* Model;
  46. QModelIndex RootIndex;
  47. Qt::Orientation Orientation;
  48. bool HeaderIsUpdating;
  49. bool ItemsAreUpdating;
  50. bool ForceCheckability;
  51. /// 0 means no propagation
  52. /// -1 means unlimited propagation
  53. /// 1 means propagate to top-level indexes
  54. /// 2 means propagate to top-level and their children
  55. /// ...
  56. int PropagateDepth;
  57. Qt::CheckState DefaultCheckState;
  58. };
  59. //----------------------------------------------------------------------------
  60. ctkCheckableModelHelperPrivate::ctkCheckableModelHelperPrivate(ctkCheckableModelHelper& object)
  61. : q_ptr(&object)
  62. {
  63. this->Model = 0;
  64. this->HeaderIsUpdating = false;
  65. this->ItemsAreUpdating = false;
  66. this->ForceCheckability = false;
  67. this->PropagateDepth = -1;
  68. this->DefaultCheckState = Qt::Unchecked;
  69. }
  70. //-----------------------------------------------------------------------------
  71. ctkCheckableModelHelperPrivate::~ctkCheckableModelHelperPrivate()
  72. {
  73. }
  74. //----------------------------------------------------------------------------
  75. void ctkCheckableModelHelperPrivate::init()
  76. {
  77. }
  78. //----------------------------------------------------------------------------
  79. Qt::CheckState ctkCheckableModelHelperPrivate::checkState(
  80. const QModelIndex& index, bool *checkable)const
  81. {
  82. Q_Q(const ctkCheckableModelHelper);
  83. QVariant indexCheckState = index != q->rootIndex() ?
  84. q->model()->data(index, Qt::CheckStateRole):
  85. q->model()->headerData(0, q->orientation(), Qt::CheckStateRole);
  86. return static_cast<Qt::CheckState>(indexCheckState.toInt(checkable));
  87. }
  88. //----------------------------------------------------------------------------
  89. void ctkCheckableModelHelperPrivate::setCheckState(
  90. const QModelIndex& modelIndex, Qt::CheckState newCheckState)
  91. {
  92. Q_Q(ctkCheckableModelHelper);
  93. if (modelIndex != q->rootIndex())
  94. {
  95. q->model()->setData(modelIndex, newCheckState, Qt::CheckStateRole);
  96. }
  97. else
  98. {
  99. q->model()->setHeaderData(0, q->orientation(), newCheckState, Qt::CheckStateRole);
  100. }
  101. }
  102. //----------------------------------------------------------------------------
  103. void ctkCheckableModelHelperPrivate::setIndexCheckState(
  104. const QModelIndex& index, Qt::CheckState checkState)
  105. {
  106. bool checkable = false;
  107. this->checkState(index, &checkable);
  108. if (!checkable && !this->ForceCheckability)
  109. {
  110. // The index is not checkable and we don't want to force checkability
  111. return;
  112. }
  113. this->setCheckState(index, checkState);
  114. this->propagateCheckStateToChildren(index);
  115. }
  116. //-----------------------------------------------------------------------------
  117. int ctkCheckableModelHelperPrivate::indexDepth(const QModelIndex& modelIndex)const
  118. {
  119. int depth = -1;
  120. QModelIndex parentIndex = modelIndex;
  121. while (parentIndex.isValid())
  122. {
  123. ++depth;
  124. parentIndex = parentIndex.parent();
  125. }
  126. return depth;
  127. }
  128. //-----------------------------------------------------------------------------
  129. void ctkCheckableModelHelperPrivate
  130. ::updateCheckState(const QModelIndex& modelIndex)
  131. {
  132. Q_Q(ctkCheckableModelHelper);
  133. bool checkable = false;
  134. int oldCheckState = this->checkState(modelIndex, &checkable);
  135. if (!checkable)
  136. {
  137. return;
  138. }
  139. Qt::CheckState newCheckState = Qt::PartiallyChecked;
  140. bool firstCheckableChild = true;
  141. const int rowCount = q->orientation() == Qt::Horizontal ?
  142. q->model()->rowCount(modelIndex) : 1;
  143. const int columnCount = q->orientation() == Qt::Vertical ?
  144. q->model()->columnCount(modelIndex) : 1;
  145. for (int r = 0; r < rowCount; ++r)
  146. {
  147. for (int c = 0; c < columnCount; ++c)
  148. {
  149. QModelIndex child = q->model()->index(r, c, modelIndex);
  150. QVariant childCheckState = q->model()->data(child, Qt::CheckStateRole);
  151. int childState = childCheckState.toInt(&checkable);
  152. if (!checkable)
  153. {
  154. continue;
  155. }
  156. if (firstCheckableChild)
  157. {
  158. newCheckState = static_cast<Qt::CheckState>(childState);
  159. firstCheckableChild = false;
  160. }
  161. if (newCheckState != childState)
  162. {
  163. newCheckState = Qt::PartiallyChecked;
  164. }
  165. if (newCheckState == Qt::PartiallyChecked)
  166. {
  167. break;
  168. }
  169. }
  170. if (!firstCheckableChild && newCheckState == Qt::PartiallyChecked)
  171. {
  172. break;
  173. }
  174. }
  175. if (oldCheckState == newCheckState)
  176. {
  177. return;
  178. }
  179. this->setCheckState(modelIndex, newCheckState);
  180. if (modelIndex != q->rootIndex())
  181. {
  182. this->updateCheckState(modelIndex.parent());
  183. }
  184. }
  185. //-----------------------------------------------------------------------------
  186. void ctkCheckableModelHelperPrivate
  187. ::propagateCheckStateToChildren(const QModelIndex& modelIndex)
  188. {
  189. Q_Q(ctkCheckableModelHelper);
  190. int indexDepth = this->indexDepth(modelIndex);
  191. if (this->PropagateDepth == 0 ||
  192. !(indexDepth < this->PropagateDepth || this->PropagateDepth == -1))
  193. {
  194. return;
  195. }
  196. bool checkable = false;
  197. Qt::CheckState checkState = this->checkState(modelIndex, &checkable);
  198. if (!checkable || checkState == Qt::PartiallyChecked)
  199. {
  200. return;
  201. }
  202. while (this->ForceCheckability && q->model()->canFetchMore(modelIndex))
  203. {
  204. q->model()->fetchMore(modelIndex);
  205. }
  206. const int rowCount = q->orientation() == Qt::Horizontal ?
  207. q->model()->rowCount(modelIndex) : 1;
  208. const int columnCount = q->orientation() == Qt::Vertical ?
  209. q->model()->columnCount(modelIndex) : 1;
  210. for (int r = 0; r < rowCount; ++r)
  211. {
  212. for (int c = 0; c < columnCount; ++c)
  213. {
  214. QModelIndex child = q->model()->index(r, c, modelIndex);
  215. this->setIndexCheckState(child, checkState);
  216. }
  217. }
  218. }
  219. //-----------------------------------------------------------------------------
  220. void ctkCheckableModelHelperPrivate
  221. ::forceCheckability(const QModelIndex& modelIndex)
  222. {
  223. Q_Q(ctkCheckableModelHelper);
  224. if (!this->ForceCheckability)
  225. {
  226. return;
  227. }
  228. this->setCheckState(modelIndex, this->DefaultCheckState);
  229. if (qobject_cast<QStandardItemModel*>(q->model()))
  230. {
  231. QStandardItem* item = modelIndex != q->rootIndex() ?
  232. qobject_cast<QStandardItemModel*>(q->model())->itemFromIndex(modelIndex) :
  233. (q->orientation() == Qt::Horizontal ?
  234. qobject_cast<QStandardItemModel*>(q->model())->horizontalHeaderItem(0) :
  235. qobject_cast<QStandardItemModel*>(q->model())->verticalHeaderItem(0));
  236. item->setCheckable(true);
  237. }
  238. }
  239. //----------------------------------------------------------------------------
  240. ctkCheckableModelHelper::ctkCheckableModelHelper(
  241. Qt::Orientation orient, QObject* objectParent)
  242. : QObject(objectParent)
  243. , d_ptr(new ctkCheckableModelHelperPrivate(*this))
  244. {
  245. Q_D(ctkCheckableModelHelper);
  246. d->Orientation = orient;
  247. d->init();
  248. }
  249. //-----------------------------------------------------------------------------
  250. ctkCheckableModelHelper::~ctkCheckableModelHelper()
  251. {
  252. }
  253. //-----------------------------------------------------------------------------
  254. Qt::Orientation ctkCheckableModelHelper::orientation()const
  255. {
  256. Q_D(const ctkCheckableModelHelper);
  257. return d->Orientation;
  258. }
  259. //-----------------------------------------------------------------------------
  260. QAbstractItemModel* ctkCheckableModelHelper::model()const
  261. {
  262. Q_D(const ctkCheckableModelHelper);
  263. return d->Model;
  264. }
  265. //-----------------------------------------------------------------------------
  266. void ctkCheckableModelHelper::setModel(QAbstractItemModel *newModel)
  267. {
  268. Q_D(ctkCheckableModelHelper);
  269. QAbstractItemModel *current = this->model();
  270. if (current == newModel)
  271. {
  272. return;
  273. }
  274. if(current)
  275. {
  276. this->disconnect(
  277. current, SIGNAL(headerDataChanged(Qt::Orientation, int, int)),
  278. this, SLOT(onHeaderDataChanged(Qt::Orientation, int, int)));
  279. this->disconnect(
  280. current, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
  281. this, SLOT(onDataChanged(const QModelIndex&, const QModelIndex&)));
  282. this->disconnect(
  283. current, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
  284. this, SLOT(onColumnsInserted(const QModelIndex &, int, int)));
  285. this->disconnect(
  286. current, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
  287. this, SLOT(onRowsInserted(const QModelIndex &, int, int)));
  288. }
  289. d->Model = newModel;
  290. if(newModel)
  291. {
  292. this->connect(
  293. newModel, SIGNAL(headerDataChanged(Qt::Orientation, int, int)),
  294. this, SLOT(onHeaderDataChanged(Qt::Orientation, int, int)));
  295. if (d->PropagateDepth != 0)
  296. {
  297. this->connect(
  298. newModel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
  299. this, SLOT(onDataChanged(const QModelIndex&, const QModelIndex&)));
  300. }
  301. this->connect(
  302. newModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
  303. this, SLOT(onColumnsInserted(const QModelIndex &, int, int)));
  304. this->connect(
  305. newModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
  306. this, SLOT(onRowsInserted(const QModelIndex &, int, int)));
  307. if (d->ForceCheckability)
  308. {
  309. foreach(QModelIndex index, newModel->match(newModel->index(0,0), Qt::CheckStateRole, QVariant(), -1,Qt::MatchRecursive))
  310. {
  311. d->forceCheckability(index);
  312. }
  313. d->forceCheckability(this->rootIndex());
  314. }
  315. this->updateHeadersFromItems();
  316. }
  317. }
  318. //-----------------------------------------------------------------------------
  319. QModelIndex ctkCheckableModelHelper::rootIndex()const
  320. {
  321. Q_D(const ctkCheckableModelHelper);
  322. return d->RootIndex;
  323. }
  324. //-----------------------------------------------------------------------------
  325. void ctkCheckableModelHelper::setRootIndex(const QModelIndex &index)
  326. {
  327. Q_D(ctkCheckableModelHelper);
  328. d->RootIndex = index;
  329. if (d->PropagateDepth != 0)
  330. {
  331. this->updateHeadersFromItems();
  332. }
  333. }
  334. //-----------------------------------------------------------------------------
  335. void ctkCheckableModelHelper::setPropagateDepth(int depth)
  336. {
  337. Q_D(ctkCheckableModelHelper);
  338. if (d->PropagateDepth == depth)
  339. {
  340. return;
  341. }
  342. d->PropagateDepth = depth;
  343. if (!this->model())
  344. {
  345. return;
  346. }
  347. if (depth != 0)
  348. {
  349. this->connect(
  350. this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
  351. this, SLOT(onDataChanged(const QModelIndex&, const QModelIndex&)), Qt::UniqueConnection);
  352. this->updateHeadersFromItems();
  353. }
  354. else
  355. {
  356. this->disconnect(
  357. this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
  358. this, SLOT(onDataChanged(const QModelIndex&, const QModelIndex&)));
  359. }
  360. }
  361. //-----------------------------------------------------------------------------
  362. int ctkCheckableModelHelper::propagateDepth()const
  363. {
  364. Q_D(const ctkCheckableModelHelper);
  365. return d->PropagateDepth;
  366. }
  367. //-----------------------------------------------------------------------------
  368. void ctkCheckableModelHelper::setForceCheckability(bool force)
  369. {
  370. Q_D(ctkCheckableModelHelper);
  371. if (d->ForceCheckability == force)
  372. {
  373. return;
  374. }
  375. d->ForceCheckability = force;
  376. if (this->model())
  377. {
  378. d->propagateCheckStateToChildren(this->rootIndex());
  379. }
  380. }
  381. //-----------------------------------------------------------------------------
  382. bool ctkCheckableModelHelper::forceCheckability()const
  383. {
  384. Q_D(const ctkCheckableModelHelper);
  385. return d->ForceCheckability;
  386. }
  387. //-----------------------------------------------------------------------------
  388. void ctkCheckableModelHelper::setDefaultCheckState(Qt::CheckState defaultCheckState)
  389. {
  390. Q_D(ctkCheckableModelHelper);
  391. d->DefaultCheckState = defaultCheckState;
  392. }
  393. //-----------------------------------------------------------------------------
  394. Qt::CheckState ctkCheckableModelHelper::defaultCheckState()const
  395. {
  396. Q_D(const ctkCheckableModelHelper);
  397. return d->DefaultCheckState;
  398. }
  399. //-----------------------------------------------------------------------------
  400. void ctkCheckableModelHelper::setHeaderCheckState(int section, Qt::CheckState checkState)
  401. {
  402. QAbstractItemModel *current = this->model();
  403. if(current == 0)
  404. {
  405. return;
  406. }
  407. current->setHeaderData(section, this->orientation(),
  408. checkState, Qt::CheckStateRole);
  409. }
  410. //-----------------------------------------------------------------------------
  411. void ctkCheckableModelHelper::setCheckState(const QModelIndex& index, Qt::CheckState checkState)
  412. {
  413. QAbstractItemModel *current = this->model();
  414. if(current == 0)
  415. {
  416. return;
  417. }
  418. current->setData(index, checkState, Qt::CheckStateRole);
  419. }
  420. //-----------------------------------------------------------------------------
  421. void ctkCheckableModelHelper::toggleCheckState(const QModelIndex& modelIndex)
  422. {
  423. // If the section is checkable, toggle the check state.
  424. if(!this->isCheckable(modelIndex))
  425. {
  426. return;
  427. }
  428. // I've no strong feeling to turn the state checked or unchecked when the
  429. // state is PartiallyChecked.
  430. this->setCheckState(modelIndex,
  431. this->checkState(modelIndex) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
  432. }
  433. //-----------------------------------------------------------------------------
  434. void ctkCheckableModelHelper::toggleHeaderCheckState(int section)
  435. {
  436. // If the section is checkable, toggle the check state.
  437. if(!this->isHeaderCheckable(section))
  438. {
  439. return;
  440. }
  441. // I've no strong feeling to turn the state checked or unchecked when the
  442. // state is PartiallyChecked.
  443. this->setHeaderCheckState(section,
  444. this->headerCheckState(section) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
  445. }
  446. //-----------------------------------------------------------------------------
  447. void ctkCheckableModelHelper::onHeaderDataChanged(Qt::Orientation orient,
  448. int firstSection,
  449. int lastSection)
  450. {
  451. Q_D(ctkCheckableModelHelper);
  452. Q_UNUSED(firstSection);
  453. Q_UNUSED(lastSection);
  454. if(orient != this->orientation())
  455. {
  456. return;
  457. }
  458. bool oldItemsAreUpdating = d->ItemsAreUpdating;
  459. if (!d->ItemsAreUpdating)
  460. {
  461. d->ItemsAreUpdating = true;
  462. d->propagateCheckStateToChildren(this->rootIndex());
  463. }
  464. d->ItemsAreUpdating = oldItemsAreUpdating;
  465. }
  466. //-----------------------------------------------------------------------------
  467. void ctkCheckableModelHelper::updateHeadersFromItems()
  468. {
  469. Q_D(ctkCheckableModelHelper);
  470. QAbstractItemModel *currentModel = this->model();
  471. if (!currentModel)
  472. {
  473. return;
  474. }
  475. d->updateCheckState(QModelIndex());
  476. }
  477. //-----------------------------------------------------------------------------
  478. void ctkCheckableModelHelper::onDataChanged(const QModelIndex & topLeft,
  479. const QModelIndex & bottomRight)
  480. {
  481. Q_UNUSED(bottomRight);
  482. Q_D(ctkCheckableModelHelper);
  483. if(d->ItemsAreUpdating || d->PropagateDepth == 0)
  484. {
  485. return;
  486. }
  487. bool checkable = false;
  488. d->checkState(topLeft, &checkable);
  489. if (!checkable)
  490. {
  491. return;
  492. }
  493. d->ItemsAreUpdating = true;
  494. // TODO: handle topLeft "TO bottomRight"
  495. d->propagateCheckStateToChildren(topLeft);
  496. d->updateCheckState(topLeft.parent());
  497. d->ItemsAreUpdating = false;
  498. }
  499. //-----------------------------------------------------------------------------
  500. void ctkCheckableModelHelper::onColumnsInserted(const QModelIndex &parentIndex,
  501. int start, int end)
  502. {
  503. Q_D(ctkCheckableModelHelper);
  504. if (this->orientation() == Qt::Horizontal)
  505. {
  506. if (start == 0)
  507. {
  508. this->updateHeadersFromItems();
  509. }
  510. }
  511. else
  512. {
  513. if (d->ForceCheckability)
  514. {
  515. for (int i = start; i <= end; ++i)
  516. {
  517. QModelIndex index = this->model()->index(0, i, parentIndex);
  518. d->forceCheckability(index);
  519. }
  520. }
  521. this->onDataChanged(this->model()->index(0, start, parentIndex),
  522. this->model()->index(0, end, parentIndex));
  523. }
  524. }
  525. //-----------------------------------------------------------------------------
  526. void ctkCheckableModelHelper::onRowsInserted(const QModelIndex &parentIndex,
  527. int start, int end)
  528. {
  529. Q_D(ctkCheckableModelHelper);
  530. if (this->orientation() == Qt::Vertical)
  531. {
  532. if (start == 0)
  533. {
  534. this->updateHeadersFromItems();
  535. }
  536. }
  537. else
  538. {
  539. if (d->ForceCheckability)
  540. {
  541. for (int i = start; i <= end; ++i)
  542. {
  543. QModelIndex index = this->model()->index(i, 0, parentIndex);
  544. d->forceCheckability(index);
  545. }
  546. }
  547. this->onDataChanged(this->model()->index(start, 0, parentIndex),
  548. this->model()->index(end, 0, parentIndex));
  549. }
  550. }
  551. //-----------------------------------------------------------------------------
  552. bool ctkCheckableModelHelper::isHeaderCheckable(int section)const
  553. {
  554. return !this->model()->headerData(section, this->orientation(), Qt::CheckStateRole).isNull();
  555. }
  556. //-----------------------------------------------------------------------------
  557. bool ctkCheckableModelHelper::isCheckable(const QModelIndex& index)const
  558. {
  559. return !this->model()->data(index, Qt::CheckStateRole).isNull();
  560. }
  561. //-----------------------------------------------------------------------------
  562. Qt::CheckState ctkCheckableModelHelper::headerCheckState(int section)const
  563. {
  564. return static_cast<Qt::CheckState>(
  565. this->model()->headerData(section, this->orientation(), Qt::CheckStateRole).toInt());
  566. }
  567. //-----------------------------------------------------------------------------
  568. Qt::CheckState ctkCheckableModelHelper::checkState(const QModelIndex& index)const
  569. {
  570. return static_cast<Qt::CheckState>(
  571. this->model()->data(index, Qt::CheckStateRole).toInt());
  572. }
  573. //-----------------------------------------------------------------------------
  574. bool ctkCheckableModelHelper::headerCheckState(int section, Qt::CheckState& checkState)const
  575. {
  576. bool checkable = false;
  577. checkState = static_cast<Qt::CheckState>(
  578. this->model()->headerData(section, this->orientation(), Qt::CheckStateRole).toInt(&checkable));
  579. return checkable;
  580. }
  581. //-----------------------------------------------------------------------------
  582. bool ctkCheckableModelHelper::checkState(const QModelIndex& index, Qt::CheckState& checkState)const
  583. {
  584. bool checkable = false;
  585. checkState = static_cast<Qt::CheckState>(
  586. this->model()->data(index, Qt::CheckStateRole).toInt(&checkable));
  587. return checkable;
  588. }