Commit c139b824 authored by Doug Beney's avatar Doug Beney

EFFICIENT note list!

parent 3160140e
......@@ -52,14 +52,14 @@ SOURCES += \
$$PWD/ui/note_edittags.cpp \
$$PWD/src/models/items/listitemwithid.cpp \
$$PWD/src/models/sortfilter/notelistproxymodel.cpp \
$$PWD/src/models/items/notelistitemwidget.cpp \
$$PWD/ui/edittags.cpp \
$$PWD/src/models/views/customtreeview.cpp \
$$PWD/ui/trashitem.cpp \
$$PWD/src/ui-managers/notelist-views/trashview.cpp \
$$PWD/src/ui-managers/notelist-views/genericview.cpp \
$$PWD/ui/notebook_editparent.cpp \
$$PWD/src/sql/sqlmanager.cpp
$$PWD/src/sql/sqlmanager.cpp \
src/models/delegates/noteitemdelegate.cpp
HEADERS += \
$$PWD/src/meta/info/appconfig.h \
......@@ -91,14 +91,14 @@ HEADERS += \
$$PWD/ui/note_edittags.h \
$$PWD/src/models/items/listitemwithid.h \
$$PWD/src/models/sortfilter/notelistproxymodel.h \
$$PWD/src/models/items/notelistitemwidget.h \
$$PWD/ui/edittags.h \
$$PWD/src/models/views/customtreeview.h \
$$PWD/ui/trashitem.h \
$$PWD/src/ui-managers/notelist-views/trashview.h \
$$PWD/src/ui-managers/notelist-views/genericview.h \
$$PWD/ui/notebook_editparent.h \
$$PWD/src/sql/sqlmanager.h
$$PWD/src/sql/sqlmanager.h \
src/models/delegates/noteitemdelegate.h
INCLUDEPATH += $$PWD/include
INCLUDEPATH += $$PWD/src/models/views # Location of customlistview
......
#include "noteitemdelegate.h"
#include <QPainter>
#include <QDebug>
#include <QApplication>
#include <QMouseEvent>
#include <QAbstractItemModel>
#include "../items/notelistitem.h"
NoteItemDelegate::NoteItemDelegate(QListView *view, QSortFilterProxyModel *proxyModel) :
m_view(view),
m_proxyModel(proxyModel)
{
}
QRect NoteItemDelegate::getStarRect(const QStyleOptionViewItem &option) const
{
return QRect(option.rect.x()+option.rect.width()-35,
option.rect.y()+option.rect.height()/2-12,
25,25);
}
bool NoteItemDelegate::editorEvent(QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
QRect checkboxRect = getStarRect(option);
QPoint mousePoint = mouseEvent->pos();
if ( checkboxRect.contains(mousePoint) ) {
QModelIndex realIndex = m_proxyModel->mapToSource(index);
NoteListItem *item = static_cast<NoteListItem*>( realIndex.internalPointer() );
item->note()->setFavorited( !item->note()->favorited() );
return true;
}
else
m_view->setCurrentIndex(index);
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
void NoteItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == 0 ) {
QModelIndex realIndex = m_proxyModel->mapToSource(index);
NoteListItem *item = static_cast<NoteListItem*>( realIndex.internalPointer() );
// Set the background color
QBrush background =
(option.state & QStyle::State_Selected) ?
option.palette.highlight() :
option.palette.base();
painter->fillRect(option.rect, background);
if (option.state & QStyle::State_Selected)
painter->setPen(option.palette.highlightedText().color());
else
painter->setPen(option.palette.text().color());
QRect titleRect = option.rect;
titleRect.setX(titleRect.x()+5);
titleRect.setWidth(titleRect.x()-5);
QFont font=painter->font() ;
font.setPointSize(10);
// Title
font.setWeight(QFont::Bold);
painter->setFont(font);
painter->drawText(QPoint(option.rect.x()+10, option.rect.y()+23), item->note()->title());
// Date
font.setWeight(QFont::Normal);
painter->setFont(font);
painter->drawText(QPoint(option.rect.x()+10, option.rect.y()+43), item->note()->date_created_str());
// The Excerpt
QRect excerptRect = option.rect;
excerptRect.setX( excerptRect.x()+10 );
excerptRect.setY( excerptRect.y()+50 );
excerptRect.setWidth( excerptRect.width()-50 );
QString excerpt = item->note()->text();
if (excerpt.length() > 50) {
excerpt = excerpt.mid(0, 50) + "...";
}
excerpt.replace("\n", " ");
painter->drawText(excerptRect, excerpt);
painter->fillRect(QRect(
option.rect.x() + option.rect.width() - 60,
option.rect.y(),
60,
option.rect.height()), background);
QIcon favoriteIcon;
if (item->note()->favorited())
favoriteIcon = QIcon::fromTheme("vibrato-draw-star-solid");
else
favoriteIcon = QIcon::fromTheme("vibrato-draw-star");
favoriteIcon.paint(painter, getStarRect(option));
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
QSize NoteItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return QSize(200,100);
}
#ifndef NOTEITEMDELEGATE_H
#define NOTEITEMDELEGATE_H
#include <QStyledItemDelegate>
#include <QListView>
#include <QSortFilterProxyModel>
class NoteItemDelegate : public QStyledItemDelegate
{
public:
NoteItemDelegate(QListView *view, QSortFilterProxyModel *proxyModel);
QRect getStarRect(const QStyleOptionViewItem &option) const;
bool editorEvent(QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index) override;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
private:
bool checked = false;
QListView *m_view;
QSortFilterProxyModel *m_proxyModel;
};
#endif // MYDELEGATE_H
#include "notelistitemwidget.h"
#include <ui_notelistitem.h>
#include <QDebug>
NoteListItemWidget::NoteListItemWidget( Note *note ) : m_note(note)
{
m_ui_class = new Ui::NoteListItem;
m_ui_class->setupUi( this );
m_title_label = m_ui_class->titleLabel;
m_excerpt_label = m_ui_class->excerptLabel;
m_date_created_label = m_ui_class->dateCreatedLabel;
m_favoriteButton = m_ui_class->favoriteButton;
connect(m_favoriteButton, &QToolButton::clicked,
this, &NoteListItemWidget::toggleFavorited);
updateLabels();
connectSignals();
}
NoteListItemWidget::~NoteListItemWidget()
{
delete m_ui_class;
}
Note *NoteListItemWidget::note() const
{
return m_note;
}
void NoteListItemWidget::setNote(Note *note)
{
disconnectSignals();
m_note = note;
connectSignals();
updateLabels();
}
void NoteListItemWidget::updateLabels()
{
updateTitleLabel();
updateExcerptWidget();
updateDateLabel();
updateFavoriteButton();
}
void NoteListItemWidget::updateTitleLabel() {
m_title_label->setText( m_note->title() );
}
void NoteListItemWidget::updateExcerptWidget() {
QString excerpt = m_note->text();
if (excerpt.length() > 50) {
excerpt = m_note->text().mid(0, 50) + "...";
}
excerpt.replace("\n", " ");
m_excerpt_label->setText(excerpt);
}
void NoteListItemWidget::updateDateLabel() {
m_date_created_label->setText(m_note->date_created_str());
}
void NoteListItemWidget::noteTitleChanged(Note *note)
{
(void)note;
updateLabels();
}
void NoteListItemWidget::noteTextChanged(Note *note)
{
(void)note;
updateLabels();
}
void NoteListItemWidget::noteDateChanged(Note *note)
{
(void)note;
updateLabels();
}
void NoteListItemWidget::updateFavoriteButton(void) {
m_favoriteButton->setEnabled( !m_note->trashed() );
if ( m_note->favorited() )
m_favoriteButton->setIcon( QIcon::fromTheme("vibrato-draw-star-solid") );
else
m_favoriteButton->setIcon( QIcon::fromTheme("vibrato-draw-star") );
m_favoriteButton->setChecked( m_note->favorited() );
}
void NoteListItemWidget::toggleFavorited() {
m_note->setFavorited( !m_note->favorited() );
updateFavoriteButton();
}
void NoteListItemWidget::connectSignals() {
connect(m_note, &Note::noteTitleChanged,
this, &NoteListItemWidget::noteTitleChanged);
connect(m_note, &Note::noteTextChanged,
this, &NoteListItemWidget::noteTextChanged);
connect(m_note, &Note::noteDateCreatedChanged,
this, &NoteListItemWidget::noteDateChanged);
connect(m_note, &Note::noteDateModifiedChanged,
this, &NoteListItemWidget::noteDateChanged);
connect(m_note, &Note::noteFavoritedChanged,
this, &NoteListItemWidget::updateFavoriteButton);
}
void NoteListItemWidget::disconnectSignals() {
disconnect(m_note, &Note::noteTitleChanged,
this, &NoteListItemWidget::noteTitleChanged);
disconnect(m_note, &Note::noteTextChanged,
this, &NoteListItemWidget::noteTextChanged);
disconnect(m_note, &Note::noteDateCreatedChanged,
this, &NoteListItemWidget::noteDateChanged);
disconnect(m_note, &Note::noteDateModifiedChanged,
this, &NoteListItemWidget::noteDateChanged);
disconnect(m_note, &Note::noteFavoritedChanged,
this, &NoteListItemWidget::updateFavoriteButton);
}
#ifndef NOTELISTITEMWIDGET_H
#define NOTELISTITEMWIDGET_H
#include "../../meta/note.h"
#include <QLabel>
#include <QToolButton>
namespace Ui {
class NoteListItem;
}
class NoteListItemWidget : public QWidget
{
Q_OBJECT
public:
NoteListItemWidget(Note *note);
~NoteListItemWidget();
Note *note() const;
void setNote(Note *note);
void updateLabels();
void updateTitleLabel();
void updateExcerptWidget();
void updateDateLabel();
void updateFavoriteButton(void);
void setSelectedStyle(bool selected);
void toggleFavorited();
void connectSignals();
void disconnectSignals();
private:
Ui::NoteListItem *m_ui_class;
Note *m_note;
QLabel *m_title_label;
QLabel *m_excerpt_label;
QLabel *m_date_created_label;
QToolButton *m_favoriteButton;
private slots:
void noteDateChanged(Note *note);
void noteTitleChanged(Note *note);
void noteTextChanged(Note *note);
};
#endif // NOTELISTITEMWIDGET_H
......@@ -15,9 +15,8 @@ NoteListProxyModel::NoteListProxyModel(QListView *view, Database *db) :
{
setDynamicSortFilter(true);
noteListItemTimer = new QTimer(this);
connect(noteListItemTimer, SIGNAL(timeout()), this, SLOT(processNoteListItemPayloads()));
noteListItemTimer->start(20);
m_delegate = new NoteItemDelegate(m_view, this);
m_view->setItemDelegate(m_delegate);
}
QVariant NoteListProxyModel::data(const QModelIndex &index, int role) const
......@@ -28,45 +27,12 @@ QVariant NoteListProxyModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole)
return QVariant();
QModelIndex realIndex = mapToSource(index);
NoteListItem *item = static_cast<NoteListItem*>( realIndex.internalPointer() );
if ( !m_view->indexWidget(index) ) {
struct noteListItemPayload payload;
payload.index = index;
payload.item = item;
const_cast<NoteListProxyModel*>(this)->addNoteListItemPayload(index, item);
}
//QModelIndex realIndex = mapToSource(index);
// NoteListItem *item = static_cast<NoteListItem*>( realIndex.internalPointer() );
return QVariant();
}
void NoteListProxyModel::addNoteListItemPayload(QModelIndex index, NoteListItem *item) {
struct noteListItemPayload payload;
payload.index = index;
payload.item = item;
noteListItemPayloads.append(payload);
}
void NoteListProxyModel::processNoteListItemPayloads() {
if ( noteListItemPayloads.length() == 0 )
return;
struct noteListItemPayload
payload = noteListItemPayloads.at(0);
QModelIndex index = payload.index;
NoteListItem *item = payload.item;
if ( !m_view->indexWidget(index) &&
index.isValid() ) {
QWidget *widget = new NoteListItemWidget(item->note());
m_view->setIndexWidget( index, widget );
item->setWidget(widget);
}
noteListItemPayloads.removeFirst();
}
void NoteListProxyModel::setSortingMethod(int sortingMethod)
{
m_sortingMethod = sortingMethod;
......@@ -74,7 +40,6 @@ void NoteListProxyModel::setSortingMethod(int sortingMethod)
void NoteListProxyModel::invalidateFilter()
{
noteListItemPayloads.clear();
QSortFilterProxyModel::invalidateFilter();
emit invalidatedFilter();
}
......
......@@ -10,9 +10,8 @@
#include <QListView>
#include <QVector>
#include "../items/notelistitem.h"
#include "../items/notelistitemwidget.h"
#include "../../meta/db/database.h"
#include <QTimer>
#include "../delegates/noteitemdelegate.h"
class NoteListProxyModel : public QSortFilterProxyModel
{
......@@ -57,6 +56,8 @@ signals:
void invalidatedFilter();
private:
NoteItemDelegate *m_delegate;
QModelIndex m_selectedRow;
QListView *m_view;
......@@ -73,17 +74,6 @@ private:
int m_search_filter=SearchOff;
QString m_searchQuery;
QTimer *noteListItemTimer;
struct noteListItemPayload {
QModelIndex index;
NoteListItem *item;
};
QVector<struct noteListItemPayload> noteListItemPayloads;
void addNoteListItemPayload(QModelIndex index, NoteListItem *item);
public slots:
void processNoteListItemPayloads();
};
#endif // NOTELISTPROXYMODEL_H
......@@ -5,6 +5,11 @@ CustomListView::CustomListView(QWidget *parent) : QListView(parent)
}
void CustomListView::mousePressEvent(QMouseEvent *event)
{
(void) event;
}
void CustomListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
QListView::currentChanged(current, previous);
......
......@@ -13,6 +13,9 @@ class CustomListView : public QListView
public:
CustomListView(QWidget *parent=nullptr);
// Empty function to prevent mouse press event.
void mousePressEvent(QMouseEvent *event) override;
public slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment