From 67d5614be307dea0ca1fe8c46f4f66d2bac3de31 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Sun, 30 Apr 2023 16:20:13 +0200 Subject: [PATCH] restoring runepages --- include/clientapi.h | 2 + include/restclient.h | 2 +- include/runemanager.h | 11 ++++- include/runepagelist.h | 18 ++++++++ src/clientapi.cpp | 48 ++++++++++++++++++-- src/restclient.cpp | 7 ++- src/runemanager.cpp | 66 +++++++++++++++++++++------ src/runepagelist.cpp | 101 +++++++++++++++++++++++++++++++++++++++-- ui/runemanager.ui | 78 +++++++++++++++---------------- ui/runepagelist.ui | 3 ++ 10 files changed, 267 insertions(+), 69 deletions(-) diff --git a/include/clientapi.h b/include/clientapi.h index d476a98..aa6caed 100644 --- a/include/clientapi.h +++ b/include/clientapi.h @@ -206,6 +206,8 @@ public: std::vector getAllRunePages(); bool selectRunePage(uint64_t id); bool editRunePage(const RunePage& page); + bool createRunePage(const RunePage& page); + bool deleteRunePage(uint64_t id); std::vector getAllRuneAspekts(); std::vector getAllRuneStyles(); diff --git a/include/restclient.h b/include/restclient.h index 70b132a..ae68e4c 100644 --- a/include/restclient.h +++ b/include/restclient.h @@ -15,7 +15,7 @@ public: POST, PUT, PATCH, - // DELETE + DELETE }; struct WebException { diff --git a/include/runemanager.h b/include/runemanager.h index 50f673c..000e60e 100644 --- a/include/runemanager.h +++ b/include/runemanager.h @@ -5,6 +5,8 @@ #include #include "config.h" +#include "runeaspekt.h" +#include "runestyle.h" namespace Ui { class RuneManager; @@ -26,12 +28,17 @@ private slots: void loadRunes(); void setRunesEnabled(bool enabled); - void clientRunePageRenamed(QListWidgetItem* item); - + void saveRunePageClient(int id, QString name, const RunePage& rp); void saveRunePageAA(int id, QString name, const RunePage& rp); + void deleteRunepageClient(int id); + void deleteRunepageAA(int id); + private: Ui::RuneManager* ui; std::shared_ptr client; Config* config = nullptr; + + std::vector runeInfo; + std::vector runeStyles; }; diff --git a/include/runepagelist.h b/include/runepagelist.h index 77b7109..523b534 100644 --- a/include/runepagelist.h +++ b/include/runepagelist.h @@ -6,6 +6,8 @@ #include "clientapi.h" #include "config.h" +#include "runeaspekt.h" +#include "runestyle.h" namespace Ui { class RunePageList; @@ -29,15 +31,31 @@ public: void loadRunePages(const std::vector& pages); void loadRunePages(const std::vector>& pages); + void setRuneInfos(const std::vector& runeInfo, const std::vector& runeStyles); + signals: void runepageChanged(int id, QString name, const RunePage& rp); + void runepageDeleted(int id); protected: virtual void dropEvent(QDropEvent* event) override; +private slots: + void itemChangedCallback(QListWidgetItem* item); + void openContextMenu(const QPoint&); + void deleteCurrentItem(); + private: + void clearItems(); void addRunepageItem(QString name, int id, const ::RunePage& rp, bool isCurrent = false); + QString getRuneDescription(const ::RunePage& runepage); + QString getRuneText(uint32_t id); + QString getRuneStyleByID(uint32_t id); + + const std::vector* runeInfo = nullptr; + const std::vector* runeStyles = nullptr; + Ui::RunePageList* ui; QListWidget* other = nullptr; bool isClient; diff --git a/src/clientapi.cpp b/src/clientapi.cpp index 4082da1..8fd08e7 100644 --- a/src/clientapi.cpp +++ b/src/clientapi.cpp @@ -225,7 +225,7 @@ bool ClientAPI::selectRunePage(uint64_t id) { if(doc.isEmpty()) return true; // ok // error - Log::warn << "error selecting runepage: " << id << " " << doc.toJson().toStdString(); + qWarning() << "error selecting runepage: " << id << " " << doc.toJson().toStdString(); return false; } @@ -246,13 +246,51 @@ bool ClientAPI::editRunePage(const RunePage& page) { QJsonDocument reqdoc(pagereq); const std::string requestdocstr = reqdoc.toJson(QJsonDocument::JsonFormat::Compact).toStdString(); - Log::info << "requeststr: " << requestdocstr; + qInfo() << "requeststr: " << requestdocstr; QJsonDocument doc = request("lol-perks/v1/pages/" + std::to_string(page.id), Method::PUT, requestdocstr); if(doc.isEmpty()) return true; // ok // error - Log::warn << "error editing runepage: " << page.id << " " << doc.toJson().toStdString(); + qWarning() << "error editing runepage: " << page.id << " " << doc.toJson().toStdString(); + + return false; +} + +bool ClientAPI::createRunePage(const RunePage& page) { + QJsonObject pagereq; + + pagereq["name"] = QString::fromStdString(page.name); + pagereq["primaryStyleId"] = (int) page.runepage.primaryStyle; + pagereq["subStyleId"] = (int) page.runepage.secondaryStyle; + + QJsonArray selected; + for(uint32_t sel : page.runepage.selectedAspects) { + selected.push_back((int) sel); + } + + pagereq["selectedPerkIds"] = selected; + + QJsonDocument reqdoc(pagereq); + const std::string requestdocstr = reqdoc.toJson(QJsonDocument::JsonFormat::Compact).toStdString(); + qInfo() << "requeststr: " << requestdocstr; + QJsonDocument doc = request("lol-perks/v1/pages/", Method::POST, requestdocstr); + + if(doc.isEmpty()) return true; // ok + + // error + qWarning() << "error creating runepage: " << page.name << " " << doc.toJson().toStdString(); + + return false; +} + +bool ClientAPI::deleteRunePage(uint64_t id) { + QJsonDocument doc = request("lol-perks/v1/pages/" + std::to_string(id), Method::DELETE); + + if(doc.isEmpty()) return true; // ok + + // error + qWarning() << "error deleteing runepage: " << id << " " << doc.toJson().toStdString(); return false; } @@ -261,7 +299,7 @@ std::vector ClientAPI::getAllRuneAspekts() { QJsonDocument doc = request("lol-perks/v1/perks"); if(!doc.isArray()) { - Log::warn << __PRETTY_FUNCTION__ << " doc is not array"; + qWarning() << __PRETTY_FUNCTION__ << " doc is not array"; return {}; } @@ -280,7 +318,7 @@ std::vector ClientAPI::getAllRuneStyles() { QJsonDocument doc = request("lol-perks/v1/styles"); if(!doc.isArray()) { - Log::warn << __PRETTY_FUNCTION__ << " doc is not array"; + qWarning() << __PRETTY_FUNCTION__ << " doc is not array"; return {}; } diff --git a/src/restclient.cpp b/src/restclient.cpp index ba00992..5878b50 100644 --- a/src/restclient.cpp +++ b/src/restclient.cpp @@ -119,8 +119,11 @@ QByteArray RestClient::requestRaw(const std::string& url, Method m, const std::s curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); headerlist = curl_slist_append(headerlist, "Content-Type: application/json"); break; - //case Method::DELETE: - // curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); break; + case Method::DELETE: + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str()); + headerlist = curl_slist_append(headerlist, "Content-Type: application/json"); + break; } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); diff --git a/src/runemanager.cpp b/src/runemanager.cpp index f70d991..7351b3a 100644 --- a/src/runemanager.cpp +++ b/src/runemanager.cpp @@ -15,6 +15,10 @@ RuneManager::RuneManager(QWidget* parent) : QWidget(parent), ui(new Ui::RuneMana ui->listaaRunes->setOther(ui->listClientRunes); QObject::connect(ui->listaaRunes, &RunePageList::runepageChanged, this, &RuneManager::saveRunePageAA); + QObject::connect(ui->listClientRunes, &RunePageList::runepageChanged, this, &RuneManager::saveRunePageClient); + + QObject::connect(ui->listaaRunes, &RunePageList::runepageDeleted, this, &RuneManager::deleteRunepageAA); + QObject::connect(ui->listClientRunes, &RunePageList::runepageDeleted, this, &RuneManager::deleteRunepageClient); loadRunes(); } @@ -29,6 +33,9 @@ void RuneManager::setConfig(Config& config) { } void RuneManager::loadRunes() { + this->ui->btnRetry->setEnabled(false); + QCoreApplication::processEvents(); + if(!client) { auto ca = ClientAccess::find(); @@ -38,12 +45,20 @@ void RuneManager::loadRunes() { } if(client) { + // load meta data + runeInfo = client->getAllRuneAspekts(); + runeStyles = client->getAllRuneStyles(); + + this->ui->listClientRunes->setRuneInfos(runeInfo, runeStyles); + this->ui->listaaRunes->setRuneInfos(runeInfo, runeStyles); + // load runepages const std::vector runePages = client->getAllRunePages(); ui->listClientRunes->loadRunePages(runePages); } setRunesEnabled(!!client); // cast to bool + this->ui->btnRetry->setEnabled(true); } @@ -52,24 +67,25 @@ void RuneManager::setRunesEnabled(bool enabled) { this->ui->lblaaRunes->setEnabled(enabled); this->ui->listClientRunes->setEnabled(enabled); this->ui->listaaRunes->setEnabled(enabled); - this->ui->btnDelete->setEnabled(enabled); - - this->ui->btnRetry->setEnabled(!enabled); } -void RuneManager::clientRunePageRenamed(QListWidgetItem* item) { - uint32_t pageId = item->data(RunePageList::RoleId).toUInt(); - const ::RunePage* page = (::RunePage*) item->data(RunePageList::RolePointer).toULongLong(); - qDebug() << "edit page: " << pageId << "setname:" << item->text(); - +void RuneManager::saveRunePageClient(int id, QString name, const RunePage& rp) { if(client) { ClientAPI::RunePage newPage; - newPage.id = pageId; - newPage.name = item->text().toStdString(); - newPage.runepage = *page; + newPage.name = name.toStdString(); + newPage.runepage = rp; + newPage.id = id; - if(!client->editRunePage(newPage)) { - // TODO: some error occured + if(id == -1) { + // create new page + if(!client->createRunePage(newPage)) { + // TODO: some error occured + } + } else { + // edit existing page + if(!client->editRunePage(newPage)) { + // TODO: some error occured + } } } } @@ -85,6 +101,7 @@ void RuneManager::saveRunePageAA(int id, QString name, const RunePage& rp) { } else { if((int) pages.size() > id && id >= 0) { pages.at(id)->runepage = rp; + pages.at(id)->name = name; } else { // unkown id qWarning() << "unknown runepage id:" << id; @@ -96,3 +113,26 @@ void RuneManager::saveRunePageAA(int id, QString name, const RunePage& rp) { // reload runes ui->listaaRunes->loadRunePages(pages); } + +void RuneManager::deleteRunepageClient(int id) { + if(client) { + if(!client->deleteRunePage(id)) { + // TODO: some error occured + } + } +} + +void RuneManager::deleteRunepageAA(int id) { + if(!config) return; + + Config::RootConfig& rc = config->getConfig(); + auto& pages = rc.runePages; + if((int) pages.size() > id && id >= 0) { + pages.erase(pages.begin() + id); + + config->save(); + } else { + // unkown id + qWarning() << "unknown runepage id:" << id; + } +} diff --git a/src/runepagelist.cpp b/src/runepagelist.cpp index 434ea0a..e967b5c 100644 --- a/src/runepagelist.cpp +++ b/src/runepagelist.cpp @@ -3,10 +3,15 @@ #include #include +#include #include +#include RunePageList::RunePageList(QWidget* parent) : QListWidget(parent), ui(new Ui::RunePageList) { ui->setupUi(this); + + QObject::connect(this, &QListWidget::itemChanged, this, &RunePageList::itemChangedCallback); + QObject::connect(this, &QListWidget::customContextMenuRequested, this, &RunePageList::openContextMenu); } RunePageList::~RunePageList() { @@ -14,20 +19,25 @@ RunePageList::~RunePageList() { } void RunePageList::loadRunePages(const std::vector& pages) { - clear(); + clearItems(); for(const ClientAPI::RunePage& rp : pages) { addRunepageItem(QString::fromStdString(rp.name), rp.id, rp.runepage, rp.isCurrent); } } void RunePageList::loadRunePages(const std::vector>& pages) { - clear(); + clearItems(); for(size_t i = 0; i < pages.size(); ++i) { std::shared_ptr rp = pages.at(i); addRunepageItem(rp->name, i, rp->runepage); } } +void RunePageList::setRuneInfos(const std::vector& runeInfo, const std::vector& runeStyles) { + this->runeInfo = &runeInfo; + this->runeStyles = &runeStyles; +} + void RunePageList::dropEvent(QDropEvent* event) { qDebug() << "drop event"; if(event->source() == nullptr || event->source() != other) { @@ -45,7 +55,7 @@ void RunePageList::dropEvent(QDropEvent* event) { // compare rune pages for duplicates? - QListWidget::dropEvent(event); + // QListWidget::dropEvent(event); // save change QString name = item->text(); @@ -54,16 +64,99 @@ void RunePageList::dropEvent(QDropEvent* event) { emit runepageChanged(-1, name, *oldPage); } +void RunePageList::itemChangedCallback(QListWidgetItem* item) { + int pageId = item->data(RunePageList::RoleId).toUInt(); + QString newName = item->text(); + const ::RunePage* page = (::RunePage*) item->data(RunePageList::RolePointer).toULongLong(); + emit runepageChanged(pageId, newName, *page); +} + +void RunePageList::openContextMenu(const QPoint& pos) { + QPoint globalPos = mapToGlobal(pos); + + QMenu menu; + menu.addAction(QIcon::fromTheme("edit-delete"), RunePageList::tr("Delete"), this, &RunePageList::deleteCurrentItem); + + menu.exec(globalPos); +} + +void RunePageList::deleteCurrentItem() { + QListWidgetItem* item = currentItem(); + if (item) { + uint32_t id = item->data(RoleId).toUInt(); + RunePage* page = (RunePage*) item->data(RolePointer).toULongLong(); + removeItemWidget(item); + emit runepageDeleted(id); + + delete item; + delete page; + } +} + +void RunePageList::clearItems() { + while(count()) { + QListWidgetItem* item = takeItem(0); + delete (RunePage*) item->data(RolePointer).toULongLong(); + delete item; + } + + clear(); +} + void RunePageList::addRunepageItem(QString name, int id, const ::RunePage& rp, bool isCurrent) { QListWidgetItem* item = new QListWidgetItem(name); item->setData(RoleId, (uint) id); item->setData(RolePointer, (qulonglong) new ::RunePage(rp)); + QString tooltipStr; if(id != -1) { - item->setToolTip(QString("id: %0").arg(id)); + tooltipStr = QString("id: %0\n").arg(id); } + tooltipStr += getRuneDescription(rp); + item->setToolTip(tooltipStr); item->setFlags(item->flags() | Qt::ItemIsEditable); if(isCurrent) { item->setSelected(true); } addItem(item); } + +QString RunePageList::getRuneDescription(const ::RunePage& runepage) { + QString outStr; + outStr.reserve(100); + QTextStream out(&outStr); + + if(! (bool) runepage) { + return {}; + } + + out << getRuneStyleByID(runepage.primaryStyle) << ' ' << RunePageList::tr("with") << ' ' << getRuneStyleByID(runepage.secondaryStyle); + + for(uint32_t rune : runepage.selectedAspects) { + out << '\n' << getRuneText(rune); + } + return outStr; +} + +QString RunePageList::getRuneText(uint32_t id) { + if(runeInfo != nullptr) { + for(const RuneAspekt& ra : *runeInfo) { + if(ra.id == id) { + return QString::fromStdString(ra.name); + } + } + } + + return QString("(%0)").arg(id); +} + +QString RunePageList::getRuneStyleByID(uint32_t id) { + if(runeStyles != nullptr) { + auto it = std::find_if(runeStyles->begin(), runeStyles->end(), [id](const RuneStyle& rs) { return rs.id == id; }); + + if(it != runeStyles->end()) { + return QString::fromStdString(it->name); + } + } + + return QString("(%0)").arg(id); +} diff --git a/ui/runemanager.ui b/ui/runemanager.ui index 6743d38..614eab5 100644 --- a/ui/runemanager.ui +++ b/ui/runemanager.ui @@ -11,8 +11,22 @@ + + + + Runes in the Client + + + - + + + Runes in the Autoacceptor + + + + + true @@ -21,29 +35,8 @@ - - - - Runes in the Client - - - - - - - Delete - - - - - - - Runes in the Autoacceptor - - - - - + + true @@ -55,7 +48,25 @@ - Retry + Reload + + + + + + + + + + false + + + Runes from the client get copied to the autoacceptor automatically. + +This Feature is in development. + + + Auto Copy Runes @@ -86,25 +97,8 @@ - - listClientRunes - itemChanged(QListWidgetItem*) - RuneManager - clientRunePageRenamed(QListWidgetItem*) - - - 266 - 229 - - - 644 - 240 - - - loadRunes() - clientRunePageRenamed(QListWidgetItem*) diff --git a/ui/runepagelist.ui b/ui/runepagelist.ui index 71832e9..382e54f 100644 --- a/ui/runepagelist.ui +++ b/ui/runepagelist.ui @@ -10,6 +10,9 @@ 300 + + Qt::CustomContextMenu +