#include "GroupView.h"
#include <QPainter>
#include <QApplication>
#include <QtMath>
#include <QMouseEvent>
#include <QListView>
#include <QPersistentModelIndex>
#include <QDrag>
#include <QMimeData>
#include <QCache>
#include <QScrollBar>
#include "VisualGroup.h"
#include <QDebug>
template <typename T> bool listsIntersect(const QList<T> &l1, const QList<T> t2)
{
for (auto &item : l1)
{
if (t2.contains(item))
{
return true;
}
}
return false;
}
GroupView::GroupView(QWidget *parent)
: QAbstractItemView(parent)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setAcceptDrops(true);
setAutoScroll(true);
}
GroupView::~GroupView()
{
qDeleteAll(m_groups);
m_groups.clear();
}
void GroupView::setModel(QAbstractItemModel *model)
{
QAbstractItemView::setModel(model);
connect(model, &QAbstractItemModel::modelReset, this, &GroupView::modelReset);
}
void GroupView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles)
{
scheduleDelayedItemsLayout();
}
void GroupView::rowsInserted(const QModelIndex &parent, int start, int end)
{
scheduleDelayedItemsLayout();
}
void GroupView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
scheduleDelayedItemsLayout();
}
class LocaleString : public QString
{
public:
LocaleString(const char *s) : QString(s)
{
}
LocaleString(const QString &s) : QString(s)
{
}
};
inline bool operator<(const LocaleString &lhs, const LocaleString &rhs)
{
return (QString::localeAwareCompare(lhs, rhs) < 0);
}
void GroupView::updateGeometries()
{
geometryCache.clear();
int previousScroll = verticalScrollBar()->value();
QMap<LocaleString, VisualGroup *> cats;
for (int i = 0; i < model()->rowCount(); ++i)
{
const QString groupName =
model()->index(i, 0).data(GroupViewRoles::GroupRole).toString();
if (!cats.contains(groupName))
{
VisualGroup *old = this->category(groupName);
if (old)
{
cats.insert(groupName, new VisualGroup(old));
}
else
{
cats.insert(groupName, new VisualGroup(groupName, this));
}
}
}
/*if (m_editedCategory)
{
m_editedCategory = cats[m_editedCategory->text];
}*/
qDeleteAll(m_groups);
m_groups = cats.values();
for (auto cat : m_groups)
{
cat->update();
}
if (m_groups.isEmpty())
{
verticalScrollBar()->setRange(0, 0);
}
else
{
int totalHeight = 0;
// top margin
totalHeight += m_categoryMargin;
int itemScroll = 0;
for (auto category : m_groups)
{
category->m_verticalPosition = totalHeight;
totalHeight += category->totalHeight() + m_categoryMargin;
if(!itemScroll && category->totalHeight() != 0)
{
itemScroll = category->contentHeight() / category->numRows();
}
}
// do not divide by zero
if(itemScroll == 0)
itemScroll = 64;
totalHeight += m_bottomMargin;
verticalScrollBar()->setSingleStep ( itemScroll );
const int rowsPerPage = qMax ( viewport()->height() / itemScroll, 1 );
verticalScrollBar()->setPageStep ( rowsPerPage * itemScroll );
verticalScrollBar()->setRange(0, totalHeight - height());
}
verticalScrollBar()->setValue(qMin(previousScroll, verticalScrollBar()->maximum()));
viewport()->update();
}
void GroupView::modelReset()
{
scheduleDelayedItemsLayout();
executeDelayedItemsLayout();
}
bool GroupView::isIndexHidden(const QModelIndex &index) const
{
VisualGroup *cat = category(index);
if (cat)
{
return cat->collapsed;
}
else
{
return false;
}
}
VisualGroup *GroupView::category(const