[nostalgia/studio] Flesh out editor tab system and cleanup studio::Project to use exceptions instead of returning error codes
This commit is contained in:
parent
aa34239eb5
commit
f634c208ac
@ -1,7 +1,3 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.11)
|
|
||||||
|
|
||||||
project(nostalgia-studio)
|
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.11)
|
|
||||||
|
|
||||||
project(NostalgiaStudio)
|
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
|
@ -114,6 +114,10 @@ QString OxFSFile::name() const {
|
|||||||
return m_path.mid(m_path.lastIndexOf("/") + 1);
|
return m_path.mid(m_path.lastIndexOf("/") + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString OxFSFile::path() const {
|
||||||
|
return "/" + m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// OxFSModel
|
// OxFSModel
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@ class OxFSFile {
|
|||||||
OxFSFile *parentItem();
|
OxFSFile *parentItem();
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
|
||||||
|
QString path() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OxFSModel: public QAbstractItemModel {
|
class OxFSModel: public QAbstractItemModel {
|
||||||
|
@ -22,4 +22,8 @@ QWidget *Plugin::makeEditor(QString, const Context*) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<EditorMaker> Plugin::editors(const Context*) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QWizardPage>
|
#include <QWizardPage>
|
||||||
|
|
||||||
@ -22,14 +19,15 @@
|
|||||||
namespace nostalgia::studio {
|
namespace nostalgia::studio {
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
|
QString appName;
|
||||||
|
QString orgName;
|
||||||
QWidget *tabParent = nullptr;
|
QWidget *tabParent = nullptr;
|
||||||
const Project *project = nullptr;
|
const Project *project = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EditorMaker {
|
struct EditorMaker {
|
||||||
virtual ~EditorMaker() = default;
|
QStringList fileTypes;
|
||||||
|
std::function<QWidget*(QString)> make;
|
||||||
virtual QWidget *make(QString path, const Context *ctx) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Plugin {
|
class Plugin {
|
||||||
@ -43,6 +41,8 @@ class Plugin {
|
|||||||
|
|
||||||
virtual QWidget *makeEditor(QString path, const Context *ctx);
|
virtual QWidget *makeEditor(QString path, const Context *ctx);
|
||||||
|
|
||||||
|
virtual QVector<EditorMaker> editors(const Context *ctx);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,6 @@ namespace nostalgia::studio {
|
|||||||
|
|
||||||
using namespace ox;
|
using namespace ox;
|
||||||
|
|
||||||
QString Project::ROM_FILE = "/ROM.oxfs";
|
|
||||||
|
|
||||||
Project::Project(QString path): m_fs(path.toUtf8()) {
|
Project::Project(QString path): m_fs(path.toUtf8()) {
|
||||||
qDebug() << "Project:" << path;
|
qDebug() << "Project:" << path;
|
||||||
m_path = path;
|
m_path = path;
|
||||||
@ -29,54 +27,35 @@ void Project::create() {
|
|||||||
QDir().mkpath(m_path);
|
QDir().mkpath(m_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Project::openRomFs() {
|
|
||||||
QFile file(m_path + ROM_FILE);
|
|
||||||
auto buffSize = file.size();
|
|
||||||
auto buff = std::make_unique<uint8_t[]>(buffSize);
|
|
||||||
if (file.exists()) {
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
if (file.read(reinterpret_cast<char*>(buff.get()), buffSize) > 0) {
|
|
||||||
m_fsBuff = std::move(buff);
|
|
||||||
if (m_fs.valid()) {
|
|
||||||
return OxError(0);
|
|
||||||
} else {
|
|
||||||
return OxError(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return OxError(2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return OxError(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error Project::saveRomFs() const {
|
|
||||||
ox::Error err(0);
|
|
||||||
//QFile file(m_path + ROM_FILE);
|
|
||||||
//err |= file.open(QIODevice::WriteOnly) == false;
|
|
||||||
//err |= file.write((const char*) m_fsBuff.get(), m_fs.size()) == -1;
|
|
||||||
//file.close();
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
PassThroughFS *Project::romFs() {
|
PassThroughFS *Project::romFs() {
|
||||||
return &m_fs;
|
return &m_fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Project::mkdir(QString path) const {
|
void Project::mkdir(QString path) const {
|
||||||
auto err = m_fs.mkdir(path.toUtf8().data(), true);
|
oxThrowError(m_fs.mkdir(path.toUtf8().data(), true));
|
||||||
emit updated(path);
|
emit updated(path);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error Project::write(QString path, uint8_t *buff, size_t buffLen) const {
|
ox::FileStat Project::stat(QString path) const {
|
||||||
auto err = m_fs.write(path.toUtf8().data(), buff, buffLen);
|
auto [s, e] = m_fs.stat(path.toUtf8().data());
|
||||||
|
oxThrowError(e);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Project::exists(QString path) const {
|
||||||
|
return m_fs.stat(path.toUtf8().data()).error == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Project::writeBuff(QString path, uint8_t *buff, size_t buffLen) const {
|
||||||
|
oxThrowError(m_fs.write(path.toUtf8().data(), buff, buffLen));
|
||||||
emit updated(path);
|
emit updated(path);
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::ValErr<ox::FileStat> Project::stat(QString path) const {
|
std::vector<uint8_t> Project::loadBuff(QString path) const {
|
||||||
return m_fs.stat(path.toUtf8().data());
|
std::vector<uint8_t> buff(stat(path).size);
|
||||||
|
const auto csPath = path.toUtf8();
|
||||||
|
oxThrowError(m_fs.read(csPath.data(), buff.data(), buff.size()));
|
||||||
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,7 @@ class Project: public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString ROM_FILE;
|
|
||||||
|
|
||||||
QString m_path = "";
|
QString m_path = "";
|
||||||
std::unique_ptr<uint8_t[]> m_fsBuff;
|
|
||||||
mutable ox::PassThroughFS m_fs;
|
mutable ox::PassThroughFS m_fs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -34,23 +31,27 @@ class Project: public QObject {
|
|||||||
|
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
ox::Error openRomFs();
|
|
||||||
|
|
||||||
ox::Error saveRomFs() const;
|
|
||||||
|
|
||||||
ox::PassThroughFS *romFs();
|
ox::PassThroughFS *romFs();
|
||||||
|
|
||||||
ox::Error mkdir(QString path) const;
|
void mkdir(QString path) const;
|
||||||
|
|
||||||
ox::Error write(QString path, uint8_t *buff, size_t buffLen) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a MetalClaw object to the project at the given path.
|
* Writes a MetalClaw object to the project at the given path.
|
||||||
*/
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error writeObj(QString path, T *obj) const;
|
void writeObj(QString path, T *obj) const;
|
||||||
|
|
||||||
ox::ValErr<ox::FileStat> stat(QString path) const;
|
template<typename T>
|
||||||
|
std::unique_ptr<T> loadObj(QString path) const;
|
||||||
|
|
||||||
|
ox::FileStat stat(QString path) const;
|
||||||
|
|
||||||
|
bool exists(QString path) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void writeBuff(QString path, uint8_t *buff, size_t buffLen) const;
|
||||||
|
|
||||||
|
std::vector<uint8_t> loadBuff(QString path) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updated(QString path) const;
|
void updated(QString path) const;
|
||||||
@ -58,19 +59,22 @@ class Project: public QObject {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ox::Error Project::writeObj(QString path, T *obj) const {
|
void Project::writeObj(QString path, T *obj) const {
|
||||||
auto buffLen = 1024 * 1024 * 10;
|
std::vector<uint8_t> buff(10 * ox::units::MB, 0);
|
||||||
QByteArray buff(buffLen, 0);
|
|
||||||
|
|
||||||
// write MetalClaw
|
// write MetalClaw
|
||||||
size_t mcSize = 0;
|
size_t mcSize = 0;
|
||||||
oxReturnError(ox::writeMC(reinterpret_cast<uint8_t*>(buff.data()), buffLen, obj, &mcSize));
|
oxThrowError(ox::writeMC(buff.data(), buff.size(), obj, &mcSize));
|
||||||
// write to FS
|
// write to FS
|
||||||
oxReturnError(write(path, reinterpret_cast<uint8_t*>(buff.data()), mcSize));
|
writeBuff(path, buff.data(), mcSize);
|
||||||
|
|
||||||
emit updated(path);
|
emit updated(path);
|
||||||
|
}
|
||||||
|
|
||||||
return OxError(0);
|
template<typename T>
|
||||||
|
std::unique_ptr<T> Project::loadObj(QString path) const {
|
||||||
|
auto obj = std::make_unique<T>();
|
||||||
|
auto buff = loadBuff(path);
|
||||||
|
oxThrowError(ox::readMC<T>(buff.data(), buff.size(), obj.get()));
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,16 @@ MainWindow::MainWindow(QString profilePath) {
|
|||||||
move(screenSize.width() * (1 - sizePct) / 2, screenSize.height() * (1 - sizePct) / 2);
|
move(screenSize.width() * (1 - sizePct) / 2, screenSize.height() * (1 - sizePct) / 2);
|
||||||
|
|
||||||
setWindowTitle(m_profile.appName);
|
setWindowTitle(m_profile.appName);
|
||||||
|
m_ctx.appName = m_profile.appName;
|
||||||
|
m_ctx.orgName = m_profile.orgName;
|
||||||
|
|
||||||
m_tabbar = new QTabBar(this);
|
m_tabs = new QTabWidget(this);
|
||||||
setCentralWidget(m_tabbar);
|
auto tabBar = m_tabs->tabBar();
|
||||||
|
setCentralWidget(m_tabs);
|
||||||
|
m_tabs->setTabsClosable(true);
|
||||||
|
connect(m_tabs, &QTabWidget::tabCloseRequested, this, &MainWindow::closeTab);
|
||||||
|
connect(tabBar, &QTabBar::tabMoved, this, &MainWindow::moveTab);
|
||||||
|
tabBar->setMovable(true);
|
||||||
|
|
||||||
setupMenu();
|
setupMenu();
|
||||||
setupProjectExplorer();
|
setupProjectExplorer();
|
||||||
@ -95,6 +102,12 @@ void MainWindow::loadPlugin(QString pluginPath) {
|
|||||||
auto plugin = qobject_cast<Plugin*>(loader.instance());
|
auto plugin = qobject_cast<Plugin*>(loader.instance());
|
||||||
if (plugin) {
|
if (plugin) {
|
||||||
m_plugins.push_back(plugin);
|
m_plugins.push_back(plugin);
|
||||||
|
auto editorMakers = plugin->editors(&m_ctx);
|
||||||
|
for (const auto &em : editorMakers) {
|
||||||
|
for (const auto &ext : em.fileTypes) {
|
||||||
|
m_editorMakers[ext] = em;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qInfo() << loader.errorString();
|
qInfo() << loader.errorString();
|
||||||
}
|
}
|
||||||
@ -157,6 +170,8 @@ void MainWindow::setupProjectExplorer() {
|
|||||||
m_projectExplorer = new QTreeView(dock);
|
m_projectExplorer = new QTreeView(dock);
|
||||||
m_projectExplorer->header()->hide();
|
m_projectExplorer->header()->hide();
|
||||||
dock->setWidget(m_projectExplorer);
|
dock->setWidget(m_projectExplorer);
|
||||||
|
|
||||||
|
connect(m_projectExplorer, &QTreeView::activated, this, &MainWindow::openFileSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockWidget) {
|
void MainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockWidget) {
|
||||||
@ -190,7 +205,7 @@ QAction *MainWindow::addAction(QMenu *menu, QString text, QString toolTip,
|
|||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::readState(QString) {
|
int MainWindow::readState() {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
QSettings settings(m_profile.orgName, m_profile.appName);
|
QSettings settings(m_profile.orgName, m_profile.appName);
|
||||||
@ -201,17 +216,15 @@ int MainWindow::readState(QString) {
|
|||||||
err |= readJson(json, &m_state);
|
err |= readJson(json, &m_state);
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
err |= openProject(m_state.projectPath);
|
openProject(m_state.projectPath);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::writeState(QString) {
|
void MainWindow::writeState() {
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
// generate JSON for application specific state info
|
// generate JSON for application specific state info
|
||||||
QString json;
|
QString json;
|
||||||
err |= writeJson(&json, &m_state);
|
writeJson(&json, &m_state);
|
||||||
|
|
||||||
QSettings settings(m_profile.orgName, m_profile.appName);
|
QSettings settings(m_profile.orgName, m_profile.appName);
|
||||||
settings.beginGroup("MainWindow");
|
settings.beginGroup("MainWindow");
|
||||||
@ -219,14 +232,40 @@ int MainWindow::writeState(QString) {
|
|||||||
settings.setValue("windowState", saveState());
|
settings.setValue("windowState", saveState());
|
||||||
settings.setValue("json", json);
|
settings.setValue("json", json);
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::openProject(QString projectPath) {
|
/**
|
||||||
auto err = closeProject();
|
* Read open editor tabs for current project.
|
||||||
|
*/
|
||||||
|
QStringList MainWindow::readTabs() {
|
||||||
|
QStringList tabs;
|
||||||
|
QSettings settings(m_profile.orgName, m_profile.appName);
|
||||||
|
settings.beginReadArray("MainWindow/Project:" + m_state.projectPath);
|
||||||
|
auto size = settings.beginReadArray("openEditors");
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
tabs.append(settings.value("filePath").toString());
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
return tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write open editor tabs for current project.
|
||||||
|
*/
|
||||||
|
void MainWindow::writeTabs(QStringList tabs) {
|
||||||
|
QSettings settings(m_profile.orgName, m_profile.appName);
|
||||||
|
settings.beginWriteArray("MainWindow/Project:" + m_state.projectPath + "/openEditors");
|
||||||
|
for (int i = 0; i < tabs.size(); i++) {
|
||||||
|
settings.setArrayIndex(i);
|
||||||
|
settings.setValue("filePath", tabs[i]);
|
||||||
|
}
|
||||||
|
settings.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openProject(QString projectPath) {
|
||||||
|
closeProject();
|
||||||
auto project = new Project(projectPath);
|
auto project = new Project(projectPath);
|
||||||
if (err == 0) {
|
|
||||||
if (m_ctx.project) {
|
if (m_ctx.project) {
|
||||||
delete m_ctx.project;
|
delete m_ctx.project;
|
||||||
m_ctx.project = nullptr;
|
m_ctx.project = nullptr;
|
||||||
@ -234,16 +273,25 @@ int MainWindow::openProject(QString projectPath) {
|
|||||||
m_ctx.project = project;
|
m_ctx.project = project;
|
||||||
m_oxfsView = new OxFSModel(project->romFs());
|
m_oxfsView = new OxFSModel(project->romFs());
|
||||||
m_projectExplorer->setModel(m_oxfsView);
|
m_projectExplorer->setModel(m_oxfsView);
|
||||||
connect(m_ctx.project, SIGNAL(updated(QString)), m_oxfsView, SLOT(updateFile(QString)));
|
connect(m_ctx.project, &Project::updated, m_oxfsView, &OxFSModel::updateFile);
|
||||||
m_importAction->setEnabled(true);
|
m_importAction->setEnabled(true);
|
||||||
m_state.projectPath = projectPath;
|
m_state.projectPath = projectPath;
|
||||||
qInfo() << "Open project:" << projectPath;
|
// reopen tabs
|
||||||
|
auto openTabs = readTabs();
|
||||||
|
for (auto t : openTabs) {
|
||||||
|
openFile(t, true);
|
||||||
}
|
}
|
||||||
return err;
|
qInfo() << "Open project:" << projectPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MainWindow::closeProject() {
|
void MainWindow::closeProject() {
|
||||||
auto err = 0;
|
// delete tabs
|
||||||
|
while (m_tabs->count()) {
|
||||||
|
auto t = m_tabs->widget(0);
|
||||||
|
m_tabs->removeTab(0);
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_ctx.project) {
|
if (m_ctx.project) {
|
||||||
disconnect(m_ctx.project, SIGNAL(updated(QString)), m_oxfsView, SLOT(updateFile(QString)));
|
disconnect(m_ctx.project, SIGNAL(updated(QString)), m_oxfsView, SLOT(updateFile(QString)));
|
||||||
|
|
||||||
@ -261,7 +309,29 @@ int MainWindow::closeProject() {
|
|||||||
m_importAction->setEnabled(false);
|
m_importAction->setEnabled(false);
|
||||||
|
|
||||||
m_state.projectPath = "";
|
m_state.projectPath = "";
|
||||||
return err;
|
}
|
||||||
|
|
||||||
|
void MainWindow::openFile(QString path, bool force) {
|
||||||
|
if (!force && readTabs().contains(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto dotIdx = path.lastIndexOf('.') + 1;
|
||||||
|
if (dotIdx == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto ext = path.mid(dotIdx);
|
||||||
|
const auto lastSlash = path.lastIndexOf('/') + 1;
|
||||||
|
auto tabName = path.mid(lastSlash);
|
||||||
|
if (m_editorMakers.contains(ext)) {
|
||||||
|
auto tab = m_editorMakers[ext].make(path);
|
||||||
|
m_tabs->addTab(tab, tabName);
|
||||||
|
// save new tab to application state
|
||||||
|
auto openTabs = readTabs();
|
||||||
|
if (!openTabs.contains(path)) {
|
||||||
|
openTabs.append(path);
|
||||||
|
}
|
||||||
|
writeTabs(openTabs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onExit() {
|
void MainWindow::onExit() {
|
||||||
@ -271,16 +341,35 @@ void MainWindow::onExit() {
|
|||||||
|
|
||||||
// private slots
|
// private slots
|
||||||
|
|
||||||
int MainWindow::openProject() {
|
void MainWindow::openProject() {
|
||||||
auto projectPath = QFileDialog::getExistingDirectory(this, tr("Select Project Directory..."), QDir::homePath());
|
auto projectPath = QFileDialog::getExistingDirectory(this, tr("Select Project Directory..."), QDir::homePath());
|
||||||
int err = 0;
|
|
||||||
if (projectPath != "") {
|
if (projectPath != "") {
|
||||||
err |= openProject(projectPath);
|
openProject(projectPath);
|
||||||
if (err == 0) {
|
writeState();
|
||||||
err |= writeState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
|
||||||
|
void MainWindow::openFileSlot(QModelIndex file) {
|
||||||
|
auto path = static_cast<OxFSFile*>(file.internalPointer())->path();
|
||||||
|
return openFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::closeTab(int idx) {
|
||||||
|
auto tab = m_tabs->widget(idx);
|
||||||
|
m_tabs->removeTab(idx);
|
||||||
|
delete tab;
|
||||||
|
|
||||||
|
// remove from open tabs list
|
||||||
|
auto tabs = readTabs();
|
||||||
|
tabs.removeAt(idx);
|
||||||
|
writeTabs(tabs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::moveTab(int from, int to) {
|
||||||
|
// move tab in open tabs list
|
||||||
|
auto tabs = readTabs();
|
||||||
|
tabs.move(from, to);
|
||||||
|
writeTabs(tabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showNewWizard() {
|
void MainWindow::showNewWizard() {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTabBar>
|
#include <QTabWidget>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
@ -91,8 +91,9 @@ class MainWindow: public QMainWindow {
|
|||||||
QVector<QPointer<QDockWidget>> m_dockWidgets;
|
QVector<QPointer<QDockWidget>> m_dockWidgets;
|
||||||
QTreeView *m_projectExplorer = nullptr;
|
QTreeView *m_projectExplorer = nullptr;
|
||||||
QVector<Plugin*> m_plugins;
|
QVector<Plugin*> m_plugins;
|
||||||
|
QHash<QString, EditorMaker> m_editorMakers;
|
||||||
QPointer<OxFSModel> m_oxfsView = nullptr;
|
QPointer<OxFSModel> m_oxfsView = nullptr;
|
||||||
QTabBar *m_tabbar = nullptr;
|
QTabWidget *m_tabs = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MainWindow(QString profilePath);
|
MainWindow(QString profilePath);
|
||||||
@ -122,25 +123,47 @@ class MainWindow: public QMainWindow {
|
|||||||
QAction *addAction(QMenu *menu, QString text, QString toolTip,
|
QAction *addAction(QMenu *menu, QString text, QString toolTip,
|
||||||
QKeySequence::StandardKey key, void (*cb)());
|
QKeySequence::StandardKey key, void (*cb)());
|
||||||
|
|
||||||
int readState(QString path = StateFilePath);
|
int readState();
|
||||||
|
|
||||||
int writeState(QString path = StateFilePath);
|
void writeState();
|
||||||
|
|
||||||
int openProject(QString);
|
/**
|
||||||
|
* Read open editor tabs for current project.
|
||||||
|
*/
|
||||||
|
QStringList readTabs();
|
||||||
|
|
||||||
int closeProject();
|
/**
|
||||||
|
* Write open editor tabs for current project.
|
||||||
|
*/
|
||||||
|
void writeTabs(QStringList tabs);
|
||||||
|
|
||||||
|
void openProject(QString);
|
||||||
|
|
||||||
|
void closeProject();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param force forces the reopening of the file even if it is already open
|
||||||
|
*/
|
||||||
|
void openFile(QString path, bool force = false);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onExit();
|
void onExit();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
int openProject();
|
void openProject();
|
||||||
|
|
||||||
|
void openFileSlot(QModelIndex);
|
||||||
|
|
||||||
|
void closeTab(int idx);
|
||||||
|
|
||||||
|
void moveTab(int from, int to);
|
||||||
|
|
||||||
void showNewWizard();
|
void showNewWizard();
|
||||||
|
|
||||||
void showImportWizard();
|
void showImportWizard();
|
||||||
|
|
||||||
void refreshProjectExplorer(QString path);
|
void refreshProjectExplorer(QString path);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ const QString NewWorldWizard::FIELD_WORLD_PATH = "World.WorldPath";
|
|||||||
NewWorldWizard::NewWorldWizard(const Context *ctx) {
|
NewWorldWizard::NewWorldWizard(const Context *ctx) {
|
||||||
addLineEdit(tr("&Name:"), FIELD_WORLD_PATH, "", [this, ctx](QString worldName) {
|
addLineEdit(tr("&Name:"), FIELD_WORLD_PATH, "", [this, ctx](QString worldName) {
|
||||||
worldName = PATH_ZONES + worldName;
|
worldName = PATH_ZONES + worldName;
|
||||||
auto [stat, err] = ctx->project->stat(worldName);
|
auto exists = ctx->project->exists(worldName);
|
||||||
if (err) {
|
if (exists) {
|
||||||
this->showValidationError(tr("World already exists: %1").arg(worldName));
|
this->showValidationError(tr("World already exists: %1").arg(worldName));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,8 @@ QVector<WizardMaker> WorldEditorPlugin::newWizards(const Context *ctx) {
|
|||||||
qDebug() << "creating Region";
|
qDebug() << "creating Region";
|
||||||
auto path = PATH_ZONES + w->field(NewWorldWizard::FIELD_WORLD_PATH).toString();
|
auto path = PATH_ZONES + w->field(NewWorldWizard::FIELD_WORLD_PATH).toString();
|
||||||
Region rgn;
|
Region rgn;
|
||||||
oxReturnError(ctx->project->mkdir(PATH_ZONES));
|
ctx->project->mkdir(PATH_ZONES);
|
||||||
ctx->project->saveRomFs();
|
ctx->project->writeObj(path, &rgn);
|
||||||
oxReturnError(ctx->project->writeObj(path, &rgn));
|
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user