#include "pch.h" #include "legacy_document_session_services.h" #include "app.h" #include "legacy_app_dialog_services.h" #include "legacy_document_canvas_services.h" #include "legacy_canvas_view_services.h" #include "legacy_history_services.h" #include "node_dialog_open.h" #include namespace pp::panopainter { namespace { void log_legacy_document_save_snapshot( const char* context, const pp::app::DocumentCanvasSaveSnapshotReport& report) { LOG( "%s document snapshot: %ux%u layers=%zu frames=%zu capturedFaces=%zu pendingFaces=%zu ppiReady=%s", context, report.width, report.height, report.layer_count, report.frame_count, report.captured_face_payloads, report.pending_face_payloads, report.can_export_ppi ? "true" : "false"); } pp::foundation::Status prepare_legacy_document_save_snapshot(App& app, const char* context) { auto snapshot = capture_legacy_canvas_document_payload_snapshot(app); if (!snapshot) { LOG("%s document snapshot failed: %s", context, snapshot.status().message); return snapshot.status(); } const auto report = pp::app::make_document_canvas_save_snapshot_report(snapshot.value()); log_legacy_document_save_snapshot(context, report); return pp::foundation::Status::success(); } void project_save_after_snapshot(App& app, const std::string& path) { const auto status = prepare_legacy_document_save_snapshot(app, "project-save"); if (!status.ok()) LOG("project save snapshot bridge retained legacy save after failure: %s", status.message); app.canvas->m_canvas->project_save(path); } void project_save_after_snapshot(App& app) { const auto status = prepare_legacy_document_save_snapshot(app, "project-save"); if (!status.ok()) LOG("project save snapshot bridge retained legacy save after failure: %s", status.message); app.canvas->m_canvas->project_save(); } void project_save_after_snapshot(App& app, std::function on_complete) { const auto status = prepare_legacy_document_save_snapshot(app, "project-save-before-workflow"); if (!status.ok()) LOG("project save snapshot bridge retained legacy save after failure: %s", status.message); app.canvas->m_canvas->project_save(std::move(on_complete)); } void create_legacy_new_document( App& app, const pp::app::NewDocumentPlan& plan, const std::shared_ptr& dialog) { app.doc_name = plan.target.name; app.doc_path = plan.target.path; app.doc_filename = plan.target.name + ".ppi"; app.doc_dir = plan.target.directory; app.layers->clear(); app.canvas->m_canvas->m_layers.clear(); app.canvas->m_canvas->resize(plan.resolution, plan.resolution); const auto reset_status = execute_legacy_canvas_camera_reset(app); if (!reset_status.ok()) LOG("New document camera reset failed: %s", reset_status.message); pp::panopainter::clear_legacy_history(); app.layers->add_layer("Default", false, true); app.canvas->m_canvas->m_unsaved = true; app.canvas->m_canvas->m_newdoc = false; app.title_update(); dialog->destroy(); App::I->hideKeyboard(); } class LegacyNewDocumentServices final : public pp::app::NewDocumentServices { public: LegacyNewDocumentServices(App& app, std::shared_ptr dialog) noexcept : app_(app) , dialog_(std::move(dialog)) { } void create_new_document(const pp::app::NewDocumentPlan& plan) override { create_legacy_new_document(app_, plan, dialog_); } void prompt_overwrite_new_document(const pp::app::NewDocumentPlan& plan) override { auto msgbox = pp::panopainter::create_legacy_app_message_dialog( app_, pp::app::plan_document_session_prompt( pp::app::DocumentSessionPromptKind::new_document_overwrite)); auto* app = &app_; auto dialog = dialog_; msgbox->btn_ok->on_click = [app, msgbox, dialog, plan](Node*) { create_legacy_new_document(*app, plan, dialog); msgbox->destroy(); }; } private: App& app_; std::shared_ptr dialog_; }; void save_legacy_document_file( App& app, const pp::app::DocumentFileSavePlan& plan, const std::shared_ptr& dialog) { project_save_after_snapshot(app, plan.target.path); app.doc_name = plan.target.name; app.doc_path = plan.target.path; app.doc_dir = plan.target.directory; app.title_update(); dialog->destroy(); App::I->hideKeyboard(); } class LegacyDocumentFileSaveServices final : public pp::app::DocumentFileSaveServices { public: LegacyDocumentFileSaveServices(App& app, std::shared_ptr dialog) noexcept : app_(app) , dialog_(std::move(dialog)) { } void save_document_file(const pp::app::DocumentFileSavePlan& plan) override { save_legacy_document_file(app_, plan, dialog_); } void prompt_overwrite_document_file(const pp::app::DocumentFileSavePlan& plan) override { auto msgbox = pp::panopainter::create_legacy_app_message_dialog( app_, pp::app::plan_document_session_prompt( pp::app::DocumentSessionPromptKind::document_file_overwrite, plan.target.name)); auto* app = &app_; auto dialog = dialog_; msgbox->btn_ok->on_click = [app, msgbox, dialog, plan](Node*) { save_legacy_document_file(*app, plan, dialog); msgbox->destroy(); }; } private: App& app_; std::shared_ptr dialog_; }; class LegacyDocumentVersionSaveServices final : public pp::app::DocumentVersionSaveServices { public: explicit LegacyDocumentVersionSaveServices(App& app) noexcept : app_(app) { } void save_document_version(const pp::app::DocumentVersionTarget& target) override { app_.doc_name = target.name; app_.doc_path = target.path; app_.canvas->m_canvas->m_unsaved = true; app_.title_update(); project_save_after_snapshot(app_, app_.doc_path); } private: App& app_; }; class LegacyCloseRequestServices final : public pp::app::CloseRequestServices { public: LegacyCloseRequestServices(App& app, bool& dialog_already_opened) noexcept : app_(app) , dialog_already_opened_(dialog_already_opened) { } void request_close_now() override { } void show_unsaved_close_prompt() override { auto* app = &app_; auto* dialog_already_opened = &dialog_already_opened_; auto m = pp::panopainter::create_legacy_app_message_dialog( app_, pp::app::plan_document_session_prompt( pp::app::DocumentSessionPromptKind::close_unsaved_document)); m->btn_ok->on_click = [app](Node*) { app->request_app_close(); Canvas::I->m_unsaved = false; }; m->btn_cancel->on_click = [dialog_already_opened, m](Node*) { m->destroy(); *dialog_already_opened = false; }; dialog_already_opened_ = true; } private: App& app_; bool& dialog_already_opened_; }; class LegacyDocumentSaveServices final : public pp::app::DocumentSaveServices { public: explicit LegacyDocumentSaveServices(App& app) noexcept : app_(app) { } void show_save_dialog() override { app_.dialog_save(); } void save_existing_document() override { project_save_after_snapshot(app_); } void save_document_version() override { app_.dialog_save_ver(); } private: App& app_; }; class LegacyDocumentWorkflowServices final : public pp::app::DocumentWorkflowServices { public: LegacyDocumentWorkflowServices(App& app, std::function action) noexcept : app_(app) , action_(std::move(action)) { } void continue_workflow_now() override { action_(); } void prompt_save_before_continue() override { auto m = pp::panopainter::create_legacy_app_message_dialog( app_, pp::app::plan_document_session_prompt( pp::app::DocumentSessionPromptKind::save_before_workflow_continue)); auto* app = &app_; auto action = action_; m->btn_ok->on_click = [app, m, action](Node*) { project_save_after_snapshot(*app, [app, m, action](bool success) { if (success) action(); else { const auto plan = pp::app::plan_document_session_prompt( pp::app::DocumentSessionPromptKind::document_save_error); app->message_box(plan.title, plan.message, plan.show_cancel); } }); m->destroy(); }; m->btn_cancel->on_click = [m, action](Node*) { action(); m->destroy(); }; } private: App& app_; std::function action_; }; } // namespace pp::foundation::Status execute_legacy_close_request_decision( App& app, pp::app::CloseRequestDecision decision, bool& dialog_already_opened) { LegacyCloseRequestServices services(app, dialog_already_opened); return pp::app::execute_close_request_decision(decision, services); } pp::foundation::Status execute_legacy_document_save_decision( App& app, pp::app::DocumentSaveDecision decision) { LegacyDocumentSaveServices services(app); return pp::app::execute_document_save_decision(decision, services); } pp::foundation::Status execute_legacy_document_workflow_decision( App& app, pp::app::DocumentWorkflowDecision decision, std::function action) { LegacyDocumentWorkflowServices services(app, std::move(action)); return pp::app::execute_document_workflow_decision(decision, services); } pp::foundation::Status execute_legacy_new_document_plan( App& app, const pp::app::NewDocumentPlan& plan, std::shared_ptr dialog) { LegacyNewDocumentServices services(app, std::move(dialog)); return pp::app::execute_new_document_plan(plan, services); } pp::foundation::Status execute_legacy_document_file_save_plan( App& app, const pp::app::DocumentFileSavePlan& plan, std::shared_ptr dialog) { LegacyDocumentFileSaveServices services(app, std::move(dialog)); return pp::app::execute_document_file_save_plan(plan, services); } pp::foundation::Status execute_legacy_document_version_save( App& app, const pp::app::DocumentVersionTarget& target) { LegacyDocumentVersionSaveServices services(app); return pp::app::execute_document_version_save(target, services); } } // namespace pp::panopainter