mylistview.cpp \
mylistfiltermodel.cpp \
reporteditordialog.cpp \
- versiondialog.cpp
+ versiondialog.cpp \
+ mylistitemdelegate.cpp
HEADERS += mainwindow.h \
databaseconnectiondialog.h \
mylistview.h \
mylistfiltermodel.h \
reporteditordialog.h \
- versiondialog.h
+ versiondialog.h \
+ mylistitemdelegate.h
FORMS += mainwindow.ui \
databaseconnectiondialog.ui
#include "mylistmodel.h"
#include "mylistnode.h"
#include "mylistfiltermodel.h"
+#include "mylistitemdelegate.h"
#include "unknownfilelookuptask.h"
#include "addrelatedepisodestask.h"
#include "filelocationchecktask.h"
myListFilterModel = new MyListFilterModel(this);
myListFilterModel->setSourceModel(myListModel);
ui->myListView->setModel(myListFilterModel);
+ ui->myListView->setItemDelegate(new MyListItemDelegate(ui->myListView));
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
ui->myListView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
#else
--- /dev/null
+#include "mylistitemdelegate.h"
+
+#include "mylistfiltermodel.h"
+#include "mylistnode.h"
+
+#include <QDoubleSpinBox>
+
+#include <QDebug>
+
+MyListItemDelegate::MyListItemDelegate(QWidget *parent) :
+ QStyledItemDelegate(parent)
+{
+}
+
+QWidget *MyListItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ using namespace LocalMyList;
+
+ if (!isVoteField(index))
+ return QStyledItemDelegate::createEditor(parent, option, index);
+
+ QDoubleSpinBox *ed = new QDoubleSpinBox(parent);
+
+ ed->setRange(0.99, 10.00);
+ ed->setDecimals(2);
+ ed->setSingleStep(0.50);
+ ed->setSpecialValueText(tr("No Vote/Revoke"));
+ return ed;
+}
+
+void MyListItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ if (!isVoteField(index))
+ return QStyledItemDelegate::setEditorData(editor, index);
+
+ double vote = index.data(Qt::EditRole).toDouble();
+
+ if (vote < 1.00 || vote > 10.00)
+ vote = 5.00;
+
+ QDoubleSpinBox *ed = qobject_cast<QDoubleSpinBox *>(editor);
+ ed->setValue(vote);
+}
+
+void MyListItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
+{
+ if (!isVoteField(index))
+ QStyledItemDelegate::setModelData(editor, model, index);
+
+ QDoubleSpinBox *ed = qobject_cast<QDoubleSpinBox *>(editor);
+ model->setData(index, ed->value());
+}
+
+bool MyListItemDelegate::isVoteField(const QModelIndex &index) const
+{
+ using namespace LocalMyList;
+ const MyListFilterModel *model = qobject_cast<const MyListFilterModel *>(index.model());
+ const MyListNode *node = model->node(index);
+
+ return (node->type() == MyListNode::AnimeNode
+ || node->type() == MyListNode::EpisodeNode)
+ && index.column() == 3;
+}
--- /dev/null
+#ifndef MYLISTITEMDELEGATE_H
+#define MYLISTITEMDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+class MyListItemDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ explicit MyListItemDelegate(QWidget *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
+ void setEditorData(QWidget *editor, const QModelIndex &index ) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
+
+private:
+ bool isVoteField(const QModelIndex &index) const;
+};
+
+#endif // MYLISTITEMDELEGATE_H
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showCustomContextMenu(QPoint)));
this->setExpandsOnDoubleClick(false);
- connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(openFileRequested(QModelIndex)));
+ connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(doubleClick(QModelIndex)));
openAction = new QAction(tr("Open"), this);
connect(openAction, SIGNAL(triggered()), this, SLOT(requestOpenFile()));
customContextMenuIndex = QModelIndex();
}
+void MyListView::doubleClick(const QModelIndex &index)
+{
+ if (!(model()->flags(index) & Qt::ItemIsEditable))
+ emit openFileRequested(index);
+}
+
void MyListView::requestOpenFile()
{
emit openFileRequested(customContextMenuIndex);
private slots:
MyListFilterModel *myListFilterModel() const;
void showCustomContextMenu(const QPoint &pos);
+ void doubleClick(const QModelIndex &index);
void requestOpenFile();
void markAnimeWatched();
void markEpisodeWatched();
if (!fid)
return;
- PendingMyListUpdate request;
- request.fid = fid;
- request.setMyWatched = true;
- request.myWatched = when;
- database()->addPendingMyListUpdate(request);
+ PendingMyListUpdate pmu;
+ pmu.fid = fid;
+ pmu.setMyWatched = true;
+ pmu.myWatched = when;
+
+ database()->addPendingMyListUpdate(pmu);
+}
+
+void MyList::voteAnime(int aid, double vote)
+{
+ PendingMyListUpdate pmu;
+ pmu.aid = aid;
+ pmu.setVote = true;
+ pmu.vote = vote;
+
+ database()->addPendingMyListUpdate(pmu);
+}
+
+void MyList::voteEpisode(int eid, double vote)
+{
+ Episode e = database()->getEpisode(eid);
+
+ if (!e.eid)
+ return;
+
+ voteEpisode(e.aid, e.epno, e.type, vote);
+}
+
+void MyList::voteEpisode(int aid, int epno, const QString &epType, double vote)
+{
+ PendingMyListUpdate pmu;
+ pmu.aid = aid;
+ pmu.epno = epno;
+ pmu.eptype = epType;
+ pmu.setVote = true;
+ pmu.vote = vote;
+
+ database()->addPendingMyListUpdate(pmu);
}
public slots:
void markWatched(int fid, QDateTime when = QDateTime::currentDateTime());
+ void voteAnime(int aid, double vote);
+ void voteEpisode(int eid, double vote);
+ void voteEpisode(int aid, int epno, const QString &epType, double vote);
+
AbstractTask *addFile(const QFileInfo &file);
AbstractTask *addDirectory(const QDir &directory);
AbstractTask *importTitles(const QFileInfo &file);
if (!index.isValid())
return 0;
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ MyListNode *item = static_cast<MyListNode *>(index.internalPointer());
+
+ return item->flags(index);
}
QVariant MyListModel::data(const QModelIndex &index, int role) const
return item->data(index.column(), role);
}
+bool MyListModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (!index.isValid())
+ return false;
+
+ MyListNode *item = static_cast<MyListNode *>(index.internalPointer());
+
+ bool ret = item->setData(index.column(), value, role);
+
+ if (ret)
+ emit dataChanged(index, index);
+
+ return ret;
+}
+
QModelIndex MyListModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
delete query;
}
+Qt::ItemFlags MyListNode::flags(const QModelIndex &index) const
+{
+ Q_UNUSED(index);
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
MyListNode *MyListNode::child(int row)
{
return childItems.value(row);
return QVariant();
}
+bool MyListNode::setData(int column, const QVariant &data, int role)
+{
+ Q_UNUSED(column);
+ Q_UNUSED(data);
+ Q_UNUSED(role);
+ return false;
+}
+
MyListNode *MyListNode::parent()
{
return parentItem;
model->animeSet.erase(model->animeSet.s_iterator_to(animeData));
}
+Qt::ItemFlags MyListAnimeNode::flags(const QModelIndex &index) const
+{
+ return MyListNode::flags(index) | (index.column() == 3 ? Qt::ItemIsEditable : 0);
+}
+
QVariant MyListAnimeNode::data(int column, int role) const
{
switch (role)
return QString("%1 of %2").arg(animeData.watchedEpisodes)
.arg(animeData.episodesInMyList);
}
+ break;
case Qt::ToolTipRole:
switch (column)
{
if (!animeData.data.titleKanji.isEmpty())
return animeData.data.titleKanji;
}
+ break;
+ case Qt::EditRole:
+ switch (column)
+ {
+ case 3:
+ return animeData.data.myVote;
+ }
+ break;
}
return QVariant();
}
+bool MyListAnimeNode::setData(int column, const QVariant &data, int role)
+{
+ if (role != Qt::EditRole)
+ return false;
+
+ switch (column)
+ {
+ case 3:
+ {
+ double vote = data.toDouble();
+
+ if (qFuzzyCompare(animeData.data.myVote, vote))
+ return false;
+
+ if (vote < 1.0 || vote > 10.0)
+ vote = 0;
+
+ animeData.data.myVote = vote;
+
+ MyList::instance()->voteAnime(animeData.data.aid, vote);
+
+ return true;
+ }
+ }
+ return false;
+}
+
void MyListAnimeNode::fetchMore()
{
qDebug() << "fetching some more for aid" << id();
MyListNode(MyListModel *model, NodeType type = RootNode, int totalRowCount = -1, MyListNode *parent = 0);
virtual ~MyListNode();
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
+
MyListNode *child(int row);
int childCount() const;
int columnCount() const;
virtual QVariant data(int column, int role) const;
+ virtual bool setData(int column, const QVariant &data, int role);
int row() const;
MyListNode *parent();
MyListAnimeNode(MyListModel *model, const AnimeData &data, int totalRowCount, MyListNode *parent);
~MyListAnimeNode();
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
QVariant data(int column, int role) const;
+ bool setData(int column, const QVariant &data, int role);
void fetchMore();
void fetchComplete();
int id() const;