From 14ec8a711b316e775b957a5784f176d674493bc9 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Mon, 1 May 2023 22:36:11 +0200 Subject: [PATCH] add runeeditor --- include/clientapi.h | 9 +- include/runeaspektbutton.h | 43 +++++++ include/runeeditor.h | 59 +++++++++ include/runepagelist.h | 7 +- include/runestyle.h | 15 +++ lolautoaccept.pro | 6 + src/clientapi.cpp | 37 +++++- src/clientapi_json.cpp | 21 ++++ src/runeaspektbutton.cpp | 68 +++++++++++ src/runeeditor.cpp | 238 +++++++++++++++++++++++++++++++++++++ src/runemanager.cpp | 85 ++++++++----- src/runepagelist.cpp | 50 +++++++- ui/runeaspektbutton.ui | 18 +++ ui/runeeditor.ui | 79 ++++++++++++ 14 files changed, 703 insertions(+), 32 deletions(-) create mode 100644 include/runeaspektbutton.h create mode 100644 include/runeeditor.h create mode 100644 src/runeaspektbutton.cpp create mode 100644 src/runeeditor.cpp create mode 100644 ui/runeaspektbutton.ui create mode 100644 ui/runeeditor.ui diff --git a/include/clientapi.h b/include/clientapi.h index aa6caed..5288170 100644 --- a/include/clientapi.h +++ b/include/clientapi.h @@ -1,8 +1,10 @@ #pragma once #include "clientaccess.h" -#include "restclient.h" +#include "datadragonimagecache.h" +#include "memoryimagecache.h" #include "position.h" +#include "restclient.h" #include "runeaspekt.h" #include "runepage.h" #include "runestyle.h" @@ -214,8 +216,13 @@ public: const std::string& getRuneStyleByID(uint32_t id); + QPixmap getImageResource(QString path); + private: ClientAccess access; + + MemoryImageCache memImageCache; + DataDragonImageCache imageCache; }; std::ostream& operator<<(std::ostream&, const ClientAPI::ReadyCheckState&); diff --git a/include/runeaspektbutton.h b/include/runeaspektbutton.h new file mode 100644 index 0000000..22fd7f6 --- /dev/null +++ b/include/runeaspektbutton.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include + +namespace Ui { + class RuneAspektButton; +} + +class RuneAspektButton : public QPushButton { + Q_OBJECT + +public: + explicit RuneAspektButton(QWidget* parent = nullptr); + ~RuneAspektButton(); + + void setAspektsVector(std::vector& aspekts); + void setAspketSlot(int slot); + void setAspektId(uint32_t id); + + bool isSelected() const; + +signals: + void aspektToggled(bool newState); + +public slots: + void buttonPressed(); + void dataChanged(); + +private slots: + void setShowSelection(bool selected); // show/hide the red border + +public: + uint32_t aspektId = 0; + int aspektSlot = -1; + +private: + Ui::RuneAspektButton* ui; + + std::vector* aspekts = nullptr; +}; + diff --git a/include/runeeditor.h b/include/runeeditor.h new file mode 100644 index 0000000..50cf738 --- /dev/null +++ b/include/runeeditor.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include + +#include "runeaspekt.h" +#include "runepage.h" +#include "runestyle.h" + +namespace Ui { + class RuneEditor; +} + +class ClientAPI; +class RuneAspektButton; +class QGridLayout; + +class RuneEditor : public QDialog { + Q_OBJECT + +public: + explicit RuneEditor(QWidget* parent = nullptr); + ~RuneEditor(); + + void setClient(ClientAPI& client); + void setRunepage(const ::RunePage& rp); + + void selectStyle(uint32_t id); + void selectSubStyle(uint32_t id); + + void clearLayout(QLayout* layout); + + void setName(QString text); + QString getName() const; + + constexpr const RunePage& getRunepage() const { return runepage; } + +signals: + void selectionChanged(); + +private slots: + void aspectCliecked(); + +private: + const RuneStyle* getRuneStyle(uint32_t id) const; + RuneAspektButton* createStyleButton(const RuneStyle& rs, bool selected); + RuneAspektButton* createAspektButton(const RuneAspekt& ra); + RuneAspektButton* createButtonFromResource(QString resource); + void fillRuneStyle(QGridLayout* target, const RuneStyle& rs, bool subRunes = false); + QString fixString(QString text); + + Ui::RuneEditor* ui; + + ClientAPI* client = nullptr; + ::RunePage runepage; + std::vector aspekts; + std::vector styles; +}; diff --git a/include/runepagelist.h b/include/runepagelist.h index c6e3edc..5c2ca74 100644 --- a/include/runepagelist.h +++ b/include/runepagelist.h @@ -15,6 +15,7 @@ namespace Ui { class DataDragon; class DropEvent; +class ClientAPI; class RunePageList : public QListWidget { Q_OBJECT @@ -26,7 +27,8 @@ public: explicit RunePageList(QWidget* parent = nullptr); ~RunePageList(); - constexpr void setClient(bool b) { isClient = b; } + constexpr void setIsClient(bool b) { isClient = b; } + constexpr void setClient(ClientAPI& client) { this->client = &client; } constexpr void setOther(QListWidget* other) { this->other = other; } constexpr void setDataDragon(DataDragon& dd) { this->dd = ⅆ } @@ -46,6 +48,8 @@ private slots: void itemChangedCallback(QListWidgetItem* item); void openContextMenu(const QPoint&); void deleteCurrentItem(); + void editCurrentItem(); + void duplicateCurrentItem(); private: void clearItems(); @@ -61,5 +65,6 @@ private: Ui::RunePageList* ui; QListWidget* other = nullptr; DataDragon* dd = nullptr; + ClientAPI* client = nullptr; bool isClient; }; diff --git a/include/runestyle.h b/include/runestyle.h index a6b2e02..9a77c04 100644 --- a/include/runestyle.h +++ b/include/runestyle.h @@ -2,16 +2,31 @@ #include #include +#include + // fwd. class QJsonObject; +struct RuneStyleSlot { + std::vector perks; + QString type; + + RuneStyleSlot(); + RuneStyleSlot(const QJsonObject& json); +}; + struct RuneStyle { uint32_t id; std::string name; std::string iconPath; std::string tooltip; + std::vector allowedSubStyles; + QString idName; + + std::vector runeSlots; + RuneStyle(); explicit RuneStyle(const QJsonObject& json); }; diff --git a/lolautoaccept.pro b/lolautoaccept.pro index 7ccd57e..a7f2bda 100644 --- a/lolautoaccept.pro +++ b/lolautoaccept.pro @@ -53,7 +53,9 @@ SOURCES += \ src/mainwindow.cpp \ src/memoryimagecache.cpp \ src/restclient.cpp \ + src/runeaspektbutton.cpp \ src/runedisplay.cpp \ + src/runeeditor.cpp \ src/runemanager.cpp \ src/runepage.cpp \ src/runepagelist.cpp \ @@ -83,7 +85,9 @@ HEADERS += \ include/mainwindow.h \ include/memoryimagecache.h \ include/restclient.h \ + include/runeaspektbutton.h \ include/runedisplay.h \ + include/runeeditor.h \ include/runemanager.h \ include/runepage.h \ include/runepagelist.h \ @@ -94,7 +98,9 @@ HEADERS += \ FORMS += \ ui/championsearch.ui \ ui/mainwindow.ui \ + ui/runeaspektbutton.ui \ ui/runedisplay.ui \ + ui/runeeditor.ui \ ui/runemanager.ui \ ui/runepagelist.ui \ ui/settingstab.ui \ diff --git a/src/clientapi.cpp b/src/clientapi.cpp index 8fd08e7..6bbe3c1 100644 --- a/src/clientapi.cpp +++ b/src/clientapi.cpp @@ -9,7 +9,7 @@ #include "json.h" -ClientAPI::ClientAPI(const ClientAccess& ca) : RestClient(ca.getURL()), access(ca) { +ClientAPI::ClientAPI(const ClientAccess& ca) : RestClient(ca.getURL()), access(ca), memImageCache(40), imageCache("runes", "") { basicauth = ca.getBasicAuth(); disableCertCheck = true; // enableDebugging(); @@ -332,3 +332,38 @@ std::vector ClientAPI::getAllRuneStyles() { } return out; } + +QPixmap ClientAPI::getImageResource(QString path) { + if(path.isEmpty()) return {}; + + std::string simplePath; + { + QString simplePathQ = path; + simplePath = simplePathQ.replace('/', '_').toStdString(); + } + + // query mem cache + QPixmap img = memImageCache.getImage(path.toStdString(), 0); + if(!img.isNull()) return img; + + // query HDD cache + img = imageCache.getImage(simplePath); + if(!img.isNull()) { + // update mem cache + memImageCache.addImage(img, path.toStdString(), 0); + return img; + } + + qInfo() << "requesting: " << path; + QByteArray arr = requestRaw(path.toStdString()); + QPixmap out; + out.loadFromData(arr); + + // store HDD cache + imageCache.addImageRaw(arr, simplePath); + + // store memchache + memImageCache.addImage(out, path.toStdString(), 0); + + return out; +} diff --git a/src/clientapi_json.cpp b/src/clientapi_json.cpp index f5819cb..3abf9cf 100644 --- a/src/clientapi_json.cpp +++ b/src/clientapi_json.cpp @@ -209,12 +209,33 @@ ClientAPI::RunePage::RunePage(const QJsonObject& json) { } } +RuneStyleSlot::RuneStyleSlot() {} +RuneStyleSlot::RuneStyleSlot(const QJsonObject& json) { + type = getValue(json, "type"); + + auto perksj = json["perks"]; + if(perksj.isArray()) { + perks = readVector(perksj.toArray()); + } +} + RuneStyle::RuneStyle() {} RuneStyle::RuneStyle(const QJsonObject& json) { id = getValue(json, "id", 0); name = getValue(json, "name"); iconPath = getValue(json, "iconPath"); tooltip = getValue(json, "tooltip"); + idName = getValue(json, "idName"); + + auto subStylesRef = json["allowedSubStyles"]; + if(subStylesRef.isArray()) { + allowedSubStyles = readVector(subStylesRef.toArray()); + } + + auto runeSlotsRef = json["slots"]; + if(runeSlotsRef.isArray()) { + runeSlots = readVector(runeSlotsRef.toArray()); + } } diff --git a/src/runeaspektbutton.cpp b/src/runeaspektbutton.cpp new file mode 100644 index 0000000..971f85e --- /dev/null +++ b/src/runeaspektbutton.cpp @@ -0,0 +1,68 @@ +#include "runeaspektbutton.h" +#include "ui_runeaspektbutton.h" + +#include + +RuneAspektButton::RuneAspektButton(QWidget* parent) : QPushButton(parent), ui(new Ui::RuneAspektButton) { + ui->setupUi(this); + + QObject::connect(this, &QPushButton::pressed, this, &RuneAspektButton::buttonPressed); +} + +RuneAspektButton::~RuneAspektButton() { + delete this->ui; +} + +void RuneAspektButton::setAspektsVector(std::vector& aspekts) { + this->aspekts = &aspekts; + + dataChanged(); +} + +void RuneAspektButton::setAspketSlot(int slot) { + aspektSlot = slot; + + dataChanged(); +} + +void RuneAspektButton::setAspektId(uint32_t id) { + aspektId = id; + + dataChanged(); +} + +bool RuneAspektButton::isSelected() const { + return (aspektSlot >= 0 // aspektSlot is valid + && (int) aspekts->size() > aspektSlot // aspektSlot is valid + && aspektId != 0 // aspektId is valid + && aspekts->at(aspektSlot) == aspektId); // aspekt is selected +} + +void RuneAspektButton::buttonPressed() { + if(Q_UNLIKELY(!(aspekts && aspektSlot >= 0))) return; + + // toggle + bool oldState = isSelected(); + int newValue = (oldState ? 0 : aspektId); + aspekts->at(aspektSlot) = newValue; + + emit aspektToggled(!oldState); +} + +void RuneAspektButton::dataChanged() { + if(!aspekts) return; + + bool selection = isSelected(); + + qDebug() << text() << " datachanged - isSelected: " << selection; + + setShowSelection(selection); +} + +void RuneAspektButton::setShowSelection(bool selected) { + if(selected) { + setStyleSheet("border: 1px solid red;"); + } else { + setStyleSheet(""); + } +} \ No newline at end of file diff --git a/src/runeeditor.cpp b/src/runeeditor.cpp new file mode 100644 index 0000000..fc4de05 --- /dev/null +++ b/src/runeeditor.cpp @@ -0,0 +1,238 @@ +#include "runeeditor.h" +#include "ui_runeeditor.h" + +#include +#include +#include +#include +#include + +#include "clientapi.h" +#include "runeaspektbutton.h" + +RuneEditor::RuneEditor(QWidget* parent) : QDialog(parent), ui(new Ui::RuneEditor) { + ui->setupUi(this); + + QObject::connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &RuneEditor::accept); + QObject::connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &RuneEditor::reject); +} + +RuneEditor::~RuneEditor() { + delete this->ui; +} + +void RuneEditor::setClient(ClientAPI& client) { + this->client = &client; + + try { + // build ui + aspekts = client.getAllRuneAspekts(); + styles = client.getAllRuneStyles(); + + for(const RuneStyle& rs : styles) { + QPushButton* runeStyleBtn = createStyleButton(rs, rs.id == runepage.primaryStyle); + + if(!runeStyleBtn) continue; + + QObject::connect(runeStyleBtn, &QPushButton::pressed, [this, id = rs.id](){ + selectStyle(id); + }); + + ui->style->addWidget(runeStyleBtn); + } + } catch(RestClient::WebException& e) { + qCritical() << "webexception: " << e.curlresponse; + + if(e.curlresponse == CURLE_COULDNT_CONNECT) { + this->client = nullptr; + } + } +} + +void RuneEditor::setRunepage(const ::RunePage& rp) { + qInfo() << "runepage: " << rp.selectedAspects.size(); + + selectStyle(rp.primaryStyle); + selectSubStyle(rp.secondaryStyle); + + runepage = rp; + + emit selectionChanged(); +} + +void RuneEditor::selectStyle(uint32_t id) { + if(runepage.primaryStyle == id) return; + + const RuneStyle* style = getRuneStyle(id); + + if(style) { + runepage.primaryStyle = id; + runepage.secondaryStyle = 0; + runepage.selectedAspects.clear(); + runepage.selectedAspects.resize(9, 0); + + clearLayout(ui->substyle); + clearLayout(ui->stylePerks); + clearLayout(ui->substylePerks); + + // populate substyles + for(int subStyleId : style->allowedSubStyles) { + const RuneStyle* substyle = getRuneStyle(subStyleId); + QPushButton* subStyleBtn = createStyleButton(*substyle, false); + + if(!subStyleBtn) continue; + + QObject::connect(subStyleBtn, &QPushButton::pressed, [this, subStyleId](){ + selectSubStyle(subStyleId); + }); + + ui->substyle->addWidget(subStyleBtn); + } + + // populate perks + fillRuneStyle(ui->stylePerks, *style); + } +} + +void RuneEditor::selectSubStyle(uint32_t id) { + if(runepage.secondaryStyle == id) return; + + const RuneStyle* substyle = getRuneStyle(id); + + if(substyle) { + runepage.secondaryStyle = id; + + clearLayout(ui->substylePerks); + + // populate perks + fillRuneStyle(ui->substylePerks, *substyle, true); + } +} + +void RuneEditor::clearLayout(QLayout* layout) { + while(layout->count()) { + QLayoutItem* item = layout->takeAt(0); + delete item->widget(); + delete item; + } +} + +void RuneEditor::setName(QString text) { + ui->runepageName->setText(text); +} + +QString RuneEditor::getName() const { + return ui->runepageName->text(); +} + +void RuneEditor::aspectCliecked() { + // do something? +} + +const RuneStyle* RuneEditor::getRuneStyle(uint32_t id) const { + auto it = std::find_if(styles.cbegin(), styles.cend(), [id](const RuneStyle& rs) { + return rs.id == id; + }); + + return it == styles.cend() ? nullptr : &*it; +} + +RuneAspektButton* RuneEditor::createStyleButton(const RuneStyle& rs, bool selected) { + RuneAspektButton* styleBtn = createButtonFromResource(QString::fromStdString(rs.iconPath)); + + if(!styleBtn) return nullptr; + + styleBtn->setText(QString::fromStdString(rs.name)); + styleBtn->setToolTip(QString::fromStdString(rs.tooltip)); + + if(selected) { + styleBtn->setStyleSheet("border: 1px solid red;"); + } + + return styleBtn; +} + +RuneAspektButton* RuneEditor::createAspektButton(const RuneAspekt& ra) { + RuneAspektButton* aspektBtn = createButtonFromResource(QString::fromStdString(ra.iconPath)); + + if(!aspektBtn) return nullptr; + + aspektBtn->setText(QString::fromStdString(ra.name)); + aspektBtn->setToolTip(QString::fromStdString(ra.tooltip)); + + aspektBtn->setAspektsVector(runepage.selectedAspects); + aspektBtn->setAspektId(ra.id); + + return aspektBtn; +} + +RuneAspektButton* RuneEditor::createButtonFromResource(QString resource) { + if(!client) { + return nullptr; + } + + QPixmap icon; + try { + icon = client->getImageResource(resource.remove(0, 1)); + } catch(RestClient::WebException& e) { + qCritical() << "webexception: " << e.curlresponse; + + if(e.curlresponse == CURLE_COULDNT_CONNECT) { + client = nullptr; + } + } + + RuneAspektButton* rab = new RuneAspektButton(this); + rab->setIcon(icon); + + QObject::connect(this, &RuneEditor::selectionChanged, rab, &RuneAspektButton::dataChanged); + QObject::connect(rab, &RuneAspektButton::aspektToggled, this, &RuneEditor::aspectCliecked); + QObject::connect(rab, &RuneAspektButton::aspektToggled, this, &RuneEditor::selectionChanged); + + return rab; +} + +void RuneEditor::fillRuneStyle(QGridLayout* target, const RuneStyle& rs, bool subRunes) { + int row = 0; + for(size_t idx = 0; idx < rs.runeSlots.size(); ++idx) { + const RuneStyleSlot& rss = rs.runeSlots.at(idx); + + if(subRunes && rss.type != "kMixedRegularSplashable") continue; + + int rowOffset = 0; + if(subRunes) { + rowOffset = 4; + if(row > 0) { + rowOffset = 3; + } + } else { + if(row >= 4) { + rowOffset = 2; + } + } + + for(int perkNr = 0; perkNr < (int) rss.perks.size(); ++perkNr) { + uint32_t perk = rss.perks.at(perkNr); + auto itFound = std::find_if(aspekts.cbegin(), aspekts.cend(), [perk](const RuneAspekt& ra) { + return ra.id == perk; + }); + + if(itFound == aspekts.cend()) { + continue; + } + + RuneAspektButton* aspektBtn = createAspektButton(*itFound); + if(!aspektBtn) continue; + + aspektBtn->setAspketSlot(row + rowOffset); + + target->addWidget(aspektBtn, row, perkNr); + } + + ++ row; + } +} + +QString RuneEditor::fixString(QString text) { + return text.replace(" ", "").replace("", ""); +} diff --git a/src/runemanager.cpp b/src/runemanager.cpp index f7ac368..6d0066e 100644 --- a/src/runemanager.cpp +++ b/src/runemanager.cpp @@ -10,8 +10,8 @@ RuneManager::RuneManager(QWidget* parent) : QWidget(parent), ui(new Ui::RuneManager) { ui->setupUi(this); - ui->listClientRunes->setClient(true); - ui->listaaRunes->setClient(false); + ui->listClientRunes->setIsClient(true); + ui->listaaRunes->setIsClient(false); ui->listClientRunes->setOther(ui->listaaRunes); ui->listaaRunes->setOther(ui->listClientRunes); @@ -69,25 +69,36 @@ void RuneManager::loadRunes() { } if(client) { - // load meta data - runeInfo = client->getAllRuneAspekts(); - QCoreApplication::processEvents(); - runeStyles = client->getAllRuneStyles(); - QCoreApplication::processEvents(); + try { + // load meta data + runeInfo = client->getAllRuneAspekts(); + QCoreApplication::processEvents(); + runeStyles = client->getAllRuneStyles(); + QCoreApplication::processEvents(); - this->ui->listClientRunes->setRuneInfos(runeInfo, runeStyles); - this->ui->listaaRunes->setRuneInfos(runeInfo, runeStyles); + ui->listClientRunes->setClient(*client); + ui->listaaRunes->setClient(*client); - // load runepages - const std::vector runePages = client->getAllRunePages(); - ui->listClientRunes->loadRunePages(runePages); + this->ui->listClientRunes->setRuneInfos(runeInfo, runeStyles); + this->ui->listaaRunes->setRuneInfos(runeInfo, runeStyles); - // reload runepages - so they ids can get their names - reloadAARunes(); + // load runepages + const std::vector runePages = client->getAllRunePages(); + ui->listClientRunes->loadRunePages(runePages); - // check if autosync is enabled - if(config && config->getConfig().runepagesConfig.autoSync) { - syncRunes(); + // reload runepages - so they ids can get their names + reloadAARunes(); + + // check if autosync is enabled + if(config && config->getConfig().runepagesConfig.autoSync) { + syncRunes(); + } + } catch(RestClient::WebException& e) { + qCritical() << "webexception: " << e.curlresponse; + + if(e.curlresponse == CURLE_COULDNT_CONNECT) { + client.reset(); + } } } @@ -110,15 +121,25 @@ void RuneManager::saveRunePageClient(int id, QString name, const RunePage& rp) { newPage.runepage = rp; newPage.id = id; - if(id == -1) { - // create new page - if(!client->createRunePage(newPage)) { - // TODO: some error occured + try { + 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 + } } - } else { - // edit existing page - if(!client->editRunePage(newPage)) { - // TODO: some error occured + } catch(RestClient::WebException& e) { + qCritical() << "webexception: " << e.curlresponse; + + if(e.curlresponse == CURLE_COULDNT_CONNECT) { + client.reset(); + + setRunesEnabled(false); } } } @@ -150,8 +171,18 @@ void RuneManager::saveRunePageAA(int id, QString name, const RunePage& rp) { void RuneManager::deleteRunepageClient(int id) { if(client) { - if(!client->deleteRunePage(id)) { - // TODO: some error occured + try { + if(!client->deleteRunePage(id)) { + // TODO: some error occured + } + } catch(RestClient::WebException& e) { + qCritical() << "webexception: " << e.curlresponse; + + if(e.curlresponse == CURLE_COULDNT_CONNECT) { + client.reset(); + + setRunesEnabled(false); + } } } } diff --git a/src/runepagelist.cpp b/src/runepagelist.cpp index ef6aa69..e01a53d 100644 --- a/src/runepagelist.cpp +++ b/src/runepagelist.cpp @@ -8,6 +8,7 @@ #include #include "datadragon.h" +#include "runeeditor.h" RunePageList::RunePageList(QWidget* parent) : QListWidget(parent), ui(new Ui::RunePageList) { ui->setupUi(this); @@ -41,7 +42,6 @@ void RunePageList::setRuneInfos(const std::vector& runeInfo, const s } void RunePageList::dropEvent(QDropEvent* event) { - qDebug() << "drop event"; if(event->source() == nullptr || event->source() != other) { event->ignore(); return; @@ -53,7 +53,6 @@ void RunePageList::dropEvent(QDropEvent* event) { return; } QListWidgetItem* item = selected.at(0); - qDebug() << "data: " << item->data(RoleId); // compare rune pages for duplicates? @@ -78,6 +77,8 @@ void RunePageList::openContextMenu(const QPoint& pos) { QMenu menu; menu.addAction(QIcon::fromTheme("edit-delete"), RunePageList::tr("Delete"), this, &RunePageList::deleteCurrentItem); + menu.addAction(QIcon::fromTheme("document-open"), RunePageList::tr("Edit (Beta)"), this, &RunePageList::editCurrentItem); + menu.addAction(QIcon::fromTheme("edit-copy"), RunePageList::tr("Duplicate"), this, &RunePageList::duplicateCurrentItem); menu.exec(globalPos); } @@ -96,6 +97,51 @@ void RunePageList::deleteCurrentItem() { } } +void RunePageList::editCurrentItem() { + QListWidgetItem* item = currentItem(); + if(!item) return; + + RunePage* rp = (RunePage*) item->data(RolePointer).toULongLong(); + const uint32_t id = item->data(RoleId).toUInt(); + + RuneEditor re; + + re.setName(item->text()); + re.setClient(*client); + re.setRunepage(*rp); + + int result = re.exec(); + + // check result - save + if(result == QDialog::Accepted) { + + // update config + emit runepageChanged(id, re.getName(), re.getRunepage()); + } +} + +void RunePageList::duplicateCurrentItem() { + QListWidgetItem* item = currentItem(); + if(!item) return; + + const RunePage* rp = (RunePage*) item->data(RolePointer).toULongLong(); + + QString name = item->text(); + + static const QRegularExpression regex(".*(\\d)+$"); + QRegularExpressionMatchIterator regexIt = regex.globalMatch(name); + int num = 0; + if(regexIt.hasNext()) { + QRegularExpressionMatch match = regexIt.next(); + QStringRef ref = match.capturedRef(1); + name.chop(ref.size()); + num = ref.toInt(); + } + name += QString::number(num+1); + + emit runepageChanged(-1, name, *rp); +} + void RunePageList::clearItems() { while(count()) { QListWidgetItem* item = takeItem(0); diff --git a/ui/runeaspektbutton.ui b/ui/runeaspektbutton.ui new file mode 100644 index 0000000..5ed7177 --- /dev/null +++ b/ui/runeaspektbutton.ui @@ -0,0 +1,18 @@ + + + + + RuneAspektButton + + + + 0 + 0 + 400 + 300 + + + + + + diff --git a/ui/runeeditor.ui b/ui/runeeditor.ui new file mode 100644 index 0000000..11b3209 --- /dev/null +++ b/ui/runeeditor.ui @@ -0,0 +1,79 @@ + + + RuneEditor + + + + 0 + 0 + 576 + 455 + + + + Runepage Editor + + + + + + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 40 + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Save + + + + + + + 10 + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 120 + + + + + + + + +