diff --git a/data/layout.xml b/data/layout.xml
index 80dd024..7f73f3f 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -460,6 +460,14 @@
+
+
+
+
+
+
+
+
diff --git a/engine/app_dialogs.cpp b/engine/app_dialogs.cpp
index ba10df2..787602d 100644
--- a/engine/app_dialogs.cpp
+++ b/engine/app_dialogs.cpp
@@ -21,21 +21,46 @@ void App::dialog_newdoc()
dialog->btn_ok->on_click = [this, dialog](Node*)
{
- doc_name = dialog->input->m_string;
- if (auto docname = layout[main_id]->find("txt-docname"))
- docname->set_text(("Panodoc: " + doc_name).c_str());
-
- layers->clear();
- canvas->m_canvas->m_layers.clear();
- canvas->m_canvas->m_order.clear();
- canvas->reset_camera();
- ActionManager::clear();
-
- canvas->m_canvas->layer_add("Default");
- layers->add_layer("Default");
-
- dialog->destroy();
- App::I.hideKeyboard();
+ std::string name = dialog->input->m_string;
+ std::string path = data_path + "/" + name + ".pano";
+
+ auto action = [this, dialog, name] {
+ doc_name = name;
+ if (auto docname = layout[main_id]->find("txt-docname"))
+ docname->set_text(("Panodoc: " + doc_name).c_str());
+
+ layers->clear();
+ canvas->m_canvas->m_layers.clear();
+ canvas->m_canvas->m_order.clear();
+ canvas->reset_camera();
+ ActionManager::clear();
+
+ canvas->m_canvas->layer_add("Default");
+ layers->add_layer("Default");
+
+ dialog->destroy();
+ App::I.hideKeyboard();
+ };
+
+ if (Asset::exist(path, false))
+ {
+ // ask confirm is file already exist
+ auto msgbox = new NodeMessageBox();
+ msgbox->m_manager = &layout;
+ msgbox->init();
+ msgbox->m_title->set_text("Warning");
+ msgbox->m_message->set_text("A document with this name already exists, continue?");
+ msgbox->btn_ok->on_click = [this, msgbox, action](Node*) {
+ action();
+ msgbox->destroy();
+ };
+ layout[main_id]->add_child(msgbox);
+ }
+ else
+ {
+ action();
+ }
+
};
dialog->btn_cancel->on_click = [this, dialog](Node*)
{
@@ -120,23 +145,58 @@ void App::dialog_save()
App::I.showKeyboard();
- layout[main_id]->add_child(dialog);
- layout[main_id]->update();
-
dialog->btn_ok->on_click = [this, dialog](Node*)
{
- doc_name = dialog->input->m_string;
- if (auto docname = layout[main_id]->find("txt-docname"))
- docname->set_text(("Panodoc: " + doc_name).c_str());
- canvas->m_canvas->project_save(data_path + "/" + doc_name + ".pano");
- dialog->destroy();
- App::I.hideKeyboard();
+ std::string name = dialog->input->m_string;
+ std::string path = data_path + "/" + name + ".pano";
+
+ if (name.empty())
+ {
+ auto msgbox = new NodeMessageBox();
+ msgbox->m_manager = &layout;
+ msgbox->init();
+ msgbox->m_title->set_text("Warning");
+ msgbox->m_message->set_text("You need to specify a name to file.");
+ layout[main_id]->add_child(msgbox);
+ return;
+ }
+
+ auto action = [this, dialog, name, path] {
+ doc_name = name;
+ if (auto docname = layout[main_id]->find("txt-docname"))
+ docname->set_text(("Panodoc: " + doc_name).c_str());
+ canvas->m_canvas->project_save(path);
+ dialog->destroy();
+ App::I.hideKeyboard();
+ };
+
+ if (Asset::exist(path, false))
+ {
+ // ask confirm is file already exist
+ auto msgbox = new NodeMessageBox();
+ msgbox->m_manager = &layout;
+ msgbox->init();
+ msgbox->m_title->set_text("Warning");
+ msgbox->m_message->set_text(("Are you sure you want to overwrite " + name + "?").c_str());
+ msgbox->btn_ok->on_click = [this, msgbox, action](Node*) {
+ action();
+ msgbox->destroy();
+ };
+ layout[main_id]->add_child(msgbox);
+ }
+ else
+ {
+ action();
+ }
};
dialog->btn_cancel->on_click = [this, dialog](Node*)
{
dialog->destroy();
App::I.hideKeyboard();
};
+
+ layout[main_id]->add_child(dialog);
+ layout[main_id]->update();
}
}
diff --git a/engine/app_layout.cpp b/engine/app_layout.cpp
index caa48ea..bb932d6 100644
--- a/engine/app_layout.cpp
+++ b/engine/app_layout.cpp
@@ -366,10 +366,59 @@ void App::init_menu_file()
popup->destroy();
};
popup->find("file-save")->on_click = [this](Node*) {
+ if (doc_name.empty())
+ {
+ dialog_save();
+ }
+ else
+ {
+ canvas->m_canvas->project_save(data_path + "/" + doc_name + ".pano");
+ }
+ popup->mouse_release();
+ popup->destroy();
+ };
+ popup->find("file-save-as")->on_click = [this](Node*) {
dialog_save();
popup->mouse_release();
popup->destroy();
};
+ popup->find("file-save-ver")->on_click = [this](Node*) {
+ if (doc_name.empty())
+ {
+ dialog_save();
+ }
+ else
+ {
+ int current = 0;
+ std::string next = doc_name + ".01";
+ std::string base = doc_name;
+
+ std::regex r(R"((.*)\.(\w{2})$)");
+ std::smatch m;
+ if (std::regex_search(doc_name, m, r))
+ {
+ std::string base = m[1].str();
+ current = atoi(m[2].str().c_str());
+ }
+
+ for (int i = current + 1; i < 99; i++)
+ {
+ static char tmp_name[256];
+ sprintf(tmp_name, "%s.%02d", base.c_str(), i);
+ next = tmp_name;
+ if (Asset::exist(data_path + "/" + next + ".pano", false))
+ continue;
+ break;
+ }
+
+ doc_name = next;
+ if (auto docname = layout[main_id]->find("txt-docname"))
+ docname->set_text(("Panodoc: " + doc_name).c_str());
+ canvas->m_canvas->project_save(data_path + "/" + next + ".pano");
+ }
+ popup->mouse_release();
+ popup->destroy();
+ };
popup->find("file-export")->on_click = [this](Node*) {
dialog_export();
popup->mouse_release();
diff --git a/engine/asset.cpp b/engine/asset.cpp
index 6a87884..8852162 100644
--- a/engine/asset.cpp
+++ b/engine/asset.cpp
@@ -18,6 +18,24 @@ bool Asset::delete_file(const std::string& path)
return true;
}
+bool Asset::exist(std::string path, bool is_asset)
+{
+ if (is_asset)
+ {
+ Asset asset;
+ if (asset.open(path.c_str()))
+ {
+ asset.close();
+ return true;
+ }
+ }
+ else
+ {
+ std::ifstream f(path);
+ return f.is_open();
+ }
+}
+
std::vector Asset::list_files(std::string folder, bool is_asset, const std::string& filter_regex)
{
std::vector names;
diff --git a/engine/asset.h b/engine/asset.h
index abbf6a5..174a719 100644
--- a/engine/asset.h
+++ b/engine/asset.h
@@ -8,6 +8,7 @@ public:
AAsset* m_asset = nullptr;
#endif
static std::vector list_files(std::string folder, bool is_asset, const std::string& filter_regex);
+ static bool exist(std::string path, bool is_asset);
static bool delete_file(const std::string& path);
std::string m_current_path;