const QVariant value = model()->data(index).value(role);
const QString text = value.toString();
if (!text.isEmpty()) {
- width = qMax(width, qreal(option.margin * 2 + option.fontMetrics.width(text)));
+ const qreal columnMargin = option.margin * 3;
+ width = qMax(width, qreal(2 * columnMargin + option.fontMetrics.width(text)));
+ }
+
+ if (role == "name") {
+ const QHash<QByteArray, QVariant> values = model()->data(index);
+ Q_ASSERT(values.contains("expansionLevel"));
+
+ // Increase the width by the expansion-toggle and the current expansion level
+ const int expansionLevel = values.value("expansionLevel", 0).toInt();
+ width += option.margin + expansionLevel * itemSize().height() + KIconLoader::SizeSmall;
+
+ // Increase the width by the required space for the icon
+ width += option.margin * 2 + option.iconSize;
}
return QSizeF(width, height);
const int scaledIconSize = widgetHeight - 2 * option.margin;
const int fontHeight = option.fontMetrics.height();
- qreal x = m_expansionArea.right() + option.margin * 3 + scaledIconSize;
+ const qreal columnMargin = option.margin * 3;
+ const qreal firstColumnInc = m_expansionArea.right() + option.margin * 2 + scaledIconSize;
+ qreal x = firstColumnInc;
const qreal y = qMax(qreal(option.margin), (widgetHeight - fontHeight) / 2);
foreach (const QByteArray& role, m_sortedVisibleRoles) {
m_text[textId].setText(text);
const qreal requiredWidth = option.fontMetrics.width(text);
- m_textPos[textId] = QPointF(x, y);
+ m_textPos[textId] = QPointF(x + columnMargin, y);
const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
x += columnWidth;
switch (textId) {
case Name: {
m_textBoundingRect = QRectF(m_textPos[textId].x() - option.margin, 0,
- requiredWidth + 2 * option.margin, size().height());
+ requiredWidth + 2 * option.margin, size().height());
// The column after the name should always be aligned on the same x-position independent
// from the expansion-level shown in the name column
- x -= m_expansionArea.right();
+ x -= firstColumnInc;
break;
}
case Size:
// The values for the size should be right aligned
- m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * option.margin;
+ m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * columnMargin;
break;
default:
if (m_roleOperation == ResizeRoleOperation) {
const QByteArray pressedRole = m_visibleRoles.at(m_pressedRoleIndex);
- qreal roleWidth = m_visibleRolesWidths.value(pressedRole);
- roleWidth += event->pos().x() - event->lastPos().x();
- roleWidth = qMax(minimumRoleWidth(), roleWidth);
+ qreal previousWidth = m_visibleRolesWidths.value(pressedRole);
+ qreal currentWidth = previousWidth;
+ currentWidth += event->pos().x() - event->lastPos().x();
+ currentWidth = qMax(minimumRoleWidth(), currentWidth);
- m_visibleRolesWidths.insert(pressedRole, roleWidth);
+ m_visibleRolesWidths.insert(pressedRole, currentWidth);
update();
+
+ emit visibleRoleWidthChanged(pressedRole, currentWidth, previousWidth);
} else if ((event->pos() - m_pressedMousePos).manhattanLength() >= QApplication::startDragDistance()) {
kDebug() << "Moving of role not supported yet";
m_roleOperation = MoveRoleOperation;
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
+signals:
+ /**
+ * Is emitted if the width of a visible role has been adjusted by the user with the mouse
+ * (no signal is emitted if KItemListHeader::setVisibleRoles() is invoked).
+ */
+ void visibleRoleWidthChanged(const QByteArray& role,
+ qreal currentWidth,
+ qreal previousWidth);
+
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
m_mousePos(),
m_autoScrollIncrement(0),
m_autoScrollTimer(0),
- m_header(0)
+ m_header(0),
+ m_useHeaderWidths(false)
{
setAcceptHoverEvents(true);
m_header->setVisibleRoles(m_visibleRoles);
m_header->setVisibleRolesWidths(headerRolesWidths());
m_header->setZValue(1);
+
+ m_useHeaderWidths = false;
updateHeaderWidth();
+
+ connect(m_header, SIGNAL(visibleRoleWidthChanged(QByteArray,qreal,qreal)),
+ this, SLOT(slotVisibleRoleWidthChanged(QByteArray,qreal,qreal)));
+
m_layouter->setHeaderHeight(m_header->size().height());
} else if (!show && m_header) {
delete m_header;
m_header = 0;
+ m_useHeaderWidths = false;
m_layouter->setHeaderHeight(0);
}
}
void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
{
- markVisibleRolesSizesAsDirty();
+ if (!m_useHeaderWidths) {
+ markVisibleRolesSizesAsDirty();
+ }
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
{
- markVisibleRolesSizesAsDirty();
+ if (!m_useHeaderWidths) {
+ markVisibleRolesSizesAsDirty();
+ }
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
update();
}
+void KItemListView::slotVisibleRoleWidthChanged(const QByteArray& role,
+ qreal currentWidth,
+ qreal previousWidth)
+{
+ Q_UNUSED(previousWidth);
+ Q_ASSERT(m_header);
+
+ m_useHeaderWidths = true;
+
+ if (m_visibleRolesSizes.contains(role)) {
+ QSizeF roleSize = m_visibleRolesSizes.value(role);
+ roleSize.setWidth(currentWidth);
+ m_visibleRolesSizes.insert(role, roleSize);
+ }
+
+ m_layouter->setItemSize(QSizeF()); // Forces an update in applyDynamicItemSize()
+ updateLayout();
+}
+
void KItemListView::triggerAutoScrolling()
{
if (!m_autoScrollTimer) {
if (dirty) {
m_visibleRolesSizes.clear();
m_layouter->setItemSize(QSizeF());
+ m_useHeaderWidths = false;
}
return dirty;
}
if (m_visibleRolesSizes.isEmpty()) {
m_visibleRolesSizes = visibleRoleSizes();
- foreach (KItemListWidget* widget, visibleItemListWidgets()) {
- widget->setVisibleRolesSizes(m_visibleRolesSizes);
- }
-
if (m_header) {
m_header->setVisibleRolesWidths(headerRolesWidths());
}
}
if (m_layouter->itemSize().isEmpty()) {
+ // Calculate the maximum size of an item by considering the
+ // visible role sizes and apply them to the layouter.
qreal requiredWidth = 0;
qreal requiredHeight = 0;
}
m_layouter->setItemSize(dynamicItemSize);
+
+ // Update the role sizes for all visible widgets
+ foreach (KItemListWidget* widget, visibleItemListWidgets()) {
+ widget->setVisibleRolesSizes(m_visibleRolesSizes);
+ }
}
}
int lastVisibleIndex() const;
virtual QSizeF itemSizeHint(int index) const;
+
+ /**
+ * @return The size of each visible role in case if KItemListView::itemSize()
+ * is empty. This allows to have dynamic but equal role sizes between
+ * all items. Per default an empty hash is returned.
+ */
virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
/**
void slotRubberBandPosChanged();
void slotRubberBandActivationChanged(bool active);
+ /**
+ * Is invoked if the visible role-width of one role in the header has
+ * been changed by the user. It is remembered that the user has modified
+ * the role-width, so that it won't be changed anymore automatically to
+ * calculate an optimized width.
+ */
+ void slotVisibleRoleWidthChanged(const QByteArray& role,
+ qreal currentWidth,
+ qreal previousWidth);
+
/**
* Triggers the autoscrolling if autoScroll() is enabled by checking the
* current mouse position. If the mouse position is within the autoscroll
QTimer* m_autoScrollTimer;
KItemListHeader* m_header;
+ bool m_useHeaderWidths;
friend class KItemListController;
};