Merge branch 'master' into multiple_apis
Conflicts: CMakeLists.txt src/libdanbooru/danboorupool.cpp src/libdanbooru/danboorupost.cpp src/libdanbooru/danboorutag.cpp src/libdanbooru/utils.cpp
This commit is contained in:
commit
3409fcecf9
13 changed files with 373 additions and 141 deletions
28
.drone.yml
Normal file
28
.drone.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: einar/kde
|
||||
pull: if-not-exists
|
||||
commands:
|
||||
- mkdir build
|
||||
- cmake . -d build
|
||||
- make -C build -j2
|
||||
when:
|
||||
event:
|
||||
- push
|
||||
- name: pack
|
||||
image: einar/kde
|
||||
pull: if-not-exists
|
||||
commands:
|
||||
- mkdir build
|
||||
- cmake . -d build
|
||||
- make dist -C build
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
|
||||
|
||||
|
||||
|
|
@ -7,7 +7,20 @@ set(danbooru_client_VERSION_PATCH 0)
|
|||
|
||||
set (danbooru_VERSION ${danbooru_client_VERSION_MAJOR}.${danbooru_client_VERSION_MINOR}.${danbooru_client_VERSION_PATCH})
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${danbooru_client_VERSION_MAJOR}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${danbooru_client_VERSION_MINOR}")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${danbooru_client_VERSION_PATCH}")
|
||||
set(CPACK_SOURCE_GENERATOR "TXZ")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
set(CPACK_SOURCE_IGNORE_FILES
|
||||
"/build/;/.bzr/;~$;/.git/;${CPACK_SOURCE_IGNORE_FILES}")
|
||||
include(CPack)
|
||||
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||
|
||||
find_package (ECM REQUIRED NO_MODULE)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
|
||||
|
||||
set(REQUIRED_QT_VERSION "5.4.0")
|
||||
|
@ -29,6 +42,7 @@ find_package(Qt5Test ${REQUIRED_QT_VERSION})
|
|||
find_package(KF5 ${KF5_VERSION} REQUIRED
|
||||
IconThemes # Handling of icons
|
||||
CoreAddons # Caches
|
||||
TextWidgets # Spin boxes
|
||||
GuiAddons # Image cache
|
||||
Completion # KComboBox
|
||||
XmlGui # User interface
|
||||
|
@ -37,23 +51,17 @@ find_package(KF5 ${KF5_VERSION} REQUIRED
|
|||
Wallet # Password handling
|
||||
Declarative # QML
|
||||
I18n # i18n
|
||||
FileMetaData # Tagging
|
||||
# DocTools # Disabled until manual's ready
|
||||
)
|
||||
|
||||
# Not a framework yet, hence separate
|
||||
find_package(KF5 "5.6.0" COMPONENTS
|
||||
FileMetaData)
|
||||
|
||||
|
||||
include(ECMInstallIcons)
|
||||
include(KDEInstallDirs)
|
||||
include(KDECompilerSettings)
|
||||
include(KDECMakeSettings)
|
||||
include(FeatureSummary)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set_package_properties(KF5FileMetaData PROPERTIES TYPE OPTIONAL PURPOSE "Required for file tagging")
|
||||
set_package_properties(Qt5Test PROPERTIES TYPE OPTIONAL PURPOSE "Required to build tests")
|
||||
|
||||
# add_subdirectory( doc )
|
||||
|
|
|
@ -42,6 +42,7 @@ target_link_libraries(danbooru_client PUBLIC
|
|||
Qt5::Qml
|
||||
Qt5::QuickWidgets
|
||||
KF5::CoreAddons
|
||||
KF5::TextWidgets
|
||||
KF5::IconThemes
|
||||
KF5::Completion
|
||||
KF5::I18n
|
||||
|
|
|
@ -33,25 +33,25 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QCoreApplication::setApplicationName(QLatin1String("danbooru-client"));
|
||||
QCoreApplication::setApplicationVersion(QLatin1String(DANBOORU_CLIENT_VERSION_STRING));
|
||||
QCoreApplication::setOrganizationDomain(QLatin1String("dennogumi.org"));
|
||||
QCoreApplication::setApplicationName(QStringLiteral("danbooru-client"));
|
||||
QCoreApplication::setApplicationVersion(QStringLiteral(DANBOORU_CLIENT_VERSION_STRING));
|
||||
QCoreApplication::setOrganizationDomain(QStringLiteral("dennogumi.org"));
|
||||
QApplication::setApplicationDisplayName(i18n("Danbooru Client"));
|
||||
KLocalizedString::setApplicationDomain("danbooru-client");
|
||||
|
||||
KAboutData aboutData(I18N_NOOP(QLatin1String("danbooru-client")),
|
||||
i18n("Danbooru Client"),
|
||||
QLatin1String(DANBOORU_CLIENT_VERSION_STRING),
|
||||
QStringLiteral(DANBOORU_CLIENT_VERSION_STRING),
|
||||
i18n("KF5 based Danbooru client"),
|
||||
KAboutLicense::GPL_V3,
|
||||
i18n("(C) 2015 Luca Beltrame"),
|
||||
QString("Using libdanbooru version %1").arg(LIBDANBOORU_VERSION_STRING),
|
||||
QLatin1String("https://git.dennogumi.org/kde/danbooru-client"),
|
||||
QLatin1String("https://git.dennogumi.org/kde/danbooru-client")
|
||||
QStringLiteral("https://git.dennogumi.org/kde/danbooru-client"),
|
||||
QStringLiteral("https://git.dennogumi.org/kde/danbooru-client")
|
||||
);
|
||||
|
||||
aboutData.addAuthor(i18n("Luca Beltrame"), i18n("Developer"),
|
||||
QLatin1String("lbeltrame@kde.org")
|
||||
QStringLiteral("lbeltrame@kde.org")
|
||||
);
|
||||
|
||||
KAboutData::setApplicationData(aboutData);
|
||||
|
|
|
@ -38,14 +38,14 @@ const QMap< QUrl, QString > initBoardSalts()
|
|||
|
||||
QMap< QUrl, QString > boardSalts;
|
||||
|
||||
boardSalts.insert(QUrl("http://konachan.com"),
|
||||
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||
boardSalts.insert(QUrl("http://konachan.net"),
|
||||
QString("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||
boardSalts.insert(QUrl("http://yande.re"),
|
||||
QString("choujin-steiner--%1--"));
|
||||
boardSalts.insert(QUrl("http://danbooru.donmai.us"),
|
||||
QString("choujin-steiner--%1--"));
|
||||
boardSalts.insert(QUrl(QStringLiteral("http://konachan.com")),
|
||||
QStringLiteral("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||
boardSalts.insert(QUrl(QStringLiteral("http://konachan.net")),
|
||||
QStringLiteral("So-I-Heard-You-Like-Mupkids-?--%1--"));
|
||||
boardSalts.insert(QUrl(QStringLiteral("http://yande.re")),
|
||||
QStringLiteral("choujin-steiner--%1--"));
|
||||
boardSalts.insert(QUrl(QStringLiteral("http://danbooru.donmai.us")),
|
||||
QStringLiteral("choujin-steiner--%1--"));
|
||||
|
||||
return boardSalts;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList,
|
|||
setupUi(this);
|
||||
|
||||
danbooruUrlComboBox->setFocus();
|
||||
closeButton->setIcon(QIcon::fromTheme(QLatin1String("dialog-close")));
|
||||
closeButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
|
||||
closeButton->setToolTip(i18n("Close dialog and discard changes"));
|
||||
userLineEdit->setClearButtonEnabled(true);
|
||||
passwdLineEdit->setClearButtonEnabled(true);
|
||||
|
@ -74,7 +74,7 @@ DanbooruConnectWidget::DanbooruConnectWidget(QVector< QUrl > urlList,
|
|||
|
||||
danbooruUrlComboBox->clear();
|
||||
|
||||
for (auto item : urlList) {
|
||||
Q_FOREACH(const auto& item, urlList) {
|
||||
danbooruUrlComboBox->insertUrl(urlList.indexOf(item), item);
|
||||
}
|
||||
|
||||
|
@ -128,20 +128,20 @@ void DanbooruConnectWidget::getWalletData()
|
|||
return;
|
||||
}
|
||||
|
||||
m_username = valueMap[QLatin1String("username")];
|
||||
m_username = valueMap[QStringLiteral("username")];
|
||||
|
||||
QString hashedPassword;
|
||||
|
||||
// TODO: Handle the case where the "salt" is not known
|
||||
hashedPassword = boardSalts.value(key);
|
||||
|
||||
hashedPassword = hashedPassword.arg(valueMap[QLatin1String("password")]);
|
||||
hashedPassword = hashedPassword.arg(valueMap[QStringLiteral("password")]);
|
||||
hashedPassword = QCryptographicHash::hash(hashedPassword.toUtf8(),
|
||||
QCryptographicHash::Sha1).toHex();
|
||||
|
||||
m_password = hashedPassword;
|
||||
userLineEdit->setText(m_username);
|
||||
passwdLineEdit->setText(valueMap[QLatin1String("password")]);
|
||||
passwdLineEdit->setText(valueMap[QStringLiteral("password")]);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ void DanbooruConnectWidget::setBoards(const QVector<QUrl> &urlList)
|
|||
|
||||
danbooruUrlComboBox->clear();
|
||||
|
||||
for (auto item : urlList) {
|
||||
Q_FOREACH(const auto& item, urlList) {
|
||||
danbooruUrlComboBox->insertUrl(urlList.indexOf(item), item);
|
||||
}
|
||||
|
||||
|
@ -195,8 +195,8 @@ void DanbooruConnectWidget::accept()
|
|||
|
||||
if (m_wallet && !m_wallet->hasEntry(currentBoard)) {
|
||||
QMap<QString, QString> dataMap;
|
||||
dataMap.insert(QLatin1String("username"), m_username);
|
||||
dataMap.insert(QLatin1String("password"), passwdLineEdit->text());
|
||||
dataMap.insert(QStringLiteral("username"), m_username);
|
||||
dataMap.insert(QStringLiteral("password"), passwdLineEdit->text());
|
||||
m_wallet->writeMap(m_boardUrl.url(), dataMap);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,12 @@ DanbooruSearchWidget::DanbooruSearchWidget(QWidget *parent): QWidget(parent)
|
|||
|
||||
tagLineEdit->setPlaceholderText(i18n("Type search tags."));
|
||||
tagLineEdit->setToolTip(i18n("Type search tags. An empty string searches all posts."));
|
||||
widthSpinBox->setSuffix(ki18np(" pixel", " pixels"));
|
||||
heightSpinBox->setSuffix(ki18np(" pixel", " pixels"));
|
||||
|
||||
widthSpinBox->setValue(0);
|
||||
heightSpinBox->setValue(0);
|
||||
|
||||
|
||||
connect(searchButton, &QPushButton::clicked, this, &DanbooruSearchWidget::accept);
|
||||
connect(tagLineEdit, &QLineEdit::returnPressed, this, &DanbooruSearchWidget::accept);
|
||||
|
@ -49,11 +55,24 @@ QStringList DanbooruSearchWidget::selectedTags() const
|
|||
return m_tags;
|
||||
}
|
||||
|
||||
unsigned int DanbooruSearchWidget::selectedWidth() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
unsigned int DanbooruSearchWidget::selectedHeight() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
|
||||
void DanbooruSearchWidget::accept()
|
||||
{
|
||||
|
||||
m_tags = tagLineEdit->text().split(",");
|
||||
m_tags = tagLineEdit->text().split(QStringLiteral(","));
|
||||
m_width = widthSpinBox->value();
|
||||
m_height = heightSpinBox->value();
|
||||
Q_EMIT(accepted());
|
||||
}
|
||||
|
||||
} // namespace Danbooru
|
||||
} // namespace Danbooru
|
||||
|
|
|
@ -34,9 +34,13 @@ public:
|
|||
explicit DanbooruSearchWidget(QWidget *parent = 0);
|
||||
~DanbooruSearchWidget();
|
||||
QStringList selectedTags() const;
|
||||
unsigned int selectedWidth() const;
|
||||
unsigned int selectedHeight() const;
|
||||
|
||||
private:
|
||||
QStringList m_tags;
|
||||
unsigned int m_width;
|
||||
unsigned int m_height;
|
||||
|
||||
private Q_SLOTS:
|
||||
void accept();
|
||||
|
@ -49,4 +53,4 @@ Q_SIGNALS:
|
|||
|
||||
} // namespace Danbooru
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -46,12 +46,12 @@ namespace Danbooru
|
|||
using KIO::StoredTransferJob;
|
||||
using KIO::MultiGetJob;
|
||||
|
||||
const QString DanbooruService::POST_URL = "post/index.json" ;
|
||||
const QString DanbooruService::TAG_URL = "tag/index.xml";
|
||||
const QString DanbooruService::POOL_URL = "pool/index.json";
|
||||
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";
|
||||
const QString DanbooruService::POST_URL = QStringLiteral("post/index.json");
|
||||
const QString DanbooruService::TAG_URL = QStringLiteral("tag/index.xml");
|
||||
const QString DanbooruService::POOL_URL = QStringLiteral("pool/index.json");
|
||||
const QString DanbooruService::ARTIST_URL = QStringLiteral("artist/index.json");
|
||||
const QString DanbooruService::POOL_DATA_URL = QStringLiteral("pool/show.xml");
|
||||
const QString DanbooruService::RELATED_TAG_URL = QStringLiteral("tag/related.json");
|
||||
|
||||
DanbooruService::DanbooruService(QUrl boardUrl, QString username,
|
||||
QString password, KImageCache *cache,
|
||||
|
@ -81,8 +81,8 @@ void DanbooruService::getPostList()
|
|||
|
||||
QMap<QString, QString> parameters;
|
||||
|
||||
parameters.insert("limit", QString::number(m_maxPosts));
|
||||
parameters.insert("page", QString::number(m_currentPage));
|
||||
parameters.insert(QStringLiteral("limit"), QString::number(m_maxPosts));
|
||||
parameters.insert(QStringLiteral("page"), QString::number(m_currentPage));
|
||||
|
||||
QUrl danbooruUrl = requestUrl(m_url, POST_URL, m_username,
|
||||
m_password, parameters, m_tags);
|
||||
|
@ -102,12 +102,12 @@ void DanbooruService::getPostList()
|
|||
void DanbooruService::getTagList(int limit, QString name)
|
||||
{
|
||||
QMap<QString, QString> parameters;
|
||||
parameters.insert("limit", QString::number(limit));
|
||||
parameters.insert(QStringLiteral("limit"), QString::number(limit));
|
||||
|
||||
if (!name.isEmpty()) {
|
||||
parameters.insert("name", name);
|
||||
parameters.insert(QStringLiteral("name"), name);
|
||||
}
|
||||
parameters.insert("order", "date");
|
||||
parameters.insert(QStringLiteral("order"), QStringLiteral("date"));
|
||||
|
||||
QUrl danbooruUrl = requestUrl(m_url, TAG_URL, m_username, m_password,
|
||||
parameters);
|
||||
|
@ -124,10 +124,10 @@ void DanbooruService::getPool(int poolId, int page)
|
|||
|
||||
QMap<QString, QString> parameters;
|
||||
|
||||
parameters.insert("id", QString::number(poolId));
|
||||
parameters.insert(QStringLiteral("id"), QString::number(poolId));
|
||||
|
||||
if (page > 1) {
|
||||
parameters.insert("page", QString::number(page));
|
||||
parameters.insert(QStringLiteral("page"), QString::number(page));
|
||||
}
|
||||
|
||||
QUrl danbooruUrl = requestUrl(m_url, POOL_DATA_URL, m_username,
|
||||
|
@ -156,7 +156,7 @@ void DanbooruService::getPoolList()
|
|||
danbooruUrl = requestUrl(m_url, POOL_URL, m_username, m_password);
|
||||
} else {
|
||||
QMap<QString, QString> map;
|
||||
map.insert("page", QString::number(m_currentPage));
|
||||
map.insert(QStringLiteral("page"), QString::number(m_currentPage));
|
||||
|
||||
danbooruUrl = requestUrl(m_url, POOL_URL, m_username,
|
||||
m_password, map);
|
||||
|
@ -185,13 +185,12 @@ void DanbooruService::getPoolList()
|
|||
QList<QVariant> poolList = parseDanbooruResult(data, &ok).toList();
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto element : poolList) {
|
||||
Q_FOREACH(const auto & element, poolList) {
|
||||
QVariantMap map = element.toMap();
|
||||
|
||||
DanbooruPool *pool = new DanbooruPool(map);
|
||||
Q_EMIT(poolDownloaded(pool));
|
||||
}
|
||||
|
@ -211,24 +210,24 @@ void DanbooruService::getRelatedTags(const QStringList &tags,
|
|||
QString type;
|
||||
switch (tagType) {
|
||||
case DanbooruTag::General:
|
||||
type = "general";
|
||||
type = QStringLiteral("general");
|
||||
break;
|
||||
case DanbooruTag::Artist:
|
||||
type = "artist";
|
||||
type = QStringLiteral("artist");
|
||||
break;
|
||||
case DanbooruTag::Copyright:
|
||||
type = "copyright";
|
||||
type = QStringLiteral("copyright");
|
||||
break;
|
||||
case DanbooruTag::Character:
|
||||
type = "character";
|
||||
type = QStringLiteral("character");
|
||||
break;
|
||||
case DanbooruTag::Unknown:
|
||||
type = "unknown";
|
||||
type = QStringLiteral("unknown");
|
||||
break;
|
||||
}
|
||||
|
||||
QMap<QString, QString> parameters;
|
||||
parameters.insert("type", type);
|
||||
parameters.insert(QStringLiteral("type"), type);
|
||||
|
||||
QUrl danbooruUrl = requestUrl(m_url, RELATED_TAG_URL, m_username,
|
||||
m_password, parameters, tags);
|
||||
|
@ -254,7 +253,7 @@ void DanbooruService::getRelatedTags(const QStringList &tags,
|
|||
QVariantMap tagList = parseDanbooruResult(data, &ok).toMap();
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,7 +272,7 @@ void DanbooruService::getRelatedTags(const QStringList &tags,
|
|||
continue;
|
||||
}
|
||||
|
||||
for (auto tag : tags) {
|
||||
Q_FOREACH(auto &tag, tags) {
|
||||
// We get the first element in the list, the second is
|
||||
// the ID which is useless (no API methods in Danbooru)
|
||||
QString tagName = tag.toList()[0].toString();
|
||||
|
@ -298,15 +297,15 @@ const QStringList DanbooruService::allowedRatings() const
|
|||
QStringList ratings;
|
||||
|
||||
if (m_maxRating.testFlag(DanbooruPost::Safe)) {
|
||||
ratings.append("Safe");
|
||||
ratings.append(QStringLiteral("Safe"));
|
||||
}
|
||||
|
||||
if (m_maxRating.testFlag(DanbooruPost::Questionable)) {
|
||||
ratings.append("Questionable");
|
||||
ratings.append(QStringLiteral("Questionable"));
|
||||
}
|
||||
|
||||
if (m_maxRating.testFlag(DanbooruPost::Explicit)) {
|
||||
ratings.append("Explicit");
|
||||
ratings.append(QStringLiteral("Explicit"));
|
||||
}
|
||||
|
||||
return ratings;
|
||||
|
@ -330,6 +329,16 @@ int DanbooruService::maxPosts() const
|
|||
return m_maxPosts;
|
||||
}
|
||||
|
||||
int DanbooruService::minimumWidth() const
|
||||
{
|
||||
return m_minimumWidth > 0 ? m_minimumWidth: -1;
|
||||
}
|
||||
|
||||
int DanbooruService::minimumHeight() const
|
||||
{
|
||||
return m_minimumHeight > 0 ? m_minimumHeight: -1;
|
||||
}
|
||||
|
||||
void DanbooruService::nextPostPage()
|
||||
{
|
||||
m_currentPage++;
|
||||
|
@ -371,14 +380,15 @@ void DanbooruService::processTagList(KJob *job)
|
|||
|
||||
// Most Danbooru implementations return tags in wrong order when
|
||||
// using JSON, so we have to fall back to XML
|
||||
QList<QVariant> tagList = parseDanbooruResult(data, "tag", &ok);
|
||||
QList<QVariant> tagList = parseDanbooruResult(data, QStringLiteral("tag"),
|
||||
&ok);
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto element : tagList) {
|
||||
Q_FOREACH(const auto& element, tagList) {
|
||||
QVariantMap map = element.toMap();
|
||||
DanbooruTag *tag = new DanbooruTag(map);
|
||||
|
||||
|
@ -402,7 +412,7 @@ void DanbooruService::processPostList(KJob *job)
|
|||
StoredTransferJob *jobResult = qobject_cast<StoredTransferJob *>(job);
|
||||
|
||||
if (jobResult == 0) {
|
||||
Q_EMIT(downloadError(QString("Internal error")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Internal error")));
|
||||
return;
|
||||
|
||||
}
|
||||
|
@ -416,13 +426,13 @@ void DanbooruService::processPostList(KJob *job)
|
|||
|
||||
if (needsXML) {
|
||||
// Special cases for pools
|
||||
postList = parseDanbooruResult(data, QString("post"), &ok);
|
||||
postList = parseDanbooruResult(data, QStringLiteral("post"), &ok);
|
||||
} else {
|
||||
postList = parseDanbooruResult(data, &ok).toList();
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
Q_EMIT(downloadError(QString("Unable to decode data")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Unable to decode data")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -436,7 +446,7 @@ void DanbooruService::processPostList(KJob *job)
|
|||
|
||||
m_postsToFetch = postList.length();
|
||||
|
||||
for (auto element : postList) {
|
||||
Q_FOREACH(const auto& element, postList) {
|
||||
|
||||
QVariantMap map = element.toMap();
|
||||
DanbooruPost *post = new DanbooruPost(map);
|
||||
|
@ -449,6 +459,18 @@ void DanbooruService::processPostList(KJob *job)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (post->width() < minimumWidth()) {
|
||||
m_postsToFetch--;
|
||||
delete post;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (post->height() < minimumHeight()) {
|
||||
m_postsToFetch--;
|
||||
delete post;
|
||||
continue;
|
||||
}
|
||||
|
||||
QPixmap pix;
|
||||
|
||||
// qCDebug(LIBDANBOORU) << "About to donwload images";
|
||||
|
@ -491,7 +513,7 @@ void DanbooruService::processPostList(KJob *job)
|
|||
|
||||
if (!pix.loadFromData(jobResult->data()))
|
||||
{
|
||||
Q_EMIT(downloadError(QString("Pixmap data could not be loaded")));
|
||||
Q_EMIT(downloadError(QStringLiteral("Pixmap data could not be loaded")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -546,7 +568,7 @@ void DanbooruService::setBlacklist(const QStringList &blacklist)
|
|||
|
||||
m_blacklist.clear();
|
||||
|
||||
for (auto element : blacklist) {
|
||||
for (const auto& element : blacklist) {
|
||||
m_blacklist.insert(element);
|
||||
}
|
||||
|
||||
|
@ -618,4 +640,16 @@ void DanbooruService::setCurrentPage(int page)
|
|||
m_currentPage = page;
|
||||
}
|
||||
|
||||
void Danbooru::DanbooruService::setResolution(unsigned int width, unsigned int height)
|
||||
{
|
||||
if (width > 0) {
|
||||
m_minimumWidth = width;
|
||||
}
|
||||
|
||||
if (height > 0) {
|
||||
m_minimumHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace Danbooru
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
Danbooru::Ratings m_maxRating;
|
||||
int m_maxPosts;
|
||||
int m_currentPage;
|
||||
unsigned int m_minimumHeight = 0;
|
||||
unsigned int m_minimumWidth = 0;
|
||||
QStringList m_tags;
|
||||
|
||||
unsigned int m_postsToFetch; // To tell when to quit
|
||||
|
@ -162,7 +164,7 @@ public:
|
|||
* @param name The name of the tag to retrieve, or an empty string
|
||||
*
|
||||
**/
|
||||
void getTagList(int limit = 10, QString name = "");
|
||||
void getTagList(int limit = 10, QString name = QStringLiteral(""));
|
||||
|
||||
/**
|
||||
* @brief Get tags related to a specific, user supplied list.
|
||||
|
@ -207,6 +209,10 @@ public:
|
|||
**/
|
||||
QStringList postTags() const;
|
||||
|
||||
int minimumWidth() const;
|
||||
|
||||
int minimumHeight() const;
|
||||
|
||||
/**
|
||||
* @brief Resets the service to the default state, clearing the page counters.
|
||||
**/
|
||||
|
@ -282,6 +288,11 @@ public:
|
|||
|
||||
void setPostTags(const QStringList &tags);
|
||||
|
||||
void setResolution(unsigned int width = 0, unsigned int height = 0);
|
||||
|
||||
void setMinimumWidth(unsigned int width) { m_minimumWidth = width; };
|
||||
void setMinimumHeight(unsigned int height) { m_minimumHeight = height; };
|
||||
|
||||
private Q_SLOTS:
|
||||
void processPostList(KJob *job);
|
||||
void processTagList(KJob *job);
|
||||
|
|
|
@ -119,16 +119,18 @@ DanbooruMainWindow::DanbooruMainWindow(QWidget *parent)
|
|||
KDeclarative::KDeclarative declarative;
|
||||
declarative.setDeclarativeEngine(m_view->engine());
|
||||
declarative.setupBindings();
|
||||
m_view->setFocusPolicy(Qt::StrongFocus);
|
||||
m_view->setFocus();
|
||||
|
||||
auto qmlViewPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
|
||||
qApp->applicationName() + QLatin1String("/danbooruimageview.qml"));
|
||||
qApp->applicationName() + QStringLiteral("/danbooruimageview.qml"));
|
||||
|
||||
QQmlContext *ctxt = m_view->rootContext();
|
||||
ctxt->setContextProperty("danbooruModel", m_model);
|
||||
ctxt->setContextProperty("danbooruService", m_service);
|
||||
ctxt->setContextProperty(QStringLiteral("danbooruModel"), m_model);
|
||||
ctxt->setContextProperty(QStringLiteral("danbooruService"), m_service);
|
||||
m_view->setSource(QUrl::fromLocalFile(qmlViewPath));
|
||||
m_view->rootObject()->setProperty("poolMode", QVariant(false));
|
||||
ctxt->setContextProperty("infiniteScroll", DanbooruSettings::self()->infiniteScrolling());
|
||||
ctxt->setContextProperty(QStringLiteral("infiniteScroll"), DanbooruSettings::self()->infiniteScrolling());
|
||||
|
||||
auto rootObj = m_view->rootObject();
|
||||
connect(m_service, SIGNAL(postDownloadFinished()), rootObj, SIGNAL(downloadFinished()));
|
||||
|
@ -140,7 +142,8 @@ DanbooruMainWindow::DanbooruMainWindow(QWidget *parent)
|
|||
|
||||
// then, setup our actions
|
||||
setupActions();
|
||||
setupGUI(KXmlGuiWindow::ToolBar | Keys | Save | Create, "danbooru-clientui.rc");
|
||||
setupGUI(KXmlGuiWindow::ToolBar | Keys | Save | Create,
|
||||
QStringLiteral("danbooru-clientui.rc"));
|
||||
|
||||
// connections
|
||||
|
||||
|
@ -154,11 +157,11 @@ DanbooruMainWindow::DanbooruMainWindow(QWidget *parent)
|
|||
m_service->setPassword(m_connectWidget->password());
|
||||
}
|
||||
|
||||
actionCollection()->action(QLatin1String("fetch"))->setEnabled(true);
|
||||
actionCollection()->action(QLatin1String("find"))->setEnabled(true);
|
||||
actionCollection()->action(QLatin1String("poolDownload"))->setEnabled(true);
|
||||
actionCollection()->action(QLatin1String("tags"))->setEnabled(true);
|
||||
actionCollection()->action(QLatin1String("morePosts"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("fetch"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("find"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("poolDownload"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("tags"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("morePosts"))->setEnabled(true);
|
||||
|
||||
if (DanbooruSettings::self()->autoDownload()) {
|
||||
|
||||
|
@ -196,15 +199,19 @@ DanbooruMainWindow::DanbooruMainWindow(QWidget *parent)
|
|||
|
||||
connect(m_searchWidget, &DanbooruSearchWidget::accepted, [this]() {
|
||||
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QLatin1String("SearchView"));
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QStringLiteral("SearchView"));
|
||||
searchDockWidget->hide();
|
||||
|
||||
handlePostDownload(m_searchWidget->selectedTags(), true /* relatedTags */);
|
||||
handlePostDownload(m_searchWidget->selectedTags(),
|
||||
true /* relatedTags */,
|
||||
m_searchWidget->selectedWidth() /* minimumWidth */,
|
||||
m_searchWidget->selectedHeight() /* minimumHeight */
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
connect(m_searchWidget, &DanbooruSearchWidget::rejected, [this]() {
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QLatin1String("SearchView"));
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QStringLiteral("SearchView"));
|
||||
searchDockWidget->hide();
|
||||
});
|
||||
|
||||
|
@ -212,7 +219,7 @@ DanbooruMainWindow::DanbooruMainWindow(QWidget *parent)
|
|||
|
||||
if (m_tagModel->rowCount() == 0) {
|
||||
// Only get tags if we don't have any already
|
||||
for (auto tag : m_model->postTags()) {
|
||||
Q_FOREACH(const auto& tag, m_model->postTags()) {
|
||||
m_service->getTagList(1, tag);
|
||||
}
|
||||
}
|
||||
|
@ -243,10 +250,11 @@ void DanbooruMainWindow::loadSettings()
|
|||
QVector<QUrl> boardsList;
|
||||
|
||||
QStringList::const_iterator it;
|
||||
auto configList = DanbooruSettings::self()->boards();
|
||||
|
||||
for (it = DanbooruSettings::self()->boards().constBegin();
|
||||
it != DanbooruSettings::self()->boards().constEnd();
|
||||
++it) {
|
||||
for (it = configList.constBegin();
|
||||
it != configList.constEnd();
|
||||
++it) {
|
||||
|
||||
boardsList.append(QUrl::fromUserInput(*it));
|
||||
|
||||
|
@ -260,7 +268,7 @@ void DanbooruMainWindow::loadSettings()
|
|||
|
||||
m_tagWidget->setBlackList(DanbooruSettings::self()->tagBlacklist());
|
||||
|
||||
m_view->rootContext()->setContextProperty("infiniteScroll",
|
||||
m_view->rootContext()->setContextProperty(QStringLiteral("infiniteScroll"),
|
||||
DanbooruSettings::self()->infiniteScrolling());
|
||||
|
||||
}
|
||||
|
@ -269,23 +277,23 @@ void DanbooruMainWindow::setupActions()
|
|||
{
|
||||
|
||||
QAction *connectAction = new QAction(
|
||||
QIcon::fromTheme(QLatin1String("document-open-remote")),
|
||||
QIcon::fromTheme(QStringLiteral("document-open-remote")),
|
||||
i18n("Connect..."),
|
||||
this);
|
||||
|
||||
QAction *fetchAction = new QAction(QIcon::fromTheme(QLatin1String("download")),
|
||||
QAction *fetchAction = new QAction(QIcon::fromTheme(QStringLiteral("download")),
|
||||
i18n("Download"), this);
|
||||
KToggleAction *findAction = new KToggleAction(QIcon::fromTheme(QLatin1String("edit-find")),
|
||||
KToggleAction *findAction = new KToggleAction(QIcon::fromTheme(QStringLiteral("edit-find")),
|
||||
i18n("Search"), this);
|
||||
KToggleAction *poolAction = new KToggleAction(QIcon::fromTheme(QLatin1String("image-x-generic")),
|
||||
KToggleAction *poolAction = new KToggleAction(QIcon::fromTheme(QStringLiteral("image-x-generic")),
|
||||
i18n("Pools"), this);
|
||||
QAction *nextPageAction = new QAction(QIcon::fromTheme(QLatin1String("go-next")),
|
||||
QAction *nextPageAction = new QAction(QIcon::fromTheme(QStringLiteral("go-next")),
|
||||
i18n("More posts"), this);
|
||||
QAction *nextPoolAction = new QAction(QIcon::fromTheme(QLatin1String("go-next")),
|
||||
QAction *nextPoolAction = new QAction(QIcon::fromTheme(QStringLiteral("go-next")),
|
||||
i18n("More pools"), this);
|
||||
|
||||
KDualAction *tagAction = new KDualAction(i18n("Show tags"), i18n("Hide tags"), this);
|
||||
tagAction->setIconForStates(QIcon::fromTheme(QLatin1String("tag")));
|
||||
tagAction->setIconForStates(QIcon::fromTheme(QStringLiteral("tag")));
|
||||
|
||||
fetchAction->setEnabled(false);
|
||||
findAction->setEnabled(false);
|
||||
|
@ -297,13 +305,13 @@ void DanbooruMainWindow::setupActions()
|
|||
findAction->setChecked(false);
|
||||
tagAction->setEnabled(false);
|
||||
|
||||
actionCollection()->addAction(QLatin1String("connect"), connectAction);
|
||||
actionCollection()->addAction(QLatin1String("fetch"), fetchAction);
|
||||
actionCollection()->addAction(QLatin1String("find"), findAction);
|
||||
actionCollection()->addAction(QLatin1String("poolDownload"), poolAction);
|
||||
actionCollection()->addAction(QLatin1String("tags"), tagAction);
|
||||
actionCollection()->addAction(QLatin1String("morePosts"), nextPageAction);
|
||||
actionCollection()->addAction(QLatin1String("morePools"), nextPoolAction);
|
||||
actionCollection()->addAction(QStringLiteral("connect"), connectAction);
|
||||
actionCollection()->addAction(QStringLiteral("fetch"), fetchAction);
|
||||
actionCollection()->addAction(QStringLiteral("find"), findAction);
|
||||
actionCollection()->addAction(QStringLiteral("poolDownload"), poolAction);
|
||||
actionCollection()->addAction(QStringLiteral("tags"), tagAction);
|
||||
actionCollection()->addAction(QStringLiteral("morePosts"), nextPageAction);
|
||||
actionCollection()->addAction(QStringLiteral("morePools"), nextPoolAction);
|
||||
|
||||
actionCollection()->setDefaultShortcut(connectAction, KStandardShortcut::Open);
|
||||
actionCollection()->setDefaultShortcut(findAction, KStandardShortcut::Find);
|
||||
|
@ -319,7 +327,7 @@ void DanbooruMainWindow::setupActions()
|
|||
return;
|
||||
}
|
||||
|
||||
QDockWidget *poolDockWidget = findChild<QDockWidget *>(QLatin1String("PoolView"));
|
||||
QDockWidget *poolDockWidget = findChild<QDockWidget *>(QStringLiteral("PoolView"));
|
||||
|
||||
if (checked) {
|
||||
|
||||
|
@ -329,19 +337,19 @@ void DanbooruMainWindow::setupActions()
|
|||
}
|
||||
|
||||
poolDockWidget->show();
|
||||
actionCollection()->action(QLatin1String("morePools"))->setEnabled(true);
|
||||
actionCollection()->action(QStringLiteral("morePools"))->setEnabled(true);
|
||||
m_tableView->show();
|
||||
|
||||
} else {
|
||||
poolDockWidget->hide();
|
||||
actionCollection()->action(QLatin1String("morePools"))->setEnabled(false);
|
||||
actionCollection()->action(QStringLiteral("morePools"))->setEnabled(false);
|
||||
m_tableView->hide();
|
||||
}
|
||||
});
|
||||
|
||||
connect(findAction, &KToggleAction::toggled, [this](bool checked) {
|
||||
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QLatin1String("SearchView"));
|
||||
QDockWidget *searchDockWidget = findChild<QDockWidget *>(QStringLiteral("SearchView"));
|
||||
|
||||
if (checked) {
|
||||
searchDockWidget->show();
|
||||
|
@ -355,7 +363,7 @@ void DanbooruMainWindow::setupActions()
|
|||
|
||||
connect(tagAction, &KDualAction::activeChanged, [this](bool checked) {
|
||||
|
||||
QDockWidget *tagDockWidget = findChild<QDockWidget *>(QLatin1String("TagView"));
|
||||
QDockWidget *tagDockWidget = findChild<QDockWidget *>(QStringLiteral("TagView"));
|
||||
|
||||
if (checked) {
|
||||
tagDockWidget->show();
|
||||
|
@ -392,7 +400,7 @@ void DanbooruMainWindow::setupDockWidgets()
|
|||
QDockWidget *poolDockWidget = new QDockWidget(i18n("Pools"), this);
|
||||
poolDockWidget->setAllowedAreas(Qt::BottomDockWidgetArea);
|
||||
poolDockWidget->setWidget(m_tableView);
|
||||
poolDockWidget->setObjectName("PoolView");
|
||||
poolDockWidget->setObjectName(QStringLiteral("PoolView"));
|
||||
|
||||
// Prevent the use of winId() when detached, leads to QQuickWidget bugs
|
||||
poolDockWidget->setFeatures(QDockWidget::DockWidgetClosable);
|
||||
|
@ -404,7 +412,7 @@ void DanbooruMainWindow::setupDockWidgets()
|
|||
QDockWidget *searchDockWidget = new QDockWidget(QLatin1String(""), this);
|
||||
searchDockWidget->setAllowedAreas(Qt::TopDockWidgetArea);
|
||||
searchDockWidget->setWidget(m_searchWidget);
|
||||
searchDockWidget->setObjectName("SearchView");
|
||||
searchDockWidget->setObjectName(QStringLiteral("SearchView"));
|
||||
|
||||
searchDockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
||||
addDockWidget(Qt::TopDockWidgetArea, searchDockWidget);
|
||||
|
@ -414,10 +422,10 @@ void DanbooruMainWindow::setupDockWidgets()
|
|||
searchDockWidget->hide();
|
||||
m_searchWidget->hide();
|
||||
|
||||
QDockWidget *tagDockWidget = new QDockWidget(QLatin1String("Tags"), this);
|
||||
QDockWidget *tagDockWidget = new QDockWidget(QStringLiteral("Tags"), this);
|
||||
tagDockWidget->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
tagDockWidget->setWidget(m_tagWidget);
|
||||
tagDockWidget->setObjectName("TagView");
|
||||
tagDockWidget->setObjectName(QStringLiteral("TagView"));
|
||||
tagDockWidget->setFeatures(QDockWidget::DockWidgetClosable);
|
||||
addDockWidget(Qt::RightDockWidgetArea, tagDockWidget);
|
||||
|
||||
|
@ -427,15 +435,15 @@ void DanbooruMainWindow::setupDockWidgets()
|
|||
// Connections
|
||||
|
||||
connect(poolDockWidget, &QDockWidget::visibilityChanged, [this](bool visible) {
|
||||
actionCollection()->action(QLatin1String("poolDownload"))->setChecked(visible);
|
||||
actionCollection()->action(QStringLiteral("poolDownload"))->setChecked(visible);
|
||||
});
|
||||
|
||||
connect(searchDockWidget, &QDockWidget::visibilityChanged, [this](bool visible) {
|
||||
actionCollection()->action(QLatin1String("find"))->setChecked(visible);
|
||||
actionCollection()->action(QStringLiteral("find"))->setChecked(visible);
|
||||
});
|
||||
|
||||
connect(tagDockWidget, &QDockWidget::visibilityChanged, [this](bool visible) {
|
||||
qobject_cast<KDualAction *>(actionCollection()->action(QLatin1String("tags")))->setActive(visible);
|
||||
qobject_cast<KDualAction *>(actionCollection()->action(QStringLiteral("tags")))->setActive(visible);
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -467,13 +475,13 @@ void DanbooruMainWindow::downloadPosts()
|
|||
|
||||
void DanbooruMainWindow::optionsPreferences()
|
||||
{
|
||||
KConfigDialog *dialog = new KConfigDialog(this, "danboorusettings",
|
||||
KConfigDialog *dialog = new KConfigDialog(this, QStringLiteral("danboorusettings"),
|
||||
DanbooruSettings::self());
|
||||
|
||||
dialog->addPage(new GeneralPage(DanbooruSettings::self(), this), i18n("General"),
|
||||
"table");
|
||||
QStringLiteral("table"));
|
||||
dialog->addPage(new BlacklistPage(DanbooruSettings::self(), this), i18n("Tag blacklist"),
|
||||
"configure");
|
||||
QStringLiteral("configure"));
|
||||
connect(dialog, &KConfigDialog::settingsChanged, this, &DanbooruMainWindow::loadSettings);
|
||||
dialog->show();
|
||||
}
|
||||
|
@ -506,13 +514,15 @@ void DanbooruMainWindow::slotHandleDownload(const QUrl &url, const QVariant tags
|
|||
saveDialog->setMimeTypeFilters(filters);
|
||||
} else {
|
||||
filters.reserve(2);
|
||||
filters << "Images (*.png *.gif *.jpg)" << "All files (*.*)";
|
||||
filters << QStringLiteral("Images (*.png *.gif *.jpg)")
|
||||
<< QStringLiteral("All files (*.*)");
|
||||
saveDialog->setNameFilters(filters);
|
||||
}
|
||||
|
||||
// Prevent invalid characters (":" can be a tag in Danbooru)
|
||||
if (remoteFile.contains(":")) {
|
||||
remoteFile.replace(":", "_");
|
||||
if (remoteFile.contains(QStringLiteral(":"))) {
|
||||
remoteFile.replace(QStringLiteral(":"),
|
||||
QStringLiteral("_"));
|
||||
}
|
||||
|
||||
saveDialog->selectFile(remoteFile);
|
||||
|
@ -578,12 +588,21 @@ void DanbooruMainWindow::clearModels()
|
|||
|
||||
}
|
||||
|
||||
void DanbooruMainWindow::handlePostDownload(const QStringList &tags, bool relatedTags)
|
||||
void DanbooruMainWindow::handlePostDownload(const QStringList &tags, bool relatedTags,
|
||||
unsigned int minimumWidth, unsigned int minimumHeight)
|
||||
{
|
||||
clearModels();
|
||||
m_view->rootObject()->setProperty("poolMode", QVariant(false));
|
||||
m_service->setPostTags(tags);
|
||||
|
||||
if (minimumWidth > 0) {
|
||||
m_service->setMinimumWidth(minimumWidth);
|
||||
}
|
||||
|
||||
if (minimumHeight > 0) {
|
||||
m_service->setMinimumHeight(minimumHeight);
|
||||
}
|
||||
|
||||
if (relatedTags) {
|
||||
m_service->getRelatedTags(tags);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,8 @@ private:
|
|||
void setupDockWidgets();
|
||||
void setupConnections();
|
||||
void clearModels();
|
||||
void handlePostDownload(const QStringList &tags = QStringList(), bool relatedTags = false);
|
||||
void handlePostDownload(const QStringList &tags = QStringList(), bool relatedTags = false,
|
||||
unsigned int minimumWidth = 0, unsigned int minimumHeight = 0);
|
||||
|
||||
private Q_SLOTS:
|
||||
void connectToBoard();
|
||||
|
|
|
@ -42,12 +42,16 @@ Rectangle {
|
|||
signal downloadRequested(url url, var tags)
|
||||
signal downloadStarted()
|
||||
signal fileInfo(url name, var tags)
|
||||
|
||||
signal shareButtonClicked(url url)
|
||||
|
||||
KRun {
|
||||
id: runner
|
||||
}
|
||||
|
||||
Clipboard {
|
||||
id: clipboard
|
||||
}
|
||||
|
||||
onDownloadFinished: {
|
||||
|
||||
grid.opacity = 1
|
||||
|
@ -64,6 +68,10 @@ Rectangle {
|
|||
runningIndicator.running = true
|
||||
}
|
||||
|
||||
onShareButtonClicked: {
|
||||
clipboard.content = url;
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: runningIndicator
|
||||
z: 1
|
||||
|
@ -121,8 +129,6 @@ Rectangle {
|
|||
height: parent.height
|
||||
width: parent.width
|
||||
|
||||
//
|
||||
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: {
|
||||
|
@ -137,11 +143,13 @@ Rectangle {
|
|||
onEntered: {
|
||||
viewButton.opacity = 1
|
||||
downloadButton.opacity = 1
|
||||
shareButton.opacity = 1
|
||||
}
|
||||
|
||||
onExited: {
|
||||
viewButton.opacity = 0
|
||||
downloadButton.opacity = 0
|
||||
shareButton.opacity = 0
|
||||
}
|
||||
|
||||
Button {
|
||||
|
@ -198,19 +206,51 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: shareButton
|
||||
iconName: "edit-copy"
|
||||
tooltip: i18n("Copy link to clipboard")
|
||||
visible: opacity > 0
|
||||
opacity: 0
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: (pixItem.height - pixItem.paintedHeight) / 2
|
||||
anchors.rightMargin: (pixItem.width - pixItem.paintedWidth) / 2
|
||||
|
||||
height: pixItem.height * 0.15
|
||||
width: pixItem.height * 0.15
|
||||
z: 1
|
||||
|
||||
onClicked: {
|
||||
rootObj.shareButtonClicked(fileUrl)
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: sizeText
|
||||
anchors.left: pixItem.left
|
||||
text: i18n("File size: %1", KCoreAddons.Format.formatByteSize(fileSize))
|
||||
}
|
||||
Text {
|
||||
id: resolutionText
|
||||
anchors.left: pixItem.left
|
||||
text: i18n("Resolution: %1 x %2", resolution.width, resolution.height)
|
||||
}
|
||||
|
||||
Text {
|
||||
id: ratingText
|
||||
anchors.left: pixItem.left
|
||||
text: {
|
||||
|
||||
if (rating == DanbooruPost.Safe) {
|
||||
|
@ -246,6 +286,7 @@ Rectangle {
|
|||
|
||||
model: danbooruModel
|
||||
delegate: viewDelegate
|
||||
interactive: true
|
||||
focus: true
|
||||
|
||||
Component.onCompleted: { currentIndex = -1; forceActiveFocus()}
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>387</width>
|
||||
<height>45</height>
|
||||
<width>371</width>
|
||||
<height>160</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
@ -19,21 +19,76 @@
|
|||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>37</width>
|
||||
<height>29</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="heightLabel">
|
||||
<property name="text">
|
||||
<string>Minimum height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="widthLabel">
|
||||
<property name="text">
|
||||
<string>Minimum width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dialog-close"/>
|
||||
<iconset theme="dialog-close">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="2" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>37</width>
|
||||
<height>29</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="KPluralHandlingSpinBox" name="heightSpinBox">
|
||||
<property name="maximum">
|
||||
<number>16834</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="KPluralHandlingSpinBox" name="widthSpinBox">
|
||||
<property name="maximum">
|
||||
<number>16834</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="tagLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
|
@ -46,7 +101,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="3">
|
||||
<widget class="KLineEdit" name="tagLineEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
|
@ -62,16 +130,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>KPluralHandlingSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>kpluralhandlingspinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue