#include <QtGui>
#include <QByteArray>
#include <QLinearGradient>
#include "TreeItem.h"
#include "TreeModel.h"
#include "TreeView.h"
TreeModel::TreeModel(const QList<Group> &data, const QList<Leaf> &values, QObject *parent, TreeView* view)
: QAbstractItemModel(parent)
{
//QList<QVariant> rootData;
//QString rootData = "Name";// << "Comments";
rootItem = NULL;
view_ = view;
groups_ = data;
leafs_ = values;
setupModelData();// .split(QString("\n")), rootItem);
}
TreeModel::~TreeModel()
{
delete rootItem;
}
void TreeModel::addNewGroup(QString value)
{
groups_.push_back(Group(value,groups_.size(),-1));
setupModelData();
reset();
}
void TreeModel::removeGroup(int groupId)
{
QList<Group> result;
for(QList<Group>::iterator it = groups_.begin(), itend = groups_.end();
it != itend; ++it)
if( it->groupId() != groupId)
result.push_back(*it);
groups_ = result;
setupModelData();
//emit dataChanged();
reset();
}
int TreeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
bool TreeModel::setData ( const QModelIndex & index, const QVariant & value, int role )
{
if( role == Qt::EditRole)
{
TreeItem* item = getItem(index);// static_cast<TreeItem*>(index.internalPointer());
if( !item->isLeaf() )
{
GroupTreeItem* gti = (GroupTreeItem*)item;
int pos = findGroupPositionById( gti->getGroupInfo()->groupId() );
if( pos >=0 )
{
groups_[pos].setName(value.toString());
item->setData(value.toString());
}
}
return true;
}
else
{
return false;
}
}
int TreeModel::findLeafPositionByName(QString name)
{
int pos = 0;
for(QList<Leaf>::iterator it = leafs_.begin(), itend = leafs_.end();
it != itend; ++it)
{
Leaf s = (*it);
if( s.name() == name )
return pos;
pos++;
}
return -1;
}
int TreeModel::findGroupPositionById(int groupId)
{
int pos = 0;
for(QList<Group>::iterator it = groups_.begin(), itend = groups_.end();
it != itend; ++it)
{
Group g = (*it);
if( g.groupId() == groupId )
return pos;//&(*it);
pos++;
}
return -1;
}
TreeItem* TreeModel::getItem(const QModelIndex &index)const
{
TreeItem* ti = static_cast<TreeItem*>(index.internalPointer());
return ti;
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
switch( role )
{
case Qt::DecorationRole:
{
TreeItem *item = getItem(index);
if( item->isLeaf() )
return QIcon(":/Resources/putty-icon.png");
else
return QIcon(":/Resources/folder.png");
break;
}
case Qt::EditRole:
{
TreeItem *item = getItem(index);//static_cast<TreeItem*>(index.internalPointer());
return item->data(index.column());
break;
}
break;
case Qt::DisplayRole:
{
TreeItem *item = getItem(index);//static_cast<TreeItem*>(index.internalPointer());
return item->data(index.column());
break;
}
// case Qt::BackgroundRole:
// {
// /*QLinearGradient gradient(0, 0, 50, 5);
// gradient.setColorAt(0, QColor::fromRgbF(0, 1, 0, 1));
// gradient.setColorAt(1, QColor::fromRgbF(0, 0, 0, 0));
// */
// /* int lastVal=0;
// QBrush brush(QColor(0, 0, 0, 64));
// //QLinearGradient gradient(rect().topLeft(), rect().bottomRight());
// QLinearGradient gradient(0,0, 100,5);
// const QColor col = brush.color();
// gradient.setColorAt(0, col);
// gradient.setColorAt(1, col.dark(int(200 + lastVal * 50)));*/
// /* QLinearGradient linearGradient(0, 0, 100, 50);
// linearGradient.setColorAt(0.0, Qt::white);
// linearGradient.setColorAt(0.2, Qt::green);
// linearGradient.setColorAt(1.0, Qt::black);
//*/
// QGradientStops stops;
// //QLinearGradient gradient(frame.topLeft(), frame.topLeft() + QPointF(200,200));
// QLinearGradient gradient(0,0,100,50);
// stops << QGradientStop(0.0, QColor(60, 60, 60));
// stops << QGradientStop(0.5, QColor(102, 176, 54));
// //stops << QGradientStop(((frame.height() + h)/2 )/frame.height(), QColor(157, 195, 55));
// stops << QGradientStop(1.0, QColor(215, 215, 215));
// gradient.setStops(stops);
// //gradient.setStart(innerFrame.topLeft());
// //gradient.setFinalStop(innerFrame.bottomRight());
// stops.clear();
// stops << QGradientStop(0.0, QColor(215, 255, 200));
// stops << QGradientStop(0.5, QColor(102, 176, 54));
// stops << QGradientStop(1.0, QColor(0, 0, 0));
// gradient.setStops(stops);
// //painter->setBrush(QBrush(gradient));
// //QGradient gardient;
// //gardient.setCoordinateMode(QLinearGradient);
// //QColor c( 209,121,59 );
// //int factor = 200;
// //return QVariant( QBrush( c.darker(factor) ) );
// return QVariant( QBrush( gradient ) );
// }
// break;
default:
return QVariant();
}
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
// if (!index.isValid())
// return 0;
// return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
if(!index.isValid())
return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;
Qt::ItemFlags flags;
TreeItem* item = getItem(index);
//if( item->isLeaf() )
// flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled| Qt::ItemIsDropEnabled;
//else
flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled| Qt::ItemIsDropEnabled;
//if(mColumns.at(index.column()).isEditable)
if( !item->isLeaf() )
flags |= Qt::ItemIsEditable;
return flags;
}
Qt::DropActions TreeModel::supportedDropActions() const
{
//return Qt::CopyAction | Qt::MoveAction;
return Qt::MoveAction;
}
bool TreeModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
if (action == Qt::IgnoreAction)
return true;
qDebug() << "dropMimeData: " << "row=" << row << ",column=" << column << ",parent=" << parent;
if(!data->hasFormat("application/x-qabstractitemmodeldatalist") )
return true;
QByteArray encoded = data->data("application/x-qabstractitemmodeldatalist");
QDataStream stream(&encoded, QIODevice::ReadOnly);
while (!stream.atEnd())
{
int fromrow, fromcol;
QMap<int, QVariant> roleDataMap;
stream >> fromrow >> fromcol >> roleDataMap;
qDebug() << "fromrow=" << fromrow << ",fromcol=" << fromcol << ",roleDataMap=" << roleDataMap;
QVariant v = roleDataMap[0];
QModelIndexList selectList = view_->selectedIndexes();
if( selectList.size() == 0 )
break;
//GroupTreeItem* item2Move = (GroupTreeItem*)rootItem->findChildByText(v.toString());
//QList<QTreeWidgetItem *> selectList = this->in selectedItems();
//TreeItem* item2Move = selectList.at(0);
const QModelIndex selectedindex = selectList.at(0);
TreeItem* item2Move = getItem(selectedindex);
//TreeItem* item2Move = rootItem->findChildByText(v.toString());
if( item2Move )
{
GroupTreeItem* item;
if( parent.isValid())
item = (GroupTreeItem*)getItem(parent);
else
item = (GroupTreeItem*)rootItem;
if(item2Move->isLeaf())
{
int pos = findLeafPositionByName(((LeafTreeItem*)item2Move)->getLeafInfo()->name());
if( row >0 )
{
TreeItem* treeit = item->child(row-1);
if( treeit->isLeaf() )
{
QMessageBox::warning(NULL,tr("Operation not possible"),tr("You can move PuTTY sessions only to groups"));
}
else
{
qDebug() << leafs_[pos].name() << " now have parent: " << ((GroupTreeItem*)treeit)->getGroupInfo()->groupId();
leafs_[pos].setGroupId(((GroupTreeItem*)treeit)->getGroupInfo()->groupId());
}
}else{
qDebug() << leafs_[pos].name() << " now have root parent ";
leafs_[pos].setGroupId(((GroupTreeItem*)rootItem)->getGroupInfo()->groupId());
}
}
else
{
int pos =/*Group* g =*/ findGroupPositionById(((GroupTreeItem*)item2Move)->getGroupInfo()->groupId());
if( row >0 )
{
item = (GroupTreeItem*)item->child(row-1);
//qDebug() << groups_[pos].groupId() << " now have parent: " << item->getGroupInfo()->groupId();
groups_[pos].setParentGroupId(item->getGroupInfo()->groupId());
}else{
//qDebug() << groups_[pos].groupId() << " now have root parent ";
groups_[pos].setParentGroupId(((GroupTreeItem*)rootItem)->getGroupInfo()->groupId());
}
}
setupModelData();
reset();
view_->expandAll();
}
}
//QList<QUrl> dd = data->urls();
//qDebug() << dd;
//qDebug() << data->data();
return true;
}
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
//if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
// return rootItem->data(section);
return QVariant();
}
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
TreeItem *parentItem;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
TreeItem *parentItem = childItem->parent();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int TreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentItem;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
return parentItem->childCount();
}
void TreeModel::recreateLeafs()
{
foreach(Leaf s, leafs_)
{
//if( s.groupId() == -1 )
//{
TreeItem* myparent = dynamic_cast<GroupTreeItem*>(rootItem)->findChildByGroupId(s.groupId());
if( myparent )
myparent->appendChild(new LeafTreeItem(s, myparent ));
//}
}
}
void TreeModel::recreateNodes()
{
if(rootItem)
delete rootItem;
rootItem = new GroupTreeItem(Group("Name",-1,-1));
// foreach(Group g, groups_)
// {
// qDebug() << g.name() << "of id:" << g.groupId() << ", parent:" << g.parentGroupId();
// }
foreach(Group g, groups_)
{
if( g.parentGroupId() == -1 )
{
rootItem->appendChild(new GroupTreeItem(g, rootItem ));
}
}
for(int i=0;i<groups_.size();++i)
//foreach(Group g, groups_)
{
if( i < 0 )
continue;
Group g = groups_[i];
if( g.parentGroupId() == -1 )
continue;
TreeItem* test = dynamic_cast<GroupTreeItem*>(rootItem)->findChildByGroupId(g.groupId());
if( test ) //already in tree
continue;
if( GroupTreeItem* gti = dynamic_cast<GroupTreeItem*>(rootItem) )
{
TreeItem* it = gti->findChildByGroupId(g.parentGroupId());
if( it )
{
it->appendChild(new GroupTreeItem(g, it ));
i=-1;
continue;
}
}
}
}
void TreeModel::setupModelData()
{
recreateNodes();
recreateLeafs();
}
void TreeModel::refreshMe()
{
layoutChanged();
}
const TreeItem* TreeModel::getRootItem()const
{
return rootItem;
}
/*
bool TreeModel::canFetchMore(const QModelIndex& parent) const
{
if (!parent.isValid()) return false;
TreeItem *node = static_cast<TreeItem*>(parent.internalPointer());
return parentNode->hasChildren && !parentNode->children.count();
}
void TreeModel::fetchMore (const QModelIndex& parent)
{
if (!canFetchMore(parent)) return;
TreeItem *node = static_cast<TreeItem*>(parent.internalPointer());
beginInsertRows(node, 0, mm_IDs.count()-1);
setLists(node, mm_IDs, mm_Names);
endInsertRows();
}*/
void TreeModel::addItem(QString text, QString comments, TreeItem* parent)
{
TreeItem* p = NULL;
if(parent==NULL)
p=rootItem;
else
p = parent;
QModelIndex parentIndex=createIndex(p->row(),0,p);
//parentIndex = parentIndex.child(0,0);
beginInsertRows(parentIndex,p->childCount(),p->childCount());
//TreeItem *newItem=new TreeItem( (QList<QVariant>() << text << comments) ,p);
//p->appendChild(newItem);
endInsertRows();
reset();
/*
int rootRowsCount = rowCount( QModelIndex() );
qDebug() << "rootRowsCount=" << rootRowsCount;
beginInsertRows( index(rootRowsCount,0), rootRowsCount,rootRowsCount);
p->appendChild( new TreeItem( (QList<QVariant>() << text << comments) , parent) );
endInsertRows();*/
}