Route collection export targets through platform policy

This commit is contained in:
2026-06-04 17:24:36 +02:00
parent be4b88dec8
commit 401ce33498
12 changed files with 191 additions and 67 deletions

View File

@@ -185,6 +185,7 @@ public:
std::function<void(std::string path)> writer, std::function<void(const std::string& path, bool saved)> callback);
void pick_file_save(std::vector<std::string> types, std::function<void(std::string path)> callback);
[[nodiscard]] bool uses_prepared_file_writes() const;
[[nodiscard]] bool uses_work_directory_document_export_collections() const;
void pick_dir(std::function<void(std::string path)> callback);
void display_file(std::string path);
void share_file(std::string path);

View File

@@ -26,6 +26,11 @@ struct DocumentExportSuggestedName {
std::string name;
};
enum class DocumentExportCollectionDestination {
work_directory_collection,
picked_directory_stem,
};
enum class DocumentExportStartDecision {
start_now,
show_license_disabled,
@@ -72,6 +77,12 @@ struct DocumentExportMenuPlan {
bool opens_dialog = true;
};
struct DocumentExportCollectionTargetPlan {
DocumentExportCollectionKind kind = DocumentExportCollectionKind::layers;
DocumentExportCollectionDestination destination = DocumentExportCollectionDestination::picked_directory_stem;
std::string_view suffix;
};
class DocumentExportMenuServices {
public:
virtual ~DocumentExportMenuServices() = default;
@@ -193,6 +204,32 @@ public:
return plan;
}
[[nodiscard]] constexpr std::string_view document_export_collection_suffix(
DocumentExportCollectionKind kind) noexcept
{
switch (kind) {
case DocumentExportCollectionKind::layers:
return "_layers";
case DocumentExportCollectionKind::animation_frames:
return "_frames";
}
return {};
}
[[nodiscard]] constexpr DocumentExportCollectionTargetPlan plan_document_export_collection_target(
DocumentExportCollectionKind kind,
bool use_work_directory_collection) noexcept
{
return {
kind,
use_work_directory_collection
? DocumentExportCollectionDestination::work_directory_collection
: DocumentExportCollectionDestination::picked_directory_stem,
document_export_collection_suffix(kind),
};
}
[[nodiscard]] inline pp::foundation::Result<DocumentExportFileTarget> make_document_export_file_target(
std::string_view work_directory,
std::string_view document_name,

View File

@@ -53,6 +53,57 @@ namespace {
return false;
}
void start_document_export_collection(
App& app,
pp::app::DocumentExportCollectionKind kind,
const char* message_title,
const char* collection_log_message,
const char* stem_log_message)
{
const auto plan = pp::app::plan_document_export_collection_target(
kind,
app.uses_work_directory_document_export_collections());
if (plan.destination == pp::app::DocumentExportCollectionDestination::work_directory_collection) {
const auto target = pp::app::make_document_export_collection_target(
app.work_path,
app.doc_name,
plan.suffix);
if (!target) {
app.message_box(message_title, target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_collection(
app,
plan.kind,
target.value());
if (!status.ok())
LOG("%s: %s", collection_log_message, status.message);
return;
}
app.pick_dir([
&app,
kind = plan.kind,
title = std::string(message_title),
log_message = std::string(stem_log_message)
](std::string path) {
const auto target = pp::app::make_document_export_stem_target(path, app.doc_name);
if (!target) {
app.message_box(title, target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_stem(
app,
kind,
target.value());
if (!status.ok())
LOG("%s: %s", log_message.c_str(), status.message);
});
}
}
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title, int total /*= 0*/)
@@ -361,35 +412,12 @@ void App::dialog_export_layers()
if (!can_start_document_export(*this, true))
return;
#if defined(__IOS__)
const auto target = pp::app::make_document_export_collection_target(work_path, doc_name, "_layers");
if (!target) {
message_box("Export Layers", target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_collection(
start_document_export_collection(
*this,
pp::app::DocumentExportCollectionKind::layers,
target.value());
if (!status.ok())
LOG("Document layer collection export failed: %s", status.message);
#else
pick_dir([this](std::string path) {
const auto target = pp::app::make_document_export_stem_target(path, doc_name);
if (!target) {
message_box("Export Layers", target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_stem(
*this,
pp::app::DocumentExportCollectionKind::layers,
target.value());
if (!status.ok())
LOG("Document layer stem export failed: %s", status.message);
});
#endif
"Export Layers",
"Document layer collection export failed",
"Document layer stem export failed");
}
void App::dialog_export_anim_frames()
@@ -397,35 +425,12 @@ void App::dialog_export_anim_frames()
if (!can_start_document_export(*this, true))
return;
#if defined(__IOS__)
const auto target = pp::app::make_document_export_collection_target(work_path, doc_name, "_frames");
if (!target) {
message_box("Export Layers", target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_collection(
start_document_export_collection(
*this,
pp::app::DocumentExportCollectionKind::animation_frames,
target.value());
if (!status.ok())
LOG("Document animation frame collection export failed: %s", status.message);
#else
pick_dir([this](std::string path) {
const auto target = pp::app::make_document_export_stem_target(path, doc_name);
if (!target) {
message_box("Export Layers", target.status().message);
return;
}
const auto status = pp::panopainter::execute_legacy_document_export_stem(
*this,
pp::app::DocumentExportCollectionKind::animation_frames,
target.value());
if (!status.ok())
LOG("Document animation frame stem export failed: %s", status.message);
});
#endif
"Export Layers",
"Document animation frame collection export failed",
"Document animation frame stem export failed");
}
void App::dialog_export_depth()

View File

@@ -186,6 +186,11 @@ bool App::uses_prepared_file_writes() const
return active_platform_services().uses_prepared_file_writes();
}
bool App::uses_work_directory_document_export_collections() const
{
return active_platform_services().uses_work_directory_document_export_collections();
}
void App::pick_dir(std::function<void(std::string path)> callback)
{
redraw = true;

View File

@@ -64,6 +64,7 @@ public:
virtual void pick_save_file(std::vector<std::string> file_types, PickedPathCallback callback) = 0;
virtual void pick_directory(PickedPathCallback callback) = 0;
[[nodiscard]] virtual bool uses_prepared_file_writes() = 0;
[[nodiscard]] virtual bool uses_work_directory_document_export_collections() = 0;
[[nodiscard]] virtual PreparedFileTarget prepare_writable_file(
std::string_view type,
std::string_view default_name,

View File

@@ -440,6 +440,15 @@ public:
#endif
}
[[nodiscard]] bool uses_work_directory_document_export_collections() override
{
#if __IOS__
return true;
#else
return false;
#endif
}
[[nodiscard]] pp::platform::PreparedFileTarget prepare_writable_file(
std::string_view type,
std::string_view default_name,

View File

@@ -453,6 +453,11 @@ public:
return false;
}
[[nodiscard]] bool uses_work_directory_document_export_collections() override
{
return false;
}
[[nodiscard]] pp::platform::PreparedFileTarget prepare_writable_file(
std::string_view type,
std::string_view default_name,