void GroupedIconView::paintEvent(QPaintEvent* e) {
  // This code was adapted from QListView::paintEvent(), changed to use the
  // visualRect() of items, and to draw headers.

  QStyleOptionViewItemV4 option(viewOptions());
  if (isWrapping())
    option.features = QStyleOptionViewItemV2::WrapText;
  option.locale = locale();
  option.locale.setNumberOptions(QLocale::OmitGroupSeparator);
  option.widget = this;

  QPainter painter(viewport());

  const QRect viewport_rect(e->rect().translated(horizontalOffset(), verticalOffset()));
  QVector<QModelIndex> toBeRendered = IntersectingItems(viewport_rect);

  const QModelIndex current = currentIndex();
  const QAbstractItemModel *itemModel = model();
  const QItemSelectionModel *selections = selectionModel();
  const bool focus = (hasFocus() || viewport()->hasFocus()) && current.isValid();
  const QStyle::State state = option.state;
  const QAbstractItemView::State viewState = this->state();
  const bool enabled = (state & QStyle::State_Enabled) != 0;

  int maxSize = (flow() == TopToBottom)
      ? viewport()->size().width() - 2 * spacing()
      : viewport()->size().height() - 2 * spacing();

  QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
  for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
    if (!it->isValid()) {
      continue;
    }

    option.rect = visualRect(*it);

    if (flow() == TopToBottom)
      option.rect.setWidth(qMin(maxSize, option.rect.width()));
    else
      option.rect.setHeight(qMin(maxSize, option.rect.height()));

    option.state = state;
    if (selections && selections->isSelected(*it))
      option.state |= QStyle::State_Selected;
    if (enabled) {
      QPalette::ColorGroup cg;
      if ((itemModel->flags(*it) & Qt::ItemIsEnabled) == 0) {
        option.state &= ~QStyle::State_Enabled;
        cg = QPalette::Disabled;
      } else {
        cg = QPalette::Normal;
      }
      option.palette.setCurrentColorGroup(cg);
    }
    if (focus && current == *it) {
      option.state |= QStyle::State_HasFocus;
      if (viewState == EditingState)
        option.state |= QStyle::State_Editing;
    }

    itemDelegate()->paint(&painter, option, *it);
  }

  // Draw headers
  foreach (const Header& header, headers_) {
    const QRect header_rect = QRect(
          header_indent_, header.y,
          viewport()->width() - header_indent_ * 2, header_height());

    // Is this header contained in the area we're drawing?
    if (!header_rect.intersects(viewport_rect)) {
      continue;
    }

    // Draw the header
    DrawHeader(model()->index(header.first_row, 0),
               header_rect.translated(-horizontalOffset(), -verticalOffset()),
               &painter);
  }
}
int QListView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QAbstractItemView::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 1)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 1;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< Movement*>(_v) = movement(); break;
        case 1: *reinterpret_cast< Flow*>(_v) = flow(); break;
        case 2: *reinterpret_cast< bool*>(_v) = isWrapping(); break;
        case 3: *reinterpret_cast< ResizeMode*>(_v) = resizeMode(); break;
        case 4: *reinterpret_cast< LayoutMode*>(_v) = layoutMode(); break;
        case 5: *reinterpret_cast< int*>(_v) = spacing(); break;
        case 6: *reinterpret_cast< QSize*>(_v) = gridSize(); break;
        case 7: *reinterpret_cast< ViewMode*>(_v) = viewMode(); break;
        case 8: *reinterpret_cast< int*>(_v) = modelColumn(); break;
        case 9: *reinterpret_cast< bool*>(_v) = uniformItemSizes(); break;
        case 10: *reinterpret_cast< int*>(_v) = batchSize(); break;
        case 11: *reinterpret_cast< bool*>(_v) = wordWrap(); break;
        case 12: *reinterpret_cast< bool*>(_v) = isSelectionRectVisible(); break;
        }
        _id -= 13;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setMovement(*reinterpret_cast< Movement*>(_v)); break;
        case 1: setFlow(*reinterpret_cast< Flow*>(_v)); break;
        case 2: setWrapping(*reinterpret_cast< bool*>(_v)); break;
        case 3: setResizeMode(*reinterpret_cast< ResizeMode*>(_v)); break;
        case 4: setLayoutMode(*reinterpret_cast< LayoutMode*>(_v)); break;
        case 5: setSpacing(*reinterpret_cast< int*>(_v)); break;
        case 6: setGridSize(*reinterpret_cast< QSize*>(_v)); break;
        case 7: setViewMode(*reinterpret_cast< ViewMode*>(_v)); break;
        case 8: setModelColumn(*reinterpret_cast< int*>(_v)); break;
        case 9: setUniformItemSizes(*reinterpret_cast< bool*>(_v)); break;
        case 10: setBatchSize(*reinterpret_cast< int*>(_v)); break;
        case 11: setWordWrap(*reinterpret_cast< bool*>(_v)); break;
        case 12: setSelectionRectVisible(*reinterpret_cast< bool*>(_v)); break;
        }
        _id -= 13;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 13;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 13;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 13;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 13;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 13;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 13;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}