Update Noggit.sql, MapView.cpp, and 24 more files... | further work on project system

This commit is contained in:
Skarn
2022-03-12 23:07:56 +03:00
parent c7c6562645
commit b6e6bc1442
24 changed files with 776 additions and 653 deletions

View File

@@ -1,7 +1,7 @@
CREATE TABLE `UIDs` (
`MapId` int(11) NOT NULL,
`_map_id` int(11) NOT NULL,
`UID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `UIDs`
ADD PRIMARY KEY (`MapId`);
ADD PRIMARY KEY (`_map_id`);

View File

@@ -2531,7 +2531,7 @@ void MapView::createGUI()
setupHelpMenu();
setupHotkeys();
connect(_main_window, &Noggit::Ui::Windows::NoggitWindow::exit_prompt_opened, this, &MapView::on_exit_prompt);
connect(_main_window, &Noggit::Ui::Windows::NoggitWindow::exitPromptOpened, this, &MapView::on_exit_prompt);
set_editing_mode (editing_mode::ground);
}

View File

@@ -10,7 +10,7 @@
#include <noggit/tool_enums.hpp>
#include <noggit/ui/ObjectEditor.h>
#include <noggit/ui/MinimapCreator.hpp>
#include <noggit/ui/uid_fix_window.hpp>
#include <noggit/ui/UidFixWindow.hpp>
#include <noggit/unsigned_int_property.hpp>
#include <noggit/ui/tools/AssetBrowser/Ui/AssetBrowser.hpp>
#include <noggit/ui/tools/ViewportGizmo/ViewportGizmo.hpp>

View File

@@ -5,10 +5,12 @@
#include <memory>
#include <blizzard-archive-library/include/CASCArchive.hpp>
#include <blizzard-archive-library/include/ClientFile.hpp>
#include <blizzard-archive-library/include/Exception.hpp>
#include <blizzard-database-library/include/BlizzardDatabase.h>
#include <noggit/application/Configuration/NoggitApplicationConfiguration.hpp>
#include <noggit/ui/windows/downloadFileDialog/DownloadFileDialog.h>
#include <QJsonDocument>
#include <QMessageBox>
#include <QJsonObject>
#include <QFile>
#include <filesystem>
@@ -149,12 +151,12 @@ namespace Noggit::Project
class ApplicationProject
{
std::shared_ptr<NoggitProject> _activeProject;
std::shared_ptr<NoggitProject> _active_project;
std::shared_ptr<Application::NoggitApplicationConfiguration> _configuration;
public:
ApplicationProject(std::shared_ptr<Application::NoggitApplicationConfiguration> configuration)
{
_activeProject = nullptr;
_active_project = nullptr;
_configuration = configuration;
}
@@ -178,14 +180,14 @@ namespace Noggit::Project
std::shared_ptr<NoggitProject> loadProject(std::filesystem::path const& project_path)
{
auto project_reader = ApplicationProjectReader();
ApplicationProjectReader project_reader{};
auto project = project_reader.readProject(project_path);
assert(project.has_value());
std::string dbd_file_directory = _configuration->ApplicationDatabaseDefinitionsPath;
auto client_build = BlizzardDatabaseLib::Structures::Build("3.3.5.12340");
BlizzardDatabaseLib::Structures::Build client_build("3.3.5.12340");
auto client_archive_version = BlizzardArchive::ClientVersion::WOTLK;
auto client_archive_locale = BlizzardArchive::Locale::AUTO;
if (project->projectVersion == ProjectVersion::SL)
@@ -203,9 +205,17 @@ namespace Noggit::Project
}
project->ClientDatabase = std::make_shared<BlizzardDatabaseLib::BlizzardDatabase>(dbd_file_directory, client_build);
project->ClientData = std::make_shared<BlizzardArchive::ClientData>(
project->ClientPath, client_archive_version, client_archive_locale, project_path.generic_string());
try
{
project->ClientData = std::make_shared<BlizzardArchive::ClientData>(
project->ClientPath, client_archive_version, client_archive_locale, project_path.generic_string());
}
catch (BlizzardArchive::Exceptions::Locale::LocaleNotFoundError& e)
{
QMessageBox::critical(nullptr, "Error", "The client does not appear to be valid.");
return {};
}
return std::make_shared<NoggitProject>(project.value());
}

View File

@@ -15,7 +15,7 @@ namespace Noggit::Project
{
for (const auto& entry : std::filesystem::directory_iterator(project_path))
{
if (entry.path().extension() == std::string(".noggitproj"))
if (entry.path().extension() == ".noggitproj")
{
QFile input_file(QString::fromStdString(entry.path().generic_string()));
input_file.open(QIODevice::ReadOnly);

View File

@@ -1,6 +1,6 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include <noggit/ui/uid_fix_window.hpp>
#include <noggit/ui/UidFixWindow.hpp>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QFormLayout>
@@ -12,7 +12,7 @@ namespace Noggit
{
namespace Ui
{
uid_fix_window::uid_fix_window ( glm::vec3 pos
UidFixWindow::UidFixWindow (glm::vec3 pos
, math::degrees camera_pitch
, math::degrees camera_yaw
)

View File

@@ -20,12 +20,12 @@ namespace Noggit
{
namespace Ui
{
class uid_fix_window : public QDialog
class UidFixWindow : public QDialog
{
Q_OBJECT
public:
uid_fix_window (glm::vec3 pos, math::degrees camera_pitch, math::degrees camera_yaw);
UidFixWindow (glm::vec3 pos, math::degrees camera_pitch, math::degrees camera_yaw);
signals:
void fix_uid ( glm::vec3 pos

View File

@@ -248,7 +248,7 @@ MapCreationWizard::MapCreationWizard(std::shared_ptr<Project::NoggitProject> pro
});
_connection = connect(reinterpret_cast<Noggit::Ui::Windows::NoggitWindow*>(parent),
QOverload<int>::of(&Noggit::Ui::Windows::NoggitWindow::map_selected)
QOverload<int>::of(&Noggit::Ui::Windows::NoggitWindow::mapSelected)
, [&] (int index)
{
selectMap(index);

View File

@@ -8,7 +8,7 @@
#include <noggit/MapView.h>
#include <noggit/ui/windows/settingsPanel/SettingsPanel.h>
#include <noggit/ui/minimap_widget.hpp>
#include <noggit/ui/uid_fix_window.hpp>
#include <noggit/ui/UidFixWindow.hpp>
#include <noggit/uid_storage.hpp>
#include <noggit/ui/tools/MapCreationWizard/Ui/MapCreationWizard.hpp>
#include <noggit/ui/FontAwesome.hpp>
@@ -37,9 +37,9 @@
#include <noggit/application/Utils.hpp>
#ifdef USE_MYSQL_UID_STORAGE
#include <mysql/mysql.h>
#include <mysql/mysql.h>
#include <QtCore/QSettings>
#include <QtCore/QSettings>
#endif
#include "revision.h"
@@ -50,349 +50,328 @@
namespace Noggit::Ui::Windows
{
NoggitWindow::NoggitWindow(std::shared_ptr<Noggit::Application::NoggitApplicationConfiguration> application,
std::shared_ptr<Noggit::Project::NoggitProject> project)
: QMainWindow (nullptr)
, _null_widget (new QWidget (this))
NoggitWindow::NoggitWindow(std::shared_ptr<Noggit::Application::NoggitApplicationConfiguration> application,
std::shared_ptr<Noggit::Project::NoggitProject> project)
: QMainWindow(nullptr)
, _null_widget(new QWidget(this))
, _applicationConfiguration(application)
, _project(project)
{
std::stringstream title;
title << "Noggit - " << STRPRODUCTVER;
setWindowTitle(QString::fromStdString(title.str()));
setWindowIcon(QIcon(":/icon"));
if (project->projectVersion == Project::ProjectVersion::WOTLK)
{
std::stringstream title;
title << "Noggit - " << STRPRODUCTVER;
setWindowTitle (QString::fromStdString (title.str()));
setWindowIcon (QIcon (":/icon"));
if(project->projectVersion == Project::ProjectVersion::WOTLK)
{
OpenDBs(project->ClientData);
}
setCentralWidget (_null_widget);
_about = new about(this);
_settings = new settings(this);
_menuBar = menuBar();
QSettings settings;
if (!settings.value("systemWindowFrame", true).toBool())
{
QWidget *widget = new QWidget(this);
::Ui::TitleBar* titleBarWidget = setupFramelessWindow(widget, this, minimumSize(), maximumSize(), true);
titleBarWidget->horizontalLayout->insertWidget(2, _menuBar);
setMenuWidget(widget);
}
_menuBar->setNativeMenuBar(settings.value("nativeMenubar", true).toBool());
auto file_menu (_menuBar->addMenu ("&Noggit"));
auto settings_action (file_menu->addAction ("Settings"));
QObject::connect ( settings_action, &QAction::triggered
, [&]
{
_settings->show();
}
);
auto about_action (file_menu->addAction ("About"));
QObject::connect ( about_action, &QAction::triggered
, [&]
{
_about->show();
}
);
auto mapmenu_action (file_menu->addAction ("Exit"));
QObject::connect ( mapmenu_action, &QAction::triggered
, [this]
{
close();
}
);
_menuBar->adjustSize();
_buildMapListComponent = std::make_unique<Component::BuildMapListComponent>();
build_menu();
OpenDBs(project->ClientData);
}
void NoggitWindow::check_uid_then_enter_map
( glm::vec3 pos
, math::degrees camera_pitch
, math::degrees camera_yaw
, bool from_bookmark
)
{
QSettings settings;
#ifdef USE_MYSQL_UID_STORAGE
bool use_mysql = settings.value("project/mysql/enabled", false).toBool();
setCentralWidget(_null_widget);
if ((use_myqsl && mysql::hasMaxUIDStoredDB(_world->getMapID()))
|| uid_storage::hasMaxUIDStored(_world->getMapID())
)
_about = new about(this);
_settings = new settings(this);
_menuBar = menuBar();
QSettings settings;
if (!settings.value("systemWindowFrame", true).toBool())
{
QWidget* widget = new QWidget(this);
::Ui::TitleBar* titleBarWidget = setupFramelessWindow(widget, this, minimumSize(), maximumSize(), true);
titleBarWidget->horizontalLayout->insertWidget(2, _menuBar);
setMenuWidget(widget);
}
_menuBar->setNativeMenuBar(settings.value("nativeMenubar", true).toBool());
auto file_menu(_menuBar->addMenu("&Noggit"));
auto settings_action(file_menu->addAction("Settings"));
QObject::connect(settings_action, &QAction::triggered, [&]
{
_settings->show();
}
);
auto about_action(file_menu->addAction("About"));
QObject::connect(about_action, &QAction::triggered, [&]
{
_about->show();
}
);
auto mapmenu_action(file_menu->addAction("Exit"));
QObject::connect(mapmenu_action, &QAction::triggered, [this]
{
close();
}
);
_menuBar->adjustSize();
_buildMapListComponent = std::make_unique<Component::BuildMapListComponent>();
buildMenu();
}
void NoggitWindow::check_uid_then_enter_map
(glm::vec3 pos, math::degrees camera_pitch, math::degrees camera_yaw, bool from_bookmark
)
{
QSettings settings;
#ifdef USE_MYSQL_UID_STORAGE
bool use_mysql = settings.value("project/mysql/enabled", false).toBool();
if ((use_myqsl && mysql::hasMaxUIDStoredDB(_world->getMapID()))
|| uid_storage::hasMaxUIDStored(_world->getMapID())
)
{
_world->mapIndex.loadMaxUID();
enterMapAt(pos, camera_pitch, camera_yaw, from_bookmark);
}
#else
if (uid_storage::hasMaxUIDStored(_world->getMapID()))
{
if (settings.value("uid_startup_check", true).toBool())
{
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix_mode::max_uid, from_bookmark);
} else
{
_world->mapIndex.loadMaxUID();
enterMapAt(pos, camera_pitch, camera_yaw, from_bookmark);
}
#else
if (uid_storage::hasMaxUIDStored(_world->getMapID()))
{
if (settings.value("uid_startup_check", true).toBool())
{
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix_mode::max_uid, from_bookmark);
}
else
{
_world->mapIndex.loadMaxUID();
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix_mode::none, from_bookmark);
}
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix_mode::none, from_bookmark);
}
}
#endif
else
{
auto uidFixWindow(new uid_fix_window(pos, camera_pitch, camera_yaw));
uidFixWindow->show();
connect( uidFixWindow
, &Noggit::Ui::uid_fix_window::fix_uid
, [this, from_bookmark]
( glm::vec3 pos
, math::degrees camera_pitch
, math::degrees camera_yaw
, uid_fix_mode uid_fix
)
{
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix, from_bookmark);
}
);
}
}
void NoggitWindow::enterMapAt ( glm::vec3 pos
, math::degrees camera_pitch
, math::degrees camera_yaw
, uid_fix_mode uid_fix
, bool from_bookmark
)
else
{
_map_creation_wizard->destroyFakeWorld();
_map_view = (new MapView (camera_yaw, camera_pitch, pos, this,_project, std::move (_world), uid_fix, from_bookmark));
connect(_map_view, &MapView::uid_fix_failed, [this]() { prompt_uid_fix_failure(); });
connect(_settings, &settings::saved, [this]() { if (_map_view) _map_view->onSettingsSave(); });
auto uid_fix_window(new UidFixWindow(pos, camera_pitch, camera_yaw));
uid_fix_window->show();
_stack_widget->addWidget(_map_view);
_stack_widget->setCurrentIndex(1);
map_loaded = true;
}
void NoggitWindow::loadMap(int mapID)
{
_minimap->world (nullptr);
_world.reset();
auto table = _project->ClientDatabase->LoadTable("Map", readFileAsIMemStream);
auto record = table.Record(mapID);
_world = std::make_unique<World>(record.Columns["Directory"].Value, mapID, Noggit::NoggitRenderContext::MAP_VIEW);
_minimap->world(_world.get());
_project->ClientDatabase->UnloadTable("Map");
emit map_selected(mapID);
}
void NoggitWindow::build_menu()
{
_stack_widget = new StackedWidget(this);
_stack_widget->setAutoResize(true);
setCentralWidget(_stack_widget);
auto widget (new QWidget(_stack_widget));
_stack_widget->addWidget(widget);
auto layout (new QHBoxLayout (widget));
layout->setAlignment(Qt::AlignLeft);
QListWidget* bookmarks_table (new QListWidget (widget));
_continents_table = new QListWidget (widget);
QObject::connect (_continents_table, &QListWidget::itemClicked
, [this] (QListWidgetItem* item)
{
loadMap (item->data (Qt::UserRole).toInt());
}
);
QTabWidget* entry_points_tabs (new QTabWidget (widget));
entry_points_tabs->addTab (_continents_table, "Maps");
entry_points_tabs->addTab (bookmarks_table, "Bookmarks");
entry_points_tabs->setFixedWidth(300);
layout->addWidget (entry_points_tabs);
_buildMapListComponent->BuildMapList(this);
qulonglong bookmark_index (0);
for (auto entry : _project->Bookmarks)
{
auto item = new QListWidgetItem(bookmarks_table);
auto bookmark_data = Widget::MapListBookmarkData();
bookmark_data.MapName = QString::fromStdString(entry.name);
bookmark_data.Position = entry.position;
auto map_bookmark_item = new Widget::MapListBookmarkItem(bookmark_data, bookmarks_table);
item->setData (Qt::UserRole, QVariant (bookmark_index++));
item->setSizeHint(map_bookmark_item->minimumSizeHint());
bookmarks_table->setItemWidget(item, map_bookmark_item);
}
QObject::connect ( bookmarks_table, &QListWidget::itemDoubleClicked
, [this] (QListWidgetItem* item)
{
auto& entry (_project->Bookmarks.at (item->data (Qt::UserRole).toInt()));
_world.reset();
for (DBCFile::Iterator it = gMapDB.begin(); it != gMapDB.end(); ++it)
{
if (it->getInt(MapDB::MapID) == entry.map_id)
{
_world = std::make_unique<World> (it->getString(MapDB::InternalName),
entry.map_id, Noggit::NoggitRenderContext::MAP_VIEW);
check_uid_then_enter_map ( entry.position
, math::degrees (entry.camera_pitch)
, math::degrees (entry.camera_yaw)
, true
);
return;
}
}
}
);
_minimap = new minimap_widget (this);
_minimap->draw_boundaries (true);
//_minimap->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QObject::connect( _minimap, &minimap_widget::map_clicked
, [this] (::glm::vec3 const& pos)
{
check_uid_then_enter_map(pos, math::degrees(30.f), math::degrees(90.f));
}
);
auto right_side = new QTabWidget(this);
auto minimap_holder = new QScrollArea(this);
minimap_holder->setWidgetResizable(true);
minimap_holder->setAlignment(Qt::AlignCenter);
minimap_holder->setWidget(_minimap);
right_side->addTab(minimap_holder, "Enter map");
minimap_holder->setAccessibleName("main_menu_minimap_holder");
_map_creation_wizard = new Noggit::Ui::Tools::MapCreationWizard::Ui::MapCreationWizard(_project,this);
_map_wizard_connection = connect(_map_creation_wizard, &Noggit::Ui::Tools::MapCreationWizard::Ui::MapCreationWizard::map_dbc_updated
,[=]
{
_buildMapListComponent->BuildMapList(this);
}
connect(uid_fix_window, &Noggit::Ui::UidFixWindow::fix_uid, [this, from_bookmark]
(glm::vec3 pos, math::degrees camera_pitch, math::degrees camera_yaw, uid_fix_mode uid_fix
)
{
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix, from_bookmark);
}
);
}
}
right_side->addTab(_map_creation_wizard, "Edit map");
void
NoggitWindow::enterMapAt(glm::vec3 pos, math::degrees camera_pitch, math::degrees camera_yaw, uid_fix_mode uid_fix,
bool from_bookmark
)
{
_map_creation_wizard->destroyFakeWorld();
_map_view = (new MapView(camera_yaw, camera_pitch, pos, this, _project, std::move(_world), uid_fix, from_bookmark));
connect(_map_view, &MapView::uid_fix_failed, [this]()
{ promptUidFixFailure(); });
connect(_settings, &settings::saved, [this]()
{ if (_map_view) _map_view->onSettingsSave(); });
layout->addWidget(right_side);
_stack_widget->addWidget(_map_view);
_stack_widget->setCurrentIndex(1);
//setCentralWidget (_stack_widget);
map_loaded = true;
_minimap->adjustSize();
}
void NoggitWindow::loadMap(int map_id)
{
_minimap->world(nullptr);
_world.reset();
auto table = _project->ClientDatabase->LoadTable("Map", readFileAsIMemStream);
auto record = table.Record(map_id);
_world = std::make_unique<World>(record.Columns["Directory"].Value, map_id, Noggit::NoggitRenderContext::MAP_VIEW);
_minimap->world(_world.get());
_project->ClientDatabase->UnloadTable("Map");
emit mapSelected(map_id);
}
void NoggitWindow::buildMenu()
{
_stack_widget = new StackedWidget(this);
_stack_widget->setAutoResize(true);
setCentralWidget(_stack_widget);
auto widget(new QWidget(_stack_widget));
_stack_widget->addWidget(widget);
auto layout(new QHBoxLayout(widget));
layout->setAlignment(Qt::AlignLeft);
QListWidget* bookmarks_table(new QListWidget(widget));
_continents_table = new QListWidget(widget);
QObject::connect(_continents_table, &QListWidget::itemClicked, [this](QListWidgetItem* item)
{
loadMap(item->data(Qt::UserRole).toInt());
}
);
QTabWidget* entry_points_tabs(new QTabWidget(widget));
entry_points_tabs->addTab(_continents_table, "Maps");
entry_points_tabs->addTab(bookmarks_table, "Bookmarks");
entry_points_tabs->setFixedWidth(300);
layout->addWidget(entry_points_tabs);
_buildMapListComponent->buildMapList(this);
qulonglong bookmark_index(0);
for (auto entry: _project->Bookmarks)
{
auto item = new QListWidgetItem(bookmarks_table);
auto bookmark_data = Widget::MapListBookmarkData();
bookmark_data.MapName = QString::fromStdString(entry.name);
bookmark_data.Position = entry.position;
auto map_bookmark_item = new Widget::MapListBookmarkItem(bookmark_data, bookmarks_table);
item->setData(Qt::UserRole, QVariant(bookmark_index++));
item->setSizeHint(map_bookmark_item->minimumSizeHint());
bookmarks_table->setItemWidget(item, map_bookmark_item);
}
void NoggitWindow::closeEvent (QCloseEvent* event)
QObject::connect(bookmarks_table, &QListWidget::itemDoubleClicked, [this](QListWidgetItem* item)
{
auto& entry(_project->Bookmarks.at(item->data(Qt::UserRole).toInt()));
_world.reset();
for (DBCFile::Iterator it = gMapDB.begin(); it != gMapDB.end(); ++it)
{
if (it->getInt(MapDB::MapID) == entry.map_id)
{
_world = std::make_unique<World>(it->getString(MapDB::InternalName),
entry.map_id, Noggit::NoggitRenderContext::MAP_VIEW);
check_uid_then_enter_map(entry.position, math::degrees(entry.camera_pitch), math::degrees(entry.camera_yaw),
true
);
return;
}
}
}
);
_minimap = new minimap_widget(this);
_minimap->draw_boundaries(true);
//_minimap->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
QObject::connect(_minimap, &minimap_widget::map_clicked, [this](::glm::vec3 const& pos)
{
check_uid_then_enter_map(pos, math::degrees(30.f), math::degrees(90.f));
}
);
auto right_side = new QTabWidget(this);
auto minimap_holder = new QScrollArea(this);
minimap_holder->setWidgetResizable(true);
minimap_holder->setAlignment(Qt::AlignCenter);
minimap_holder->setWidget(_minimap);
right_side->addTab(minimap_holder, "Enter map");
minimap_holder->setAccessibleName("main_menu_minimap_holder");
_map_creation_wizard = new Noggit::Ui::Tools::MapCreationWizard::Ui::MapCreationWizard(_project, this);
_map_wizard_connection = connect(_map_creation_wizard,
&Noggit::Ui::Tools::MapCreationWizard::Ui::MapCreationWizard::map_dbc_updated, [=]
{
_buildMapListComponent->buildMapList(this);
}
);
right_side->addTab(_map_creation_wizard, "Edit map");
layout->addWidget(right_side);
//setCentralWidget (_stack_widget);
_minimap->adjustSize();
}
void NoggitWindow::closeEvent(QCloseEvent* event)
{
if (map_loaded)
{
if (map_loaded)
{
event->ignore();
prompt_exit(event);
}
else
{
event->ignore();
promptExit(event);
} else
{
event->accept();
}
}
void NoggitWindow::handleEventMapListContextMenuPinMap(int mapId, std::string MapName)
{
_project->pinMap(mapId, MapName);
_buildMapListComponent->buildMapList(this);
}
void NoggitWindow::handleEventMapListContextMenuUnpinMap(int mapId)
{
_project->unpinMap(mapId);
_buildMapListComponent->buildMapList(this);
}
void NoggitWindow::promptExit(QCloseEvent* event)
{
emit exitPromptOpened();
QMessageBox prompt;
prompt.setIcon(QMessageBox::Warning);
prompt.setWindowFlags(Qt::WindowStaysOnTopHint);
prompt.setText("Exit?");
prompt.setInformativeText("Any unsaved changes will be lost.");
prompt.addButton("Exit", QMessageBox::DestructiveRole);
prompt.addButton("Return to menu", QMessageBox::AcceptRole);
prompt.setDefaultButton(prompt.addButton("Cancel", QMessageBox::RejectRole));
prompt.setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
prompt.exec();
switch (prompt.buttonRole(prompt.clickedButton()))
{
case QMessageBox::AcceptRole:
_stack_widget->setCurrentIndex(0);
_stack_widget->removeLast();
delete _map_view;
_map_view = nullptr;
_minimap->world(nullptr);
map_loaded = false;
break;
case QMessageBox::DestructiveRole:
Noggit::Ui::Tools::ViewportManager::ViewportManager::unloadAll();
setCentralWidget(_null_widget = new QWidget(this));
event->accept();
}
break;
default:
event->ignore();
break;
}
}
void NoggitWindow::HandleEventMapListContextMenuPinMap(int mapId, std::string MapName)
{
_project->pinMap(mapId, MapName);
_buildMapListComponent->BuildMapList(this);
}
void NoggitWindow::promptUidFixFailure()
{
_stack_widget->setCurrentIndex(0);
void NoggitWindow::HandleEventMapListContextMenuUnpinMap(int mapId)
{
_project->unpinMap(mapId);
_buildMapListComponent->BuildMapList(this);
}
void NoggitWindow::prompt_exit(QCloseEvent* event)
{
emit exit_prompt_opened();
QMessageBox prompt;
prompt.setIcon (QMessageBox::Warning);
prompt.setWindowFlags(Qt::WindowStaysOnTopHint);
prompt.setText ("Exit?");
prompt.setInformativeText ("Any unsaved changes will be lost.");
prompt.addButton ("Exit", QMessageBox::DestructiveRole);
prompt.addButton ("Return to menu", QMessageBox::AcceptRole);
prompt.setDefaultButton (prompt.addButton ("Cancel", QMessageBox::RejectRole));
prompt.setWindowFlags (Qt::CustomizeWindowHint | Qt::WindowTitleHint);
prompt.exec();
switch (prompt.buttonRole(prompt.clickedButton()))
{
case QMessageBox::AcceptRole:
_stack_widget->setCurrentIndex(0);
_stack_widget->removeLast();
delete _map_view;
_map_view = nullptr;
_minimap->world (nullptr);
map_loaded = false;
break;
case QMessageBox::DestructiveRole:
Noggit::Ui::Tools::ViewportManager::ViewportManager::unloadAll();
setCentralWidget(_null_widget = new QWidget(this));
event->accept();
break;
default:
event->ignore();
break;
}
}
void NoggitWindow::prompt_uid_fix_failure()
{
_stack_widget->setCurrentIndex(0);
QMessageBox::critical
( nullptr
, "UID fix failed"
, "The UID fix couldn't be done because some models were missing or fucked up.\n"
"The models are listed in the log file."
, QMessageBox::Ok
QMessageBox::critical
(nullptr, "UID fix failed", "The UID fix couldn't be done because some models were missing or fucked up.\n"
"The models are listed in the log file.", QMessageBox::Ok
);
}
}
}

View File

@@ -4,7 +4,7 @@
#include <math/trig.hpp>
#include <noggit/World.h>
#include <noggit/MapView.h>
#include <noggit/ui/uid_fix_window.hpp>
#include <noggit/ui/UidFixWindow.hpp>
#include <noggit/ui/tools/MapCreationWizard/Ui/MapCreationWizard.hpp>
#include <noggit/application/Configuration/NoggitApplicationConfiguration.hpp>
#include <noggit/ui/windows/noggitWindow/components/BuildMapListComponent.hpp>
@@ -36,16 +36,16 @@ namespace Noggit::Ui::Windows
NoggitWindow(std::shared_ptr<Noggit::Application::NoggitApplicationConfiguration> application,
std::shared_ptr<Noggit::Project::NoggitProject> project);
void prompt_exit(QCloseEvent* event);
void prompt_uid_fix_failure();
void promptExit(QCloseEvent* event);
void promptUidFixFailure();
QMenuBar* _menuBar;
std::unordered_set<QWidget*> displayed_widgets;
void build_menu();
void buildMenu();
signals:
void exit_prompt_opened();
void map_selected(int map_id);
void exitPromptOpened();
void mapSelected(int map_id);
private:
@@ -54,11 +54,11 @@ namespace Noggit::Ui::Windows
std::shared_ptr<Project::NoggitProject> _project;
void HandleEventMapListContextMenuPinMap(int mapId, std::string MapName);
void HandleEventMapListContextMenuUnpinMap(int mapId);
void handleEventMapListContextMenuPinMap(int mapId, std::string MapName);
void handleEventMapListContextMenuUnpinMap(int mapId);
void loadMap (int mapID);
void loadMap (int map_id);
void check_uid_then_enter_map ( glm::vec3 pos
, math::degrees camera_pitch

View File

@@ -10,108 +10,107 @@
using namespace Noggit::Ui::Component;
void BuildMapListComponent::BuildMapList(Noggit::Ui::Windows::NoggitWindow* parent)
void BuildMapListComponent::buildMapList(Noggit::Ui::Windows::NoggitWindow* parent)
{
parent->_continents_table->clear();
const auto& table = std::string("Map");
auto mapTable = parent->_project->ClientDatabase->LoadTable(table, readFileAsIMemStream);
auto map_table = parent->_project->ClientDatabase->LoadTable(table, readFileAsIMemStream);
auto iterator = mapTable.Records();
auto pinnedMaps = std::vector<Widget::MapListData>();
auto iterator = map_table.Records();
auto pinned_maps = std::vector<Widget::MapListData>();
auto maps = std::vector<Widget::MapListData>();
while (iterator.HasRecords())
{
auto record = iterator.Next();
auto mapListData = Widget::MapListData();
Widget::MapListData map_list_data{};
for (auto const& value : record.Columns["MapName_lang"].Values)
for (auto const& value: record.Columns["MapName_lang"].Values)
{
if (value.empty())
continue;
mapListData.MapName = QString::fromUtf8(value.c_str());
map_list_data.map_name = QString::fromUtf8(value.c_str());
break;
}
mapListData.MapId = record.RecordId;
mapListData.MapTypeId = std::stoi(record.Columns["InstanceType"].Value);
mapListData.ExpansionId = std::stoi(record.Columns["ExpansionID"].Value);
map_list_data.map_id = record.RecordId;
map_list_data.map_type_id = std::stoi(record.Columns["InstanceType"].Value);
map_list_data.expansion_id = std::stoi(record.Columns["ExpansionID"].Value);
if (mapListData.MapTypeId < 0 || mapListData.MapTypeId > 5 || !World::IsEditableWorld(record))
if (map_list_data.map_type_id < 0 || map_list_data.map_type_id > 5 || !World::IsEditableWorld(record))
continue;
auto projectPinnedMaps = parent->_project->PinnedMaps;
auto project_pinned_maps = parent->_project->PinnedMaps;
auto pinnedMapFound = std::find_if(std::begin(projectPinnedMaps), std::end(projectPinnedMaps), [&](Project::NoggitProjectPinnedMap pinnedMap)
{
return pinnedMap.MapId == mapListData.MapId;
});
auto pinned_map_found = std::find_if(std::begin(project_pinned_maps), std::end(project_pinned_maps),
[&](Project::NoggitProjectPinnedMap pinned_map)
{
return pinned_map.MapId == map_list_data.map_id;
});
if (pinnedMapFound != std::end(projectPinnedMaps))
if (pinned_map_found != std::end(project_pinned_maps))
{
mapListData.Pinned = true;
pinnedMaps.push_back(mapListData);
}
else
map_list_data.pinned = true;
pinned_maps.push_back(map_list_data);
} else
{
maps.push_back(mapListData);
maps.push_back(map_list_data);
}
}
pinnedMaps.insert(pinnedMaps.end(), maps.begin(), maps.end());
pinned_maps.insert(pinned_maps.end(), maps.begin(), maps.end());
for(auto const & map : pinnedMaps)
for (auto const& map: pinned_maps)
{
auto mapListItem = new Widget::MapListItem(map, parent->_continents_table);
auto map_list_item = new Widget::MapListItem(map, parent->_continents_table);
auto item = new QListWidgetItem(parent->_continents_table);
if (map.Pinned)
if (map.pinned)
{
QObject::connect(mapListItem, &QListWidget::customContextMenuRequested,
[=](const QPoint& pos)
{
QMenu contextMenu(mapListItem->tr("Context menu"), mapListItem);
QObject::connect(map_list_item, &QListWidget::customContextMenuRequested,
[=](const QPoint& pos)
{
QMenu context_menu(map_list_item->tr("Context menu"), map_list_item);
QAction action1("Unpin Map", mapListItem);
auto icon = QIcon();
icon.addPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16, 16)));
action1.setIcon(icon);
QAction action_1("Unpin Map", map_list_item);
auto icon = QIcon();
icon.addPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16, 16)));
action_1.setIcon(icon);
QObject::connect(&action1, &QAction::triggered, [=]()
{
parent->HandleEventMapListContextMenuUnpinMap(map.MapId);
});
QObject::connect(&action_1, &QAction::triggered, [=]()
{
parent->handleEventMapListContextMenuUnpinMap(map.map_id);
});
contextMenu.addAction(&action1);
contextMenu.exec(mapListItem->mapToGlobal(pos));
});
}
else
context_menu.addAction(&action_1);
context_menu.exec(map_list_item->mapToGlobal(pos));
});
} else
{
QObject::connect(mapListItem, &QListWidget::customContextMenuRequested,
[=](const QPoint& pos)
{
QMenu contextMenu(mapListItem->tr("Context menu"), mapListItem);
QAction action1("Pin Map", mapListItem);
auto icon = QIcon();
icon.addPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16, 16)));
action1.setIcon(icon);
QObject::connect(map_list_item, &QListWidget::customContextMenuRequested,
[=](const QPoint& pos)
{
QMenu context_menu(map_list_item->tr("Context menu"), map_list_item);
QAction action_1("Pin Map", map_list_item);
auto icon = QIcon();
icon.addPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16, 16)));
action_1.setIcon(icon);
QObject::connect(&action1, &QAction::triggered, [=]()
{
parent->HandleEventMapListContextMenuPinMap(map.MapId, map.MapName.toStdString());
});
QObject::connect(&action_1, &QAction::triggered, [=]()
{
parent->handleEventMapListContextMenuPinMap(map.map_id, map.map_name.toStdString());
});
contextMenu.addAction(&action1);
contextMenu.exec(mapListItem->mapToGlobal(pos));
});
context_menu.addAction(&action_1);
context_menu.exec(map_list_item->mapToGlobal(pos));
});
}
item->setSizeHint(mapListItem->minimumSizeHint());
item->setData(Qt::UserRole, QVariant(map.MapId));
parent->_continents_table->setItemWidget(item, mapListItem);
item->setSizeHint(map_list_item->minimumSizeHint());
item->setData(Qt::UserRole, QVariant(map.map_id));
parent->_continents_table->setItemWidget(item, map_list_item);
}
parent->_project->ClientDatabase->UnloadTable(table);

View File

@@ -14,11 +14,11 @@ namespace Noggit::Ui::Component
{
friend class Noggit::Ui::Windows::NoggitWindow;
public:
void BuildMapList(Noggit::Ui::Windows::NoggitWindow* parent);
void buildMapList(Noggit::Ui::Windows::NoggitWindow* parent);
private:
void BuildPinMapContextMenu(const QPoint& pos);
void BuildUnPinMapContextMenu(const QPoint& pos);
void buildPinMapContextMenu(const QPoint& pos);
void buildUnPinMapContextMenu(const QPoint& pos);
};
}
#endif //NOGGIT_COMPONENT_BUILD_MAP_LIST_HPP

View File

@@ -4,118 +4,118 @@
namespace Noggit::Ui::Widget
{
MapListItem::MapListItem(const MapListData& data, QWidget* parent = nullptr) : QWidget(parent)
MapListItem::MapListItem(const MapListData& data, QWidget* parent = nullptr) : QWidget(parent)
{
auto layout = QGridLayout();
QIcon icon;
if (data.expansion_id == 0)
icon = QIcon(":/icon-classic");
if (data.expansion_id == 1)
icon = QIcon(":/icon-burning");
if (data.expansion_id == 2)
icon = QIcon(":/icon-wrath");
if (data.expansion_id == 3)
icon = QIcon(":/icon-cata");
if (data.expansion_id == 4)
icon = QIcon(":/icon-panda");
if (data.expansion_id == 5)
icon = QIcon(":/icon-warlords");
if (data.expansion_id == 6)
icon = QIcon(":/icon-legion");
if (data.expansion_id == 7)
icon = QIcon(":/icon-battle");
if (data.expansion_id == 8)
icon = QIcon(":/icon-shadow");
_map_icon = new QLabel("", parent);
_map_icon->setPixmap(icon.pixmap(QSize(32, 32)));
_map_icon->setGeometry(0, 0, 32, 32);
_map_icon->setObjectName("project-icon-label");
_map_icon->setStyleSheet("QLabel#project-icon-label { font-size: 12px; padding: 0px;}");
auto project_name = toCamelCase(QString(data.map_name));
_map_name = new QLabel(project_name, parent);
_map_name->setGeometry(32, 0, 300, 20);
_map_name->setObjectName("project-title-label");
_map_name->setStyleSheet("QLabel#project-title-label { font-size: 12px; }");
_map_id = new QLabel(QString::number(data.map_id), parent);
_map_id->setGeometry(32, 15, 300, 20);
_map_id->setObjectName("project-information");
_map_id->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto directory_effect = new QGraphicsOpacityEffect(this);
directory_effect->setOpacity(0.5);
_map_id->setGraphicsEffect(directory_effect);
_map_id->setAutoFillBackground(true);
auto instance_type = QString("Unknown");
if (data.map_type_id == 0)
instance_type = QString("Continent");
if (data.map_type_id == 1)
instance_type = QString("Dungeon");
if (data.map_type_id == 2)
instance_type = QString("Raid");
if (data.map_type_id == 3)
instance_type = QString("Battleground");
if (data.map_type_id == 4)
instance_type = QString("Arena");
if (data.map_type_id == 5)
instance_type = QString("Scenario");
_map_instance_type = new QLabel(instance_type, this);
_map_instance_type->setGeometry(150, 15, 125, 20);
_map_instance_type->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
_map_instance_type->setObjectName("project-information");
_map_instance_type->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto last_edited_effect = new QGraphicsOpacityEffect(this);
last_edited_effect->setOpacity(0.5);
_map_instance_type->setGraphicsEffect(last_edited_effect);
_map_instance_type->setAutoFillBackground(true);
if (data.pinned)
{
auto layout = QGridLayout();
_map_pinned_label = new QLabel("", this);
_map_pinned_label->setPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16, 16)));
_map_pinned_label->setGeometry(150, 0, 125, 20);
_map_pinned_label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
_map_pinned_label->setObjectName("project-pinned");
_map_pinned_label->setStyleSheet("QLabel#project-pinned { font-size: 10px; }");
QIcon icon;
if (data.ExpansionId == 0)
icon = QIcon(":/icon-classic");
if (data.ExpansionId == 1)
icon = QIcon(":/icon-burning");
if (data.ExpansionId == 2)
icon = QIcon(":/icon-wrath");
if (data.ExpansionId == 3)
icon = QIcon(":/icon-cata");
if (data.ExpansionId == 4)
icon = QIcon(":/icon-panda");
if (data.ExpansionId == 5)
icon = QIcon(":/icon-warlords");
if (data.ExpansionId == 6)
icon = QIcon(":/icon-legion");
if (data.ExpansionId == 7)
icon = QIcon(":/icon-battle");
if (data.ExpansionId == 8)
icon = QIcon(":/icon-shadow");
auto colour = new QGraphicsColorizeEffect(this);
colour->setColor(QColor(255, 204, 0));
colour->setStrength(1.0f);
map_icon = new QLabel("", parent);
map_icon->setPixmap(icon.pixmap(QSize(32, 32)));
map_icon->setGeometry(0, 0, 32, 32);
map_icon->setObjectName("project-icon-label");
map_icon->setStyleSheet("QLabel#project-icon-label { font-size: 12px; padding: 0px;}");
_map_pinned_label->setGraphicsEffect(colour);
_map_pinned_label->setAutoFillBackground(true);
auto projectName = toCamelCase(QString(data.MapName));
map_name = new QLabel(projectName, parent);
map_name->setGeometry(32, 0, 300, 20);
map_name->setObjectName("project-title-label");
map_name->setStyleSheet("QLabel#project-title-label { font-size: 12px; }");
map_id = new QLabel(QString::number(data.MapId), parent);
map_id->setGeometry(32, 15, 300, 20);
map_id->setObjectName("project-information");
map_id->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto directoryEffect = new QGraphicsOpacityEffect(this);
directoryEffect->setOpacity(0.5);
map_id->setGraphicsEffect(directoryEffect);
map_id->setAutoFillBackground(true);
auto instanceType = QString("Unknown");
if (data.MapTypeId == 0)
instanceType = QString("Continent");
if (data.MapTypeId == 1)
instanceType = QString("Dungeon");
if (data.MapTypeId == 2)
instanceType = QString("Raid");
if (data.MapTypeId == 3)
instanceType = QString("Battleground");
if (data.MapTypeId == 4)
instanceType = QString("Arena");
if (data.MapTypeId == 5)
instanceType = QString("Scenario");
map_instance_type = new QLabel( instanceType,this);
map_instance_type->setGeometry(150, 15, 125, 20);
map_instance_type->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
map_instance_type->setObjectName("project-information");
map_instance_type->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto lastEditedEffect = new QGraphicsOpacityEffect(this);
lastEditedEffect->setOpacity(0.5);
map_instance_type->setGraphicsEffect(lastEditedEffect);
map_instance_type->setAutoFillBackground(true);
if(data.Pinned)
{
map_pinned_label = new QLabel("", this);
map_pinned_label->setPixmap(FontAwesomeIcon(FontAwesome::star).pixmap(QSize(16,16)));
map_pinned_label->setGeometry(150, 0, 125, 20);
map_pinned_label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
map_pinned_label->setObjectName("project-pinned");
map_pinned_label->setStyleSheet("QLabel#project-pinned { font-size: 10px; }");
auto colour = new QGraphicsColorizeEffect(this);
colour->setColor(QColor(255,204,0));
colour->setStrength(1.0f);
map_pinned_label->setGraphicsEffect(colour);
map_pinned_label->setAutoFillBackground(true);
layout.addWidget(map_pinned_label);
}
setContextMenuPolicy(Qt::CustomContextMenu);
layout.addWidget(map_icon);
layout.addWidget(map_name);
layout.addWidget(map_id);
layout.addWidget(map_instance_type);
setLayout(layout.layout());
layout.addWidget(_map_pinned_label);
}
QSize MapListItem::minimumSizeHint() const
{
return QSize(300, 32);
}
setContextMenuPolicy(Qt::CustomContextMenu);
QString MapListItem::toCamelCase(const QString& s)
{
QStringList parts = s.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
layout.addWidget(_map_icon);
layout.addWidget(_map_name);
layout.addWidget(_map_id);
layout.addWidget(_map_instance_type);
setLayout(layout.layout());
}
return parts.join(" ");
}
QSize MapListItem::minimumSizeHint() const
{
return QSize(300, 32);
}
QString MapListItem::toCamelCase(const QString& s)
{
QStringList parts = s.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
return parts.join(" ");
}
}

View File

@@ -13,23 +13,23 @@ namespace Noggit::Ui::Widget
{
struct MapListData
{
QString MapName;
int MapId;
int MapTypeId;
int ExpansionId;
bool Pinned;
QString map_name;
int map_id;
int map_type_id;
int expansion_id;
bool pinned;
};
class MapListItem : public QWidget
{
Q_OBJECT
private:
QLabel* map_icon;
QLabel* map_name;
QLabel* map_id;
QLabel* map_instance_type;
QLabel* map_pinned_label;
int _maxWidth;
QLabel* _map_icon;
QLabel* _map_name;
QLabel* _map_id;
QLabel* _map_instance_type;
QLabel* _map_pinned_label;
int _max_width;
public:
MapListItem(const MapListData& data, QWidget* parent);
QSize minimumSizeHint() const override;

View File

@@ -2,9 +2,14 @@
#include <ui_NoggitProjectCreationDialog.h>
#include <QFileDialog>
#include <QSettings>
#include <QMessageBox>
NoggitProjectCreationDialog::NoggitProjectCreationDialog(ProjectInformation& project_information, QWidget* parent) :
QDialog(parent), ui(new ::Ui::NoggitProjectCreationDialog), _projectInformation(project_information)
#include <filesystem>
NoggitProjectCreationDialog::NoggitProjectCreationDialog(ProjectInformation& project_information, QWidget* parent)
: QDialog(parent)
, ui(new ::Ui::NoggitProjectCreationDialog)
, _project_information(project_information)
{
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
@@ -36,39 +41,68 @@ NoggitProjectCreationDialog::NoggitProjectCreationDialog(ProjectInformation& pro
auto default_path = settings.value("project/game_path").toString();
ui->clientPathField->setText(default_path);
QString folder_name = QFileDialog::getExistingDirectory(this
, "Select Client Directory"
, default_path
, QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
QString folder_name = QFileDialog::getExistingDirectory(this, "Select Client Directory", default_path,
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
ui->clientPathField->setText(folder_name);
}
);
QObject::connect(ui->projectPathField_browse, &QPushButton::clicked, [this]
{
QString folder_name = QFileDialog::getExistingDirectory(this
, "Select Project Directory"
, "/"
, QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
QString folder_name = QFileDialog::getExistingDirectory(this, "Select Project Directory", "/",
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
ui->projectPathField->setText(folder_name);
}
);
QObject::connect(ui->button_ok, &QPushButton::clicked, [&]
{
project_information.ProjectName = ui->projectName->text().toStdString();
project_information.GameClientPath = ui->clientPathField->text().toStdString();
project_information.GameClientVersion = ui->project_expansion->currentText().toStdString();
project_information.ProjectPath = ui->projectPathField->text().toStdString();
project_information.project_name = ui->projectName->text().toStdString();
if (project_information.project_name.empty())
{
QMessageBox::critical(this, "Error", "Project must have a name.");
return;
}
project_information.game_client_path = ui->clientPathField->text().toStdString();
if (project_information.game_client_path.empty())
{
QMessageBox::critical(this, "Error", "Game client path is empty.");
return;
}
std::filesystem::path game_path(project_information.game_client_path);
if (!std::filesystem::exists(game_path))
{
QMessageBox::critical(this, "Error", "Game client path does not exist.");
return;
}
project_information.project_path = ui->projectPathField->text().toStdString();
std::filesystem::path project_path(project_information.project_path);
if (project_path.empty())
{
QMessageBox::critical(this, "Error", "Project path is empty.");
return;
}
project_information.game_client_version = ui->project_expansion->currentText().toStdString();
done(QDialog::Accepted);
close();
}
);
QObject::connect(ui->button_cancel, &QPushButton::clicked, [&]
{
done(QDialog::Rejected);
close();
}
);

View File

@@ -10,10 +10,10 @@ class NoggitProjectCreationDialog;
struct ProjectInformation
{
std::string ProjectName;
std::string ProjectPath;
std::string GameClientPath;
std::string GameClientVersion;
std::string project_name;
std::string project_path;
std::string game_client_path;
std::string game_client_version;
};
class NoggitProjectCreationDialog : public QDialog
@@ -26,7 +26,7 @@ public:
private:
::Ui::NoggitProjectCreationDialog*ui;
ProjectInformation& _projectInformation;
ProjectInformation& _project_information;
};
#endif //NOGGIT_PROJECT_CREATION_DIALOG_HPP

View File

@@ -29,20 +29,27 @@ NoggitProjectSelectionWindow::NoggitProjectSelectionWindow(Noggit::Application::
_settings = new Noggit::Ui::settings(this);
_create_project_component = std::make_unique<Component::CreateProjectComponent>();
_load_project_component = std::make_unique<Component::LoadProjectComponent>();
Component::RecentProjectsComponent::buildRecentProjectsList(this);
QObject::connect(_ui->button_create_new_project, &QPushButton::clicked, [=, this]
{
auto project_reference = ProjectInformation();
auto project_creation_dialog = NoggitProjectCreationDialog(project_reference, this);
ProjectInformation project_reference;
NoggitProjectCreationDialog project_creation_dialog(project_reference, this);
QObject::connect(&project_creation_dialog, &QDialog::finished, [&project_reference, this](int result)
{
if (result != QDialog::Accepted)
return;
Component::CreateProjectComponent::createProject(this, project_reference);
Component::RecentProjectsComponent::buildRecentProjectsList(this);
});
project_creation_dialog.exec();
project_creation_dialog.setFixedSize(project_creation_dialog.size());
_create_project_component->createProject(this, project_reference);
Component::RecentProjectsComponent::buildRecentProjectsList(this);
}
);
@@ -72,7 +79,14 @@ NoggitProjectSelectionWindow::NoggitProjectSelectionWindow(Noggit::Application::
auto application_configuration = _noggit_application->getConfiguration();
auto application_projects_folder_path = std::filesystem::path(application_configuration->ApplicationProjectPath);
auto application_project_service = Noggit::Project::ApplicationProject(application_configuration);
auto project_to_launch = application_project_service.loadProject(filepath.parent_path());
if (!project_to_launch)
{
return;
}
Noggit::Application::NoggitApplication::instance()->setClientData(project_to_launch->ClientData);
Noggit::Project::CurrentProject::initialize(project_to_launch.get());
@@ -90,6 +104,9 @@ NoggitProjectSelectionWindow::NoggitProjectSelectionWindow(Noggit::Application::
{
auto selected_project = _load_project_component->loadProject(this);
if (!selected_project)
return;
Noggit::Project::CurrentProject::initialize(selected_project.get());
_project_selection_page = std::make_unique<Noggit::Ui::Windows::NoggitWindow>(
@@ -119,6 +136,7 @@ void NoggitProjectSelectionWindow::handleContextMenuProjectListItemDelete(std::s
switch (prompt.buttonRole(prompt.clickedButton()))
{
case QMessageBox::AcceptRole:
Component::RecentProjectsComponent::registerProjectRemove(project_path);
std::filesystem::remove_all(project_path);
break;
case QMessageBox::DestructiveRole:
@@ -129,6 +147,33 @@ void NoggitProjectSelectionWindow::handleContextMenuProjectListItemDelete(std::s
Component::RecentProjectsComponent::buildRecentProjectsList(this);
}
void NoggitProjectSelectionWindow::handleContextMenuProjectListItemForget(std::string const& project_path)
{
QMessageBox prompt;
prompt.setWindowIcon(QIcon(":/icon"));
prompt.setWindowTitle("Forget Project");
prompt.setIcon(QMessageBox::Warning);
prompt.setWindowFlags(Qt::WindowStaysOnTopHint);
prompt.setText("Data on the disk will not be removed. Continue?.");
prompt.addButton("Accept", QMessageBox::AcceptRole);
prompt.setDefaultButton(prompt.addButton("Cancel", QMessageBox::RejectRole));
prompt.setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint);
prompt.exec();
switch (prompt.buttonRole(prompt.clickedButton()))
{
case QMessageBox::AcceptRole:
Component::RecentProjectsComponent::registerProjectRemove(project_path);
break;
case QMessageBox::DestructiveRole:
default:
break;
}
Component::RecentProjectsComponent::buildRecentProjectsList(this);
}
NoggitProjectSelectionWindow::~NoggitProjectSelectionWindow()
{
delete _ui;

View File

@@ -46,10 +46,10 @@ namespace Noggit::Ui::Windows
Noggit::Ui::settings* _settings;
std::unique_ptr<Noggit::Ui::Windows::NoggitWindow> _project_selection_page;
std::unique_ptr<Component::CreateProjectComponent> _create_project_component;
std::unique_ptr<Component::LoadProjectComponent> _load_project_component;
void handleContextMenuProjectListItemDelete(std::string const& project_path);
void handleContextMenuProjectListItemForget(std::string const& project_path);
};
}
#endif // NOGGITREDPROJECTPAGE_H

View File

@@ -11,18 +11,23 @@ void CreateProjectComponent::createProject(Noggit::Ui::Windows::NoggitProjectSel
auto application_configuration = parent->_noggit_application->getConfiguration();
auto application_project_service = Noggit::Project::ApplicationProject(application_configuration);
if (!std::filesystem::exists(project_information.ProjectPath)
|| std::filesystem::is_empty(project_information.ProjectPath))
if (std::filesystem::exists(project_information.project_path))
{
application_project_service.createProject(project_information.ProjectPath,
project_information.GameClientPath,
project_information.GameClientVersion,
project_information.ProjectName);
for (const auto& entry : std::filesystem::directory_iterator(project_information.project_path))
{
if (entry.path().extension() == ".noggitproj")
{
QMessageBox::critical(parent, "Error", "Selected already contains an existing project.");
return;
}
}
}
application_project_service.createProject(project_information.project_path,
project_information.game_client_path,
project_information.game_client_version,
project_information.project_name);
RecentProjectsComponent::registerProjectChange(project_information.project_path);
RecentProjectsComponent::registerProjectChange(project_information.ProjectPath);
}
else
{
QMessageBox::critical(parent, "Error", "Selected directory is not empty.");
}
}

View File

@@ -21,7 +21,8 @@ namespace Noggit::Ui::Component
auto project = application_project_service.loadProject(project_path);
//This to not be static, but its hard to remove
Noggit::Application::NoggitApplication::instance()->setClientData(project->ClientData);
if (project)
Noggit::Application::NoggitApplication::instance()->setClientData(project->ClientData);
return project;
}

View File

@@ -34,10 +34,10 @@ void RecentProjectsComponent::buildRecentProjectsList(Noggit::Ui::Windows::Noggi
continue;
auto project_data = Noggit::Ui::Widget::ProjectListItemData();
project_data.ProjectVersion = project->projectVersion;
project_data.ProjectDirectory = QString::fromStdString(project_path.generic_string());
project_data.ProjectName = QString::fromStdString(project->ProjectName);
project_data.ProjectLastEdited = QDateTime::currentDateTime().date().toString();
project_data.project_version = project->projectVersion;
project_data.project_directory = QString::fromStdString(project_path.generic_string());
project_data.project_name = QString::fromStdString(project->ProjectName);
project_data.project_last_edited = QDateTime::currentDateTime().date().toString();
auto project_list_item = new Noggit::Ui::Widget::ProjectListItem(project_data, parent->_ui->listView);
@@ -50,16 +50,25 @@ void RecentProjectsComponent::buildRecentProjectsList(Noggit::Ui::Windows::Noggi
QMenu context_menu(project_list_item->tr("Context menu"), project_list_item);
QAction action_1("Delete Project", project_list_item);
auto icon = QIcon();
icon.addPixmap(FontAwesomeIcon(FontAwesome::trash).pixmap(QSize(16, 16)));
action_1.setIcon(icon);
action_1.setIcon(FontAwesomeIcon(FontAwesome::trash).pixmap(QSize(16, 16)));
QObject::connect(&action_1, &QAction::triggered, [=]()
{
parent->handleContextMenuProjectListItemDelete(project_data.ProjectDirectory.toStdString());
parent->handleContextMenuProjectListItemDelete(project_data.project_directory.toStdString());
});
context_menu.addAction(&action_1);
QAction action_2("Forget Project", project_list_item);
action_2.setIcon(FontAwesomeIcon(FontAwesome::cloud).pixmap(QSize(16, 16)));
QObject::connect(&action_2, &QAction::triggered, [=]()
{
parent->handleContextMenuProjectListItemForget(project_data.project_directory.toStdString());
});
context_menu.addAction(&action_2);
context_menu.exec(project_list_item->mapToGlobal(pos));
});
@@ -111,3 +120,43 @@ void RecentProjectsComponent::registerProjectChange(std::string const& project_p
settings.sync();
}
void RecentProjectsComponent::registerProjectRemove(std::string const& project_path)
{
QSettings settings;
settings.sync();
QList<QString> recent_projects;
std::size_t size = settings.beginReadArray("recent_projects");
for (int i = 0; i < size; ++i)
{
settings.setArrayIndex(i);
recent_projects.append(settings.value("project_path").toString());
}
settings.endArray();
auto it = std::find(recent_projects.begin(), recent_projects.end(), project_path.c_str());
if (it != recent_projects.end())
{
recent_projects.erase(it);
size--;
settings.remove("recent_projects");
settings.beginWriteArray("recent_projects");
for (int i = 0; i < size; ++i)
{
settings.setArrayIndex(i);
settings.setValue("project_path", recent_projects[i]);
}
settings.endArray();
settings.sync();
}
}

View File

@@ -17,6 +17,7 @@ namespace Noggit::Ui::Component
public:
static void buildRecentProjectsList(Noggit::Ui::Windows::NoggitProjectSelectionWindow* parent);
static void registerProjectChange(std::string const& project_path);
static void registerProjectRemove(std::string const& project_path);
};

View File

@@ -2,89 +2,89 @@
namespace Noggit::Ui::Widget
{
ProjectListItem::ProjectListItem(const ProjectListItemData& data, QWidget* parent = nullptr) : QWidget(parent)
{
auto layout = QGridLayout();
ProjectListItem::ProjectListItem(const ProjectListItemData& data, QWidget* parent = nullptr) : QWidget(parent)
{
auto layout = QGridLayout();
QIcon icon;
if (data.ProjectVersion == Project::ProjectVersion::WOTLK)
icon = QIcon(":/icon-wrath");
if (data.ProjectVersion == Project::ProjectVersion::SL)
icon = QIcon(":/icon-shadow");
project_version_icon = new QLabel("", parent);
project_version_icon->setPixmap(icon.pixmap(QSize(48, 48)));
project_version_icon->setGeometry(0, 5, 64, 48);
QIcon icon;
if (data.project_version == Project::ProjectVersion::WOTLK)
icon = QIcon(":/icon-wrath");
if (data.project_version == Project::ProjectVersion::SL)
icon = QIcon(":/icon-shadow");
_project_version_icon = new QLabel("", parent);
_project_version_icon->setPixmap(icon.pixmap(QSize(48, 48)));
_project_version_icon->setGeometry(0, 5, 64, 48);
auto maxWidth = parent->sizeHint().width();
auto max_width = parent->sizeHint().width();
auto projectName = toCamelCase(QString(data.ProjectName));
project_name_label = new QLabel(projectName, parent);
project_name_label->setGeometry(45, 5, maxWidth, 20);
project_name_label->setObjectName("project-title-label");
project_name_label->setStyleSheet("QLabel#project-title-label { font-size: 15px; }");
auto project_name = toCamelCase(QString(data.project_name));
_project_name_label = new QLabel(project_name, parent);
_project_name_label->setGeometry(45, 5, max_width, 20);
_project_name_label->setObjectName("project-title-label");
_project_name_label->setStyleSheet("QLabel#project-title-label { font-size: 15px; }");
project_directory_label = new QLabel(data.ProjectDirectory, parent);
project_directory_label->setGeometry(48, 20, maxWidth, 20);
project_directory_label->setObjectName("project-information");
project_directory_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
_project_directory_label = new QLabel(data.project_directory, parent);
_project_directory_label->setGeometry(48, 20, max_width, 20);
_project_directory_label->setObjectName("project-information");
_project_directory_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto directoryEffect = new QGraphicsOpacityEffect(this);
directoryEffect->setOpacity(0.5);
auto directory_effect = new QGraphicsOpacityEffect(this);
directory_effect->setOpacity(0.5);
project_directory_label->setGraphicsEffect(directoryEffect);
project_directory_label->setAutoFillBackground(true);
_project_directory_label->setGraphicsEffect(directory_effect);
_project_directory_label->setAutoFillBackground(true);
QString version;
if (data.ProjectVersion == Project::ProjectVersion::WOTLK)
version = "Wrath Of The Lich King";
if (data.ProjectVersion == Project::ProjectVersion::SL)
version = "Shadowlands";
QString version;
if (data.project_version == Project::ProjectVersion::WOTLK)
version = "Wrath Of The Lich King";
if (data.project_version == Project::ProjectVersion::SL)
version = "Shadowlands";
project_version_label = new QLabel(version, parent);
project_version_label->setGeometry(48, 35, maxWidth, 20);
project_version_label->setObjectName("project-information");
project_version_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
_project_version_label = new QLabel(version, parent);
_project_version_label->setGeometry(48, 35, max_width, 20);
_project_version_label->setObjectName("project-information");
_project_version_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto versionEffect = new QGraphicsOpacityEffect(this);
versionEffect->setOpacity(0.5);
auto version_effect = new QGraphicsOpacityEffect(this);
version_effect->setOpacity(0.5);
project_version_label->setGraphicsEffect(versionEffect);
project_version_label->setAutoFillBackground(true);
_project_version_label->setGraphicsEffect(version_effect);
_project_version_label->setAutoFillBackground(true);
project_last_edited_label = new QLabel(data.ProjectLastEdited, parent);
project_last_edited_label->setGeometry(maxWidth, 35, 125, 20);
project_last_edited_label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
project_last_edited_label->setObjectName("project-information");
project_last_edited_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
auto lastEditedEffect = new QGraphicsOpacityEffect(this);
lastEditedEffect->setOpacity(0.5);
_project_last_edited_label = new QLabel(data.project_last_edited, parent);
_project_last_edited_label->setGeometry(max_width, 35, 125, 20);
_project_last_edited_label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
_project_last_edited_label->setObjectName("project-information");
_project_last_edited_label->setStyleSheet("QLabel#project-information { font-size: 10px; }");
project_last_edited_label->setGraphicsEffect(lastEditedEffect);
project_last_edited_label->setAutoFillBackground(true);
auto last_edited_effect = new QGraphicsOpacityEffect(this);
last_edited_effect->setOpacity(0.5);
setContextMenuPolicy(Qt::CustomContextMenu);
_project_last_edited_label->setGraphicsEffect(last_edited_effect);
_project_last_edited_label->setAutoFillBackground(true);
layout.addWidget(project_version_icon);
layout.addWidget(project_name_label);
layout.addWidget(project_directory_label);
layout.addWidget(project_version_label);
layout.addWidget(project_last_edited_label);
setLayout(layout.layout());
}
setContextMenuPolicy(Qt::CustomContextMenu);
QSize ProjectListItem::minimumSizeHint() const
{
return QSize(125, 55);
}
layout.addWidget(_project_version_icon);
layout.addWidget(_project_name_label);
layout.addWidget(_project_directory_label);
layout.addWidget(_project_version_label);
layout.addWidget(_project_last_edited_label);
setLayout(layout.layout());
}
QString ProjectListItem::toCamelCase(const QString& s)
{
QStringList parts = s.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
QSize ProjectListItem::minimumSizeHint() const
{
return QSize(125, 55);
}
return parts.join(" ");
}
QString ProjectListItem::toCamelCase(const QString& s)
{
QStringList parts = s.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.size(); ++i)
parts[i].replace(0, 1, parts[i][0].toUpper());
return parts.join(" ");
}
}

View File

@@ -13,21 +13,21 @@ namespace Noggit::Ui::Widget
{
struct ProjectListItemData
{
QString ProjectName;
QString ProjectDirectory;
QString ProjectLastEdited;
Project::ProjectVersion ProjectVersion;
QString project_name;
QString project_directory;
QString project_last_edited;
Project::ProjectVersion project_version;
};
class ProjectListItem : public QWidget
{
Q_OBJECT
private:
QLabel* project_version_icon;
QLabel* project_name_label;
QLabel* project_directory_label;
QLabel* project_version_label;
QLabel* project_last_edited_label;
QLabel* _project_version_icon;
QLabel* _project_name_label;
QLabel* _project_directory_label;
QLabel* _project_version_label;
QLabel* _project_last_edited_label;
public:
ProjectListItem(const ProjectListItemData& data, QWidget* parent);
QSize minimumSizeHint() const override;