3 #include "TreeViewContent.h" 12 #include <QPaintEvent> 15 #include <QtCore/qtextstream.h> 17 #include <QVBoxLayout> 22 #include "AbstractTreeItem.h" 23 #include "TableColumn.h" 24 #include "AbstractTreeModel.h" 28 TreeViewContent::TreeViewContent(
QWidget *parent) :
32 m_parentView = (TreeView *) parent;
35 m_mousePressPos =
new QPoint;
40 verticalScrollBar()->setSingleStep(1);
41 horizontalScrollBar()->setSingleStep(10);
42 m_rowHeight = QFontMetrics(font()).height() + ITEM_PADDING;
44 ASSERT(m_rowHeight > 0);
46 setMouseTracking(
true);
47 setContextMenuPolicy(Qt::ActionsContextMenu);
48 QAction *alternateRowsAct =
new QAction(
"&Alternate row colors",
this);
49 alternateRowsAct->setCheckable(
true);
50 connect(alternateRowsAct, SIGNAL(toggled(
bool)),
51 this, SLOT(setAlternatingRowColors(
bool)));
52 addAction(alternateRowsAct);
53 alternateRowsAct->setChecked(
true);
57 TreeViewContent::~TreeViewContent() {
61 delete m_mousePressPos;
62 m_mousePressPos = NULL;
70 delete m_lastShiftSelection;
71 m_lastShiftSelection = NULL;
75 QSize TreeViewContent::minimumSizeHint()
const {
76 return QWidget::minimumSizeHint();
80 QSize TreeViewContent::sizeHint()
const {
81 return minimumSizeHint();
85 AbstractTreeModel *TreeViewContent::getModel() {
90 void TreeViewContent::setModel(AbstractTreeModel *someModel) {
92 IString msg =
"Attempted to set a NULL model!";
97 disconnect(m_model, SIGNAL(modelModified()),
this, SLOT(refresh()));
98 disconnect(m_model, SIGNAL(filterProgressChanged(
int)),
99 this, SLOT(updateItemList()));
109 connect(m_model, SIGNAL(modelModified()),
this, SLOT(refresh()));
110 connect(m_model, SIGNAL(filterProgressChanged(
int)),
111 this, SLOT(updateItemList()));
121 void TreeViewContent::refresh() {
124 if (!m_model->isFiltering()) {
125 QSize modelVisibleSize =
127 int rowCount = modelVisibleSize.height();
128 m_contentWidth = modelVisibleSize.width() + ITEM_INDENTATION;
129 verticalScrollBar()->setRange(0, qMax(rowCount - 1, 0));
130 horizontalScrollBar()->setRange(0, m_contentWidth - viewport()->width()
131 + horizontalScrollBar()->singleStep());
135 viewport()->update();
140 bool TreeViewContent::eventFilter(
QObject *target, QEvent *event) {
141 return QObject::eventFilter(target, event);
145 void TreeViewContent::mouseDoubleClickEvent(QMouseEvent *event) {
146 QPoint pressPos =
event->pos();
147 int index = pressPos.y() / m_rowHeight;
149 if (index < m_items->size()) {
150 AbstractTreeItem *item = (*m_items)[index];
151 item->setExpanded(!item->isExpanded());
156 void TreeViewContent::mousePressEvent(QMouseEvent *event) {
157 QPoint pressPos =
event->pos();
158 int index = pressPos.y() / m_rowHeight;
163 if (index < m_items->size()) {
164 AbstractTreeItem *item = (*m_items)[index];
165 if (item->isSelectable() ||
166 (item->getFirstVisibleChild() &&
167 getArrowRect(item).contains(pressPos))) {
170 if (item->getFirstVisibleChild()) {
171 QRect arrowRect(getArrowRect(item));
177 if (event->modifiers() & Qt::ControlModifier) {
178 foreach (AbstractTreeItem * child, item->getChildren()) {
179 child->setSelected(!item->isSelected());
180 if (child->isSelected())
181 newlySelectedItems.append(child);
184 item->setSelected(!item->isSelected());
185 if (item->isSelected())
186 newlySelectedItems.append(item);
188 m_lastDirectlySelectedItem = item;
189 m_lastShiftSelection->clear();
192 if (event->modifiers() & Qt::ShiftModifier) {
193 foreach (AbstractTreeItem * i, *m_lastShiftSelection)
194 i->setSelected(
false);
196 if (m_lastDirectlySelectedItem) {
199 m_model->getItems(m_lastDirectlySelectedItem, item);
203 foreach (AbstractTreeItem * i, tmp) {
204 m_lastShiftSelection->append(i);
207 if (i->getPointerType() == AbstractTreeItem::Point) {
208 foreach (AbstractTreeItem * child, i->getChildren()) {
209 child->setSelected(
true);
210 m_lastShiftSelection->append(child);
216 m_lastShiftSelection->clear();
219 foreach (AbstractTreeItem * i, *m_lastShiftSelection) {
220 i->setSelected(
true);
221 newlySelectedItems.append(i);
225 m_model->setGlobalSelection(
false);
226 item->setSelected(
true);
227 newlySelectedItems.append(item);
228 m_lastDirectlySelectedItem = item;
230 if (item->getPointerType() == AbstractTreeItem::Point) {
231 foreach (AbstractTreeItem * child, item->getChildren()) {
232 child->setSelected(
true);
233 newlySelectedItems.append(child);
237 m_lastShiftSelection->clear();
241 emit treeSelectionChanged(newlySelectedItems);
246 m_model->setGlobalSelection(
false);
249 viewport()->update();
253 void TreeViewContent::mouseReleaseEvent(QMouseEvent *event) {
255 if (item && getArrowRect(item).contains(event->pos())) {
256 item->setExpanded(!item->isExpanded());
262 viewport()->update();
264 QWidget::mousePressEvent(event);
268 void TreeViewContent::mouseMoveEvent(QMouseEvent *event) {
269 QPoint cursorPos =
event->pos();
270 int index = cursorPos.y() / m_rowHeight;
275 if (index < m_items->size() && index >= 0) {
276 AbstractTreeItem *item = (*m_items)[index];
277 if (item->isSelectable() ||
278 (item->getFirstVisibleChild() &&
279 getArrowRect(item).contains(cursorPos))) {
282 if (item->getFirstVisibleChild()) {
283 QRect arrowRect = getArrowRect(item);
289 viewport()->update();
293 void TreeViewContent::leaveEvent(QEvent *event) {
296 viewport()->update();
300 void TreeViewContent::keyPressEvent(QKeyEvent *event) {
301 if (event->key() == Qt::Key_A &&
302 event->modifiers() == Qt::ControlModifier) {
303 m_model->setGlobalSelection(
true);
304 viewport()->update();
305 emit treeSelectionChanged();
308 QWidget::keyPressEvent(event);
313 void TreeViewContent::paintEvent(QPaintEvent *event) {
315 int startRow = verticalScrollBar()->value();
316 int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
318 QPainter painter(viewport());
319 painter.setRenderHints(QPainter::Antialiasing |
320 QPainter::TextAntialiasing);
322 for (
int i = 0; i < rowCount; i++) {
326 QColor backgroundColor = palette().base().color();
328 if (i < m_items->size()) {
329 if (m_alternatingRowColors && (startRow + i) % 2 == 1)
330 backgroundColor = palette().alternateBase().color();
332 ASSERT(m_items->at(i));
333 if (m_items->at(i)->isSelected())
334 backgroundColor = palette().highlight().color();
338 QPoint relativeTopLeft(0, i * m_rowHeight);
339 QPoint scrollBarPos(horizontalScrollBar()->value(),
340 verticalScrollBar()->value());
341 QPoint absoluteTopLeft(relativeTopLeft + scrollBarPos);
342 QSize rowSize(viewport()->width(), (
int) m_rowHeight);
345 painter.fillRect(QRect(relativeTopLeft, rowSize), backgroundColor);
349 if (i < m_items->size() &&
m_hoveredItem->first == (*m_items)[i] &&
351 QPen prevPen(painter.pen());
352 QPen borderPen(prevPen);
353 borderPen.setWidth(1);
354 borderPen.setColor(palette().highlight().color());
355 painter.setPen(borderPen);
356 QPoint borderTopLeft(relativeTopLeft.x() - absoluteTopLeft.x(),
357 relativeTopLeft.y() + 1);
359 int rectWidth = qMax(m_contentWidth +
360 horizontalScrollBar()->singleStep(), viewport()->width());
361 QSize borderSize(rectWidth, rowSize.height() - 2);
362 painter.drawRect(QRect(borderTopLeft, borderSize));
363 painter.setPen(prevPen);
367 if (i < m_items->size())
368 paintItemText(&painter, i, absoluteTopLeft, relativeTopLeft);
372 QWidget::paintEvent(event);
377 void TreeViewContent::resizeEvent(QResizeEvent *event) {
378 QAbstractScrollArea::resizeEvent(event);
379 horizontalScrollBar()->setRange(0, m_contentWidth - viewport()->width()
380 + horizontalScrollBar()->singleStep());
385 void TreeViewContent::scrollContentsBy(
int dx,
int dy) {
386 QAbstractScrollArea::scrollContentsBy(dx, dy);
391 void TreeViewContent::nullify() {
397 m_lastDirectlySelectedItem = NULL;
398 m_lastShiftSelection = NULL;
399 m_mousePressPos = NULL;
403 void TreeViewContent::paintItemText(QPainter *painter,
404 int index, QPoint absolutePosition, QPoint relativePosition) {
406 ASSERT(index >= 0 && index < m_items->size());
408 QPoint point(-absolutePosition.x(), relativePosition.y());
410 AbstractTreeItem *item = (*m_items)[index];
424 AbstractTreeItem *iteratorItem = item;
425 while (iteratorItem->parent() && iteratorItem->parent()->parent()) {
426 point.setX(point.x() + ITEM_INDENTATION);
427 iteratorItem = iteratorItem->parent();
430 QPen originalPen = painter->pen();
431 if (item->isSelected()) {
432 painter->setPen(QPen(palette().highlightedText().color()));
438 if (item->getFirstVisibleChild()) {
441 QRect itemArrowRect(getArrowRect(item));
444 QPainter::CompositionMode prevMode = painter->compositionMode();
445 painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
446 QColor color = palette().button().color().darker(160);
448 painter->fillRect(itemArrowRect, color);
449 painter->setCompositionMode(prevMode);
459 painter->drawRect(itemArrowRect);
464 if (item->isExpanded())
465 drawExpandedArrow(painter, itemArrowRect);
467 drawCollapsedArrow(painter, itemArrowRect);
472 point.setX(point.x() + ITEM_INDENTATION);
475 point.setY(point.y() + ITEM_PADDING / 2);
478 int textHeight = m_rowHeight - ITEM_PADDING;
479 QRect rect(point, QSize(viewport()->width() - point.x(), textHeight));
480 painter->drawText(rect, Qt::TextDontClip, item->getData().toString());
481 painter->setPen(originalPen);
486 void TreeViewContent::drawCollapsedArrow(QPainter *painter, QRect rect) {
487 rect.setTopLeft(rect.topLeft() + QPoint(4, 3));
488 rect.setBottomRight(rect.bottomRight() - QPoint(4, 2));
490 QPoint top(rect.topLeft());
491 QPoint bottom(rect.bottomLeft());
492 QPoint right(rect.right(), rect.center().y());
494 QPen prevPen = painter->pen();
495 QPen arrowPen(prevPen);
496 arrowPen.setCapStyle(Qt::RoundCap);
497 arrowPen.setJoinStyle(Qt::RoundJoin);
498 arrowPen.setWidth(2);
499 painter->setPen(arrowPen);
500 painter->drawLine(top, right);
501 painter->drawLine(bottom, right);
502 painter->setPen(prevPen);
506 void TreeViewContent::drawExpandedArrow(QPainter *painter, QRect rect) {
507 rect.setTopLeft(rect.topLeft() + QPoint(3, 4));
508 rect.setBottomRight(rect.bottomRight() - QPoint(2, 4));
510 QPoint left(rect.topLeft());
511 QPoint right(rect.topRight());
512 QPoint bottom(rect.center().x(), rect.bottom());
514 QPen prevPen = painter->pen();
515 QPen arrowPen(prevPen);
516 arrowPen.setCapStyle(Qt::RoundCap);
517 arrowPen.setJoinStyle(Qt::RoundJoin);
518 arrowPen.setWidth(2);
519 painter->setPen(arrowPen);
520 painter->drawLine(left, bottom);
521 painter->drawLine(right, bottom);
522 painter->setPen(prevPen);
526 void TreeViewContent::setAlternatingRowColors(
bool newStatus) {
527 m_alternatingRowColors = newStatus;
528 viewport()->update();
532 void TreeViewContent::updateItemList() {
533 int startRow = verticalScrollBar()->value();
534 int rowCount = (int) ceil(viewport()->height() / (double) m_rowHeight);
535 *m_items = m_model->getItems(startRow, startRow + rowCount,
536 AbstractTreeModel::AllItems,
false);
538 viewport()->update();
542 QRect TreeViewContent::getArrowRect(AbstractTreeItem *item)
const {
545 int index = m_items->indexOf(item);
546 QPoint centerOfArrow(12 - horizontalScrollBar()->value(),
547 (index * m_rowHeight) + (m_rowHeight / 2));
548 int depth = item->getDepth() - 1;
549 centerOfArrow.setX(centerOfArrow.x() + (depth * ITEM_INDENTATION));
551 arrowRect = QRect(centerOfArrow.x() - 6, centerOfArrow.y() - 6, 12, 12);
557 void TreeViewContent::scrollTo(
559 if (newlySelectedItems.size())
560 scrollTo(newlySelectedItems.last());
564 void TreeViewContent::scrollTo(AbstractTreeItem *newlySelectedItem) {
565 if (newlySelectedItem->getPointerType() == AbstractTreeItem::Measure)
566 newlySelectedItem->parent()->setExpanded(
true);
568 int row = getModel()->indexOfVisibleItem(newlySelectedItem);
571 int topRow = verticalScrollBar()->value();
574 verticalScrollBar()->setValue(row);
577 int wholeVisibleRowCount = viewport()->height() / m_rowHeight;
578 int bottomRow = topRow + wholeVisibleRowCount;
580 verticalScrollBar()->setValue(row - wholeVisibleRowCount + 1);
584 viewport()->update();
QSize getVisibleSize(int indentation) const
indentation is in pixels
This error is for when a programmer made an API call that was illegal.
QPair< AbstractTreeItem *, bool > * m_pressedItem
The bool is true if the arrow in the item was pressed.
#define _FILEINFO_
Macro for the filename and line number.
QPair< AbstractTreeItem *, bool > * m_hoveredItem
The bool is true if the mouse is hovering over the arrow.
Namespace for ISIS/Bullet specific routines.