diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 84c35520417..7672f8cb98a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,6 +51,7 @@ set(mudlet_SRCS dlgAliasMainArea.cpp dlgColorTrigger.cpp dlgComposer.cpp + dlgConfigureAreas.cpp dlgConnectionProfiles.cpp dlgIRC.cpp dlgKeysMainArea.cpp @@ -232,6 +233,7 @@ set(mudlet_UIS ui/aliases_main_area.ui ui/color_trigger.ui ui/composer.ui + ui/configure_areas.ui ui/connection_profiles.ui ui/dlgPackageExporter.ui ui/irc.ui diff --git a/src/T2DMap.cpp b/src/T2DMap.cpp index e06c5ad44d6..4209b54bced 100644 --- a/src/T2DMap.cpp +++ b/src/T2DMap.cpp @@ -3320,6 +3320,7 @@ void T2DMap::slot_createRoom() isCenterViewCall = true; mpMap->updateArea(mAreaID); isCenterViewCall = false; + emit mpMap->signal_roomsChanged(); mpMap->setUnsaved(__func__); } @@ -4106,6 +4107,7 @@ void T2DMap::slot_deleteRoom() mMultiSelectionListWidget.clear(); mMultiSelectionListWidget.hide(); repaint(); + emit mpMap->signal_roomsChanged(); mpMap->setUnsaved(__func__); } diff --git a/src/TMap.h b/src/TMap.h index 90ed91e92ef..9eabe9e33a2 100644 --- a/src/TMap.h +++ b/src/TMap.h @@ -76,6 +76,7 @@ class TMap : public QObject signals: void signal_saveErrorChanged(bool hasError); void signal_areaChanged(int areaId); + void signal_roomsChanged(); private: QString mDefaultAreaName; diff --git a/src/dlgConfigureAreas.cpp b/src/dlgConfigureAreas.cpp new file mode 100644 index 00000000000..7bdbe8dc797 --- /dev/null +++ b/src/dlgConfigureAreas.cpp @@ -0,0 +1,177 @@ +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "dlgConfigureAreas.h" +#include "dlgMapper.h" +#include "TArea.h" +#include "TMap.h" +#include "TRoomDB.h" + +#include "mudlet.h" + +#include +#include + +enum Columns +{ + ColAreaName = 0, + ColAreaId, + ColRoomCount, + ColCount +}; + +dlgConfigureAreas::dlgConfigureAreas(TMap* map, QWidget* parent) : QDialog(parent), mpMap(map) +{ + setupUi(this); + if(mpMap) { + connect(mpMap, &TMap::signal_roomsChanged, this, &dlgConfigureAreas::populateAreaList); + } + areaTable->setSelectionBehavior(QAbstractItemView::SelectRows); + areaTable->setSelectionMode(QAbstractItemView::SingleSelection); + + setWindowTitle(tr("Configure Areas")); + + areaTable->setColumnCount(3); + areaTable->setHorizontalHeaderLabels({tr("Area Name"), tr("Area ID"), tr("Rooms")}); + areaTable->setColumnHidden(1, true); + areaTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + areaTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + areaTable->horizontalHeader()->setStretchLastSection(true); + + connect(addAreaBtn, &QPushButton::clicked, this, &dlgConfigureAreas::slot_addArea); + connect(removeAreaBtn, &QPushButton::clicked, this, &dlgConfigureAreas::slot_removeArea); + + populateAreaList(); +} + +int dlgConfigureAreas::currentAreaId() const +{ + const auto selected = areaTable->selectionModel()->selectedRows(); + if (selected.isEmpty()) { + return -1; + } + + return areaTable->item(selected.first().row(), ColAreaId)->text().toInt(); +} + +void dlgConfigureAreas::refreshAreas(bool added, const QString& areaName) +{ + if(!mpMap || !mpMap->mpMapper) + return; + + auto mapper = mpMap->mpMapper; + mapper->updateAreaComboBox(); + QComboBox* combo = mapper->findChild(); + + QString targetArea; + if(added) { + targetArea = areaName; + } + else { + targetArea = mpMap->getDefaultAreaName(); + } + + const int index = combo->findText(targetArea); + if(index >= 0) { + mapper->slot_switchArea(index); + combo->setCurrentIndex(index); + } + + mpMap->setUnsaved(__func__); +} + +void dlgConfigureAreas::populateAreaList() +{ + if (!mpMap || !mpMap->mpRoomDB) { + return; + } + + areaTable->setRowCount(0); + const auto& areaNames = mpMap->mpRoomDB->getAreaNamesMap(); + int row = 0; + for (auto it = areaNames.begin(); it != areaNames.end(); ++it) { + const int areaId = it.key(); + const QString& areaName = it.value(); + int roomCount = 0; + if (TArea* area = mpMap->mpRoomDB->getArea(areaId)) { + roomCount = area->getAreaRooms().size(); + } + + areaTable->insertRow(row); + areaTable->setItem(row, ColAreaName, new QTableWidgetItem(areaName)); + areaTable->setItem(row, ColAreaId, new QTableWidgetItem(QString::number(areaId))); + areaTable->setItem(row, ColRoomCount, new QTableWidgetItem(QString::number(roomCount))); + ++row; + } +} + +void dlgConfigureAreas::slot_addArea() +{ + if (!mpMap || !mpMap->mpRoomDB) { + return; + } + + bool ok{}; + const QString rawName = QInputDialog::getText(this, tr("Add Area:"), tr("Area Name"), QLineEdit::Normal, QString(), &ok); + const QString name = rawName.trimmed(); + if (!ok || name.isEmpty()) { + return; + } + + if (mpMap->mpRoomDB->getAreaNamesMap().values().count(name) > 0) { + statusLabel->setText(tr("Area with this name already exists.")); + return; + } + + mpMap->mpRoomDB->addArea(name); + statusLabel->clear(); + + populateAreaList(); + refreshAreas(true, name); +} + +void dlgConfigureAreas::slot_removeArea() +{ + if (!mpMap || !mpMap->mpRoomDB) { + return; + } + + const int areaId = currentAreaId(); + if (areaId == -1) { + statusLabel->setText(tr("Default area cannot be deleted.")); + return; + } + + TArea* area = mpMap->mpRoomDB->getArea(areaId); + const int roomCount = area ? area->getAreaRooms().size() : 0; + if (roomCount > 0) { + const auto reply = QMessageBox::warning(this, tr("Delete area"), tr("This will also delete %1 rooms.\nDo you want to continue?").arg(roomCount), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No); + + if (reply != QMessageBox::Yes) { + return; + } + } + + mpMap->mpRoomDB->removeArea(areaId); + statusLabel->clear(); + + populateAreaList(); + refreshAreas(false, QString()); +} + diff --git a/src/dlgConfigureAreas.h b/src/dlgConfigureAreas.h new file mode 100644 index 00000000000..2c1fb4c2949 --- /dev/null +++ b/src/dlgConfigureAreas.h @@ -0,0 +1,45 @@ +#ifndef MUDLET_DLGCONFIGUREAREAS_H +#define MUDLET_DLGCONFIGUREAREAS_H + +/*************************************************************************** + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "ui_configure_areas.h" +#include + +class TMap; + +class dlgConfigureAreas : public QDialog, public Ui::configure_areas +{ + Q_OBJECT + +public: + dlgConfigureAreas(TMap* map, QWidget* parent = nullptr); + +public slots: + void slot_addArea(); + void slot_removeArea(); + +private: + void populateAreaList(); + void refreshAreas(bool added, const QString& areaName); + int currentAreaId() const; + + TMap* mpMap = nullptr; +}; + +#endif //MUDLET_DLGCONFIGUREAREAS_H diff --git a/src/dlgMapper.cpp b/src/dlgMapper.cpp index 9e4f58c7bfe..95dccc536c6 100644 --- a/src/dlgMapper.cpp +++ b/src/dlgMapper.cpp @@ -598,6 +598,11 @@ void dlgMapper::slot_setupMapperMenu() menu->addAction(show3DMapAction); #endif + menu->addSeparator(); + auto* newAreaConfigurator = new QAction(tr("Configure areas"), this); + connect(newAreaConfigurator, &QAction::triggered, mudlet::self(), &mudlet::slot_newAreaConfigurator); + menu->addAction(newAreaConfigurator); + // Add separator and Info submenu menu->addSeparator(); mpInfoMenu = menu->addMenu(tr("Info overlays")); diff --git a/src/mudlet.cpp b/src/mudlet.cpp index d96fd2ca036..f63090f7820 100644 --- a/src/mudlet.cpp +++ b/src/mudlet.cpp @@ -50,6 +50,7 @@ #include "TToolBar.h" #include "XMLimport.h" #include "dlgAboutDialog.h" +#include "dlgConfigureAreas.h" #include "dlgConnectionProfiles.h" #include "dlgIRC.h" #include "dlgMapper.h" @@ -1767,6 +1768,18 @@ void mudlet::slot_newMapWindow() } } +void mudlet::slot_newAreaConfigurator() +{ + Host* pHost = getActiveHost(); + if (!pHost || !pHost->mpMap) { + return; + } + + auto* dlg = new dlgConfigureAreas(pHost->mpMap.data(), this); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); +} + void mudlet::updateWindowMenu() { // Clean up existing window list actions diff --git a/src/mudlet.h b/src/mudlet.h index fede1a7bc60..01ba2327437 100644 --- a/src/mudlet.h +++ b/src/mudlet.h @@ -437,6 +437,7 @@ public slots: void slot_toggleAlwaysOnTop(); void slot_minimize(); void slot_newMapWindow(); + void slot_newAreaConfigurator(); void updateWindowMenu(); void slot_activateMainWindow(); void slot_activateDetachedWindow(); diff --git a/src/ui/configure_areas.ui b/src/ui/configure_areas.ui new file mode 100644 index 00000000000..aa0cbf20393 --- /dev/null +++ b/src/ui/configure_areas.ui @@ -0,0 +1,80 @@ + + + configure_areas + + + Configure Areas + + + + + + + + + + + + Area Name + + + + + Rooms + + + + + + + + + + + + color: red; + + + + + + + + + + + Add Area + + + + + + + + Remove Area + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + \ No newline at end of file