Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
QmitkPatientTableHeaderView.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 // semantic relations UI module
15 
16 // qt
17 #include <QPainter>
18 #include <QSize>
19 
21  : QHeaderView(Qt::Horizontal, parent)
22  , m_HeaderModel(nullptr)
23 {
24  // nothing here
25 }
26 
28 {
29  // nothing here
30 }
31 
32 void QmitkPatientTableHeaderView::setModel(QAbstractItemModel* model)
33 {
34  // retrieve the header model from the given table model
35  QVariant variant = model->data(QModelIndex(), HorizontalHeaderDataRole);
36  if (variant.isValid() && variant.canConvert<QStandardItemModel*>())
37  {
38  m_HeaderModel = variant.value<QStandardItemModel*>();
39  }
40 
41  QHeaderView::setModel(model);
42 }
43 
44 void QmitkPatientTableHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const
45 {
46  if (rect.isValid())
47  {
48  int top = rect.y();
49 
50  QModelIndex leafIndex = HeaderIndex(logicalIndex);
51  QModelIndexList indexes = ParentIndexList(leafIndex);
52  for (const auto& index : indexes)
53  {
54  top = PaintHeader(painter, index, logicalIndex, rect, top);
55  }
56 
57  return;
58  }
59 
60  QHeaderView::paintSection(painter, rect, logicalIndex);
61 }
62 
64 {
65  if (nullptr != m_HeaderModel)
66  {
67  QModelIndex headerIndex = HeaderIndex(logicalIndex);
68  if (headerIndex.isValid())
69  {
70  QSize headerSize = HeaderSize(headerIndex);
71  headerIndex = headerIndex.parent();
72  while (headerIndex.isValid())
73  {
74  QSize currentHeaderSize = HeaderSize(headerIndex);
75  headerSize.rheight() += currentHeaderSize.height();
76  if (currentHeaderSize.width() > headerSize.width())
77  {
78  headerSize.rwidth() = currentHeaderSize.width();
79  }
80 
81  headerIndex = headerIndex.parent();
82  }
83  return headerSize;
84  }
85  }
86 
87  return QHeaderView::sectionSizeFromContents(logicalIndex);
88 }
89 
90 int QmitkPatientTableHeaderView::PaintHeader(QPainter* painter, const QModelIndex& currentIndex, int logicalIndex, const QRect& sectionRect, int top) const
91 {
92  QModelIndex headerIndex = HeaderIndex(logicalIndex);
93  int height = HeaderSize(currentIndex).height();
94  if (currentIndex == headerIndex)
95  {
96  height = sectionRect.height() - top;
97  }
98  int left = CurrentHeaderLeft(currentIndex, headerIndex, logicalIndex, sectionRect.left());
99  int width = CurrentHeaderWidth(currentIndex, headerIndex, logicalIndex);
100 
101  QStyleOptionHeader headerStyleOptions;
102  initStyleOption(&headerStyleOptions);
103  headerStyleOptions.text = currentIndex.data(Qt::DisplayRole).toString();
104  headerStyleOptions.textAlignment = Qt::AlignCenter;
105  painter->save();
106 
107  QRect rect(left, top, width, height);
108  headerStyleOptions.rect = rect;
109  style()->drawControl(QStyle::CE_Header, &headerStyleOptions, painter, this);
110  painter->restore();
111 
112  return top + height;
113 }
114 
115 QSize QmitkPatientTableHeaderView::HeaderSize(const QModelIndex& index) const
116 {
117  QFont font = this->font();
118  font.setBold(true);
119  QFontMetrics fontMetrics(font);
120  QSize fontSize = fontMetrics.size(0, index.data(Qt::DisplayRole).toString());
121  QSize emptyFontSize = fontMetrics.size(0, "");
122 
123  return fontSize + emptyFontSize;
124 }
125 
126 int QmitkPatientTableHeaderView::CurrentHeaderLeft(const QModelIndex& currentIndex, const QModelIndex& headerIndex, int sectionIndex, int left) const
127 {
128  QModelIndexList headerList = ListHeader(currentIndex);
129  if (!headerList.empty())
130  {
131  int index = headerList.indexOf(headerIndex);
132  int firstHeaderSectionIndex = sectionIndex - index;
133  --index;
134  for (; index >= 0; --index)
135  {
136  left -= sectionSize(firstHeaderSectionIndex + index);
137  }
138  }
139 
140  return left;
141 }
142 
143 int QmitkPatientTableHeaderView::CurrentHeaderWidth(const QModelIndex& currentIndex, const QModelIndex& headerIndex, int sectionIndex) const
144 {
145  QModelIndexList headerList = ListHeader(currentIndex);
146  if (headerList.empty())
147  {
148  return sectionSize(sectionIndex);
149  }
150 
151  int width = 0;
152  int index = headerList.indexOf(headerIndex);
153  int firstHeaderSectionIndex = sectionIndex - index;
154  for (int i = 0; i < headerList.size(); ++i)
155  {
156  width += sectionSize(firstHeaderSectionIndex + i);
157  }
158 
159  return width;
160 }
161 
162 QModelIndexList QmitkPatientTableHeaderView::ParentIndexList(QModelIndex index) const
163 {
164  QModelIndexList indexList;
165  while (index.isValid())
166  {
167  indexList.push_front(index);
168  index = index.parent();
169  }
170 
171  return indexList;
172 }
173 
174 QModelIndex QmitkPatientTableHeaderView::HeaderIndex(int sectionIndex) const
175 {
176  if (nullptr != m_HeaderModel)
177  {
178  int currentHeaderIndex = -1;
179  for (int i = 0; i < m_HeaderModel->columnCount(); ++i)
180  {
181  QModelIndex modelIndex = FindHeader(m_HeaderModel->index(0, i), sectionIndex, currentHeaderIndex);
182  if (modelIndex.isValid())
183  {
184  return modelIndex;
185  }
186  }
187  }
188 
189  return QModelIndex();
190 }
191 
192 QModelIndex QmitkPatientTableHeaderView::FindHeader(const QModelIndex& currentIndex, int sectionIndex, int& currentHeaderIndex) const
193 {
194  if (currentIndex.isValid())
195  {
196  int childCount = currentIndex.model()->columnCount(currentIndex);
197  if (childCount > 0)
198  {
199  for (int i = 0; i < childCount; ++i)
200  {
201  QModelIndex modelIndex = FindHeader(currentIndex.child(0, i), sectionIndex, currentHeaderIndex);
202  if (modelIndex.isValid())
203  {
204  return modelIndex;
205  }
206  }
207  }
208  else
209  {
210  ++currentHeaderIndex;
211  if (currentHeaderIndex == sectionIndex)
212  {
213  return currentIndex;
214  }
215  }
216  }
217 
218  return QModelIndex();
219 }
220 
221 QModelIndexList QmitkPatientTableHeaderView::ListHeader(const QModelIndex& currentIndex) const
222 {
223  QModelIndexList headerList;
224  if (currentIndex.isValid())
225  {
226  int childCount = currentIndex.model()->columnCount(currentIndex);
227  if (childCount > 0)
228  {
229  for (int i = 0; i < childCount; ++i)
230  {
231  headerList += ListHeader(currentIndex.child(0, i));
232  }
233  }
234  else
235  {
236  headerList.push_back(currentIndex);
237  }
238  }
239  return headerList;
240 }
QmitkPatientTableHeaderView(QWidget *parent=nullptr)
QSize sectionSizeFromContents(int logicalIndex) const override
Get the section size by retrieving the text content. The section size is dependent on the child and p...
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override
Paint each header using &#39;PaintHeader&#39;. This function is overwritten from QHeaderView.
void setModel(QAbstractItemModel *model) override
Set the model of the table view of this header view. This model returns a standard item model for the...