QCMakeCacheView.cxx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "QCMakeCacheView.h"
  14. #include <QToolButton>
  15. #include <QFileDialog>
  16. #include <QHBoxLayout>
  17. #include <QHeaderView>
  18. #include <QEvent>
  19. QCMakeCacheView::QCMakeCacheView(QWidget* p)
  20. : QTableView(p), Init(false)
  21. {
  22. QCMakeCacheModel* m = new QCMakeCacheModel(this);
  23. this->setModel(m);
  24. this->horizontalHeader()->setStretchLastSection(true);
  25. this->verticalHeader()->hide();
  26. QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this);
  27. this->setItemDelegate(delegate);
  28. }
  29. void QCMakeCacheView::showEvent(QShowEvent* e)
  30. {
  31. if(!this->Init)
  32. {
  33. // initialize the table view column size
  34. int colWidth = this->columnWidth(0) + this->columnWidth(1);
  35. this->setColumnWidth(0, colWidth/2);
  36. this->setColumnWidth(1, colWidth/2);
  37. this->Init = true;
  38. }
  39. return QTableView::showEvent(e);
  40. }
  41. QCMakeCacheModel* QCMakeCacheView::cacheModel() const
  42. {
  43. return qobject_cast<QCMakeCacheModel*>(this->model());
  44. }
  45. QModelIndex QCMakeCacheView::moveCursor(CursorAction act,
  46. Qt::KeyboardModifiers mod)
  47. {
  48. // tab through values only (not names)
  49. QModelIndex current = this->currentIndex();
  50. if(act == MoveNext)
  51. {
  52. if(!current.isValid())
  53. {
  54. return this->model()->index(0, 1);
  55. }
  56. else if(current.column() == 0)
  57. {
  58. return this->model()->index(current.row(), 1);
  59. }
  60. else
  61. {
  62. return this->model()->index(current.row()+1, 1);
  63. }
  64. }
  65. else if(act == MovePrevious)
  66. {
  67. if(!current.isValid())
  68. {
  69. return this->model()->index(0, 1);
  70. }
  71. else
  72. {
  73. return this->model()->index(current.row()-1, 1);
  74. }
  75. }
  76. return QTableView::moveCursor(act, mod);
  77. }
  78. QCMakeCacheModel::QCMakeCacheModel(QObject* p)
  79. : QAbstractTableModel(p), NewCount(0), IsDirty(false)
  80. {
  81. }
  82. QCMakeCacheModel::~QCMakeCacheModel()
  83. {
  84. }
  85. bool QCMakeCacheModel::isDirty() const
  86. {
  87. return this->IsDirty;
  88. }
  89. static uint qHash(const QCMakeCacheProperty& p)
  90. {
  91. return qHash(p.Key);
  92. }
  93. void QCMakeCacheModel::setProperties(const QCMakeCachePropertyList& props)
  94. {
  95. QSet<QCMakeCacheProperty> newProps = props.toSet();
  96. QSet<QCMakeCacheProperty> oldProps = this->Properties.toSet();
  97. oldProps.intersect(newProps);
  98. newProps.subtract(oldProps);
  99. this->NewCount = newProps.count();
  100. this->Properties.clear();
  101. this->Properties = newProps.toList();
  102. qSort(this->Properties);
  103. QCMakeCachePropertyList tmp = oldProps.toList();
  104. qSort(tmp);
  105. this->Properties += tmp;
  106. this->reset();
  107. this->IsDirty = false;
  108. }
  109. QCMakeCachePropertyList QCMakeCacheModel::properties() const
  110. {
  111. return this->Properties;
  112. }
  113. int QCMakeCacheModel::columnCount (const QModelIndex& /*parent*/ ) const
  114. {
  115. return 2;
  116. }
  117. QVariant QCMakeCacheModel::data (const QModelIndex& index, int role) const
  118. {
  119. if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
  120. {
  121. return this->Properties[index.row()].Key;
  122. }
  123. else if(index.column() == 0 && role == Qt::ToolTipRole)
  124. {
  125. return this->data(index, Qt::DisplayRole).toString() + "\n" +
  126. this->data(index, QCMakeCacheModel::HelpRole).toString();
  127. }
  128. else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
  129. {
  130. if(this->Properties[index.row()].Type != QCMakeCacheProperty::BOOL)
  131. {
  132. return this->Properties[index.row()].Value;
  133. }
  134. }
  135. else if(index.column() == 1 && role == Qt::CheckStateRole)
  136. {
  137. if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
  138. {
  139. return this->Properties[index.row()].Value.toBool() ? Qt::Checked : Qt::Unchecked;
  140. }
  141. }
  142. else if(role == QCMakeCacheModel::HelpRole)
  143. {
  144. return this->Properties[index.row()].Help;
  145. }
  146. else if(role == QCMakeCacheModel::TypeRole)
  147. {
  148. return this->Properties[index.row()].Type;
  149. }
  150. else if(role == QCMakeCacheModel::AdvancedRole)
  151. {
  152. return this->Properties[index.row()].Advanced;
  153. }
  154. else if(role == Qt::BackgroundRole && index.row()+1 <= this->NewCount)
  155. {
  156. return QBrush(QColor(255,100,100));
  157. }
  158. return QVariant();
  159. }
  160. QModelIndex QCMakeCacheModel::parent (const QModelIndex& /*index*/) const
  161. {
  162. return QModelIndex();
  163. }
  164. int QCMakeCacheModel::rowCount (const QModelIndex& parent) const
  165. {
  166. if(parent.isValid())
  167. {
  168. return 0;
  169. }
  170. return this->Properties.count();
  171. }
  172. QVariant QCMakeCacheModel::headerData (int section, Qt::Orientation orient, int role) const
  173. {
  174. // return header labels
  175. if(role == Qt::DisplayRole && orient == Qt::Horizontal)
  176. {
  177. return section == 0 ? "Name" : "Value";
  178. }
  179. return QVariant();
  180. }
  181. Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& index) const
  182. {
  183. Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
  184. // all column 1's are editable
  185. if(index.column() == 1)
  186. {
  187. f |= Qt::ItemIsEditable;
  188. // booleans are editable in place
  189. if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
  190. {
  191. f |= Qt::ItemIsUserCheckable;
  192. }
  193. }
  194. return f;
  195. }
  196. bool QCMakeCacheModel::setData (const QModelIndex& index, const QVariant& value, int role)
  197. {
  198. if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
  199. {
  200. this->Properties[index.row()].Key = value.toString();
  201. this->IsDirty = true;
  202. emit this->dataChanged(index, index);
  203. }
  204. else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
  205. {
  206. this->Properties[index.row()].Value = value.toString();
  207. this->IsDirty = true;
  208. emit this->dataChanged(index, index);
  209. }
  210. else if(index.column() == 1 && (role == Qt::CheckStateRole))
  211. {
  212. this->Properties[index.row()].Value = value.toInt() == Qt::Checked;
  213. this->IsDirty = true;
  214. emit this->dataChanged(index, index);
  215. }
  216. return false;
  217. }
  218. QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
  219. : QItemDelegate(p)
  220. {
  221. }
  222. QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* parent,
  223. const QStyleOptionViewItem&, const QModelIndex& index) const
  224. {
  225. QVariant type = index.data(QCMakeCacheModel::TypeRole);
  226. if(type == QCMakeCacheProperty::BOOL)
  227. {
  228. return NULL;
  229. }
  230. else if(type == QCMakeCacheProperty::PATH)
  231. {
  232. return new QCMakeCachePathEditor(index.data().toString(), false, parent);
  233. }
  234. else if(type == QCMakeCacheProperty::FILEPATH)
  235. {
  236. return new QCMakeCachePathEditor(index.data().toString(), true, parent);
  237. }
  238. return new QLineEdit(parent);
  239. }
  240. QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp, QWidget* p)
  241. : QWidget(p), LineEdit(this), IsFilePath(fp)
  242. {
  243. QHBoxLayout* l = new QHBoxLayout(this);
  244. l->setMargin(0);
  245. l->setSpacing(0);
  246. l->addWidget(&this->LineEdit);
  247. QToolButton* tb = new QToolButton(this);
  248. tb->setText("...");
  249. l->addWidget(tb);
  250. QObject::connect(tb, SIGNAL(clicked(bool)),
  251. this, SLOT(chooseFile()));
  252. this->LineEdit.setText(file);
  253. tb->setFocusProxy(&this->LineEdit);
  254. this->setFocusProxy(&this->LineEdit);
  255. }
  256. void QCMakeCachePathEditor::chooseFile()
  257. {
  258. QString path;
  259. if(this->IsFilePath)
  260. {
  261. path = QFileDialog::getOpenFileName(this, "TODO");
  262. }
  263. else
  264. {
  265. path = QFileDialog::getExistingDirectory(this, "TODO", this->value());
  266. }
  267. if(!path.isEmpty())
  268. {
  269. this->LineEdit.setText(path);
  270. }
  271. }