23 #include "tablewidgetreorderable.h"
27 #include <QHeaderView>
29 #include <QProxyStyle>
31 class TableWidgetReorderableStyle :
public QProxyStyle
34 using QProxyStyle::QProxyStyle;
36 void drawPrimitive(QStyle::PrimitiveElement element,
const QStyleOption *option, QPainter *painter,
const QWidget *widget =
nullptr)
const override;
39 void TableWidgetReorderableStyle::drawPrimitive(QStyle::PrimitiveElement element,
40 const QStyleOption *option, QPainter *painter,
const QWidget *widget)
const
42 if (element == PE_IndicatorItemViewItemDrop && !option->rect.isNull() && widget)
45 QPoint cursorPos = QCursor::pos();
46 QPoint tablePos = table->mapFromGlobal(cursorPos);
47 tablePos.setX(tablePos.x() - table->verticalHeader()->width());
48 tablePos.setY(tablePos.y() - table->horizontalHeader()->height());
49 int targetRow = table->determineDragRow(tablePos.y());
50 QStyleOption newOption = *option;
51 if (targetRow < table->rowCount())
53 newOption.rect.setTop(table->rowViewportPosition(targetRow));
57 int lastRow = table->rowCount() - 1;
60 int bottom = table->rowViewportPosition(lastRow) + table->rowHeight(lastRow);
61 newOption.rect.setTop(bottom);
63 newOption.rect.setHeight(0);
64 newOption.rect.setLeft(0);
66 newOption.rect.setRight(widget->width());
67 QProxyStyle::drawPrimitive(element, &newOption, painter, widget);
71 QProxyStyle::drawPrimitive(element, option, painter, widget);
75 TableWidgetReorderable::TableWidgetReorderable(QWidget *parent)
76 : QTableWidget(parent)
78 this->setStyle(
new TableWidgetReorderableStyle());
81 void TableWidgetReorderable::dropEvent(QDropEvent *event)
83 if (event->source() !=
this)
88 int newRow = determineDragRow(event->pos().y());
89 QList<QTableWidgetItem*> selectedItems = this->selectedItems();
91 for (QTableWidgetItem *item : selectedItems)
92 uniqueRows.insert(item->row());
93 for (
int n = 0; n < uniqueRows.count(); ++n)
94 this->insertRow(newRow);
96 int currentOldRow = -1;
97 int currentNewRow = newRow - 1;
98 QList<int> deleteRows;
99 for (QTableWidgetItem *selectedItem : selectedItems)
101 int column = selectedItem->column();
102 if (selectedItem->row() != currentOldRow)
104 currentOldRow = selectedItem->row();
105 deleteRows.append(currentOldRow);
108 QWidget *cellWidget = this->cellWidget(currentOldRow, column);
109 this->takeItem(currentOldRow, column);
110 this->setItem(currentNewRow, column, selectedItem);
111 this->setCellWidget(currentNewRow, column, cellWidget);
114 std::sort(deleteRows.begin(), deleteRows.end());
115 for (
int i = deleteRows.count() - 1; i >= 0; --i)
116 this->removeRow(deleteRows[i]);
118 emit rowsReordered();
121 int TableWidgetReorderable::determineDragRow(
int y)
const
129 int directRow = this->rowAt(y);
131 return this->rowCount();
132 int rowPosition = this->rowViewportPosition(directRow);
133 int rowHeight = this->rowHeight(directRow);
134 int rowLocalY = y - rowPosition;
135 return (rowLocalY < rowHeight / 2) ? directRow : directRow + 1;