656 lines
20 KiB
C++
656 lines
20 KiB
C++
|
|
#include "qmtreeview.h"
|
||
|
|
|
||
|
|
#include <QPen>
|
||
|
|
#include <QPainter>
|
||
|
|
#include <QStyleOptionFrame>
|
||
|
|
#include <QHeaderView>
|
||
|
|
#include <QPushButton>
|
||
|
|
#include <QtEvents>
|
||
|
|
#include <QMenu>
|
||
|
|
#include <QMimeData>
|
||
|
|
// Implementation
|
||
|
|
|
||
|
|
#include <QDebug>
|
||
|
|
|
||
|
|
#include "treemodel.h"
|
||
|
|
|
||
|
|
|
||
|
|
QMTreeView::QMTreeView(QWidget *parent):
|
||
|
|
QTreeView(parent)
|
||
|
|
{
|
||
|
|
header()->setFixedHeight(30);
|
||
|
|
QPushButton * cornerbutton = new QPushButton(this);
|
||
|
|
setCornerWidget(cornerbutton);
|
||
|
|
connect(cornerbutton, &QPushButton::released, this, &QMTreeView::onCornerButtonRelease);
|
||
|
|
|
||
|
|
setLineWidth(1);
|
||
|
|
setAlternatingRowColors(false);
|
||
|
|
|
||
|
|
setAcceptDrops(true); // Habilita el drop
|
||
|
|
setDropIndicatorShown(true);
|
||
|
|
setTreePosition(0);
|
||
|
|
|
||
|
|
return;
|
||
|
|
setStyleSheet("QHeaderView::section:horizontal {"
|
||
|
|
"background-color: qlineargradient(spread:reflect,"
|
||
|
|
"x1:0, y1:0, x2:0, y2:1,"
|
||
|
|
"stop:0 rgba(255, 255, 255, 255),"
|
||
|
|
"stop:1 rgba(164, 164, 164, 255));"
|
||
|
|
"border: 1px solid rgb(153, 153, 153);"
|
||
|
|
"border-width: 0 1px 1px 0;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::item {"
|
||
|
|
"border-bottom: 0.5px solid lightgray;"
|
||
|
|
"selection-color: black;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::item:selected { /*被选中的index*/"
|
||
|
|
"background: qlineargradient("
|
||
|
|
"x1: 0, y1: 0, x2: 0, y2: 1,"
|
||
|
|
"stop: 0 #FAFBFE,"
|
||
|
|
"stop: 1 #DCDEF1);"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch {"
|
||
|
|
"background: yellow;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:has-siblings:!adjoins-item {"
|
||
|
|
"background: cyan;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:has-siblings:adjoins-item {"
|
||
|
|
"background: red;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:!has-children:!has-siblings:adjoins-item {"
|
||
|
|
"background: blue;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:closed:has-children:has-siblings {"
|
||
|
|
"background: black;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:has-children:!has-siblings:closed {"
|
||
|
|
"background: gray;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:open:has-children:has-siblings {"
|
||
|
|
"background: magenta;"
|
||
|
|
"}"
|
||
|
|
"QTreeView::branch:open:has-children:!has-siblings {"
|
||
|
|
"background: green;}");
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::resizeEvent(QResizeEvent *event)
|
||
|
|
{
|
||
|
|
QTreeView::resizeEvent(event);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
void QMTreeView::drawTree(QPainter *painter, const QRegion ®ion) const
|
||
|
|
{
|
||
|
|
QTreeView::drawTree(painter, region);
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (model() && model()->rowCount() > 0)
|
||
|
|
{
|
||
|
|
QTreeView::drawTree(painter, region);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// If no items draw a text in the center of the viewport.
|
||
|
|
QPainter painter(viewport());
|
||
|
|
QString text(tr("There are no elements in this view"));
|
||
|
|
QRect textRect = painter.fontMetrics().boundingRect(text);
|
||
|
|
textRect.moveCenter(viewport()->rect().center());
|
||
|
|
painter.drawText(textRect, Qt::AlignCenter, text);
|
||
|
|
}
|
||
|
|
|
||
|
|
*/
|
||
|
|
/*
|
||
|
|
Q_D(const QTreeView);
|
||
|
|
const QVector<QTreeViewItem> viewItems = d->viewItems;
|
||
|
|
|
||
|
|
QStyleOptionViewItem option = d->viewOptionsV1();
|
||
|
|
const QStyle::State state = option.state;
|
||
|
|
d->current = 0;
|
||
|
|
|
||
|
|
if (viewItems.count() == 0 || d->header->count() == 0 || !d->itemDelegate) {
|
||
|
|
d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
int firstVisibleItemOffset = 0;
|
||
|
|
const int firstVisibleItem = d->firstVisibleItem(&firstVisibleItemOffset);
|
||
|
|
if (firstVisibleItem < 0) {
|
||
|
|
d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
const int viewportWidth = d->viewport->width();
|
||
|
|
|
||
|
|
QPoint hoverPos = d->viewport->mapFromGlobal(QCursor::pos());
|
||
|
|
d->hoverBranch = d->itemDecorationAt(hoverPos);
|
||
|
|
|
||
|
|
QVector<int> drawn;
|
||
|
|
bool multipleRects = (region.rectCount() > 1);
|
||
|
|
for (const QRect &a : region) {
|
||
|
|
const QRect area = (multipleRects
|
||
|
|
? QRect(0, a.y(), viewportWidth, a.height())
|
||
|
|
: a);
|
||
|
|
d->leftAndRight = d->startAndEndColumns(area);
|
||
|
|
|
||
|
|
int i = firstVisibleItem; // the first item at the top of the viewport
|
||
|
|
int y = firstVisibleItemOffset; // we may only see part of the first item
|
||
|
|
|
||
|
|
// start at the top of the viewport and iterate down to the update area
|
||
|
|
for (; i < viewItems.count(); ++i) {
|
||
|
|
const int itemHeight = d->itemHeight(i);
|
||
|
|
if (y + itemHeight > area.top())
|
||
|
|
break;
|
||
|
|
y += itemHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
// paint the visible rows
|
||
|
|
for (; i < viewItems.count() && y <= area.bottom(); ++i) {
|
||
|
|
const int itemHeight = d->itemHeight(i);
|
||
|
|
option.rect.setRect(0, y, viewportWidth, itemHeight);
|
||
|
|
option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
|
||
|
|
| (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
|
||
|
|
| (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
|
||
|
|
d->current = i;
|
||
|
|
d->spanning = viewItems.at(i).spanning;
|
||
|
|
if (!multipleRects || !drawn.contains(i)) {
|
||
|
|
drawRow(painter, option, viewItems.at(i).index);
|
||
|
|
if (multipleRects) // even if the rect only intersects the item,
|
||
|
|
drawn.append(i); // the entire item will be painted
|
||
|
|
}
|
||
|
|
y += itemHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (y <= area.bottom()) {
|
||
|
|
d->current = i;
|
||
|
|
d->paintAlternatingRowColors(painter, &option, y, area.bottom());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
//}
|
||
|
|
|
||
|
|
void QMTreeView::drawRow(QPainter * painter, const QStyleOptionViewItem & options, const QModelIndex & index) const
|
||
|
|
{
|
||
|
|
QTreeView::drawRow(painter, options, index);
|
||
|
|
//return;
|
||
|
|
|
||
|
|
int m_iWidth = 1;
|
||
|
|
QColor m_gridLineColor = QColor(200, 200, 200);
|
||
|
|
|
||
|
|
QPen pen;
|
||
|
|
pen.setWidth(m_iWidth);
|
||
|
|
pen.setColor(m_gridLineColor);
|
||
|
|
|
||
|
|
QBrush brush;
|
||
|
|
brush.setColor(QColor(0,0,0,0));
|
||
|
|
|
||
|
|
painter->save();
|
||
|
|
painter->setPen(pen);
|
||
|
|
painter->setBrush(brush);
|
||
|
|
painter->drawRect(options.rect);
|
||
|
|
painter->restore();
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const
|
||
|
|
{
|
||
|
|
if (!index.isValid()) {
|
||
|
|
QTreeView::drawBranches(painter, rect, index);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Calcula el ancho del branch basado en el nivel de profundidad
|
||
|
|
int depth = 0;
|
||
|
|
QModelIndex parentIndex = index.parent();
|
||
|
|
while (parentIndex.isValid()) {
|
||
|
|
++depth;
|
||
|
|
parentIndex = parentIndex.parent();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Calcula el ancho del branch
|
||
|
|
int branchWidth = depth * indentation();
|
||
|
|
|
||
|
|
// Dibuja el rectángulo del branch
|
||
|
|
QRect branchRect(rect.left(), rect.top(), branchWidth, rect.height());
|
||
|
|
painter->save();
|
||
|
|
painter->setBrush(Qt::yellow); // Cambia el color según prefieras
|
||
|
|
painter->setPen(Qt::NoPen); // Sin bordes
|
||
|
|
painter->drawRect(branchRect);
|
||
|
|
painter->restore();
|
||
|
|
|
||
|
|
// Llama al método base para que Qt dibuje el resto
|
||
|
|
QTreeView::drawBranches(painter, rect, index);
|
||
|
|
return;
|
||
|
|
|
||
|
|
|
||
|
|
QTreeView::drawBranches(painter, rect, index);
|
||
|
|
//return;
|
||
|
|
|
||
|
|
//int m_iWidth = 1;
|
||
|
|
QColor m_gridLineColor = QColor(200, 200, 200);
|
||
|
|
|
||
|
|
QPen pen;
|
||
|
|
//pen.setWidth(m_iWidth);
|
||
|
|
pen.setColor(m_gridLineColor);
|
||
|
|
|
||
|
|
QBrush brush;
|
||
|
|
brush.setColor(QColor(0,0,0,0));
|
||
|
|
|
||
|
|
//painter->save();
|
||
|
|
painter->setPen(pen);
|
||
|
|
painter->setBrush(brush);
|
||
|
|
painter->drawRect(rect);
|
||
|
|
//painter->restore();
|
||
|
|
|
||
|
|
//const QTreeViewItem &viewItem = d->viewItems.at(item);
|
||
|
|
//int level = viewItem.level;
|
||
|
|
|
||
|
|
|
||
|
|
//Q_Q(const QMTreeView);
|
||
|
|
/*
|
||
|
|
const bool reverse = isRightToLeft();
|
||
|
|
const int indent = d->indent;
|
||
|
|
const int outer = d->rootDecoration ? 0 : 1;
|
||
|
|
const int item = d->current;
|
||
|
|
const QTreeViewItem &viewItem = d->viewItems.at(item);
|
||
|
|
int level = viewItem.level;
|
||
|
|
QRect primitive(reverse ? rect.left() : rect.right() + 1, rect.top(), indent, rect.height());
|
||
|
|
|
||
|
|
QModelIndex parent = index.parent();
|
||
|
|
QModelIndex current = parent;
|
||
|
|
QModelIndex ancestor = current.parent();
|
||
|
|
|
||
|
|
QStyleOptionViewItem opt = viewOptions();
|
||
|
|
QStyle::State extraFlags = QStyle::State_None;
|
||
|
|
if (isEnabled())
|
||
|
|
extraFlags |= QStyle::State_Enabled;
|
||
|
|
if (hasFocus())
|
||
|
|
extraFlags |= QStyle::State_Active;
|
||
|
|
QPoint oldBO = painter->brushOrigin();
|
||
|
|
if (verticalScrollMode() == QAbstractItemView::ScrollPerPixel)
|
||
|
|
painter->setBrushOrigin(QPoint(0, verticalOffset()));
|
||
|
|
|
||
|
|
if (d->alternatingColors) {
|
||
|
|
opt.features.setFlag(QStyleOptionViewItem::Alternate, d->current & 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
// When hovering over a row, pass State_Hover for painting the branch
|
||
|
|
// indicators if it has the decoration (aka branch) selected.
|
||
|
|
bool hoverRow = selectionBehavior() == QAbstractItemView::SelectRows
|
||
|
|
&& opt.showDecorationSelected
|
||
|
|
&& index.parent() == d->hover.parent()
|
||
|
|
&& index.row() == d->hover.row();
|
||
|
|
|
||
|
|
if (d->selectionModel->isSelected(index))
|
||
|
|
extraFlags |= QStyle::State_Selected;
|
||
|
|
|
||
|
|
if (level >= outer) {
|
||
|
|
// start with the innermost branch
|
||
|
|
primitive.moveLeft(reverse ? primitive.left() : primitive.left() - indent);
|
||
|
|
opt.rect = primitive;
|
||
|
|
|
||
|
|
const bool expanded = viewItem.expanded;
|
||
|
|
const bool children = viewItem.hasChildren;
|
||
|
|
bool moreSiblings = viewItem.hasMoreSiblings;
|
||
|
|
|
||
|
|
opt.state = QStyle::State_Item | extraFlags
|
||
|
|
| (moreSiblings ? QStyle::State_Sibling : QStyle::State_None)
|
||
|
|
| (children ? QStyle::State_Children : QStyle::State_None)
|
||
|
|
| (expanded ? QStyle::State_Open : QStyle::State_None);
|
||
|
|
opt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch);
|
||
|
|
|
||
|
|
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
|
||
|
|
}
|
||
|
|
// then go out level by level
|
||
|
|
for (--level; level >= outer; --level) { // we have already drawn the innermost branch
|
||
|
|
primitive.moveLeft(reverse ? primitive.left() + indent : primitive.left() - indent);
|
||
|
|
opt.rect = primitive;
|
||
|
|
opt.state = extraFlags;
|
||
|
|
bool moreSiblings = false;
|
||
|
|
if (d->hiddenIndexes.isEmpty()) {
|
||
|
|
moreSiblings = (d->model->rowCount(ancestor) - 1 > current.row());
|
||
|
|
} else {
|
||
|
|
int successor = item + viewItem.total + 1;
|
||
|
|
while (successor < d->viewItems.size()
|
||
|
|
&& d->viewItems.at(successor).level >= uint(level)) {
|
||
|
|
const QTreeViewItem &successorItem = d->viewItems.at(successor);
|
||
|
|
if (successorItem.level == uint(level)) {
|
||
|
|
moreSiblings = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
successor += successorItem.total + 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (moreSiblings)
|
||
|
|
opt.state |= QStyle::State_Sibling;
|
||
|
|
opt.state.setFlag(QStyle::State_MouseOver, hoverRow || item == d->hoverBranch);
|
||
|
|
|
||
|
|
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, this);
|
||
|
|
current = ancestor;
|
||
|
|
ancestor = current.parent();
|
||
|
|
}
|
||
|
|
painter->setBrushOrigin(oldBO);*/
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
int indexRowSizeHint(const QModelIndex &index)
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int rowHeight(const QModelIndex &index)
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
void QMTreeView::keyPressEvent(QKeyEvent *e)
|
||
|
|
{
|
||
|
|
bool bNextCellOnEnter = true;
|
||
|
|
bool bNextRowOnLastCol = true;
|
||
|
|
/*
|
||
|
|
Key_Left = 0x01000012,
|
||
|
|
Key_Up = 0x01000013,
|
||
|
|
Key_Right = 0x01000014,
|
||
|
|
Key_Down = 0x01000015,
|
||
|
|
*/
|
||
|
|
if(bNextCellOnEnter && (e->key() == Qt::Key_Return | e->key() == Qt::Key_Enter | e->key() == Qt::Key_Right))
|
||
|
|
{
|
||
|
|
qint32 cr = currentIndex().row(),
|
||
|
|
cc = currentIndex().column(),
|
||
|
|
c = model()->columnCount();
|
||
|
|
|
||
|
|
QHeaderView *hdr = static_cast<QHeaderView*>(header());
|
||
|
|
|
||
|
|
if(hdr)
|
||
|
|
cc = hdr->visualIndex(cc);
|
||
|
|
|
||
|
|
if(cc + 1 < c)
|
||
|
|
{
|
||
|
|
moveTo(cr, cc + 1);
|
||
|
|
|
||
|
|
if(editTriggers() == QAbstractItemView::AllEditTriggers)
|
||
|
|
edit(currentIndex());
|
||
|
|
}
|
||
|
|
else if(bNextRowOnLastCol)
|
||
|
|
{
|
||
|
|
// TODO: comporbar si tiene hijos y si tiene mover el selector a este.
|
||
|
|
|
||
|
|
if(cr < model()->rowCount() - 1)
|
||
|
|
moveTo(cr + 1, 0);
|
||
|
|
if(editTriggers() == QAbstractItemView::AllEditTriggers)
|
||
|
|
edit(currentIndex());
|
||
|
|
}
|
||
|
|
else
|
||
|
|
QTreeView::keyPressEvent(e);
|
||
|
|
}
|
||
|
|
else if(e->key() == Qt::Key_Left /*&& currentIndex().row() == model()->rowCount() - 1*/)
|
||
|
|
{
|
||
|
|
qint32 cr = currentIndex().row(),
|
||
|
|
cc = currentIndex().column(),
|
||
|
|
c = model()->columnCount();
|
||
|
|
|
||
|
|
QHeaderView *hdr = static_cast<QHeaderView*>(header());
|
||
|
|
|
||
|
|
if(hdr)
|
||
|
|
cc = hdr->visualIndex(cc);
|
||
|
|
|
||
|
|
if(cc - 1 > -1)
|
||
|
|
{
|
||
|
|
moveTo(cr, cc - 1);
|
||
|
|
|
||
|
|
if(editTriggers() == QAbstractItemView::AllEditTriggers)
|
||
|
|
edit(currentIndex());
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
else if(bNextRowOnLastCol)
|
||
|
|
{
|
||
|
|
// TODO: comporbar si tiene hijos y si tiene mover el selector a este.
|
||
|
|
|
||
|
|
if(cr < model()->rowCount() - 1)
|
||
|
|
moveTo(cr + 1, 0);
|
||
|
|
if(editTriggers() == QAbstractItemView::AllEditTriggers)
|
||
|
|
edit(currentIndex());
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
else
|
||
|
|
QTreeView::keyPressEvent(e);
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
else if(e->key() == Qt::Key_Up)
|
||
|
|
{
|
||
|
|
qint32 cr = currentIndex().row(),
|
||
|
|
cc = currentIndex().column(),
|
||
|
|
c = model()->columnCount();
|
||
|
|
|
||
|
|
if(cr > 0)
|
||
|
|
moveTo(cr - 1, currentIndex().column());
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
else if(e->key() == Qt::Key_Down && currentIndex().row() == model()->rowCount() - 1)
|
||
|
|
{
|
||
|
|
addNewRecord(currentIndex());
|
||
|
|
|
||
|
|
//QTreeView::keyPressEvent(e); // quitar esto
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
else if(e->key() == Qt::Key_Down)
|
||
|
|
{
|
||
|
|
qint32 cr = currentIndex().row(),
|
||
|
|
cc = currentIndex().column(),
|
||
|
|
c = model()->columnCount();
|
||
|
|
|
||
|
|
if(cr < model()->rowCount() - 1)
|
||
|
|
moveTo(cr + 1, currentIndex().column());
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
else
|
||
|
|
{
|
||
|
|
QModelIndex c(currentIndex());
|
||
|
|
|
||
|
|
QTreeView::keyPressEvent(e);
|
||
|
|
|
||
|
|
if(c.row() != currentIndex().row() || c.column() != currentIndex().column())
|
||
|
|
{
|
||
|
|
selectionModel()->select(currentIndex(), QItemSelectionModel::Select);
|
||
|
|
selectionModel()->select(c, QItemSelectionModel::Deselect);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::moveTo(int r, int c)
|
||
|
|
{
|
||
|
|
QHeaderView *hdr = static_cast<QHeaderView*>(header());
|
||
|
|
if(!hdr)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if(c > hdr->count() - 1)
|
||
|
|
c = hdr->count() - 1;
|
||
|
|
|
||
|
|
if(r > model()->rowCount() - 1)
|
||
|
|
r = model()->rowCount() - 1;
|
||
|
|
|
||
|
|
c = nextVisibleIndex(hdr->logicalIndex(c));
|
||
|
|
|
||
|
|
QModelIndex oi = currentIndex(),
|
||
|
|
ix = model()->index(r, c, oi.parent().isValid() ? oi.parent() : QModelIndex());
|
||
|
|
|
||
|
|
qDebug() << "Pos" << r << ":" << c << "MoveTo" << ix << "IsValid ?" << ix.isValid();
|
||
|
|
if(ix.isValid())
|
||
|
|
{
|
||
|
|
QItemSelection os(currentIndex(), currentIndex());
|
||
|
|
|
||
|
|
setCurrentIndex(ix);
|
||
|
|
selectionModel()->setCurrentIndex(ix, QItemSelectionModel::ClearAndSelect);
|
||
|
|
|
||
|
|
QItemSelection ns(currentIndex(), currentIndex());
|
||
|
|
|
||
|
|
QTreeView::selectionChanged(os, ns);
|
||
|
|
|
||
|
|
qDebug() << "MOveTo" << currentIndex();
|
||
|
|
//emit onPositionChanged(currentRow(), currentColumn());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int QMTreeView::nextVisibleIndex(int c)
|
||
|
|
{
|
||
|
|
QHeaderView *hdr = static_cast<QHeaderView*>(header());
|
||
|
|
if(!hdr)
|
||
|
|
return c;
|
||
|
|
|
||
|
|
if(c > hdr->count() - 1)
|
||
|
|
return nextVisibleIndex(hdr->count() - 1);
|
||
|
|
|
||
|
|
for(int i = c; i < hdr->count() - 1; i++)
|
||
|
|
{
|
||
|
|
if(!hdr->isSectionHidden(i))
|
||
|
|
return i;
|
||
|
|
}
|
||
|
|
return c;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool QMTreeView::addNewRecord(const QModelIndex &index)
|
||
|
|
{
|
||
|
|
if(editTriggers() == QAbstractItemView::NoEditTriggers) // read Only
|
||
|
|
return false;
|
||
|
|
|
||
|
|
insertRow();
|
||
|
|
scrollToBottom();
|
||
|
|
moveTo(model()->rowCount(), nextVisibleIndex(0));
|
||
|
|
|
||
|
|
/*
|
||
|
|
if(!bCanAddRow)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
if(model() && model()->inherits("PBSDataModel"))
|
||
|
|
{
|
||
|
|
PBSDataModel *pModel = static_cast<PBSDataModel*>(model());
|
||
|
|
if(pModel)
|
||
|
|
{
|
||
|
|
int r = currentIndex().row(),
|
||
|
|
c = currentIndex().column();
|
||
|
|
|
||
|
|
if(!pModel->haveEmptyRow())
|
||
|
|
{
|
||
|
|
pModel->insertEmptyRow();
|
||
|
|
emit newRecordAdd();
|
||
|
|
|
||
|
|
resizeRowToContents(pModel->rowCount());
|
||
|
|
scrollToBottom();
|
||
|
|
|
||
|
|
if(bGotoFirstCellOnNewRec)
|
||
|
|
c = nextVisibleIndex(0);
|
||
|
|
moveTo(pModel->rowCount(), c);
|
||
|
|
|
||
|
|
emit newRecordAdd();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
model()->insertRow(model()->rowCount(QModelIndex()));
|
||
|
|
model()->submit();
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::insertChild()
|
||
|
|
{
|
||
|
|
QModelIndex selindex = selectionModel()->currentIndex();
|
||
|
|
QAbstractItemModel *treemodel = model();
|
||
|
|
|
||
|
|
if (treemodel->columnCount(selindex) == 0)
|
||
|
|
{
|
||
|
|
if (!treemodel->insertColumn(0, selindex))
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!treemodel->insertRow(0, treemodel->index(selindex.row(), 0, selindex.parent())))
|
||
|
|
return;
|
||
|
|
|
||
|
|
/*
|
||
|
|
for (int column = 0; column < treemodel->columnCount(selindex); ++column)
|
||
|
|
{
|
||
|
|
QModelIndex child = treemodel->index(0, column, selindex);
|
||
|
|
treemodel->setData(child, QVariant(""), Qt::EditRole);
|
||
|
|
if (!treemodel->headerData(column, Qt::Horizontal).isValid())
|
||
|
|
treemodel->setHeaderData(column, Qt::Horizontal, QVariant("[No header]"), Qt::EditRole);
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
selectionModel()->setCurrentIndex(treemodel->index(0, 0, selindex),
|
||
|
|
QItemSelectionModel::ClearAndSelect);
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::addRow()
|
||
|
|
{
|
||
|
|
//QModelIndex selindex = selectionModel()->currentIndex();
|
||
|
|
QAbstractItemModel *treemodel = model();
|
||
|
|
|
||
|
|
if (!treemodel->insertRow(treemodel->rowCount()))
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::insertRow()
|
||
|
|
{
|
||
|
|
QModelIndex selindex = selectionModel()->currentIndex();
|
||
|
|
QAbstractItemModel *treemodel = model();
|
||
|
|
|
||
|
|
//int i = 1;
|
||
|
|
//setFirstColumnSpanned(i, model()->index(i, 0), true);
|
||
|
|
|
||
|
|
if (!treemodel->insertRow(selindex.row() + 1, selindex.parent()))
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::removeRow()
|
||
|
|
{
|
||
|
|
QModelIndex selindex = selectionModel()->currentIndex();
|
||
|
|
QAbstractItemModel *treemodel = model();
|
||
|
|
treemodel->removeRow(selindex.row(), selindex.parent());
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::onCornerButtonRelease()
|
||
|
|
{
|
||
|
|
QMenu *menu = new QMenu();
|
||
|
|
menu->addAction(new QAction("javi"));
|
||
|
|
menu->exec();
|
||
|
|
|
||
|
|
//QPushButton *bt = static_cast<QPushButton *>(cornerWidget());
|
||
|
|
//bt->setMenu(menu);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void QMTreeView::dragEnterEvent(QDragEnterEvent *event) {
|
||
|
|
if (event->mimeData()->hasText()) {
|
||
|
|
event->acceptProposedAction();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::dragMoveEvent(QDragMoveEvent *event) {
|
||
|
|
if (event->mimeData()->hasText()) {
|
||
|
|
event->acceptProposedAction();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void QMTreeView::dropEvent(QDropEvent *event) {
|
||
|
|
if (event->mimeData()->hasText()) {
|
||
|
|
QString data = event->mimeData()->text();
|
||
|
|
QStringList items = data.split("\n");
|
||
|
|
|
||
|
|
// Aquí puedes insertar los datos en el modelo del QTreeView
|
||
|
|
QAbstractItemModel *treeModel = model();
|
||
|
|
for (const QString &item : items) {
|
||
|
|
if (!item.isEmpty()) {
|
||
|
|
QModelIndex parentIndex = currentIndex();
|
||
|
|
treeModel->insertRow(treeModel->rowCount(parentIndex), parentIndex);
|
||
|
|
QModelIndex newItemIndex = treeModel->index(treeModel->rowCount(parentIndex) - 1, 0, parentIndex);
|
||
|
|
treeModel->setData(newItemIndex, item);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
event->acceptProposedAction();
|
||
|
|
}
|
||
|
|
}
|