ctkAddRemoveComboBox.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. All rights reserved.
  5. Distributed under a BSD License. See LICENSE.txt file.
  6. This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
  7. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the above copyright notice for more information.
  9. =========================================================================*/
  10. // Qt includes
  11. #include <QDebug>
  12. // CTK includes
  13. #include <ctkPimpl.h>
  14. #include "ctkAddRemoveComboBox.h"
  15. #include "ui_ctkAddRemoveComboBox.h"
  16. //-----------------------------------------------------------------------------
  17. class ctkAddRemoveComboBoxPrivate : public ctkPrivate<ctkAddRemoveComboBox>,
  18. public Ui_ctkAddRemoveComboBox
  19. {
  20. public:
  21. ctkAddRemoveComboBoxPrivate();
  22. ///
  23. /// Insert 'None' item
  24. /// Note: Also make sure that no signal is emitted while the item is inserted
  25. /// That function doesn't prevent from inserting multiple time the 'None' item
  26. void insertEmptyItem();
  27. void connectComboBox(QComboBox* combobox);
  28. public:
  29. /// Empty item
  30. QString EmptyText;
  31. /// Set to true when inserting the 'None' item.
  32. /// Will prevent the itemAdded signal from being sent
  33. bool AddingEmptyItem;
  34. /// Set to true when removing the 'None' item.
  35. /// Will prevent the itemRemoved signal from being sent
  36. bool RemovingEmptyItem;
  37. /// Actions state
  38. bool AddEnabled;
  39. bool RemoveEnabled;
  40. bool EditEnabled;
  41. /// If true, it means there is no item beside of the 'None' one
  42. bool HasEmptyItem;
  43. };
  44. // --------------------------------------------------------------------------
  45. // ctkAddRemoveComboBoxPrivate methods
  46. // --------------------------------------------------------------------------
  47. ctkAddRemoveComboBoxPrivate::ctkAddRemoveComboBoxPrivate()
  48. {
  49. this->EmptyText = "None";
  50. this->AddingEmptyItem = false;
  51. this->RemovingEmptyItem = false;
  52. this->AddEnabled = true;
  53. this->RemoveEnabled = true;
  54. this->EditEnabled = true;
  55. this->HasEmptyItem = false;
  56. }
  57. // --------------------------------------------------------------------------
  58. void ctkAddRemoveComboBoxPrivate::insertEmptyItem()
  59. {
  60. if (!this->HasEmptyItem )
  61. {
  62. this->AddingEmptyItem = true;
  63. this->ComboBox->insertItem(0, this->EmptyText);
  64. this->AddingEmptyItem = false;
  65. this->HasEmptyItem = true;
  66. }
  67. }
  68. // --------------------------------------------------------------------------
  69. void ctkAddRemoveComboBoxPrivate::connectComboBox(QComboBox* comboBox)
  70. {
  71. CTK_P(ctkAddRemoveComboBox);
  72. QObject::connect(comboBox, SIGNAL(activated(int)),
  73. p, SIGNAL(activated(int)));
  74. QObject::connect(comboBox, SIGNAL(currentIndexChanged(int)),
  75. p, SIGNAL(currentIndexChanged(int)));
  76. /*
  77. this->connect(ctk_d()->ComboBox->model(),
  78. SIGNAL(rowsAboutToBeInserted(const QModelIndex & _parent, int start, int end )),
  79. SLOT(onRowsAboutToBeInserted(const QModelIndex & _parent, int start, int end )));
  80. */
  81. QObject::connect(comboBox->model(),
  82. SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
  83. p, SLOT(onRowsAboutToBeRemoved(const QModelIndex & , int , int )));
  84. QObject::connect(comboBox->model(),
  85. SIGNAL(rowsInserted(const QModelIndex &, int, int )),
  86. p, SLOT(onRowsInserted(const QModelIndex &, int, int)));
  87. QObject::connect(comboBox->model(),
  88. SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
  89. p, SLOT(onRowsRemoved(const QModelIndex &, int, int )));
  90. }
  91. // --------------------------------------------------------------------------
  92. // ctkAddRemoveComboBox methods
  93. // --------------------------------------------------------------------------
  94. ctkAddRemoveComboBox::ctkAddRemoveComboBox(QWidget* _parent) : Superclass(_parent)
  95. {
  96. CTK_INIT_PRIVATE(ctkAddRemoveComboBox);
  97. CTK_D(ctkAddRemoveComboBox);
  98. d->setupUi(this);
  99. // connect
  100. d->connectComboBox(d->ComboBox);
  101. this->connect(d->AddPushButton, SIGNAL(pressed()), SLOT(onAdd()));
  102. this->connect(d->RemovePushButton, SIGNAL(pressed()), SLOT(onRemove()));
  103. this->connect(d->EditPushButton, SIGNAL(pressed()), SLOT(onEdit()));
  104. // Add default 'empty item'
  105. d->insertEmptyItem();
  106. }
  107. // --------------------------------------------------------------------------
  108. void ctkAddRemoveComboBox::printAdditionalInfo()
  109. {
  110. CTK_D(ctkAddRemoveComboBox);
  111. qDebug() << "ctkAddRemoveComboBox:" << this << endl
  112. << " EmptyText:" << d->EmptyText << endl
  113. << " AddingEmptyItem:" << d->AddingEmptyItem << endl
  114. << " RemovingEmptyItem:" << d->RemovingEmptyItem << endl
  115. << " AddEnabled:" << d->AddEnabled << endl
  116. << " RemoveEnabled:" << d->RemoveEnabled << endl
  117. << " EditEnabled:" << d->EditEnabled << endl
  118. << " HasEmptyItem:" << d->HasEmptyItem;
  119. }
  120. // --------------------------------------------------------------------------
  121. void ctkAddRemoveComboBox::setComboBox(QComboBox* comboBox)
  122. {
  123. CTK_D(ctkAddRemoveComboBox);
  124. if ((comboBox == d->ComboBox) ||
  125. comboBox->count())
  126. {
  127. return;
  128. }
  129. QLayoutItem* oldComboBoxItem = this->layout()->takeAt(0);
  130. QComboBox* oldComboBox = qobject_cast<QComboBox*>(oldComboBoxItem->widget());
  131. comboBox->setSizePolicy(oldComboBox->sizePolicy());
  132. comboBox->setEnabled(this->comboBoxEnabled());
  133. delete oldComboBoxItem;
  134. dynamic_cast<QBoxLayout*>(this->layout())->insertWidget(0, comboBox);
  135. d->connectComboBox(comboBox);
  136. d->ComboBox = comboBox;
  137. delete oldComboBox;
  138. // Add default 'empty item'
  139. d->insertEmptyItem();
  140. }
  141. // --------------------------------------------------------------------------
  142. void ctkAddRemoveComboBox::setEmptyText(const QString& text)
  143. {
  144. CTK_D(ctkAddRemoveComboBox);
  145. if (d->HasEmptyItem)
  146. {
  147. Q_ASSERT(d->ComboBox->count() == 1);
  148. this->setItemText(0, text);
  149. }
  150. d->EmptyText = text;
  151. }
  152. // --------------------------------------------------------------------------
  153. CTK_GET_CXX(ctkAddRemoveComboBox, QString, emptyText, EmptyText);
  154. // --------------------------------------------------------------------------
  155. void ctkAddRemoveComboBox::onRowsInserted(const QModelIndex & _parent, int start, int end)
  156. {
  157. CTK_D(ctkAddRemoveComboBox);
  158. if (_parent != d->ComboBox->rootModelIndex())
  159. {// Rows that are to be added in the model are not displayed by the combobox
  160. return;
  161. }
  162. if (d->HasEmptyItem && !d->AddingEmptyItem)
  163. {
  164. // Remove the Empty item as some real items have been added
  165. d->HasEmptyItem = false;
  166. d->RemovingEmptyItem = true;
  167. d->ComboBox->removeItem(start == 0 ? end + 1 : 0);
  168. d->RemovingEmptyItem = false;
  169. if (d->RemoveEnabled)
  170. {
  171. d->RemovePushButton->setEnabled(true);
  172. }
  173. if (d->EditEnabled)
  174. {
  175. d->EditPushButton->setEnabled(true);
  176. }
  177. // Since we just removed the empty item, we need to shift the start/end items if needed
  178. if (start > 0 )
  179. {
  180. --start;
  181. --end;
  182. }
  183. }
  184. // Emit signal only if the items added is *NOT* the Empty item
  185. if (!d->AddingEmptyItem)
  186. {
  187. for (int i = start; i <= end; ++i)
  188. {
  189. emit this->itemAdded(i);
  190. }
  191. }
  192. }
  193. // --------------------------------------------------------------------------
  194. void ctkAddRemoveComboBox::onRowsAboutToBeRemoved(const QModelIndex & _parent, int start, int end)
  195. {
  196. CTK_D(ctkAddRemoveComboBox);
  197. if (_parent != d->ComboBox->rootModelIndex())
  198. {//rows that are to be added in the model are not displayed by the combobox
  199. return;
  200. }
  201. // if the user try to remove the Empty item, don't send event
  202. if (d->RemovingEmptyItem)
  203. {
  204. return;
  205. }
  206. for (int i = start; i <= end; ++i)
  207. {
  208. emit this->itemAboutToBeRemoved(i);
  209. }
  210. }
  211. // --------------------------------------------------------------------------
  212. void ctkAddRemoveComboBox::onRowsRemoved(const QModelIndex & _parent, int start, int end)
  213. {
  214. CTK_D(ctkAddRemoveComboBox);
  215. if (_parent != d->ComboBox->rootModelIndex())
  216. {//rows that are to be added in the model are not displayed by the combobox
  217. return;
  218. }
  219. // the combobox is now empty, add the EmptyItem if needed
  220. if (d->ComboBox->count() == 0)
  221. {
  222. // Add default 'empty item'
  223. d->insertEmptyItem();
  224. if (d->RemoveEnabled)
  225. {
  226. d->RemovePushButton->setEnabled(false);
  227. }
  228. if (d->EditEnabled)
  229. {
  230. d->EditPushButton->setEnabled(false);
  231. }
  232. }
  233. if (!d->RemovingEmptyItem)
  234. {
  235. for (int i = start; i <= end; ++i)
  236. {
  237. emit this->itemRemoved(i);
  238. }
  239. }
  240. }
  241. // --------------------------------------------------------------------------
  242. void ctkAddRemoveComboBox::setComboBoxEnabled(bool enable)
  243. {
  244. ctk_d()->ComboBox->setEnabled(enable);
  245. }
  246. // --------------------------------------------------------------------------
  247. bool ctkAddRemoveComboBox::comboBoxEnabled()const
  248. {
  249. //const cast as I'm not sure why isEnabledTo doesn't take a const
  250. return ctk_d()->ComboBox->isEnabledTo(const_cast<ctkAddRemoveComboBox*>(this));
  251. }
  252. // --------------------------------------------------------------------------
  253. void ctkAddRemoveComboBox::setAddEnabled(bool enable)
  254. {
  255. CTK_D(ctkAddRemoveComboBox);
  256. d->AddPushButton->setEnabled(enable);
  257. d->AddEnabled = enable;
  258. }
  259. // --------------------------------------------------------------------------
  260. bool ctkAddRemoveComboBox::addEnabled()const
  261. {
  262. return ctk_d()->AddEnabled;
  263. }
  264. // --------------------------------------------------------------------------
  265. void ctkAddRemoveComboBox::setRemoveEnabled(bool enable)
  266. {
  267. CTK_D(ctkAddRemoveComboBox);
  268. if (this->count() > 0)
  269. {
  270. d->RemovePushButton->setEnabled(enable);
  271. }
  272. d->RemoveEnabled = enable;
  273. }
  274. // --------------------------------------------------------------------------
  275. bool ctkAddRemoveComboBox::removeEnabled()const
  276. {
  277. return ctk_d()->RemoveEnabled;
  278. }
  279. // --------------------------------------------------------------------------
  280. void ctkAddRemoveComboBox::setEditEnabled(bool enable)
  281. {
  282. CTK_D(ctkAddRemoveComboBox);
  283. if (this->count() > 0)
  284. {
  285. d->EditPushButton->setEnabled(enable);
  286. }
  287. d->EditEnabled = enable;
  288. }
  289. // --------------------------------------------------------------------------
  290. bool ctkAddRemoveComboBox::editEnabled()const
  291. {
  292. return ctk_d()->EditEnabled;
  293. }
  294. // --------------------------------------------------------------------------
  295. void ctkAddRemoveComboBox::onAdd()
  296. {
  297. }
  298. // --------------------------------------------------------------------------
  299. void ctkAddRemoveComboBox::onRemove()
  300. {
  301. }
  302. // --------------------------------------------------------------------------
  303. void ctkAddRemoveComboBox::onEdit()
  304. {
  305. }
  306. // --------------------------------------------------------------------------
  307. int ctkAddRemoveComboBox::count()const
  308. {
  309. CTK_D(const ctkAddRemoveComboBox);
  310. return (d->HasEmptyItem ? 0 : d->ComboBox->count());
  311. }
  312. // --------------------------------------------------------------------------
  313. CTK_GET_CXX(ctkAddRemoveComboBox, bool, empty, HasEmptyItem);
  314. // --------------------------------------------------------------------------
  315. void ctkAddRemoveComboBox::setCurrentIndex(int index)
  316. {
  317. return ctk_d()->ComboBox->setCurrentIndex(index);
  318. }
  319. // --------------------------------------------------------------------------
  320. void ctkAddRemoveComboBox::insertItem(int index, const QString &text, const QVariant &userDataVariable)
  321. {
  322. //qDebug() << __FUNCTION__ << " " << index << " " << text << " " << userDataVariable ;
  323. ctk_d()->ComboBox->insertItem(index, text, userDataVariable);
  324. }
  325. // --------------------------------------------------------------------------
  326. void ctkAddRemoveComboBox::insertItem(int index, const QIcon &icon, const QString &text, const QVariant &userDataVariable)
  327. {
  328. ctk_d()->ComboBox->insertItem(index, icon, text, userDataVariable);
  329. }
  330. // --------------------------------------------------------------------------
  331. void ctkAddRemoveComboBox::insertItems(int index, const QStringList &texts)
  332. {
  333. ctk_d()->ComboBox->insertItems(index, texts);
  334. }
  335. // --------------------------------------------------------------------------
  336. int ctkAddRemoveComboBox::findText(const QString & text, Qt::MatchFlags flags)const
  337. {
  338. CTK_D(const ctkAddRemoveComboBox);
  339. if (d->HasEmptyItem)
  340. { // if the scene is empty, don't even try to find the text (it could be the
  341. // one of the EmptyText prop.
  342. return -1;
  343. }
  344. return d->ComboBox->findText(text, flags);
  345. }
  346. // --------------------------------------------------------------------------
  347. int ctkAddRemoveComboBox::findData(const QVariant &dataVariable, int role, Qt::MatchFlags flags)const
  348. {
  349. CTK_D(const ctkAddRemoveComboBox);
  350. if (d->HasEmptyItem)
  351. { // if the scene is empty, don't even try to find the dataVariable
  352. return -1;
  353. }
  354. return d->ComboBox->findData(dataVariable, role, flags);
  355. }
  356. // --------------------------------------------------------------------------
  357. QString ctkAddRemoveComboBox::itemText(int index) const
  358. {
  359. CTK_D(const ctkAddRemoveComboBox);
  360. if (d->HasEmptyItem)
  361. {
  362. return QString();
  363. }
  364. return d->ComboBox->itemText(index);
  365. }
  366. // --------------------------------------------------------------------------
  367. QVariant ctkAddRemoveComboBox::itemData(int index, int role) const
  368. {
  369. CTK_D(const ctkAddRemoveComboBox);
  370. if (d->HasEmptyItem)
  371. {
  372. return QVariant();
  373. }
  374. return d->ComboBox->itemData(index,role);
  375. }
  376. // --------------------------------------------------------------------------
  377. void ctkAddRemoveComboBox::setItemText(int index, const QString& text)
  378. {
  379. CTK_D(ctkAddRemoveComboBox);
  380. if (d->HasEmptyItem)
  381. {
  382. return;
  383. }
  384. return d->ComboBox->setItemText(index, text);
  385. }
  386. // --------------------------------------------------------------------------
  387. void ctkAddRemoveComboBox::setItemData(int index, const QVariant& dataVariable, int role)
  388. {
  389. CTK_D(ctkAddRemoveComboBox);
  390. if (d->HasEmptyItem)
  391. {
  392. return;
  393. }
  394. d->ComboBox->setItemData(index, dataVariable, role);
  395. }
  396. // --------------------------------------------------------------------------
  397. int ctkAddRemoveComboBox::currentIndex() const
  398. {
  399. CTK_D(const ctkAddRemoveComboBox);
  400. return d->HasEmptyItem ? -1 : d->ComboBox->currentIndex();
  401. }
  402. // --------------------------------------------------------------------------
  403. void ctkAddRemoveComboBox::removeItem(int index)
  404. {
  405. CTK_D(ctkAddRemoveComboBox);
  406. if (d->HasEmptyItem)
  407. {
  408. return;
  409. }
  410. d->ComboBox->removeItem(index);
  411. }
  412. // --------------------------------------------------------------------------
  413. void ctkAddRemoveComboBox::clear()
  414. {
  415. CTK_D(ctkAddRemoveComboBox);
  416. if (d->HasEmptyItem)
  417. {
  418. return;
  419. }
  420. d->ComboBox->clear();
  421. }
  422. // --------------------------------------------------------------------------
  423. QModelIndex ctkAddRemoveComboBox::rootModelIndex()const
  424. {
  425. return ctk_d()->ComboBox->rootModelIndex();
  426. }
  427. // --------------------------------------------------------------------------
  428. void ctkAddRemoveComboBox::setRootModelIndex(const QModelIndex& root)
  429. {
  430. ctk_d()->ComboBox->setRootModelIndex(root);
  431. }
  432. // --------------------------------------------------------------------------
  433. int ctkAddRemoveComboBox::modelColumn()const
  434. {
  435. return ctk_d()->ComboBox->modelColumn();
  436. }
  437. // --------------------------------------------------------------------------
  438. QAbstractItemModel* ctkAddRemoveComboBox::model()const
  439. {
  440. return ctk_d()->ComboBox->model();
  441. }