From 39aac8c95bf1e84b4126f6b32bda55c85e992752 Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Sun, 5 Oct 2014 09:53:19 +0200 Subject: [PATCH] Run astyle-kdelibs on the source --- src/danbooruclientview.cpp | 77 +++--- src/danbooruclientview.h | 69 +++--- src/danbooruconnectwidget.cpp | 39 ++- src/danbooruconnectwidget.h | 64 ++--- src/libdanbooru/danbooru.h | 4 +- src/libdanbooru/danboorupool.cpp | 12 +- src/libdanbooru/danboorupool.h | 115 ++++----- src/libdanbooru/danboorupost.cpp | 13 +- src/libdanbooru/danboorupost.h | 296 ++++++++++++----------- src/libdanbooru/danbooruservice.cpp | 152 ++++++------ src/libdanbooru/danbooruservice.h | 351 ++++++++++++++------------- src/libdanbooru/danboorutag.cpp | 3 +- src/libdanbooru/danboorutag.h | 70 +++--- src/libdanbooru/utils.cpp | 223 ++++++++--------- src/libdanbooru/utils.h | 154 ++++++------ src/main.cpp | 25 +- src/mainwindow.cpp | 93 ++++---- src/mainwindow.h | 77 +++--- src/model/danboorupostdelegate.cpp | 356 ++++++++++++++-------------- src/model/danboorupostdelegate.h | 86 ++++--- src/model/danboorupostmodel.cpp | 144 +++++------ src/model/danboorupostmodel.h | 68 +++--- 22 files changed, 1227 insertions(+), 1264 deletions(-) diff --git a/src/danbooruclientview.cpp b/src/danbooruclientview.cpp index ec8ee88..e40cdb1 100644 --- a/src/danbooruclientview.cpp +++ b/src/danbooruclientview.cpp @@ -17,8 +17,6 @@ * along with Danbooru Client. If not, see . */ - - #include "danbooruclientview.h" // Own @@ -35,54 +33,53 @@ #include #include -namespace Danbooru { +namespace Danbooru +{ - DanbooruClientView::DanbooruClientView(QWidget * parent): QWidget(parent), - m_model(new DanbooruPostModel(this)), - m_delegate(0), - m_service(0), - m_timer(0) - { - setupUi(this); +DanbooruClientView::DanbooruClientView(QWidget *parent): QWidget(parent), + m_model(new DanbooruPostModel(this)), + m_delegate(0), + m_service(0), + m_timer(0) +{ + setupUi(this); - m_delegate = new DanbooruPostDelegate(m_listView); + m_delegate = new DanbooruPostDelegate(m_listView); - m_listView->setFlow(QListView::LeftToRight); - m_listView->setResizeMode(QListView::Adjust); - m_listView->setWrapping(true); - m_listView->setViewMode(QListView::IconMode); - m_listView->setGridSize(QSize(256,256)); + m_listView->setFlow(QListView::LeftToRight); + m_listView->setResizeMode(QListView::Adjust); + m_listView->setWrapping(true); + m_listView->setViewMode(QListView::IconMode); + m_listView->setGridSize(QSize(256, 256)); - m_listView->setModel(m_model); - m_listView->setItemDelegate(m_delegate); + m_listView->setModel(m_model); + m_listView->setItemDelegate(m_delegate); - // signal-slot connections + // signal-slot connections - connect(m_delegate, &DanbooruPostDelegate::postDownloadRequested, this, &DanbooruClientView::slotHandleDownload); - connect(m_delegate, &DanbooruPostDelegate::postViewRequested, this, &DanbooruClientView::slotHandleView); -// connect(m_listView, SIGNAL(clicked(const QModelIndex&)), parent(), -// SLOT(displayInfo(const QModelIndex&)); + connect(m_delegate, &DanbooruPostDelegate::postDownloadRequested, this, &DanbooruClientView::slotHandleDownload); + connect(m_delegate, &DanbooruPostDelegate::postViewRequested, this, &DanbooruClientView::slotHandleView); +// connect(m_listView, SIGNAL(clicked(QModelIndex)), parent(), +// SLOT(displayInfo(QModelIndex)); +} - } +DanbooruClientView::~DanbooruClientView() +{ - DanbooruClientView::~DanbooruClientView() - { +} - } - - void DanbooruClientView::slotHandleDownload(QUrl url) - { - // TODO - Q_UNUSED(url) - } - - void DanbooruClientView::slotHandleView(QUrl url) - { - KRun* runViewer = new KRun(url, this /*window*/, true /*showProgressInfo*/, - "" /*asn*/); - runViewer->setAutoDelete(true); - } +void DanbooruClientView::slotHandleDownload(QUrl url) +{ + // TODO + Q_UNUSED(url) +} +void DanbooruClientView::slotHandleView(QUrl url) +{ + KRun *runViewer = new KRun(url, this /*window*/, true /*showProgressInfo*/, + "" /*asn*/); + runViewer->setAutoDelete(true); +} } // namespace Danbooru diff --git a/src/danbooruclientview.h b/src/danbooruclientview.h index 2c63591..a4c3f43 100644 --- a/src/danbooruclientview.h +++ b/src/danbooruclientview.h @@ -28,47 +28,48 @@ class QTimer; -namespace Danbooru { +namespace Danbooru +{ - class DanbooruPostModel; - class DanbooruPostDelegate; - class DanbooruService; +class DanbooruPostModel; +class DanbooruPostDelegate; +class DanbooruService; + +/** + * This is the main view class for danbooru_client. Most of the non-menu, + * non-toolbar, and non-statusbar (e.g., non frame) GUI code should go + * here. + * + * @short Main view + * @author %{AUTHOR} <%{EMAIL}> + * @version %{VERSION} + */ + +class DanbooruClientView : public QWidget, public Ui::DanbooruClientView +{ + Q_OBJECT + +public: + /** + * Default constructor + */ + DanbooruClientView(QWidget *parent = 0); /** - * This is the main view class for danbooru_client. Most of the non-menu, - * non-toolbar, and non-statusbar (e.g., non frame) GUI code should go - * here. - * - * @short Main view - * @author %{AUTHOR} <%{EMAIL}> - * @version %{VERSION} + * Destructor */ + virtual ~DanbooruClientView(); - class DanbooruClientView : public QWidget, public Ui::DanbooruClientView - { - Q_OBJECT +private Q_SLOTS: + void slotHandleDownload(QUrl); + void slotHandleView(QUrl); - public: - /** - * Default constructor - */ - DanbooruClientView(QWidget *parent=0); +private: + DanbooruPostModel *m_model; + DanbooruPostDelegate *m_delegate; + DanbooruService *m_service; - /** - * Destructor - */ - virtual ~DanbooruClientView(); - - private Q_SLOTS: - void slotHandleDownload(QUrl); - void slotHandleView(QUrl); - - private: - DanbooruPostModel* m_model; - DanbooruPostDelegate* m_delegate; - DanbooruService* m_service; - - QTimer* m_timer; + QTimer *m_timer; }; diff --git a/src/danbooruconnectwidget.cpp b/src/danbooruconnectwidget.cpp index d7d52a7..4232f43 100644 --- a/src/danbooruconnectwidget.cpp +++ b/src/danbooruconnectwidget.cpp @@ -27,10 +27,10 @@ #include - using KWallet::Wallet; -namespace Danbooru { +namespace Danbooru +{ const QMap< QUrl, QString > initBoardSalts() { @@ -38,13 +38,13 @@ const QMap< QUrl, QString > initBoardSalts() QMap< QUrl, QString > boardSalts; boardSalts.insert(QUrl("http://konachan.com"), - QString("So-I-Heard-You-Like-Mupkids-?--%1--")); + QString("So-I-Heard-You-Like-Mupkids-?--%1--")); boardSalts.insert(QUrl("http://konachan.net"), - QString("So-I-Heard-You-Like-Mupkids-?--%1--")); + QString("So-I-Heard-You-Like-Mupkids-?--%1--")); boardSalts.insert(QUrl("http://yande.re"), - QString("choujin-steiner--%1--")); + QString("choujin-steiner--%1--")); boardSalts.insert(QUrl("http://danbooru.donmai.us"), - QString("choujin-steiner--%1--")); + QString("choujin-steiner--%1--")); return boardSalts; } @@ -52,9 +52,9 @@ const QMap< QUrl, QString > initBoardSalts() const QMap DanbooruConnectWidget::boardSalts = initBoardSalts(); DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList, - QWidget* parent): - QWidget(parent), - m_wallet(0) + QWidget *parent): + QWidget(parent), + m_wallet(0) { setupUi(this); @@ -74,13 +74,13 @@ DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList, danbooruUrlComboBox->clear(); - for (auto item: urlList) { + for (auto item : urlList) { danbooruUrlComboBox->insertUrl(urlList.indexOf(item), item); } m_wallet = Wallet::openWallet(Wallet::NetworkWallet(), winid, - Wallet::Asynchronous - ); + Wallet::Asynchronous + ); connect(m_wallet, &KWallet::Wallet::walletOpened, this, &DanbooruConnectWidget::checkWallet); @@ -122,7 +122,6 @@ void DanbooruConnectWidget::getWalletData() if (m_wallet->hasEntry(key)) { - if (m_wallet->readMap(key, valueMap) != 0) { return; } @@ -133,7 +132,6 @@ void DanbooruConnectWidget::getWalletData() } } - void DanbooruConnectWidget::toggleLineEdits(int state) { if (state == Qt::Unchecked) { @@ -145,7 +143,6 @@ void DanbooruConnectWidget::toggleLineEdits(int state) } } - void DanbooruConnectWidget::emitRejected() { Q_EMIT rejected(); @@ -161,7 +158,6 @@ QString DanbooruConnectWidget::username() const return m_username; } - QString DanbooruConnectWidget::password() const { return m_password; @@ -178,7 +174,7 @@ void DanbooruConnectWidget::accept() if (!m_username.isEmpty() && !m_password.isEmpty()) { if (m_wallet && !m_wallet->hasEntry(m_boardUrl.url())) { - QMap dataMap; + QMap dataMap; dataMap.insert(QLatin1String("username"), m_username); dataMap.insert(QLatin1String("password"), m_password); m_wallet->writeMap(m_boardUrl.url(), dataMap); @@ -186,16 +182,15 @@ void DanbooruConnectWidget::accept() hashedPassword = boardSalts.value(m_boardUrl).arg(m_password); hashedPassword = QCryptographicHash::hash(hashedPassword.toUtf8(), - QCryptographicHash::Sha1 - ).toHex(); + QCryptographicHash::Sha1 + ).toHex(); } - DanbooruService* service = new DanbooruService(m_boardUrl, m_username, - hashedPassword); + DanbooruService *service = new DanbooruService(m_boardUrl, m_username, + hashedPassword); Q_EMIT(connectionEstablished(service)); hide(); } - }; // namespace Danbooru diff --git a/src/danbooruconnectwidget.h b/src/danbooruconnectwidget.h index c5d4a1c..4af7d55 100644 --- a/src/danbooruconnectwidget.h +++ b/src/danbooruconnectwidget.h @@ -28,46 +28,48 @@ #include -namespace KWallet { - class Wallet; +namespace KWallet +{ +class Wallet; } -namespace Danbooru { +namespace Danbooru +{ - class DanbooruService; +class DanbooruService; - const QMap< QUrl, QString > initBoardSalts(); +const QMap< QUrl, QString > initBoardSalts(); - class DanbooruConnectWidget: public QWidget, public Ui::DanbooruConnectWidget { - Q_OBJECT +class DanbooruConnectWidget: public QWidget, public Ui::DanbooruConnectWidget +{ + Q_OBJECT - public: - explicit DanbooruConnectWidget(QVector urlList, - QWidget* parent = 0); - ~DanbooruConnectWidget(); +public: + explicit DanbooruConnectWidget(QVector urlList, + QWidget *parent = 0); + ~DanbooruConnectWidget(); - QString username() const; - QString password() const; - QUrl boardUrl() const; + QString username() const; + QString password() const; + QUrl boardUrl() const; - private: - QUrl m_boardUrl; - QString m_username; - QString m_password; - KWallet::Wallet* m_wallet; - static const QMap boardSalts; +private: + QUrl m_boardUrl; + QString m_username; + QString m_password; + KWallet::Wallet *m_wallet; + static const QMap boardSalts; - Q_SIGNALS: - void connectionEstablished(DanbooruService* service); - void rejected(); +Q_SIGNALS: + void connectionEstablished(DanbooruService *service); + void rejected(); - - private Q_SLOTS: - void checkWallet(bool); - void getWalletData(); - void toggleLineEdits(int state); - void emitRejected(); - void accept(); - }; +private Q_SLOTS: + void checkWallet(bool); + void getWalletData(); + void toggleLineEdits(int state); + void emitRejected(); + void accept(); +}; } // namespace Danbooru diff --git a/src/libdanbooru/danbooru.h b/src/libdanbooru/danbooru.h index b1cef14..8425a4b 100644 --- a/src/libdanbooru/danbooru.h +++ b/src/libdanbooru/danbooru.h @@ -32,8 +32,8 @@ * @file danbooru.h * **/ -namespace Danbooru { - +namespace Danbooru +{ }; // namespace Danbooru diff --git a/src/libdanbooru/danboorupool.cpp b/src/libdanbooru/danboorupool.cpp index 9d3f0c2..176dc8b 100644 --- a/src/libdanbooru/danboorupool.cpp +++ b/src/libdanbooru/danboorupool.cpp @@ -22,10 +22,11 @@ #include "danboorupool.h" -namespace Danbooru { +namespace Danbooru +{ -DanbooruPool::DanbooruPool(const QVariantMap& postData, QObject* parent): - QObject(parent), m_posts(QList()) +DanbooruPool::DanbooruPool(const QVariantMap &postData, QObject *parent): + QObject(parent), m_posts(QList()) { m_id = postData.value("id").toInt(); m_name = postData.value("name").toString(); @@ -68,13 +69,12 @@ void DanbooruPool::addPosts(QList< int > posts) m_posts.append(posts); } -void DanbooruPool::addPosts(const QStringList& posts) +void DanbooruPool::addPosts(const QStringList &posts) { - for (auto post: posts) { + for (auto post : posts) { m_posts.append(post.toInt()); } } - } // namespace Danbooru diff --git a/src/libdanbooru/danboorupool.h b/src/libdanbooru/danboorupool.h index 5618ca6..efaf887 100644 --- a/src/libdanbooru/danboorupool.h +++ b/src/libdanbooru/danboorupool.h @@ -37,74 +37,75 @@ #include #include -namespace Danbooru { +namespace Danbooru +{ - /** - * @brief Class representing a Danbooru pool. - * - * Pools are organized groups of images, often by a common theme, for - * example taken from the same artbook. They are identified by unique IDs - * and are represented by a name, a description, and the posts they - * contain. - * - * @author Luca Beltrame (lbeltrame@kde.org) - * - * **/ - class DanbooruPool : public QObject - { +/** + * @brief Class representing a Danbooru pool. + * + * Pools are organized groups of images, often by a common theme, for + * example taken from the same artbook. They are identified by unique IDs + * and are represented by a name, a description, and the posts they + * contain. + * + * @author Luca Beltrame (lbeltrame@kde.org) + * + * **/ +class DanbooruPool : public QObject +{ Q_OBJECT - private: - int m_id; - int m_postCount; - QString m_name; - QString m_description; - QList m_posts; +private: + int m_id; + int m_postCount; + QString m_name; + QString m_description; + QList m_posts; - public: +public: - /** - * @brief Construct a Danbooru pool from a QVariantMap. - * - * This form is the easiest to use and should be used when dealing with - * responses in JSON format. Unfortunately most Danbooru - * implementations produce broken JSON for some responses. - * - * @param postData A QVariantMap from parsed JSON representing the - * data from a single pool. - * - * - **/ - DanbooruPool(const QVariantMap& postData, QObject* parent = 0); + /** + * @brief Construct a Danbooru pool from a QVariantMap. + * + * This form is the easiest to use and should be used when dealing with + * responses in JSON format. Unfortunately most Danbooru + * implementations produce broken JSON for some responses. + * + * @param postData A QVariantMap from parsed JSON representing the + * data from a single pool. + * + * + **/ + DanbooruPool(const QVariantMap &postData, QObject *parent = 0); - /** - * @brief Construct a Danbooru pool from a QVariantMap. - * - * This form is the easiest to use and should be used when dealing with - * responses in JSON format. Unfortunately most Danbooru - * implementations produce broken JSON for some responses. - * - * @param postData A QXmlStreamAttributes instance holding the - * attributes for the given pool. - * - * - **/ - DanbooruPool(const QXmlStreamAttributes& postData, QObject* parent=0); + /** + * @brief Construct a Danbooru pool from a QVariantMap. + * + * This form is the easiest to use and should be used when dealing with + * responses in JSON format. Unfortunately most Danbooru + * implementations produce broken JSON for some responses. + * + * @param postData A QXmlStreamAttributes instance holding the + * attributes for the given pool. + * + * + **/ + DanbooruPool(const QXmlStreamAttributes &postData, QObject *parent = 0); - int id() const; - int postCount() const; - QString name() const; - QString description() const; - QList posts() const; + int id() const; + int postCount() const; + QString name() const; + QString description() const; + QList posts() const; - void addPost(int post); - void addPosts(QList posts); - void addPosts(const QStringList& posts); - }; + void addPost(int post); + void addPosts(QList posts); + void addPosts(const QStringList &posts); +}; }; // namespace Danbooru -Q_DECLARE_METATYPE(Danbooru::DanbooruPool*) +Q_DECLARE_METATYPE(Danbooru::DanbooruPool *) #endif // DANBOORUPOOL_H diff --git a/src/libdanbooru/danboorupost.cpp b/src/libdanbooru/danboorupost.cpp index b5c3aec..7a596b9 100644 --- a/src/libdanbooru/danboorupost.cpp +++ b/src/libdanbooru/danboorupost.cpp @@ -33,14 +33,13 @@ #include "danboorupost.h" - namespace Danbooru { const QMap DanbooruPost::RATING_MAP = initRatingMap(); DanbooruPost::DanbooruPost(QVariantMap postData, QPixmap pixmap, - QObject* parent): + QObject *parent): QObject(parent), m_pixmap(pixmap) { @@ -57,7 +56,7 @@ DanbooruPost::DanbooruPost(QVariantMap postData, QPixmap pixmap, } -DanbooruPost::DanbooruPost(QXmlStreamAttributes& postData, QPixmap pixmap, QObject* parent): +DanbooruPost::DanbooruPost(QXmlStreamAttributes &postData, QPixmap pixmap, QObject *parent): QObject(parent), m_pixmap(pixmap) { @@ -73,12 +72,10 @@ DanbooruPost::DanbooruPost(QXmlStreamAttributes& postData, QPixmap pixmap, QObje m_rating = RATING_MAP.value(postData.value("rating").toString()); } - DanbooruPost::~DanbooruPost() { } - const QMap< QString, DanbooruPost::Rating > DanbooruPost::initRatingMap() { @@ -91,13 +88,11 @@ const QMap< QString, DanbooruPost::Rating > DanbooruPost::initRatingMap() } - -bool DanbooruPost::operator==(const Danbooru::DanbooruPost& other) +bool DanbooruPost::operator==(const Danbooru::DanbooruPost &other) { return m_url == other.m_url && m_id == other.m_id; } - void DanbooruPost::setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; @@ -155,7 +150,5 @@ Danbooru::DanbooruPost::Rating DanbooruPost::rating() const return m_rating; } - } // namespace Danbooru - diff --git a/src/libdanbooru/danboorupost.h b/src/libdanbooru/danboorupost.h index d0e6513..0b464b3 100644 --- a/src/libdanbooru/danboorupost.h +++ b/src/libdanbooru/danboorupost.h @@ -45,28 +45,28 @@ #include "danbooru.h" +namespace Danbooru +{ -namespace Danbooru { - - /** - * @brief A class representing a Danbooru post. - * - * A Danbooru post is an object that models the posts present in a - * Danbooru board, that is an image with associated information. - * - * In particular, posts contain information on the id, size and dimensions - * of the image, its tags, "preview url" (URL to the thumbnail) and - * file URL. - * - * This is used directly by the DanbooruService class. - * - * @author Luca Beltrame (lbeltrame@kde.org) - * - * @see DanbooruService, DanbooruPool - * - **/ - class DanbooruPost : public QObject - { +/** + * @brief A class representing a Danbooru post. + * + * A Danbooru post is an object that models the posts present in a + * Danbooru board, that is an image with associated information. + * + * In particular, posts contain information on the id, size and dimensions + * of the image, its tags, "preview url" (URL to the thumbnail) and + * file URL. + * + * This is used directly by the DanbooruService class. + * + * @author Luca Beltrame (lbeltrame@kde.org) + * + * @see DanbooruService, DanbooruPool + * + **/ +class DanbooruPost : public QObject +{ Q_OBJECT @@ -76,7 +76,7 @@ namespace Danbooru { Q_PROPERTY(QSet tags READ tags) Q_PROPERTY(QUrl thumbnailUrl READ thumbnailUrl) - public: +public: /** * @brief Ratings for a Danbooru item @@ -88,140 +88,136 @@ namespace Danbooru { Safe = 1, /**< Safe for the general public **/ Questionable = 2, /**< Might contain hints of risqueness of violence **/ Explicit = 4 /**< Explicit material **/ - }; - Q_DECLARE_FLAGS(Ratings, DanbooruPost::Rating) - - - private: - - QPixmap m_pixmap; - - // basic features of a post - - int m_id; - int m_height; - int m_width; - int m_size; - - QUrl m_url; - QUrl m_thumbnailUrl; - QSet m_tags; - DanbooruPost::Rating m_rating; - - static const QMap RATING_MAP; - - // Private functions - - static const QMap< QString, Rating > initRatingMap(); - - public: - - /** - * @brief Construct a Danbooru post from a QVariantMap. - * - * This form is the easiest to use and should be used when dealing with - * responses in JSON format. Unfortunately most Danbooru - * implementations produce broken JSON for some responses. - * - * @param postData A QVariantMap from parsed JSON representing the - * data from a single post. - * @param pixmap A QPixmap pointer to the post thumbnail. - * @param parent A pointer to the parent QObject. - * - **/ - explicit DanbooruPost(QVariantMap postData, QPixmap pixmap = QPixmap(), - QObject* parent = 0); - - /** - * @brief Construct a Danbooru post from XML attributes - * - * This is an overloaded function which uses XML attributes rather - * than JSON. It should be used in case the JSON responses aren't - * complete or broken (for example pools' posts in most Danbooru - * instances). - * - * @param postData A QXmlStreamAttributes instance holding the - * attributes for the given post. - * @param pixmap A QPixmap pointer to the post thumbnail. - * @param parent A pointer to the parent QObject. - * - **/ - explicit DanbooruPost(QXmlStreamAttributes& postData, - QPixmap pixmap = QPixmap(), QObject* parent =0); - - bool operator==(const DanbooruPost&); - - ~DanbooruPost(); - - // Post attributes - - /** - * @return The ID of the post. - **/ - int id() const; - - /** - * @return The height in pixels of the post's image. - **/ - int height() const; - - /** - * @return The width in pixels of the post's image. - **/ - int width() const; - - /** - * @return The size in bytes of the post's image. - **/ - int size() const; - - /** - * @return The URL to the post's image. - **/ - const QUrl fileUrl() const; - - /** - * @return The tags associated to the post. - **/ - const QSet< QString > tags() const; - - /** - * @return The URL to the post's thumbnail. - **/ - const QUrl thumbnailUrl() const; - - /** - * @return A pointer to the thumbnail's pixmap. - **/ - QPixmap pixmap() const; - - /** - * @return The current post's rating. - **/ - Rating rating() const; - - /** - * Set the post's pixmap to a specific QPixmap instance's pointer. - * - **/ - void setPixmap(const QPixmap& pixmap); - - /** - * @return A string representation of the post. - * - * **/ - const QString toString(); - - - }; + Q_DECLARE_FLAGS(Ratings, DanbooruPost::Rating) +private: - Q_DECLARE_OPERATORS_FOR_FLAGS(DanbooruPost::Ratings) + QPixmap m_pixmap; + + // basic features of a post + + int m_id; + int m_height; + int m_width; + int m_size; + + QUrl m_url; + QUrl m_thumbnailUrl; + QSet m_tags; + DanbooruPost::Rating m_rating; + + static const QMap RATING_MAP; + + // Private functions + + static const QMap< QString, Rating > initRatingMap(); + +public: + + /** + * @brief Construct a Danbooru post from a QVariantMap. + * + * This form is the easiest to use and should be used when dealing with + * responses in JSON format. Unfortunately most Danbooru + * implementations produce broken JSON for some responses. + * + * @param postData A QVariantMap from parsed JSON representing the + * data from a single post. + * @param pixmap A QPixmap pointer to the post thumbnail. + * @param parent A pointer to the parent QObject. + * + **/ + explicit DanbooruPost(QVariantMap postData, QPixmap pixmap = QPixmap(), + QObject *parent = 0); + + /** + * @brief Construct a Danbooru post from XML attributes + * + * This is an overloaded function which uses XML attributes rather + * than JSON. It should be used in case the JSON responses aren't + * complete or broken (for example pools' posts in most Danbooru + * instances). + * + * @param postData A QXmlStreamAttributes instance holding the + * attributes for the given post. + * @param pixmap A QPixmap pointer to the post thumbnail. + * @param parent A pointer to the parent QObject. + * + **/ + explicit DanbooruPost(QXmlStreamAttributes &postData, + QPixmap pixmap = QPixmap(), QObject *parent = 0); + + bool operator==(const DanbooruPost &); + + ~DanbooruPost(); + + // Post attributes + + /** + * @return The ID of the post. + **/ + int id() const; + + /** + * @return The height in pixels of the post's image. + **/ + int height() const; + + /** + * @return The width in pixels of the post's image. + **/ + int width() const; + + /** + * @return The size in bytes of the post's image. + **/ + int size() const; + + /** + * @return The URL to the post's image. + **/ + const QUrl fileUrl() const; + + /** + * @return The tags associated to the post. + **/ + const QSet< QString > tags() const; + + /** + * @return The URL to the post's thumbnail. + **/ + const QUrl thumbnailUrl() const; + + /** + * @return A pointer to the thumbnail's pixmap. + **/ + QPixmap pixmap() const; + + /** + * @return The current post's rating. + **/ + Rating rating() const; + + /** + * Set the post's pixmap to a specific QPixmap instance's pointer. + * + **/ + void setPixmap(const QPixmap &pixmap); + + /** + * @return A string representation of the post. + * + * **/ + const QString toString(); + +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(DanbooruPost::Ratings) }; // namespace Danbooru -Q_DECLARE_METATYPE(Danbooru::DanbooruPost*) +Q_DECLARE_METATYPE(Danbooru::DanbooruPost *) #endif // DANBOORUPOST_H diff --git a/src/libdanbooru/danbooruservice.cpp b/src/libdanbooru/danbooruservice.cpp index 79c3e8e..121e619 100644 --- a/src/libdanbooru/danbooruservice.cpp +++ b/src/libdanbooru/danbooruservice.cpp @@ -53,9 +53,9 @@ const QString DanbooruService::ARTIST_URL = "artist/index.json"; const QString DanbooruService::POOL_DATA_URL = "pool/show.xml"; const QString DanbooruService::RELATED_TAG_URL = "tag/related.json"; -DanbooruService::DanbooruService(QUrl& boardUrl, QString username, - QString password, KImageCache* cache, - QObject* parent): +DanbooruService::DanbooruService(QUrl &boardUrl, QString username, + QString password, KImageCache *cache, + QObject *parent): QObject(parent), m_url(boardUrl), m_username(username), @@ -71,7 +71,6 @@ DanbooruService::~DanbooruService() } - void DanbooruService::getPostList(int page, QStringList tags, int limit) { @@ -89,7 +88,7 @@ void DanbooruService::getPostList(int page, QStringList tags, int limit) // qDebug() << "Final constructed post URL" << danbooruUrl.url(); - KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload, + KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload, KIO::HideProgressInfo); // This job can use JSON data @@ -97,7 +96,6 @@ void DanbooruService::getPostList(int page, QStringList tags, int limit) connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPostList); - } void DanbooruService::getTagList(int limit, QString name) @@ -114,38 +112,38 @@ void DanbooruService::getTagList(int limit, QString name) parameters); //qDebug() << "Final constructed tag URL" << danbooruUrl.url(); - KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload, + KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload, KIO::HideProgressInfo); - connect(job, &KIO::StoredTransferJob::result, [this](KJob* job) { - - if (job->error()) { - Q_EMIT(downloadError(job->errorString())); - return; - } - - StoredTransferJob* jobResult = qobject_cast(job); - QByteArray data = jobResult->data(); - - bool ok; - - // Most Danbooru implementations return tags in wrong order when - // using JSON, so we have to fall back to XML - QList tagList = parseDanbooruResult(data, "tag", &ok); - - if (!ok) { - Q_EMIT(downloadError(QString("Unable to decode data"))); - return; - } - - for (auto element : tagList) { - QVariantMap map = element.toMap(); - DanbooruTag* tag = new DanbooruTag(map); - Q_EMIT(tagDownloaded(tag)); - } + connect(job, &KIO::StoredTransferJob::result, [this](KJob * job) { + if (job->error()) { + Q_EMIT(downloadError(job->errorString())); + return; } - ); + + StoredTransferJob *jobResult = qobject_cast(job); + QByteArray data = jobResult->data(); + + bool ok; + + // Most Danbooru implementations return tags in wrong order when + // using JSON, so we have to fall back to XML + QList tagList = parseDanbooruResult(data, "tag", &ok); + + if (!ok) { + Q_EMIT(downloadError(QString("Unable to decode data"))); + return; + } + + for (auto element : tagList) { + QVariantMap map = element.toMap(); + DanbooruTag *tag = new DanbooruTag(map); + Q_EMIT(tagDownloaded(tag)); + } + + } + ); } void DanbooruService::getPool(int poolId, int page) @@ -164,8 +162,7 @@ void DanbooruService::getPool(int poolId, int page) //qDebug() << "Final constructed pool URL" << danbooruUrl.url(); - - KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload, + KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload, KIO::HideProgressInfo); //HACK: Most Danbooru implementations don't provide valid data on @@ -194,21 +191,21 @@ void DanbooruService::getPoolList(int page) //qDebug() << "Final constructed pool list URL" << danbooruUrl.url(); - KIO::StoredTransferJob* job = KIO::storedGet(danbooruUrl, KIO::NoReload, + KIO::StoredTransferJob *job = KIO::storedGet(danbooruUrl, KIO::NoReload, KIO::HideProgressInfo); // This job can use JSON data job->setProperty("needsXML", false); // connect(job, &KIO::StoredTransferJob::result, this, &DanbooruService::processPoolList); - connect(job, &KIO::StoredTransferJob::result, [this] (KJob* job) { + connect(job, &KIO::StoredTransferJob::result, [this](KJob * job) { if (job->error()) { Q_EMIT(downloadError(job->errorString())); return; } - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); QByteArray data = jobResult->data(); bool ok; @@ -222,7 +219,7 @@ void DanbooruService::getPoolList(int page) for (auto element : poolList) { QVariantMap map = element.toMap(); - DanbooruPool* pool = new DanbooruPool(map); + DanbooruPool *pool = new DanbooruPool(map); Q_EMIT(poolDownloaded(pool)); } @@ -230,11 +227,11 @@ void DanbooruService::getPoolList(int page) Q_EMIT(poolDownloadFinished()); } - ); + ); } -void DanbooruService::getRelatedTags(const QStringList& tags, +void DanbooruService::getRelatedTags(const QStringList &tags, DanbooruTag::TagType tagType) { @@ -265,19 +262,19 @@ void DanbooruService::getRelatedTags(const QStringList& tags, //qDebug() << "Final constructed related tag URL" << danbooruUrl.url(); - StoredTransferJob* job = KIO::storedGet( + StoredTransferJob *job = KIO::storedGet( danbooruUrl, KIO::NoReload, KIO::HideProgressInfo ); - connect(job, &StoredTransferJob::result, [this](KJob* job) { + connect(job, &StoredTransferJob::result, [this](KJob * job) { if (job->error()) { - Q_EMIT(downloadError(job->errorString())); - return; + Q_EMIT(downloadError(job->errorString())); + return; } - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); QByteArray data = jobResult->data(); bool ok; @@ -314,13 +311,13 @@ void DanbooruService::getRelatedTags(const QStringList& tags, } - ); + ); } // Getters / setters -void DanbooruService::setBlacklist(const QSet< QString >& blacklist) +void DanbooruService::setBlacklist(const QSet< QString > &blacklist) { if (!blacklist.isEmpty()) { @@ -329,7 +326,6 @@ void DanbooruService::setBlacklist(const QSet< QString >& blacklist) } - const QSet< QString > DanbooruService::blacklist() const { return m_blacklist; @@ -384,7 +380,7 @@ const DanbooruPost::Ratings DanbooruService::maximumAllowedRating() const // Slots -void DanbooruService::processPostList(KJob* job) +void DanbooruService::processPostList(KJob *job) { // qDebug() << "Got post data OK"; @@ -393,7 +389,7 @@ void DanbooruService::processPostList(KJob* job) Q_EMIT(downloadError(job->errorString())); } - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); if (jobResult == 0) { Q_EMIT(downloadError(QString("Internal error"))); @@ -427,7 +423,7 @@ void DanbooruService::processPostList(KJob* job) for (auto element : postList) { QVariantMap map = element.toMap(); - DanbooruPost* post = new DanbooruPost(map); + DanbooruPost *post = new DanbooruPost(map); // Remove unwanted posts @@ -453,11 +449,11 @@ void DanbooruService::processPostList(KJob* job) } else { - StoredTransferJob* pixmapJob = KIO::storedGet(post->thumbnailUrl(), - KIO::NoReload, KIO::HideProgressInfo - ); + StoredTransferJob *pixmapJob = KIO::storedGet(post->thumbnailUrl(), + KIO::NoReload, KIO::HideProgressInfo + ); - KIO::Scheduler::setJobPriority(static_cast(job), 1); + KIO::Scheduler::setJobPriority(static_cast(job), 1); QVariant variant; variant.setValue(post); @@ -467,23 +463,26 @@ void DanbooruService::processPostList(KJob* job) pixmapJob->setProperty("danbooruPost", variant); - connect(pixmapJob, &StoredTransferJob::result, [post, this, pix] (KJob* job) mutable { + connect(pixmapJob, &StoredTransferJob::result, [post, this, pix](KJob * job) mutable { - if (job->error()) { + if (job->error()) + { Q_EMIT(downloadError(job->errorString())); return; } - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); - if (!pix.loadFromData(jobResult->data())) { - Q_EMIT(downloadError(QString("Pixmap data could not be loaded"))); - return; + if (!pix.loadFromData(jobResult->data())) + { + Q_EMIT(downloadError(QString("Pixmap data could not be loaded"))); + return; } post->setPixmap(pix); - if (m_cache) { + if (m_cache) + { //qDebug() << "Inserting item in cache"; m_cache->insertPixmap(post->thumbnailUrl().url(), pix); } @@ -493,7 +492,8 @@ void DanbooruService::processPostList(KJob* job) //qDebug() << "Current posts remaining" << m_currentPosts; Q_EMIT(postDownloaded(post)); - if (m_postsToFetch == 0) { + if (m_postsToFetch == 0) + { qDebug() << "Post download finished"; Q_EMIT(postDownloadFinished()); } @@ -504,30 +504,26 @@ void DanbooruService::processPostList(KJob* job) } - - } -void DanbooruService::processTagList(KJob* job) +void DanbooruService::processTagList(KJob *job) { } - -void DanbooruService::processRelatedTagList(KJob* job) +void DanbooruService::processRelatedTagList(KJob *job) { } -void DanbooruService::processPoolList(KJob* job) +void DanbooruService::processPoolList(KJob *job) { - if (job->error()) { Q_EMIT(downloadError(job->errorString())); } - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); if (jobResult == 0) { Q_EMIT(downloadError(QString("Internal error"))); @@ -549,7 +545,7 @@ void DanbooruService::processPoolList(KJob* job) for (auto element : poolList) { QVariantMap map = element.toMap(); - DanbooruPool* pool = new DanbooruPool(map); + DanbooruPool *pool = new DanbooruPool(map); Q_EMIT(poolDownloaded(pool)); } @@ -558,12 +554,12 @@ void DanbooruService::processPoolList(KJob* job) } -void DanbooruService::downloadAllTags(KJob* job) +void DanbooruService::downloadAllTags(KJob *job) { Q_UNUSED(job) } -void DanbooruService::downloadThumbnail(KJob* job) +void DanbooruService::downloadThumbnail(KJob *job) { if (job->error()) { @@ -572,11 +568,11 @@ void DanbooruService::downloadThumbnail(KJob* job) QVariant postData = job->property("danbooruPost"); - DanbooruPost* post = postData.value(); + DanbooruPost *post = postData.value(); QPixmap pix; // QPixmap* pix = new QPixmap(); - StoredTransferJob* jobResult = qobject_cast(job); + StoredTransferJob *jobResult = qobject_cast(job); if (jobResult == 0) { Q_EMIT(downloadError(QString("Internal error"))); diff --git a/src/libdanbooru/danbooruservice.h b/src/libdanbooru/danbooruservice.h index fc8f17b..3ba183f 100644 --- a/src/libdanbooru/danbooruservice.h +++ b/src/libdanbooru/danbooruservice.h @@ -24,7 +24,6 @@ #ifndef DANBOORUSERVICE_H #define DANBOORUSERVICE_H - /** * @brief Classes to interact with Danbooru boards * @file danbooruservice.h @@ -56,214 +55,214 @@ class KJob; using Danbooru::DanbooruTag; -namespace Danbooru { +namespace Danbooru +{ - class DanbooruPool; +class DanbooruPool; - using KIO::StoredTransferJob; +using KIO::StoredTransferJob; - /** - * @brief A class which provides a wrapper around Danbooru's RESTful API. - * - * This class provides access to Danbooru-based image boards - * by making the appropriate RESTful calls to the service and then - * retrieving and parsing the reuslts. - * - * @author Luca Beltrame (lbeltrame@kde.org) - * - * - **/ - class DanbooruService : public QObject - { +/** + * @brief A class which provides a wrapper around Danbooru's RESTful API. + * + * This class provides access to Danbooru-based image boards + * by making the appropriate RESTful calls to the service and then + * retrieving and parsing the reuslts. + * + * @author Luca Beltrame (lbeltrame@kde.org) + * + * + **/ +class DanbooruService : public QObject +{ Q_OBJECT - private: +private: - // URL fragments + // URL fragments - static const QString POST_URL; - static const QString TAG_URL; - static const QString POOL_URL; - static const QString ARTIST_URL; - static const QString POOL_DATA_URL; - static const QString RELATED_TAG_URL; + static const QString POST_URL; + static const QString TAG_URL; + static const QString POOL_URL; + static const QString ARTIST_URL; + static const QString POOL_DATA_URL; + static const QString RELATED_TAG_URL; - // member variables + // member variables - QUrl m_url; - QString m_username; - QString m_password; - QSet m_blacklist; - DanbooruPost::Ratings m_maxRating; + QUrl m_url; + QString m_username; + QString m_password; + QSet m_blacklist; + DanbooruPost::Ratings m_maxRating; - unsigned int m_postsToFetch; // To tell when to quit + unsigned int m_postsToFetch; // To tell when to quit - KImageCache* m_cache; // Pixmap cache + KImageCache *m_cache; // Pixmap cache - public: +public: - /** - * @brief Construct a default instance of the service. - * - * @param boardUrl The URL to connect to. - * @param username Username to use (optional) - * @param password Password to use (optional) - * @param cache A pointer to a KImageCache instance to enable caching - * of downloaded pixmaps. - * @param parent The parent QObject - * - **/ - DanbooruService(QUrl& boardUrl, QString username = QString(), - QString password = QString(), KImageCache* cache = 0, - QObject* parent = 0); + /** + * @brief Construct a default instance of the service. + * + * @param boardUrl The URL to connect to. + * @param username Username to use (optional) + * @param password Password to use (optional) + * @param cache A pointer to a KImageCache instance to enable caching + * of downloaded pixmaps. + * @param parent The parent QObject + * + **/ + DanbooruService(QUrl &boardUrl, QString username = QString(), + QString password = QString(), KImageCache *cache = 0, + QObject *parent = 0); - /** - * Default destructor. - **/ - ~DanbooruService(); + /** + * Default destructor. + **/ + ~DanbooruService(); - /** - *@brief Get posts from a the board. - * - * @param page The page containing posts (default: 1) - * @param tags The specific tags to query for (default: all tags) - * @param limit The number of posts to fetch (maximum 100) - * - **/ - void getPostList(int page=1, QStringList tags=QStringList(), - int limit=100); + /** + *@brief Get posts from a the board. + * + * @param page The page containing posts (default: 1) + * @param tags The specific tags to query for (default: all tags) + * @param limit The number of posts to fetch (maximum 100) + * + **/ + void getPostList(int page = 1, QStringList tags = QStringList(), + int limit = 100); - /** - * @brief Get a list of pools from the board. - * - * @param page The page to get pools from (default: 1) - * - **/ - void getPoolList(int page = 1); + /** + * @brief Get a list of pools from the board. + * + * @param page The page to get pools from (default: 1) + * + **/ + void getPoolList(int page = 1); - /** - * @brief Get the posts associated with a specific pool ID. - * - * @param poolId The ID of the pool to fetch posts from. - * @param page The page of the pool posts (if > 100) - * - **/ - void getPool(int poolId, int page=1); + /** + * @brief Get the posts associated with a specific pool ID. + * + * @param poolId The ID of the pool to fetch posts from. + * @param page The page of the pool posts (if > 100) + * + **/ + void getPool(int poolId, int page = 1); - /** - * @brief Get a list of tags from the board - * - * If name is supplied, a list of tags including the exact name of the - * tag is fetched from Danbooru, otherwise the most recent tags are - * retrieved. - * - * The tagDownloaded signal is emitted every time a tag has been - * retrieved. - * - * @param limit The number of tags to get. - * @param name The name of the tag to retrieve, or an empty string - * - **/ - void getTagList(int limit=10, QString name=""); + /** + * @brief Get a list of tags from the board + * + * If name is supplied, a list of tags including the exact name of the + * tag is fetched from Danbooru, otherwise the most recent tags are + * retrieved. + * + * The tagDownloaded signal is emitted every time a tag has been + * retrieved. + * + * @param limit The number of tags to get. + * @param name The name of the tag to retrieve, or an empty string + * + **/ + void getTagList(int limit = 10, QString name = ""); - /** - * @brief Get tags related to a specific, user supplied list. - * - * @param tags The tags to query for related terms - * @param tagType The type of tag to query for - **/ - void getRelatedTags(const QStringList& tags, DanbooruTag::TagType tagType = DanbooruTag::General); + /** + * @brief Get tags related to a specific, user supplied list. + * + * @param tags The tags to query for related terms + * @param tagType The type of tag to query for + **/ + void getRelatedTags(const QStringList &tags, DanbooruTag::TagType tagType = DanbooruTag::General); - /** - * @return The currently allowed ratings when downloading posts. - **/ - const QStringList allowedRatings() const; + /** + * @return The currently allowed ratings when downloading posts. + **/ + const QStringList allowedRatings() const; - /** - * @return The maximum allowed rating for a post. - **/ - const DanbooruPost::Ratings maximumAllowedRating() const; + /** + * @return The maximum allowed rating for a post. + **/ + const DanbooruPost::Ratings maximumAllowedRating() const; - /** - * @return The currently blacklisted tags. - **/ - const QSet blacklist() const; + /** + * @return The currently blacklisted tags. + **/ + const QSet blacklist() const; - void setBlacklist(const QSet& blacklist); + void setBlacklist(const QSet &blacklist); - /** - * @brief Set the maximum allowed rating for the board. - * - * Posts whose rating is higher than the maximuk allowed will not be - * downloaded. - * - **/ - void setMaximumAllowedRating(DanbooruPost::Rating rating); + /** + * @brief Set the maximum allowed rating for the board. + * + * Posts whose rating is higher than the maximuk allowed will not be + * downloaded. + * + **/ + void setMaximumAllowedRating(DanbooruPost::Rating rating); - /** - * @brief Set the tag blacklist. - * - * If a tag is in the blacklist, posts tagged with it will not be downloaded. - * - **/ - void setBlackList(QStringList blacklist); + /** + * @brief Set the tag blacklist. + * + * If a tag is in the blacklist, posts tagged with it will not be downloaded. + * + **/ + void setBlackList(QStringList blacklist); - private Q_SLOTS: - void processPostList(KJob* job); - void processPoolList(KJob* job); - void processTagList(KJob* job); - void processRelatedTagList(KJob* job); - void downloadThumbnail(KJob* job); - void downloadAllTags(KJob* job); +private Q_SLOTS: + void processPostList(KJob *job); + void processPoolList(KJob *job); + void processTagList(KJob *job); + void processRelatedTagList(KJob *job); + void downloadThumbnail(KJob *job); + void downloadAllTags(KJob *job); - Q_SIGNALS: +Q_SIGNALS: - /** - * Emitted when there are no more posts to download. - * - * Connect to this signal to know when downloading is complete. - * - **/ - void postDownloadFinished(); + /** + * Emitted when there are no more posts to download. + * + * Connect to this signal to know when downloading is complete. + * + **/ + void postDownloadFinished(); - /** - * Emitted when there are no more pools to download. - **/ - void poolDownloadFinished(); + /** + * Emitted when there are no more pools to download. + **/ + void poolDownloadFinished(); + /** + * Emitted when a download error occurred. + * + * The parameter contains the error string. + * + **/ + void downloadError(QString error); - /** - * Emitted when a download error occurred. - * - * The parameter contains the error string. - * - **/ - void downloadError(QString error); + /** + * Emitted when a post has been downloaded. + * + * The parameter contains a pointer to the post that has been + * downloaded. + **/ + void postDownloaded(Danbooru::DanbooruPost *post); - /** - * Emitted when a post has been downloaded. - * - * The parameter contains a pointer to the post that has been - * downloaded. - **/ - void postDownloaded(Danbooru::DanbooruPost* post); + /** + * Emitted when a pool has been downloaded. + * + * The parameter contains a pointer to the pool that has been + * downloaded. + **/ + void poolDownloaded(Danbooru::DanbooruPool *pool); - /** - * Emitted when a pool has been downloaded. - * - * The parameter contains a pointer to the pool that has been - * downloaded. - **/ - void poolDownloaded(Danbooru::DanbooruPool* pool); + /** + * Emitted when a tag has been downloaded. + * + * The parameter contains a pointer to the tag that has been + * downloaded. + **/ + void tagDownloaded(Danbooru::DanbooruTag *tag); - /** - * Emitted when a tag has been downloaded. - * - * The parameter contains a pointer to the tag that has been - * downloaded. - **/ - void tagDownloaded(Danbooru::DanbooruTag* tag); - - }; +}; }; #endif // DANBOORUSERVICE_H diff --git a/src/libdanbooru/danboorutag.cpp b/src/libdanbooru/danboorutag.cpp index e3a62fa..2b05ec7 100644 --- a/src/libdanbooru/danboorutag.cpp +++ b/src/libdanbooru/danboorutag.cpp @@ -25,7 +25,7 @@ namespace Danbooru { -DanbooruTag::DanbooruTag(const QVariantMap& postData, QObject* parent): +DanbooruTag::DanbooruTag(const QVariantMap &postData, QObject *parent): QObject(parent) { m_id = postData.value("id").toInt(); @@ -82,5 +82,4 @@ Danbooru::DanbooruTag::TagType DanbooruTag::type() const return m_tagType; } - }; // namespace Danbooru diff --git a/src/libdanbooru/danboorutag.h b/src/libdanbooru/danboorutag.h index 610a8ee..fde14d6 100644 --- a/src/libdanbooru/danboorutag.h +++ b/src/libdanbooru/danboorutag.h @@ -20,7 +20,6 @@ * */ - #ifndef DANBOORUTAG_H #define DANBOORUTAG_H @@ -29,54 +28,55 @@ #include "danbooru.h" -namespace Danbooru { +namespace Danbooru +{ - class DanbooruTag : public QObject - { +class DanbooruTag : public QObject +{ Q_OBJECT - public: - /** - * @brief Types of tags - * - * A Danbooru tag is not simply a string, but carries some (limited) - * semantic information. In particular, tags are organized in what they - * refer to, either something related to the image itself, or to the - * artist that drew it, or the copyrights associated to the image, or even - * the characters that are represented in it. - * - **/ +public: + /** + * @brief Types of tags + * + * A Danbooru tag is not simply a string, but carries some (limited) + * semantic information. In particular, tags are organized in what they + * refer to, either something related to the image itself, or to the + * artist that drew it, or the copyrights associated to the image, or even + * the characters that are represented in it. + * + **/ enum TagType { General = 1, /**< Generic tags **/ Artist = 2, /**< Tags related to artists **/ Copyright = 4, /** -namespace Danbooru { +namespace Danbooru +{ - QUrl requestUrl(QUrl& url, const QString& path, - const QString& username, const QString& password, - const dictMap& parameters, const QStringList& tags) - { +QUrl requestUrl(QUrl &url, const QString &path, + const QString &username, const QString &password, + const dictMap ¶meters, const QStringList &tags) +{ - QUrl danbooruUrl = QUrl(url); - danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); - danbooruUrl.setPath(danbooruUrl.path() + '/' + path); + QUrl danbooruUrl = QUrl(url); + danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); + danbooruUrl.setPath(danbooruUrl.path() + '/' + path); - // If we have parameters, add them + // If we have parameters, add them - if (!parameters.isEmpty()) { - - for (auto key: parameters.keys()) { - danbooruUrl.addQueryItem(key, parameters.value(key)); - } + if (!parameters.isEmpty()) { + for (auto key : parameters.keys()) { + danbooruUrl.addQueryItem(key, parameters.value(key)); } - // Now, let's add tags should we have them - - if (!tags.isEmpty()) { - QByteArray encoded_tags = QUrl::toPercentEncoding(tags.join(" ")); - danbooruUrl.addEncodedQueryItem("tags", encoded_tags); - } - - if (!username.isEmpty() && !password.isEmpty()) { - danbooruUrl.setUserName(username); - danbooruUrl.setPassword(password); - } - - return danbooruUrl; } - QUrl requestUrl(QUrl& url, const QString& path, const QString& username, - const QString& password, const dictMap& parameters) - { + // Now, let's add tags should we have them - QUrl danbooruUrl = QUrl(url); - danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); - danbooruUrl.setPath(danbooruUrl.path() + '/' + path); - - // If we have parameters, add them - - if (!parameters.isEmpty()) { - - for (auto key: parameters.keys()) { - danbooruUrl.addQueryItem(key, parameters.value(key)); - } - - } - - if (!username.isEmpty() && !password.isEmpty()) { - danbooruUrl.setUserName(username); - danbooruUrl.setPassword(password); - } - - return danbooruUrl; + if (!tags.isEmpty()) { + QByteArray encoded_tags = QUrl::toPercentEncoding(tags.join(" ")); + danbooruUrl.addEncodedQueryItem("tags", encoded_tags); } - QUrl requestUrl(QUrl& url, const QString& path, const QString& username, - const QString& password) - { - QUrl danbooruUrl = QUrl(url); - danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); - danbooruUrl.setPath(danbooruUrl.path() + '/' + path); - - if (!username.isEmpty() && !password.isEmpty()) { - danbooruUrl.setUserName(username); - danbooruUrl.setPassword(password); - } - - return danbooruUrl; + if (!username.isEmpty() && !password.isEmpty()) { + danbooruUrl.setUserName(username); + danbooruUrl.setPassword(password); } - QList< QVariant > parseDanbooruResult(QByteArray data, QString elementName, - bool* result) - { + return danbooruUrl; +} - QXmlStreamReader reader; - reader.addData(data); +QUrl requestUrl(QUrl &url, const QString &path, const QString &username, + const QString &password, const dictMap ¶meters) +{ - QList postData; + QUrl danbooruUrl = QUrl(url); + danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); + danbooruUrl.setPath(danbooruUrl.path() + '/' + path); - while(!reader.atEnd() && !reader.hasError()) { + // If we have parameters, add them - QXmlStreamReader::TokenType token = reader.readNext(); + if (!parameters.isEmpty()) { - if (token == QXmlStreamReader::StartDocument) { - continue; - } + for (auto key : parameters.keys()) { + danbooruUrl.addQueryItem(key, parameters.value(key)); + } - if(token == QXmlStreamReader::StartElement && - reader.name() == elementName) { + } - QVariantMap values; + if (!username.isEmpty() && !password.isEmpty()) { + danbooruUrl.setUserName(username); + danbooruUrl.setPassword(password); + } - QXmlStreamAttributes attributes = reader.attributes(); + return danbooruUrl; +} + +QUrl requestUrl(QUrl &url, const QString &path, const QString &username, + const QString &password) +{ + QUrl danbooruUrl = QUrl(url); + danbooruUrl = danbooruUrl.adjusted(QUrl::StripTrailingSlash); + danbooruUrl.setPath(danbooruUrl.path() + '/' + path); + + if (!username.isEmpty() && !password.isEmpty()) { + danbooruUrl.setUserName(username); + danbooruUrl.setPassword(password); + } + + return danbooruUrl; +} + +QList< QVariant > parseDanbooruResult(QByteArray data, QString elementName, + bool *result) +{ + + QXmlStreamReader reader; + reader.addData(data); + + QList postData; + + while (!reader.atEnd() && !reader.hasError()) { + + QXmlStreamReader::TokenType token = reader.readNext(); + + if (token == QXmlStreamReader::StartDocument) { + continue; + } + + if (token == QXmlStreamReader::StartElement && + reader.name() == elementName) { + + QVariantMap values; + + QXmlStreamAttributes attributes = reader.attributes(); // qDebug() << attributes; - for (auto attribute: attributes) { - values.insert(attribute.name().toString(), - attribute.value().toString()); - } - - if (values.isEmpty()) { - *result = false; - qWarning() << "No results found when parsing XML"; - return QList(); - } - - QVariant converted = QVariant(values); - - postData.append(converted); + for (auto attribute : attributes) { + values.insert(attribute.name().toString(), + attribute.value().toString()); } + + if (values.isEmpty()) { + *result = false; + qWarning() << "No results found when parsing XML"; + return QList(); + } + + QVariant converted = QVariant(values); + + postData.append(converted); } - *result = true; - return postData; + } + *result = true; + return postData; +} + +QVariant parseDanbooruResult(QByteArray data, bool *result) +{ + + QJsonDocument parsed = QJsonDocument::fromJson(data); + + if (parsed.isNull()) { + return QList(); } - QVariant parseDanbooruResult(QByteArray data, bool* result) - { + QVariant postData = parsed.toVariant(); - QJsonDocument parsed = QJsonDocument::fromJson(data); + *result = true; - if (parsed.isNull()) { - return QList(); - } + return postData; +} - QVariant postData = parsed.toVariant(); - - *result = true; - - return postData; - } - - -bool isPostBlacklisted(DanbooruPost *post, QSet blacklist, DanbooruPost::Ratings maxRating ) { +bool isPostBlacklisted(DanbooruPost *post, QSet blacklist, DanbooruPost::Ratings maxRating) +{ if (post->rating() > maxRating) { return true; } - for (auto tag: post->tags()) { + for (auto tag : post->tags()) { if (blacklist.contains(tag)) { - return true; + return true; } } diff --git a/src/libdanbooru/utils.h b/src/libdanbooru/utils.h index ebe5ce4..035f386 100644 --- a/src/libdanbooru/utils.h +++ b/src/libdanbooru/utils.h @@ -39,90 +39,88 @@ * **/ -namespace Danbooru { +namespace Danbooru +{ - typedef QMap dictMap; +typedef QMap dictMap; - /** @brief Generate a request URL for a Danbooru board. - * - * Given an URL and an API path, this function builds a - * proper URL which is used for the specific API operation. - * The processing follows the "normal" way of encoding URLs. - * - * @param url The board URL. - * @param path The API path of the call to use - * @param username The username to supply (optional) - * @param password The password to use (optional) - * @param parameters A map of key,values representing the parameters - * to use. - * @param tags The tags to supply (optional). - * - * @return A constructed URL to be used for a Danbooru API call. - * @author Luca Beltrame (lbeltrame@kde.org) - * - * - **/ - QUrl requestUrl(QUrl& url, const QString& path, const QString& username, - const QString& password, const dictMap& parameters, - const QStringList& tags); +/** @brief Generate a request URL for a Danbooru board. + * + * Given an URL and an API path, this function builds a + * proper URL which is used for the specific API operation. + * The processing follows the "normal" way of encoding URLs. + * + * @param url The board URL. + * @param path The API path of the call to use + * @param username The username to supply (optional) + * @param password The password to use (optional) + * @param parameters A map of key,values representing the parameters + * to use. + * @param tags The tags to supply (optional). + * + * @return A constructed URL to be used for a Danbooru API call. + * @author Luca Beltrame (lbeltrame@kde.org) + * + * + **/ +QUrl requestUrl(QUrl &url, const QString &path, const QString &username, + const QString &password, const dictMap ¶meters, + const QStringList &tags); +/** @brief Generate a request URL for a Danbooru board. + * + * This is an overloaded function provided for convenience. + * + * + * @param url The board URL. + * @param path The API path of the call to use + * @param username The username to supply (optional) + * @param password The password to use (optional) + * @param parameters A map of key,values representing the parameters + * to use. + * + * @return A constructed URL to be used for a Danbooru API call. + * @author Luca Beltrame (lbeltrame@kde.org) + * + * + **/ +QUrl requestUrl(QUrl &url, const QString &path, const QString &username, + const QString &password, const dictMap ¶meters); - /** @brief Generate a request URL for a Danbooru board. - * - * This is an overloaded function provided for convenience. - * - * - * @param url The board URL. - * @param path The API path of the call to use - * @param username The username to supply (optional) - * @param password The password to use (optional) - * @param parameters A map of key,values representing the parameters - * to use. - * - * @return A constructed URL to be used for a Danbooru API call. - * @author Luca Beltrame (lbeltrame@kde.org) - * - * - **/ - QUrl requestUrl(QUrl& url, const QString& path, const QString& username, - const QString& password, const dictMap& parameters); +/** @brief Generate a request URL for a Danbooru board. + * + * This is an overloaded function provided for convenience. + * + * @param url The board URL. + * @param path The API path of the call to use + * @param username The username to supply (optional) + * @param password The password to use (optional) + * + * @return A constructed URL to be used for a Danbooru API call. + * @author Luca Beltrame (lbeltrame@kde.org) + * + * + **/ +QUrl requestUrl(QUrl &url, const QString &path, const QString &username, + const QString &password); +QList parseDanbooruResult(QByteArray data, QString xlmElement, + bool *result); +QVariant parseDanbooruResult(QByteArray data, bool *result); - /** @brief Generate a request URL for a Danbooru board. - * - * This is an overloaded function provided for convenience. - * - * @param url The board URL. - * @param path The API path of the call to use - * @param username The username to supply (optional) - * @param password The password to use (optional) - * - * @return A constructed URL to be used for a Danbooru API call. - * @author Luca Beltrame (lbeltrame@kde.org) - * - * - **/ - QUrl requestUrl(QUrl& url, const QString& path, const QString& username, - const QString& password); - - - QList parseDanbooruResult(QByteArray data, QString xlmElement, - bool* result); - QVariant parseDanbooruResult(QByteArray data, bool* result); - - /** - * @brief Check if a post can be allowed. - * - * This convenience function checks if a DanbooruPost is not allowed, either because it - * contains blacklisted tags, or because it has a higher rating than allowed. - * - * @param post A DanbooruPost pointer. - * @param blacklist A QSet containing unwanted tag names as QStrings. - * @param maxRating The maximum allowed rating expressed as a DanbooruPost::Ratings flag. - * @return true if the post is unwanted, false otherwise. - * @author Luca Beltrame (lbeltrame@kde.org) - */ - bool isPostBlacklisted(DanbooruPost *post, QSet blacklist, DanbooruPost::Ratings maxRating ); +/** + * @brief Check if a post can be allowed. + * + * This convenience function checks if a DanbooruPost is not allowed, either because it + * contains blacklisted tags, or because it has a higher rating than allowed. + * + * @param post A DanbooruPost pointer. + * @param blacklist A QSet containing unwanted tag names as QStrings. + * @param maxRating The maximum allowed rating expressed as a DanbooruPost::Ratings flag. + * @return true if the post is unwanted, false otherwise. + * @author Luca Beltrame (lbeltrame@kde.org) + */ +bool isPostBlacklisted(DanbooruPost *post, QSet blacklist, DanbooruPost::Ratings maxRating); } #endif // UTILS_H diff --git a/src/main.cpp b/src/main.cpp index 7f71056..d35cd86 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,8 +36,8 @@ static const char version[] = "%{VERSION}"; int main(int argc, char **argv) { K4AboutData about("danbooru_client", 0, ki18n("danbooru_client"), version, ki18n(description), - K4AboutData::License_GPL, ki18n("(C) %{CURRENT_YEAR} %{AUTHOR}"), KLocalizedString(), 0, "%{EMAIL}"); - about.addAuthor( ki18n("%{AUTHOR}"), KLocalizedString(), "%{EMAIL}" ); + K4AboutData::License_GPL, ki18n("(C) %{CURRENT_YEAR} %{AUTHOR}"), KLocalizedString(), 0, "%{EMAIL}"); + about.addAuthor(ki18n("%{AUTHOR}"), KLocalizedString(), "%{EMAIL}"); QApplication app(argc, argv); QCommandLineParser parser; K4AboutData::setApplicationData(aboutData); @@ -48,33 +48,26 @@ int main(int argc, char **argv) parser.process(app); aboutData.processCommandLine(&parser); - parser.addOption(QCommandLineOption(QStringList() << QLatin1String("+[URL]"), i18n( "Document to open" ))); + parser.addOption(QCommandLineOption(QStringList() << QLatin1String("+[URL]"), i18n("Document to open"))); danbooru_client *widget = new danbooru_client; // see if we are starting with session management - if (app.isSessionRestored()) - { + if (app.isSessionRestored()) { RESTORE(danbooru_client); - } - else - { + } else { // no session.. just start up normally - if (parser.positionalArguments().count() == 0) - { + if (parser.positionalArguments().count() == 0) { //danbooru_client *widget = new danbooru_client; widget->show(); - } - else - { + } else { int i = 0; - for (; i < parser.positionalArguments().count(); i++) - { + for (; i < parser.positionalArguments().count(); i++) { //danbooru_client *widget = new danbooru_client; widget->show(); } } - + } return app.exec(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4da422d..3ad8d38 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -30,49 +30,47 @@ #include -namespace Danbooru { +namespace Danbooru +{ - DanbooruMainWindow::DanbooruMainWindow() - : KXmlGuiWindow(), - m_view(new DanbooruClientView(this)), - m_service(0), - m_model(new(DanbooruPostModel(this))) - { - // tell the KXmlGuiWindow that this is indeed the main widget - setCentralWidget(m_view); +DanbooruMainWindow::DanbooruMainWindow() + : KXmlGuiWindow(), + m_view(new DanbooruClientView(this)), + m_service(0), + m_model(new(DanbooruPostModel(this))) +{ + // tell the KXmlGuiWindow that this is indeed the main widget + setCentralWidget(m_view); - // then, setup our actions - setupActions(); + // then, setup our actions + setupActions(); - // add a status bar - statusBar()->show(); + // add a status bar + statusBar()->show(); - // a call to KXmlGuiWindow::setupGUI() populates the GUI - // with actions, using KXMLGUI. - // It also applies the saved mainwindow settings, if any, and ask the - // mainwindow to automatically save settings if changed: window size, - // toolbar position, icon size, etc. - setupGUI(); + // a call to KXmlGuiWindow::setupGUI() populates the GUI + // with actions, using KXMLGUI. + // It also applies the saved mainwindow settings, if any, and ask the + // mainwindow to automatically save settings if changed: window size, + // toolbar position, icon size, etc. + setupGUI(); +} - } +DanbooruMainWindow::~DanbooruMainWindow() +{ +} - DanbooruMainWindow::~DanbooruMainWindow() - { - } +void DanbooruMainWindow::setupActions() +{ - void DanbooruMainWindow::setupActions() - { - - - - QAction * connectAction = new QAction( + QAction *connectAction = new QAction( QIcon::fromTheme(QLatin1String("document-open-remote")), i18n("Connect..."), this); - QAction * fetchAction = new QAction(QIcon::fromTheme(QLatin1String("download")), - i18n("Download"), this); + QAction *fetchAction = new QAction(QIcon::fromTheme(QLatin1String("download")), + i18n("Download"), this); connectAction->setShortcut(KStandardShortcut::open()); fetchAction->setShortcut(KStandardShortcut::find()); @@ -86,29 +84,28 @@ namespace Danbooru { connect(connectAction, &QAction::triggered, this, &DanbooruMainWindow::connectToBoard); connect(fetch, SIGNAL(triggered(bool)), this, SLOT(downloadPosts())); +} + +void DanbooruMainWindow::connectToBoard() +{ + + if (!m_view) { + return; } - void DanbooruMainWindow::connectToBoard() - { - - if (!m_view) { - return; - } +} +void DanbooruMainWindow::downloadPosts() +{ + if (!m_service) { + return; } +} - void DanbooruMainWindow::downloadPosts() - { - if (!m_service) { - return; - } - } - - void DanbooruMainWindow::optionsPreferences() - { - - } +void DanbooruMainWindow::optionsPreferences() +{ +} } // namespace Danbooru diff --git a/src/mainwindow.h b/src/mainwindow.h index b7501ac..8a81a63 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -23,55 +23,54 @@ #ifndef DANBOORU_CLIENT_H #define DANBOORU_CLIENT_H - #include -namespace Danbooru { +namespace Danbooru +{ - class DanbooruClientView; - class DanbooruService; - class DanbooruPostModel; - class DanbooruConnectWidget; +class DanbooruClientView; +class DanbooruService; +class DanbooruPostModel; +class DanbooruConnectWidget; + +/** + * This class serves as the main window for danbooru_client. It handles the + * menus, toolbars and status bars. + * + * @short Main window class + * @author Luca Beltrame + * @version 0.01 + */ +class DanbooruMainWindow : public KXmlGuiWindow +{ + Q_OBJECT +public: + /** + * Default Constructor + */ + DanbooruMainWindow(); /** - * This class serves as the main window for danbooru_client. It handles the - * menus, toolbars and status bars. - * - * @short Main window class - * @author Luca Beltrame - * @version 0.01 + * Default Destructor */ - class DanbooruMainWindow : public KXmlGuiWindow - { - Q_OBJECT - public: - /** - * Default Constructor - */ - DanbooruMainWindow(); + virtual ~DanbooruMainWindow(); - /** - * Default Destructor - */ - virtual ~DanbooruMainWindow(); +private Q_SLOTS: + void connectToBoard(); + void downloadPosts(); + void optionsPreferences(); - private Q_SLOTS: - void connectToBoard(); - void downloadPosts(); - void optionsPreferences(); +private: + void setupActions(); + void setupConnections(); - private: - void setupActions(); - void setupConnections(); +private: + DanbooruClientView *m_view; + DanbooruPostModel *m_model; + DanbooruService *m_service; + DanbooruConnectWidget *m_connectWidget; - private: - DanbooruClientView *m_view; - DanbooruPostModel* m_model; - DanbooruService* m_service; - DanbooruConnectWidget* m_connectWidget; - - - }; +}; } // namespace Danbooru #endif // _DANBOORU_CLIENT_H_ diff --git a/src/model/danboorupostdelegate.cpp b/src/model/danboorupostdelegate.cpp index 48716a1..840de4a 100644 --- a/src/model/danboorupostdelegate.cpp +++ b/src/model/danboorupostdelegate.cpp @@ -39,223 +39,221 @@ #include #include +namespace Danbooru +{ -namespace Danbooru { +const int DanbooruPostDelegate::MARGIN = 5; - const int DanbooruPostDelegate::MARGIN = 5; +DanbooruPostDelegate::DanbooruPostDelegate(QListView *itemView): QStyledItemDelegate(itemView), + m_itemView(itemView) +{ - DanbooruPostDelegate::DanbooruPostDelegate(QListView* itemView):QStyledItemDelegate(itemView), - m_itemView(itemView) - { + // Get the sizes for the buttons - // Get the sizes for the buttons + const int iconSize = KIconLoader::global()->currentSize( + KIconLoader::Toolbar + ); - const int iconSize = KIconLoader::global()->currentSize( - KIconLoader::Toolbar - ); + const QSize sz = itemView->style()->sizeFromContents( + QStyle::CT_ToolButton, 0, + QSize(iconSize, iconSize)); - const QSize sz = itemView->style()->sizeFromContents( - QStyle::CT_ToolButton, 0, - QSize(iconSize, iconSize)); + m_buttonSize = qMax(sz.width(), sz.height()); - m_buttonSize = qMax(sz.width(), sz.height()); + m_downloadButton = new QPushButton(QIcon::fromTheme("download"), + QString(), itemView); + m_viewButton = new QPushButton(QIcon::fromTheme("view-preview"), QString(), + itemView); - m_downloadButton = new QPushButton(QIcon::fromTheme("download"), - QString(), itemView); - m_viewButton = new QPushButton(QIcon::fromTheme("view-preview"), QString(), - itemView); + m_downloadButton->hide(); + m_viewButton->hide(); + m_downloadButton->resize(m_buttonSize, m_buttonSize); + m_viewButton->resize(m_buttonSize, m_buttonSize); + m_downloadButton->setToolTip(i18n("Download image")); + m_viewButton->setToolTip(i18n("View image")); + + // Signal-slot connections + + connect(m_viewButton, &QPushButton::clicked, this, &DanbooruPostDelegate::viewButtonClicked); + connect(m_downloadButton, &QPushButton::clicked, this, &DanbooruPostDelegate::downloadButtonClicked); + +} + +void DanbooruPostDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + + if (!index.isValid()) { + return; + } + + QStyleOptionViewItemV4 opt(option); + + // Pixmap + + QStyle *style = QApplication::style(); + + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0); + painter->setRenderHint(QPainter::Antialiasing); + + QPixmap pixmap = index.data(Qt::DecorationRole).value(); + + if (pixmap.isNull()) { + return; + } + + QRect rect = opt.rect; + QFontMetrics metrics = opt.fontMetrics; + QRect textRect(rect.left() + MARGIN, rect.bottom() - 3 * metrics.height(), + rect.width(), 3 * metrics.height()); + + // Scaling is unavoidable to keep things in the right dimension + + QPixmap scaled; + + // Reserve enough space for the pixmap + the 3 lines of text: + // this prevents issues with images that have height > width + // (like in yande.re which keeps a lot of scans) + + int maxHeight = rect.height() - 3 * metrics.height() - 2 * MARGIN; + + scaled = pixmap.scaled(rect.width() - 2 * MARGIN, + maxHeight, + Qt::KeepAspectRatio, + Qt::SmoothTransformation); + + QRect pixRect = scaled.rect(); + pixRect.moveCenter(rect.center()); + + // move the pixmap up to accomodate some lines of text + + pixRect.moveTo(pixRect.left(), + pixRect.top() - textRect.height() / 2); + pixRect.moveBottom(textRect.top() - MARGIN); + + painter->drawPixmap(pixRect, scaled); + + painter->save(); + + // Show buttons on mouseover + + if (option.state & QStyle::State_MouseOver) { + + // Get the bottom coordinate for the buttons + // TODO: Perhaps add some transition? + + m_downloadButton->move(pixRect.topLeft()); + m_viewButton->move(pixRect.bottomLeft() - QPoint( + 0, m_viewButton->height() - 1.5 * MARGIN)); + + m_downloadButton->show(); + m_viewButton->show(); + + } else if (!hoveredIndex().isValid()) { m_downloadButton->hide(); m_viewButton->hide(); - - m_downloadButton->resize(m_buttonSize, m_buttonSize); - m_viewButton->resize(m_buttonSize, m_buttonSize); - m_downloadButton->setToolTip(i18n("Download image")); - m_viewButton->setToolTip(i18n("View image")); - - // Signal-slot connections - - connect(m_viewButton, &QPushButton::clicked, this, &DanbooruPostDelegate::viewButtonClicked); - connect(m_downloadButton, &QPushButton::clicked, this, &DanbooruPostDelegate::downloadButtonClicked); - } - void DanbooruPostDelegate::paint(QPainter* painter, - const QStyleOptionViewItem& option, - const QModelIndex& index) const - { + painter->restore(); - if (!index.isValid()) { - return; - } + // Text - QStyleOptionViewItemV4 opt(option); + DanbooruPost *post = index.data().value(); - // Pixmap + painter->save(); - QStyle *style = QApplication::style(); + int imageHeight = post->height(); + int imageWidth = post->width(); - style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0); - painter->setRenderHint(QPainter::Antialiasing); + KFormat format; - QPixmap pixmap = index.data(Qt::DecorationRole).value(); + QString imageText = i18n( + "File size: %1", + format.formatByteSize(post->size())); - if (pixmap.isNull()) { - return; - } + KLocalizedString sizestr = ki18np("1 pixel", "%1 pixels"); - QRect rect = opt.rect; - QFontMetrics metrics = opt.fontMetrics; - QRect textRect(rect.left() + MARGIN, rect.bottom() - 3 * metrics.height(), - rect.width(), 3 * metrics.height()); + imageText += "\n"; + imageText += i18n("Resolution: %1 x %2", + sizestr.subs(imageWidth).toString(), + sizestr.subs(imageHeight).toString()); + imageText += "\n"; - // Scaling is unavoidable to keep things in the right dimension - - QPixmap scaled; - - // Reserve enough space for the pixmap + the 3 lines of text: - // this prevents issues with images that have height > width - // (like in yande.re which keeps a lot of scans) - - int maxHeight = rect.height() - 3 * metrics.height() - 2 * MARGIN; - - scaled = pixmap.scaled(rect.width() - 2 * MARGIN, - maxHeight, - Qt::KeepAspectRatio, - Qt::SmoothTransformation); - - - QRect pixRect = scaled.rect(); - pixRect.moveCenter(rect.center()); - - // move the pixmap up to accomodate some lines of text - - pixRect.moveTo(pixRect.left(), - pixRect.top() - textRect.height() / 2); - pixRect.moveBottom(textRect.top() - MARGIN); - - painter->drawPixmap(pixRect, scaled); - - painter->save(); - - // Show buttons on mouseover - - if (option.state & QStyle::State_MouseOver) { - - // Get the bottom coordinate for the buttons - // TODO: Perhaps add some transition? - - m_downloadButton->move(pixRect.topLeft()); - m_viewButton->move(pixRect.bottomLeft() - QPoint( - 0, m_viewButton->height() - 1.5 * MARGIN)); - - m_downloadButton->show(); - m_viewButton->show(); - - } else if (!hoveredIndex().isValid()) { - m_downloadButton->hide(); - m_viewButton->hide(); - } - - painter->restore(); - - // Text - - DanbooruPost* post = index.data().value(); - - painter->save(); - - int imageHeight = post->height(); - int imageWidth = post->width(); - - KFormat format; - - QString imageText = i18n( - "File size: %1", - format.formatByteSize(post->size())); - - KLocalizedString sizestr = ki18np("1 pixel", "%1 pixels"); - - imageText += "\n"; - imageText += i18n("Resolution: %1 x %2", - sizestr.subs(imageWidth).toString(), - sizestr.subs(imageHeight).toString()); - imageText += "\n"; - - QString ratingString; - - switch (post->rating()) { - case DanbooruPost::Safe: - ratingString = i18n("Safe"); - break; - case DanbooruPost::Questionable: - ratingString = i18n("Questionable"); - break; - case DanbooruPost::Explicit: - ratingString = i18n("Explicit"); - break; - default: - ratingString = i18nc("Unknown post rating", "Unknown"); - } - - imageText += i18n("Rating: %1", ratingString); - - painter->drawText(textRect, imageText); - painter->restore(); + QString ratingString; + switch (post->rating()) { + case DanbooruPost::Safe: + ratingString = i18n("Safe"); + break; + case DanbooruPost::Questionable: + ratingString = i18n("Questionable"); + break; + case DanbooruPost::Explicit: + ratingString = i18n("Explicit"); + break; + default: + ratingString = i18nc("Unknown post rating", "Unknown"); } - QSize DanbooruPostDelegate::sizeHint(const QStyleOptionViewItem& option, - const QModelIndex& index) const - { + imageText += i18n("Rating: %1", ratingString); - Q_UNUSED(option) + painter->drawText(textRect, imageText); + painter->restore(); - if (!index.isValid()) { - return QSize(); - } +} - return m_itemView->gridSize(); +QSize DanbooruPostDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_UNUSED(option) + + if (!index.isValid()) { + return QSize(); } - QModelIndex DanbooruPostDelegate::hoveredIndex() const - { - const QPoint pos = m_itemView->viewport()->mapFromGlobal(QCursor::pos()); - return m_itemView->indexAt(pos); + return m_itemView->gridSize(); + +} + +QModelIndex DanbooruPostDelegate::hoveredIndex() const +{ + const QPoint pos = m_itemView->viewport()->mapFromGlobal(QCursor::pos()); + return m_itemView->indexAt(pos); +} + +void DanbooruPostDelegate::downloadButtonClicked() +{ + QModelIndex index = hoveredIndex(); + + if (!index.isValid()) { + return; } - void DanbooruPostDelegate::downloadButtonClicked() - { - QModelIndex index = hoveredIndex(); + QVariant data = index.data(Qt::DisplayRole); + const DanbooruPost *post = data.value(); - if (!index.isValid()) { - return; - } + if (post) { + Q_EMIT(postDownloadRequested(post->fileUrl())); + } +} - QVariant data = index.data(Qt::DisplayRole); - const DanbooruPost* post = data.value(); +void DanbooruPostDelegate::viewButtonClicked() +{ - if (post) { - Q_EMIT(postDownloadRequested(post->fileUrl())); - } + QModelIndex index = hoveredIndex(); + + if (!index.isValid()) { + return; } - void DanbooruPostDelegate::viewButtonClicked() - { - - QModelIndex index = hoveredIndex(); - - if (!index.isValid()) { - return; - } - - QVariant data = index.data(Qt::DisplayRole); - const DanbooruPost* post = data.value(); - if (post) { - Q_EMIT(postViewRequested(post->fileUrl())); - } + QVariant data = index.data(Qt::DisplayRole); + const DanbooruPost *post = data.value(); + if (post) { + Q_EMIT(postViewRequested(post->fileUrl())); } - +} } // namespace Danbooru diff --git a/src/model/danboorupostdelegate.h b/src/model/danboorupostdelegate.h index 34f84e1..d6de702 100644 --- a/src/model/danboorupostdelegate.h +++ b/src/model/danboorupostdelegate.h @@ -37,67 +37,63 @@ class QListView; class QPainter; class QPushButton; +namespace Danbooru +{ -namespace Danbooru { +/** + * @brief Specific delegate for Danbooru items. + * + */ - /** - * @brief Specific delegate for Danbooru items. - * - */ +class DanbooruPost; - class DanbooruPost; - - class DanbooruPostDelegate : public QStyledItemDelegate - { +class DanbooruPostDelegate : public QStyledItemDelegate +{ Q_OBJECT - public: - DanbooruPostDelegate(QListView* itemView); +public: + DanbooruPostDelegate(QListView *itemView); - void paint(QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const; - QSize sizeHint(const QStyleOptionViewItem& option, - const QModelIndex& index) const; + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; - QModelIndex hoveredIndex() const; + QModelIndex hoveredIndex() const; - private: +private: - QListView* m_itemView; - QPushButton* m_downloadButton; - QPushButton* m_viewButton; + QListView *m_itemView; + QPushButton *m_downloadButton; + QPushButton *m_viewButton; - int m_buttonSize; - static const int MARGIN; + int m_buttonSize; + static const int MARGIN; - Q_SIGNALS: +Q_SIGNALS: - /** - * @brief Emitted when the view button is clicked. - * - * @param postUrl the URL to the full picture. - * - */ - void postViewRequested(QUrl postUrl); + /** + * @brief Emitted when the view button is clicked. + * + * @param postUrl the URL to the full picture. + * + */ + void postViewRequested(QUrl postUrl); + /** + * @brief Emitted when the download button is clicked. + * + * @param postUrl the URL to the full picture. + * + */ + void postDownloadRequested(QUrl postUrl); - /** - * @brief Emitted when the download button is clicked. - * - * @param postUrl the URL to the full picture. - * - */ - void postDownloadRequested(QUrl postUrl); +private Q_SLOTS: + void viewButtonClicked(); + void downloadButtonClicked(); - - private Q_SLOTS: - void viewButtonClicked(); - void downloadButtonClicked(); - - - - }; +}; } // namespace Danbooru diff --git a/src/model/danboorupostmodel.cpp b/src/model/danboorupostmodel.cpp index c7d7464..9070019 100644 --- a/src/model/danboorupostmodel.cpp +++ b/src/model/danboorupostmodel.cpp @@ -30,88 +30,90 @@ #include #include -namespace Danbooru { +namespace Danbooru +{ - DanbooruPostModel::DanbooruPostModel(QObject* parent): QAbstractListModel(parent) - { +DanbooruPostModel::DanbooruPostModel(QObject *parent): QAbstractListModel(parent) +{ +} + +DanbooruPostModel::~DanbooruPostModel() +{ + + if (!m_items.isEmpty()) { + qDeleteAll(m_items); + m_items.clear(); } +} - DanbooruPostModel::~DanbooruPostModel() - { +int DanbooruPostModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_items.size(); +} - if (!m_items.isEmpty()) { - qDeleteAll(m_items); - m_items.clear(); - } - } +void DanbooruPostModel::addPost(Danbooru::DanbooruPost *post) +{ - int DanbooruPostModel::rowCount(const QModelIndex& parent) const - { - Q_UNUSED(parent) - return m_items.size(); - } + beginInsertRows(QModelIndex(), m_items.size(), m_items.size()); + m_items.append(post); + endInsertRows(); +} - void DanbooruPostModel::addPost(Danbooru::DanbooruPost* post) - { - - beginInsertRows(QModelIndex(), m_items.size(), m_items.size()); - m_items.append(post); - endInsertRows(); - } - - QVariant DanbooruPostModel::data(const QModelIndex& index, int role) const - { - - if (!index.isValid()) { - return QVariant(); - } - - if (index.row() >= m_items.size() || index.row() < 0) { - return QVariant(); - } - - if (m_items.isEmpty()) { - return QVariant(); - } - - DanbooruPost* post = m_items.at(index.row()); - - if (!post) { - return QVariant(); - } - - if (role == Qt::DisplayRole) { - - QVariant variant; - variant.setValue(post); - - return variant; - } - - if (role == Qt::DecorationRole) { - const QPixmap pixmap = post->pixmap(); - return pixmap; - } - - if (role == Qt::ToolTipRole) { - return post->fileUrl().fileName(); - } +QVariant DanbooruPostModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { return QVariant(); } - void DanbooruPostModel::clear() { - - if (m_items.isEmpty()) { - return; - } - - beginRemoveRows(QModelIndex(),0, m_items.size()); - qDeleteAll(m_items); - m_items.clear(); - endRemoveRows(); - reset(); + if (index.row() >= m_items.size() || index.row() < 0) { + return QVariant(); } + if (m_items.isEmpty()) { + return QVariant(); + } + + DanbooruPost *post = m_items.at(index.row()); + + if (!post) { + return QVariant(); + } + + if (role == Qt::DisplayRole) { + + QVariant variant; + variant.setValue(post); + + return variant; + } + + if (role == Qt::DecorationRole) { + const QPixmap pixmap = post->pixmap(); + return pixmap; + } + + if (role == Qt::ToolTipRole) { + return post->fileUrl().fileName(); + } + + return QVariant(); +} + +void DanbooruPostModel::clear() +{ + + if (m_items.isEmpty()) { + return; + } + + beginRemoveRows(QModelIndex(), 0, m_items.size()); + qDeleteAll(m_items); + m_items.clear(); + endRemoveRows(); + reset(); +} + }; diff --git a/src/model/danboorupostmodel.h b/src/model/danboorupostmodel.h index dd7d6b2..1e57b20 100644 --- a/src/model/danboorupostmodel.h +++ b/src/model/danboorupostmodel.h @@ -32,49 +32,49 @@ #include #include -namespace Danbooru { +namespace Danbooru +{ - class DanbooruPost; +class DanbooruPost; - /** - * @brief A model to represent DanbooruItems - * - * Since items from a Danbooru service are sent by the service itself, - * there is no need for sorting or table-like structures: everything is - * represented as a flat list. - * - * Items are added through the addPost() slot. - * - */ - class DanbooruPostModel : public QAbstractListModel - { +/** + * @brief A model to represent DanbooruItems + * + * Since items from a Danbooru service are sent by the service itself, + * there is no need for sorting or table-like structures: everything is + * represented as a flat list. + * + * Items are added through the addPost() slot. + * + */ +class DanbooruPostModel : public QAbstractListModel +{ Q_OBJECT - public: - DanbooruPostModel(QObject* parent=0); - ~DanbooruPostModel(); +public: + DanbooruPostModel(QObject *parent = 0); + ~DanbooruPostModel(); - int rowCount(const QModelIndex& parent=QModelIndex()) const; - QVariant data(const QModelIndex& index, int role) const; - void clear(); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + void clear(); - private: - QVector m_items; +private: + QVector m_items; - public Q_SLOTS: - /** - * @brief Add a new post to the model - * - * Connect to this slot when you want to add items to the model. - * - * @param post A pointer to a DanbooruPost. - * - */ - void addPost(Danbooru::DanbooruPost* post); +public Q_SLOTS: + /** + * @brief Add a new post to the model + * + * Connect to this slot when you want to add items to the model. + * + * @param post A pointer to a DanbooruPost. + * + */ + void addPost(Danbooru::DanbooruPost *post); - }; +}; }; // namespace Danbooru - #endif // DANBOORUPOSTMODEL_H