NOISSUE use model/view for Minecraft log data

This commit is contained in:
Petr Mrázek
2016-08-18 21:31:37 +02:00
parent 9aff21c181
commit 67eca08b22
11 changed files with 555 additions and 182 deletions

View File

@ -0,0 +1,143 @@
#include "LogView.h"
#include <QTextBlock>
#include <QScrollBar>
LogView::LogView(QWidget* parent) : QPlainTextEdit(parent)
{
setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
m_defaultFormat = new QTextCharFormat(currentCharFormat());
}
LogView::~LogView()
{
}
void LogView::setWordWrap(bool wrapping)
{
if(wrapping)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setLineWrapMode(QPlainTextEdit::WidgetWidth);
}
else
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setLineWrapMode(QPlainTextEdit::NoWrap);
}
}
void LogView::setModel(QAbstractItemModel* model)
{
if(m_model)
{
disconnect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
disconnect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
disconnect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
disconnect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
}
m_model = model;
if(m_model)
{
connect(m_model, &QAbstractItemModel::modelReset, this, &LogView::repopulate);
connect(m_model, &QAbstractItemModel::rowsInserted, this, &LogView::rowsInserted);
connect(m_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &LogView::rowsAboutToBeInserted);
connect(m_model, &QAbstractItemModel::rowsRemoved, this, &LogView::rowsRemoved);
connect(m_model, &QAbstractItemModel::destroyed, this, &LogView::modelDestroyed);
}
repopulate();
}
QAbstractItemModel * LogView::model() const
{
return m_model;
}
void LogView::modelDestroyed(QObject* model)
{
if(m_model == model)
{
setModel(nullptr);
}
}
void LogView::repopulate()
{
auto doc = document();
doc->clear();
if(!m_model)
{
return;
}
rowsInserted(QModelIndex(), 0, m_model->rowCount() - 1);
}
void LogView::rowsAboutToBeInserted(const QModelIndex& parent, int first, int last)
{
Q_UNUSED(parent)
Q_UNUSED(first)
Q_UNUSED(last)
QScrollBar *bar = verticalScrollBar();
int max_bar = bar->maximum();
int val_bar = bar->value();
if (m_scroll)
{
m_scroll = (max_bar - val_bar) <= 1;
}
else
{
m_scroll = val_bar == max_bar;
}
}
void LogView::rowsInserted(const QModelIndex& parent, int first, int last)
{
for(int i = first; i <= last; i++)
{
auto idx = m_model->index(i, 0, parent);
auto text = m_model->data(idx, Qt::DisplayRole).toString();
QTextCharFormat format(*m_defaultFormat);
auto font = m_model->data(idx, Qt::FontRole);
if(font.isValid())
{
format.setFont(font.value<QFont>());
}
auto fg = m_model->data(idx, Qt::TextColorRole);
if(fg.isValid())
{
format.setForeground(fg.value<QColor>());
}
auto bg = m_model->data(idx, Qt::BackgroundRole);
if(bg.isValid())
{
format.setBackground(bg.value<QColor>());
}
auto workCursor = textCursor();
workCursor.movePosition(QTextCursor::End);
workCursor.insertText(text, format);
workCursor.insertBlock();
}
if(m_scroll && !m_scrolling)
{
m_scrolling = true;
QMetaObject::invokeMethod( this, "scrollToBottom", Qt::QueuedConnection);
}
}
void LogView::rowsRemoved(const QModelIndex& parent, int first, int last)
{
// TODO: some day... maybe
Q_UNUSED(parent)
Q_UNUSED(first)
Q_UNUSED(last)
}
void LogView::scrollToBottom()
{
m_scrolling = false;
verticalScrollBar()->setSliderPosition(verticalScrollBar()->maximum());
}
void LogView::findNext(const QString& what, bool reverse)
{
find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
}

View File

@ -0,0 +1,36 @@
#pragma once
#include <QPlainTextEdit>
#include <QAbstractItemView>
class QAbstractItemModel;
class LogView: public QPlainTextEdit
{
Q_OBJECT
public:
explicit LogView(QWidget *parent = nullptr);
virtual ~LogView();
virtual void setModel(QAbstractItemModel *model);
QAbstractItemModel *model() const;
public slots:
void setWordWrap(bool wrapping);
void findNext(const QString & what, bool reverse);
void scrollToBottom();
protected slots:
void repopulate();
// note: this supports only appending
void rowsInserted(const QModelIndex &parent, int first, int last);
void rowsAboutToBeInserted(const QModelIndex &parent, int first, int last);
// note: this supports only removing from front
void rowsRemoved(const QModelIndex &parent, int first, int last);
void modelDestroyed(QObject * model);
protected:
QAbstractItemModel *m_model = nullptr;
QTextCharFormat *m_defaultFormat = nullptr;
bool m_scroll = false;
bool m_scrolling = false;
};