/* Copyright 2016 Lee Cho Kang.
* email: pzesseto@gmail.com
* This file is part of the RbTableHeaderView.
*
* The RbTableHeaderView is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* The RbTableHeaderView is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the RbTableHeaderView. If not, see http://www.gnu.org/licenses/.
*/
/*
* RbTableHeaderView.h
* Created on: 2016. 6. 13.
*/
#include "RbTableHeaderView.h"
#include <QPainter>
#include <QStandardItem>
#include <QMouseEvent>
#include <qdrawutil.h>
RbTableHeaderItem::RbTableHeaderItem(RbTableHeaderItem* parent):
row_prop(0),column_prop(0),parent_item(parent)
{
}
RbTableHeaderItem::RbTableHeaderItem(int arow, int acolumn, RbTableHeaderItem* parent):
row_prop(arow),column_prop(acolumn),parent_item(parent)
{
}
RbTableHeaderItem::~RbTableHeaderItem()
{
}
RbTableHeaderItem* RbTableHeaderItem::insertChild(int row, int col)
{
RbTableHeaderItem* newChild = new RbTableHeaderItem(row,col,this);
child_items.insert(QPair<int,int>(row,col),newChild);
return newChild;
}
const RbTableHeaderItem* RbTableHeaderItem::child(int row,int col) const
{
QHash<QPair<int,int>,RbTableHeaderItem*>::const_iterator itr = child_items.find(QPair<int,int>(row,col));
if (itr != child_items.end()) return itr.value();
return 0;
}
RbTableHeaderItem* RbTableHeaderItem::child(int row,int col)
{
QHash<QPair<int,int>,RbTableHeaderItem*>::iterator itr = child_items.find(QPair<int,int>(row,col));
if (itr != child_items.end()) return itr.value();
return 0;
}
void RbTableHeaderItem::setText(const QString& text)
{
role_datas.insert(Qt::DisplayRole,text);
}
QVariant RbTableHeaderItem::data(int role) const
{
QHash<int,QVariant>::const_iterator itr = role_datas.find(role);
if (itr != role_datas.end()) return itr.value();
return QVariant();
}
void RbTableHeaderItem::setData(const QVariant& data, int role)
{
role_datas.insert(role,data);
}
void RbTableHeaderItem::clear()
{
QList<RbTableHeaderItem*> items = child_items.values();
foreach (RbTableHeaderItem* item, child_items)
{
if (item) delete item;
}
child_items.clear();
}
RbTableHeaderModel::RbTableHeaderModel(int rows, int cols, QObject* parent) :
QAbstractTableModel(parent),row_count_prop(rows),column_count_prop(cols),root_item(new RbTableHeaderItem())
{
}
RbTableHeaderModel::~RbTableHeaderModel()
{
root_item->clear();
delete root_item;
}
QModelIndex RbTableHeaderModel::index(int row, int column, const QModelIndex & parent) const
{
if (!hasIndex(row,column,parent)) return QModelIndex();
RbTableHeaderItem* parentItem;
if (!parent.isValid()) parentItem = root_item; // parent item is always the root_item on table model
else parentItem = static_cast<RbTableHeaderItem*>(parent.internalPointer()); // no effect
RbTableHeaderItem* childItem = parentItem->child(row,column);
if (!childItem) childItem = parentItem->insertChild(row,column);
return createIndex(row,column,childItem);
return QModelIndex();
}
QVariant RbTableHeaderModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= row_count_prop || index.row() < 0 || index.column() >= column_count_prop || index.column() < 0)
return QVariant();
RbTableHeaderItem* item = static_cast<RbTableHeaderItem*>(index.internalPointer());
return item->data(role);
}
bool RbTableHeaderModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
if (index.isValid())
{
RbTableHeaderItem* item = static_cast<RbTableHeaderItem*>(index.internalPointer());
if (role == COLUMN_SPAN_ROLE)
{
int col = index.column();
int span = value.toInt();
if (span > 0) // span size should be more than 1, else nothing to do
{
if (col+span-1 >= column_count_prop) // span size should be less than whole columns,
span = column_count_prop-col;
item->setData(span,COLUMN_SPAN_ROLE);
}
}
else if (role == ROW_SPAN_ROLE)
{
int row = index.row();
int span = value.toInt();
if (span > 0) // span size should be more than 1, else nothing to do
{
if (row+span-1 >= row_count_prop)
span = row_count_prop-row;
item->setData(span,ROW_SPAN_ROLE);
}
}
else
item->setData(value,role);
return true;
}
return false;
}
// Qt::ItemFlags RbTableHeaderModel::flags(const QModelIndex &index) const
// {
// if (!index.isValid())
// return Qt::ItemIsEnabled;
// return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
// }
RbTableHeaderView::RbTableHeaderView(Qt::Orientation orientation, int rows, int columns, QWidget* parent):
QHeaderView(orientation,parent)
{
QSize baseSectionSize;
if (orientation == Qt::Horizontal)
{
baseSectionSize.setWidth(defaultSectionSize());
baseSectionSize.setHeight(20);
}
else
{
baseSectionSize.setWidth(50);
baseSectionSize.setHeight(defaultSectionSize());
}
// create header model
RbTableHeaderModel* headerModel = new RbTableHeaderModel(rows,columns);
// set default size of item
for (int row=0;row<rows;++row)
for (int col=0;col<columns;++col)
headerModel->setData(headerModel->index(row,col),baseSectionSize,Qt::SizeHintRole);
setModel(headerModel);
connect(this, SIGNAL(sectionResized(int, int, int)), this, SLOT(onSectionResized(int,int,int)));
}
RbTableHeaderView::~RbTableHeaderView()
{
}
void RbTableHeaderView::setRowHeight(int row, int rowHeight)
{
RbTableHeaderModel* md = qobject_cast<RbTableHeaderModel*>(model());
const int cols = md->columnCount();
for (int col=0;col<cols;++col)
{
QSize sz = md->index(row,col).data(Qt::SizeHintRole).toSize();
sz.setHeight(rowHeight);
md->setData(md->index(row,col),sz,Qt::SizeHintRole);
}
if (orientation() == Qt::Vertical)
resizeSection(row,rowHeight);
}
void RbTableHeaderView::setColumnWidth(int col, int colWidth)
{
RbTableHeaderModel* md = qobject_cast<RbTableHeaderModel*>(model());
const int rows = md->rowCount();
for (int row=0;row<rows;++row)
{
QSize sz = md->index(row,col).data(Qt::SizeHintRole).toSize();
sz.setWidth(colWidth);
md->setData(md->index(row,col),sz,Qt::SizeHintRole);
}
if (orientation() == Qt::Horizontal)
resizeSection(col,colWidth);
}
void RbTableHeaderView::setSpan(int row, int column, int rowSpanCount, int columnSpanCount)
{
RbTableHeaderModel* md = qobject_cast<RbTableHeaderModel*>(model());
QModelIndex idx = md->index(row,column);
if (rowSpanCount > 0)
md->setData(idx,rowSpanCount,ROW_SPAN_ROLE);
if (columnSpanCount)
md->setData(idx,columnSpanCount,COLUMN_SPAN_ROLE);
}
void RbTableHeaderView::setCellBackgroundColor(const QModelIndex& index, const QColor& color)
{
RbTableHeaderModel* md = qobject_cast<RbTableHeaderModel*>(model());
md->setData(index,color,Qt::BackgroundRole);
}
void RbTableHeaderView::setCellForegroundColor(const QModelIndex& index, const QColor& color)
{
RbTableHeaderModel* md = qobject_cast<RbTableHeaderModel*>(model());
md->setData(index,color,Qt::ForegroundRole);
}
void RbTableHeaderView::mousePressEvent(QMouseEvent* event)
{
QHeaderView::mousePressEvent(event);
QPoint pos = event->pos();
QModelIndex index = indexAt(pos);
const int OTN = orientation();
if (index.isValid())
{
int beginSection = -1;
int endSection = -1;
int numbers = 0;
numbers = getSectionRange(index,&beginSection,&endSection);
if (numbers > 0)
{
emit sectionPressed(beginSection,endSection);
return;
}
else
{
const RbTableHeaderModel* tblModel = qobject_cast<RbTableHeaderModel*>(this->model());
const int LEVEL_CNT = (OTN == Qt::Horizontal)?tblModel-
评论3
最新资源