tycho: let Qt handle object lifetimes for us

master
an 2019-07-03 19:23:04 -04:00
parent cd854ef8ea
commit 3e9ca71dc8
6 changed files with 101 additions and 65 deletions

View File

@ -1,7 +1,7 @@
#include "tycho.h"
MapModel::MapModel(QObject *parent) :
AbstractMapModel(parent),
MapModel::MapModel(Project *parent) :
AbstractMapModel(static_cast<QWidget *>(parent)),
ProjectModel()
{
dbgPrintFunc();
@ -12,11 +12,6 @@ MapModel::~MapModel()
dbgPrintFunc();
}
ProjectModelType MapModel::type() const
{
return ProjectModelType::Map;
}
bool MapModel::isDirty() const
{
return AbstractMapModel::isDirty();

View File

@ -1,8 +1,8 @@
#include "tycho.h"
MapProps::MapProps(std::weak_ptr<MapModel> _mapModel, QWidget *parent) :
QDialog(parent),
mapModel(_mapModel)
MapProps::MapProps(Project *parent) :
QDialog(static_cast<QWidget *>(parent)),
mapModel(parent->getMapModel())
{
setupUi(this);
@ -12,8 +12,8 @@ MapProps::MapProps(std::weak_ptr<MapModel> _mapModel, QWidget *parent) :
bbox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
verticalLayout->addWidget(bbox);
connect(bbox, SIGNAL(accepted()), this, SLOT(accept()));
connect(bbox, SIGNAL(rejected()), this, SLOT(reject()));
connect(bbox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(bbox, &QDialogButtonBox::rejected, this, &QDialog::reject);
dbgPrintFunc();
}
@ -23,4 +23,9 @@ MapProps::~MapProps()
dbgPrintFunc();
}
void MapProps::accept()
{
done(QDialog::Accepted);
}
// EOF

View File

@ -1,8 +1,8 @@
#include "tycho.h"
MapView::MapView(std::weak_ptr<MapModel> _mapModel, QWidget *parent) :
QWidget(parent),
mapModel(_mapModel)
MapView::MapView(Project *parent) :
QWidget(static_cast<QWidget *>(parent)),
mapModel(parent->getMapModel())
{
setupUi(this);

View File

@ -22,7 +22,7 @@ Menu::~Menu()
void Menu::mapNew()
{
QScopedPointer proj{new Project(ProjectModelType::Map)};
QScopedPointer proj{new Project(ProjectType::Map)};
addProject(proj.take());
}
@ -40,7 +40,7 @@ void Menu::mapOpen()
"All files (*)"));
if(!fname.isEmpty()) {
QScopedPointer proj{new Project(ProjectModelType::Map)};
QScopedPointer proj{new Project(ProjectType::Map)};
if(proj->getModel()->open(fname)) {
addProject(proj.take());
@ -98,19 +98,22 @@ void Menu::openMapProperties()
{
auto proj = activeProject();
if(proj && proj->getModel()->type() == ProjectModelType::Map) {
MapProps props{proj->getMapModel(), proj};
if(proj && proj->getType() == ProjectType::Map) {
MapProps props{proj};
props.exec();
}
}
void Menu::updateActions()
{
auto proj = activeProject();
bool active = proj != nullptr;
std::optional<ProjectType> active;
actionClose->setEnabled(active);
actionMapProps->setEnabled(active);
if(auto proj = activeProject()) {
active = proj->getType();
}
actionClose->setEnabled(!!active);
actionMapProps->setEnabled(active == ProjectType::Map);
}
void Menu::closeEvent(QCloseEvent *event)

View File

@ -1,9 +1,24 @@
#include "tycho.h"
Project::Project(ProjectModelType type) :
static ProjectModel *makeModel(Project *proj)
{
switch(proj->getType()) {
case ProjectType::Map: return new MapModel(proj);
}
}
static ProjectView *makeView(Project *proj)
{
switch(proj->getType()) {
case ProjectType::Map: return new MapView(proj);
}
}
Project::Project(ProjectType _type) :
QMdiSubWindow(),
model(nullptr),
view(nullptr)
type(_type),
model(makeModel(this)),
view(makeView(this))
{
auto widget = new QWidget(this);
@ -12,15 +27,13 @@ Project::Project(ProjectModelType type) :
setWidget(widget);
setAttribute(Qt::WA_DeleteOnClose);
switch(type) {
case ProjectModelType::Map:
model.reset(new MapModel(this));
view = new MapView(getMapModel(), this);
break;
}
listView->setModel(dynamic_cast<QAbstractItemModel *>(model));
verticalLayout->insertWidget(0, dynamic_cast<QWidget *>(view));
listView->setModel(dynamic_cast<QAbstractItemModel *>(model.get()));
verticalLayout->insertWidget(0, view);
connect(listView,
SIGNAL(doubleClicked(QModelIndex const &)),
dynamic_cast<QObject *>(model),
SLOT(select(QModelIndex const &)));
dbgPrintFunc();
}
@ -30,14 +43,19 @@ Project::~Project()
dbgPrintFunc();
}
std::shared_ptr<ProjectModel> Project::getModel()
ProjectType Project::getType() const
{
return type;
}
ProjectModel *Project::getModel() const
{
return model;
}
std::shared_ptr<MapModel> Project::getMapModel()
MapModel *Project::getMapModel() const
{
return std::dynamic_pointer_cast<MapModel>(model);
return dynamic_cast<MapModel *>(model);
}
void Project::closeEvent(QCloseEvent *event)

View File

@ -3,7 +3,7 @@
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <memory>
#include <optional>
#include <vector>
#include <QApplication>
@ -25,40 +25,48 @@
#include "../ui/ui_menu.h"
#include "../ui/ui_project.h"
// Types ---------------------------------------------------------------------|
class MapModel;
class MapProps;
class MapView;
class Menu;
class Project;
enum class ProjectModelType
enum class ProjectType
{
Map,
};
// Interfaces ----------------------------------------------------------------|
class ProjectModel
{
public:
virtual ~ProjectModel() {}
virtual ProjectModelType type() const = 0;
virtual bool isDirty() const = 0;
virtual bool open(QString const &path) = 0;
virtual bool save() const = 0;
virtual bool saveAs(QString const &path) const = 0;
};
class ProjectView
{
public:
virtual ~ProjectView() {}
};
// Implementations -----------------------------------------------------------|
class MapModel final : public AbstractMapModel, public ProjectModel
{
Q_OBJECT
public:
explicit MapModel(QObject *parent = nullptr);
explicit MapModel(Project *parent);
~MapModel() override;
ProjectModelType type() const override;
bool isDirty() const override;
bool open(QString const &path) override;
bool save() const override;
@ -69,30 +77,32 @@ private:
const override;
};
class MapView final : public QWidget, public ProjectView, private Ui::MapView
{
Q_OBJECT
public:
explicit MapView(Project *parent);
~MapView();
private:
MapModel *const mapModel;
};
// UI ------------------------------------------------------------------------|
class MapProps final : public QDialog, private Ui::MapProps
{
Q_OBJECT
public:
explicit MapProps(std::weak_ptr<MapModel> mapModel,
QWidget *parent = nullptr);
explicit MapProps(Project *parent);
~MapProps();
private:
std::weak_ptr<MapModel> mapModel;
};
class MapView final : public QWidget, private Ui::MapView
{
Q_OBJECT
public:
explicit MapView(std::weak_ptr<MapModel> mapModel,
QWidget *parent = nullptr);
~MapView();
void accept() override;
private:
std::weak_ptr<MapModel> mapModel;
MapModel *const mapModel;
};
class Menu final : public QMainWindow, private Ui::Menu
@ -116,8 +126,9 @@ protected:
void openLicense(QWidget *parent);
private:
Project *activeProject() const;
Project *activeProject() const;
QMdiSubWindow *activeSubWindow() const;
void addProject(Project *proj);
};
@ -126,18 +137,22 @@ class Project final : public QMdiSubWindow, private Ui::Project
Q_OBJECT
public:
explicit Project(ProjectModelType type);
explicit Project(ProjectType type);
~Project();
std::shared_ptr<ProjectModel> getModel();
std::shared_ptr<MapModel> getMapModel();
ProjectType getType() const;
ProjectModel *getModel() const;
MapModel *getMapModel() const;
protected:
void closeEvent(QCloseEvent *event) override;
private:
std::shared_ptr<ProjectModel> model;
QWidget *view;
ProjectType const type;
ProjectModel *const model;
ProjectView *const view;
};
template<typename... VA>