diff --git a/YACReaderLibrary/db/tablemodel.cpp b/YACReaderLibrary/db/tablemodel.cpp index a72be0ba..18c8762b 100644 --- a/YACReaderLibrary/db/tablemodel.cpp +++ b/YACReaderLibrary/db/tablemodel.cpp @@ -64,11 +64,11 @@ QVariant TableModel::data(const QModelIndex &index, int role) const if (!index.isValid()) return QVariant(); - if (index.column() == Columns::Rating && role == Qt::DecorationRole) + /*if (index.column() == Columns::Rating && role == Qt::DecorationRole) { TableItem *item = static_cast(index.internalPointer()); return QPixmap(QString(":/images/rating%1.png").arg(item->data(index.column()).toInt())); - } + }*/ if (role == Qt::DecorationRole) { @@ -116,7 +116,8 @@ Qt::ItemFlags TableModel::flags(const QModelIndex &index) const { if (!index.isValid()) return 0; - + if(index.column() == Columns::Rating) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } //! [4] @@ -612,4 +613,21 @@ void TableModel::reload(const ComicDB & comic) } if(found) emit dataChanged(index(row,Columns::CurrentPage),index(row,Columns::CurrentPage)); +} + +void TableModel::updateRating(int rating, QModelIndex mi) +{ + ComicDB comic = getComic(mi); + + QSqlDatabase db = DataBaseManagement::loadDatabase(_databasePath); + //TODO optimize update + + comic.info.rating = rating; + _data[mi.row()]->setData(Columns::Rating,rating); + DBHelper::update(&(comic.info),db); + + emit dataChanged(mi,mi); + + db.close(); + QSqlDatabase::removeDatabase(_databasePath); } \ No newline at end of file diff --git a/YACReaderLibrary/db/tablemodel.h b/YACReaderLibrary/db/tablemodel.h index 76dd4e9b..4bab87fb 100644 --- a/YACReaderLibrary/db/tablemodel.h +++ b/YACReaderLibrary/db/tablemodel.h @@ -58,6 +58,7 @@ public slots: void remove(int row); void startTransaction(); void finishTransaction(); + void updateRating(int rating, QModelIndex mi); private: void setupModelData( QSqlQuery &sqlquery); diff --git a/YACReaderLibrary/db_helper.cpp b/YACReaderLibrary/db_helper.cpp index e98e9441..e16346d5 100644 --- a/YACReaderLibrary/db_helper.cpp +++ b/YACReaderLibrary/db_helper.cpp @@ -197,7 +197,7 @@ void DBHelper::update(const QString & libraryName, ComicInfo & comicInfo) db.close(); QSqlDatabase::removeDatabase(libraryPath); } - +#include void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) { QSqlQuery updateComicInfo(db); @@ -246,7 +246,8 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) "bookmark3 = :bookmark3," "brightness = :brightness," "contrast = :contrast, " - "gamma = :gamma" + "gamma = :gamma," + "rating = :rating" //-- " WHERE id = :id "); bindField(":title",comicInfo->title,updateComicInfo); @@ -294,8 +295,10 @@ void DBHelper::update(ComicInfo * comicInfo, QSqlDatabase & db) updateComicInfo.bindValue(":brightness", comicInfo->brightness); updateComicInfo.bindValue(":contrast", comicInfo->contrast); updateComicInfo.bindValue(":gamma", comicInfo->gamma); + updateComicInfo.bindValue(":rating", comicInfo->rating); - updateComicInfo.exec(); + if(!updateComicInfo.exec()) + QMessageBox::critical(0,"",updateComicInfo.lastError().text()); } void DBHelper::updateRead(ComicInfo * comicInfo, QSqlDatabase & db) diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index b7efe6e4..88fdf2c0 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -672,6 +672,7 @@ void LibraryWindow::createConnections() connect(comicView, SIGNAL(pressed(QModelIndex)), this, SLOT(centerComicFlow(QModelIndex))); connect(comicFlow, SIGNAL(centerIndexChanged(int)), this, SLOT(updateComicView(int))); + connect(comicView, SIGNAL(comicRated(int,QModelIndex)), dmCV, SLOT(updateRating(int,QModelIndex))); //actions connect(createLibraryAction,SIGNAL(triggered()),this,SLOT(createLibrary())); diff --git a/custom_widgets/yacreader_sidebar.cpp b/custom_widgets/yacreader_sidebar.cpp index 161208ae..cb496ace 100644 --- a/custom_widgets/yacreader_sidebar.cpp +++ b/custom_widgets/yacreader_sidebar.cpp @@ -9,7 +9,7 @@ #include "yacreader_titled_toolbar.h" YACReaderSideBar::YACReaderSideBar(QWidget *parent) : - QWidget(parent) + QWidget(parent) { setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Minimum); @@ -20,11 +20,11 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) : librariesTitle = new YACReaderTitledToolBar(tr("LIBRARIES")); - foldersTitle = new YACReaderTitledToolBar(tr("FOLDERS")); + foldersTitle = new YACReaderTitledToolBar(tr("FOLDERS")); selectedLibrary->setContextMenuPolicy(Qt::ActionsContextMenu); selectedLibrary->setAttribute(Qt::WA_MacShowFocusRect,false); - selectedLibrary->setFocusPolicy(Qt::NoFocus); + selectedLibrary->setFocusPolicy(Qt::NoFocus); foldersFilter->setAttribute(Qt::WA_MacShowFocusRect,false); foldersFilter->setPlaceholderText(tr("Search folders and comics")); @@ -66,7 +66,7 @@ YACReaderSideBar::YACReaderSideBar(QWidget *parent) : l->addSpacing(4); #else - l->addSpacing(6); + l->addSpacing(6); #endif l->addWidget(foldersTitle); @@ -119,7 +119,7 @@ void YACReaderSideBar::paintEvent(QPaintEvent * event) //painter.drawPixmap(width()-shadow.width(),0,shadow.width(),height(),shadow); // painter.setRenderHint(QPainter::Antialiasing); - // painter.drawLine(rect().topLeft(), rect().bottomRight()); + // painter.drawLine(rect().topLeft(), rect().bottomRight()); //QWidget::paintEvent(event); } diff --git a/custom_widgets/yacreader_table_view.cpp b/custom_widgets/yacreader_table_view.cpp index a610e217..0ec8101a 100644 --- a/custom_widgets/yacreader_table_view.cpp +++ b/custom_widgets/yacreader_table_view.cpp @@ -3,11 +3,10 @@ #include #include #include - -#include "yacreader_deleting_progress.h" +#include YACReaderTableView::YACReaderTableView(QWidget *parent) : - QTableView(parent),showDelete(false) + QTableView(parent),showDelete(false),editing(false) { setAlternatingRowColors(true); verticalHeader()->setAlternatingRowColors(true); @@ -16,13 +15,13 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) : "QTableView::item {outline: 0px; border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE; padding-bottom:1px; color:#252626;}" "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:1px solid #B8B8B8;border-right:none;}" #ifdef Q_OS_MAC - "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:none;border-right:none;}" - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #3875D7;border-top: 1px solid #3875D7; padding-bottom:1px; background-color: #3875D7; color: #FFFFFF; }" + "QTableView {border-top:1px solid #B8B8B8;border-bottom:none;border-left:none;border-right:none;}" + "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #3875D7;border-top: 1px solid #3875D7; padding-bottom:1px; background-color: #3875D7; color: #FFFFFF; }" #else - "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #D4D4D4;border-top: 1px solid #D4D4D4; padding-bottom:1px; background-color: #D4D4D4; }" + "QTableView::item:selected {outline: 0px; border-bottom: 1px solid #D4D4D4;border-top: 1px solid #D4D4D4; padding-bottom:1px; background-color: #D4D4D4; }" #endif - "QHeaderView::section:horizontal {background-color:#F5F5F5; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4); border-left:none; border-top:none; padding:4px; color:#313232;}" + "QHeaderView::section:horizontal {background-color:#F5F5F5; border-bottom:1px solid #B8BDC4; border-right:1px solid qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #D1D1D1, stop: 1 #B8BDC4); border-left:none; border-top:none; padding:4px; color:#313232;}" "QHeaderView::section:vertical {border-bottom: 1px solid #DFDFDF;border-top: 1px solid #FEFEFE;}" //"QTableView::item:hover {border-bottom: 1px solid #A3A3A3;border-top: 1px solid #A3A3A3; padding-bottom:1px; background-color: #A3A3A3; color: #FFFFFF; }" ""); @@ -44,12 +43,48 @@ YACReaderTableView::YACReaderTableView(QWidget *parent) : setSelectionBehavior(QAbstractItemView::SelectRows); setSelectionMode(QAbstractItemView::ExtendedSelection); + setItemDelegateForColumn(11,new YACReaderRatingDelegate(this)); + setEditTriggers(QAbstractItemView::NoEditTriggers); + + setMouseTracking(true); /*deletingProgress = new YACReaderDeletingProgress(this); showDeletingProgressAnimation = new QPropertyAnimation(deletingProgress,"pos"); showDeletingProgressAnimation->setDuration(150);*/ } +void YACReaderTableView::mouseMoveEvent(QMouseEvent *event) +{ + QModelIndex mi = indexAt(event->pos()); + if(mi.isValid()) + { + QList selectedIndexes = this->selectedIndexes(); + if(selectedIndexes.contains(mi)) + { + if(mi.column() == 11) + if(!editing) + { + editing = true; + currentIndexEditing = mi; + edit(mi); + } + } + } + QTableView::mouseMoveEvent(event); +} + + +void YACReaderTableView::closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) +{ + editing = false; + QTableView::closeEditor(editor,hint); +} +void YACReaderTableView::commitData ( QWidget * editor ) +{ + //TODO + emit comicRated(((StarEditor *)editor)->starRating().starCount(),currentIndexEditing); +} + void YACReaderTableView::showDeleteProgress() { /*showDelete = true; @@ -82,3 +117,250 @@ void YACReaderTableView::resizeEvent(QResizeEvent * event) QTableView::resizeEvent(event); } +#include "tableitem.h" +//------------------------------------------------------------------------------ +//YACReaderRatingDelegate------------------------------------------------------- +//------------------------------------------------------------------------------ +void YACReaderRatingDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + int rating = ((TableItem *)index.internalPointer())->data(11).toInt(); + + StarRating starRating(rating); + + QStyledItemDelegate::paint(painter, option, index); + + if(option.state | QStyle::State_Editing) + { + if (option.state & QStyle::State_Selected) + starRating.paintSelected(painter, option.rect, option.palette, + StarRating::ReadOnly); + else + starRating.paint(painter, option.rect, option.palette, + StarRating::ReadOnly); + } +} + +QSize YACReaderRatingDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + int rating = ((TableItem *)index.internalPointer())->data(11).toInt(); + StarRating starRating(rating); + return starRating.sizeHint(); +} + +QWidget *YACReaderRatingDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + +{ + StarEditor *editor = new StarEditor(parent); + connect(editor, SIGNAL(editingFinished()), + this, SLOT(sendCloseEditor())); + connect(editor, SIGNAL(commitData()), + this, SLOT(sendCommitData())); + return editor; +} + +void YACReaderRatingDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + int rating = ((TableItem *)index.internalPointer())->data(11).toInt(); + + StarRating starRating(rating); + + StarEditor *starEditor = qobject_cast(editor); + starEditor->setStarRating(starRating); +} + +void YACReaderRatingDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, + const QModelIndex &index) const +{ + QStyledItemDelegate::setModelData(editor, model, index); +} + +void YACReaderRatingDelegate::sendCommitData() +{ + StarEditor *editor = qobject_cast(sender()); + emit commitData(editor); +} +void YACReaderRatingDelegate::sendCloseEditor() +{ + StarEditor *editor = qobject_cast(sender()); + emit closeEditor(editor); +} + +//------------------------------------------------------------------------------- +//StarRating--------------------------------------------------------------------- +//------------------------------------------------------------------------------- + +const int PaintingScaleFactor = 20; + +//! [0] +StarRating::StarRating(int starCount, int maxStarCount) +{ + myStarCount = starCount; + myMaxStarCount = maxStarCount; + + int numVertex = 5; + double pi = 3.14159265359; + double angle = 3.14159265359 / numVertex; + + float rOuter = 0.3; + float rInner = 0.15; + for (int i = 0; i < 2 * numVertex; i++) + { + double r = (i & 1) == 0 ? rOuter : rInner; + starPolygon << QPointF(0.5 + cos((i * angle)-pi/2) * r, 0.5 + sin((i * angle)-pi/2) * r); + } + + diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4) + << QPointF(0.6, 0.5) << QPointF(0.5, 0.6) + << QPointF(0.4, 0.5); +} +//! [0] + +//! [1] +QSize StarRating::sizeHint() const +{ + return PaintingScaleFactor * QSize(myMaxStarCount, 1); +} +//! [1] + +//! [2] +void StarRating::paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const +{ + painter->save(); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(Qt::NoPen); + + //if (mode == Editable) { + // painter->setBrush(palette.highlight()); + //} else { + QBrush brush(QColor("#e9be0f")); + painter->setBrush(brush); + //} + + int yOffset = (rect.height() - PaintingScaleFactor) / 2; + painter->translate(rect.x(), rect.y() + yOffset); + painter->scale(PaintingScaleFactor, PaintingScaleFactor); + + for (int i = 0; i < myMaxStarCount; ++i) { + if (i < myStarCount) { + painter->drawPolygon(starPolygon, Qt::WindingFill); + } else if (mode == Editable) { + painter->drawEllipse(QPointF(0.5,0.5),0.08,0.08);//(diamondPolygon, Qt::WindingFill); + } + painter->translate(1.0, 0.0); + } + + painter->restore(); +} + +void StarRating::paintSelected(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const +{ + painter->save(); + + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(Qt::NoPen); + + QBrush star(color); + QBrush dot(color); + + int yOffset = (rect.height() - PaintingScaleFactor) / 2; + painter->translate(rect.x(), rect.y() + yOffset); + painter->scale(PaintingScaleFactor, PaintingScaleFactor); + + for (int i = 0; i < myMaxStarCount; ++i) { + if (i < myStarCount) { + painter->setBrush(star); + painter->drawPolygon(starPolygon, Qt::WindingFill); + } else { + painter->setBrush(dot); + painter->drawEllipse(QPointF(0.5,0.5),0.08,0.08); + } + painter->translate(1.0, 0.0); + } + + painter->restore(); +} + +//! [2] +void StarRating::paintSelected(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const +{ + paintSelected(painter,rect, palette,mode,QColor("#ffffff")); +} +//! [2] + +void StarRating::mouseMoveEvent(QMouseEvent *event) +{ + event->accept(); +} + + +//------------------------------------------------------------------------------- +//StarEditor--------------------------------------------------------------------- +//------------------------------------------------------------------------------- + +//! [0] +StarEditor::StarEditor(QWidget *parent) + : QWidget(parent) +{ + setMouseTracking(true); +} +//! [0] + +QSize StarEditor::sizeHint() const +{ + return myStarRating.sizeHint(); +} + +//! [1] +void StarEditor::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + myStarRating.paintSelected(&painter, rect(), this->palette(), + StarRating::Editable,QColor("#A0A0A0")); +} +//! [1] + +//! [2] +void StarEditor::mouseMoveEvent(QMouseEvent *event) +{ + int star = starAtPosition(event->x()); + + if (star != myStarRating.starCount() && star != -1) { + myStarRating.setStarCount(star); + update(); + } +} +//! [2] + +void StarEditor::leaveEvent(QEvent * event){ + emit editingFinished(); + QWidget::leaveEvent(event); +} + + +//! [3] +void StarEditor::mouseReleaseEvent(QMouseEvent * event ) +{ + emit commitData(); +} +//! [3] + +//! [4] +int StarEditor::starAtPosition(int x) +{ + int star = (x / (myStarRating.sizeHint().width() + / myStarRating.maxStarCount())) + 1; + if (star <= 0 || star > myStarRating.maxStarCount()) + return -1; + + return star; +} +//! [4] diff --git a/custom_widgets/yacreader_table_view.h b/custom_widgets/yacreader_table_view.h index b2080aa1..9e1493ee 100644 --- a/custom_widgets/yacreader_table_view.h +++ b/custom_widgets/yacreader_table_view.h @@ -2,6 +2,7 @@ #define YACREADER_TABLE_VIEW_H #include +#include class YACReaderDeletingProgress; class QResizeEvent; @@ -9,22 +10,111 @@ class QPropertyAnimation; class YACReaderTableView : public QTableView { - Q_OBJECT + Q_OBJECT public: - explicit YACReaderTableView(QWidget *parent = 0); - + explicit YACReaderTableView(QWidget *parent = 0); + signals: - + void comicRated(int,QModelIndex); public slots: void showDeleteProgress(); void hideDeleteProgress(); +protected slots: +virtual void closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ); +virtual void commitData ( QWidget * editor ); private: - YACReaderDeletingProgress * deletingProgress; + YACReaderDeletingProgress * deletingProgress; bool showDelete; QPropertyAnimation * showDeletingProgressAnimation; void resizeEvent(QResizeEvent * event); + void mouseMoveEvent(QMouseEvent *event); + + bool editing; + QModelIndex currentIndexEditing; }; +//--- + +class YACReaderRatingDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + YACReaderRatingDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {} + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + 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 slots: + void sendCloseEditor(); + void sendCommitData(); +}; + +//--- + +class StarRating +{ +public: + enum EditMode { Editable, ReadOnly }; + + StarRating(int starCount = 1, int maxStarCount = 5); + + void paint(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const; + void paintSelected(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode, QColor color) const; + void paintSelected(QPainter *painter, const QRect &rect, + const QPalette &palette, EditMode mode) const; + QSize sizeHint() const; + int starCount() const { return myStarCount; } + int maxStarCount() const { return myMaxStarCount; } + void setStarCount(int starCount) { myStarCount = starCount; } + void setMaxStarCount(int maxStarCount) { myMaxStarCount = maxStarCount; } +protected: + void mouseMoveEvent(QMouseEvent *event); +private: + QPolygonF starPolygon; + QPolygonF diamondPolygon; + int myStarCount; + int myMaxStarCount; +}; +Q_DECLARE_METATYPE(StarRating); +//--- + +class StarEditor : public QWidget +{ + Q_OBJECT + +public: + StarEditor(QWidget *parent = 0); + + QSize sizeHint() const; + void setStarRating(const StarRating &starRating) { + myStarRating = starRating; + } + StarRating starRating() { return myStarRating; } + +signals: + void editingFinished(); + void commitData(); + +protected: + void paintEvent(QPaintEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void leaveEvent(QEvent * event); + +private: + int starAtPosition(int x); + StarRating myStarRating; +}; #endif // YACREADER_TABLE_VIEW_H