1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! File-based import/export for the Edit tab: exporting the edited schedule as a
//! plain `.asc` ([`export::setup_export_asc_callback`]), and the paired native
//! `.indicatrix.toml` save/open ([`save::setup_save_native_callback`]/
//! [`open_native::setup_open_native_callback`]; legacy `.gemcut.toml` sidecars still
//! open). See this group's own `mod.rs` doc comment.
//!
//! # Module split
//!
//! Three groups of shared infrastructure every write/export/autosave/open path
//! below uses: [`solve`] (Group 1: a matching cached solve, else a background
//! solve, never inline -- `resolve_solve_at` for the generation-tagged write
//! paths with a typed failure, `resolve_solved_then` for the plain one), [`confirm`] (Group 2: the shared in-window write-confirm
//! dialog, no blocking native message dialogs), and [`picker`] (Group 3: file
//! pickers off the UI thread). [`save_helpers`]/[`catalogue`] hold the save-side
//! helpers (custom-material snapshot, degenerate-marker header, catalogue
//! write-back). Then one module per write path: [`export`] ("Export .asc"/"Export
//! Cutting Sheet"/"Export Diagram"), [`save`]/[`save_finish`]/[`atomic_write`]
//! ("Save Native"'s dialog wiring, its UI-thread success tail, and the
//! stage-then-rename disk write), [`autosave`] (Group 4: the two-minute recovery
//! snapshot), and [`open_native`]/[`open_picker`]/[`open_commit`] ("Open Native"'s
//! entry points, its file-reading/parsing, and committing a loaded design into
//! `EditorState`). Tests live in their own [`tests`] module.
use crate::;
use ;
// Re-exported at the SAME `pub(in crate::gui)` restriction `AfterSave` is already
// declared with at its own definition site (`state::core`) -- `gui::window_close`
// is a sibling of `gui::editor`, not a descendant, and cannot write
// `crate::gui::editor::state::AfterSave` directly (`state` itself is a private
// module, visible only within `editor` and its own descendants). Naming it here
// instead works because `native_io` (a descendant of `editor`) already has
// `pub(in crate::gui)` visibility of its own (see `ask_write_confirm`'s matching
// comment on the re-export block below) and CAN see `state::AfterSave` from
// inside `editor`'s subtree.
pub use crateAfterSave;
thread_local!
/// One [`on_save_completed`] listener, boxed so [`SAVE_COMPLETED_LISTENERS`] can hold
/// a heterogeneous list of them.
type SaveCompletedListener = ;
/// Stashes `state` for [`request_save_then_close`] to reach later -- called once,
/// from [`save::setup_save_native_callback`].
pub
/// `gui::window_close`'s close-confirm "Save" handler's own entry point: marks
/// [`EditorState::after_save`] as [`AfterSave::CloseWindow`] before that handler
/// invokes `EditorModel.save_native` -- see [`AfterSave`]'s own doc comment
/// for why this replaces a synchronous `is_dirty` check run right after that call
/// returns. A silent no-op if [`remember_editor_state`] has not run yet, which
/// cannot happen once `setup_editor_callbacks` has (see that function's own call
/// order) -- by the time a cutter can close the window at all, it already has.
pub
/// Registers a listener [`notify_save_completed`] calls every time a native save
/// just finished successfully (draft or real alike -- both actually wrote a file).
///
/// Exists for [`AfterSave`]: the window-close guard and the New/Load
/// Selected/Open Native unsaved-changes guard each need to run something once an
/// otherwise-asynchronous Save actually lands, but neither owns the other's own
/// render/preview/settings handles, and threading every caller's own parameters
/// through the whole write path (`save::setup_save_native_callback` ->
/// `finish_native_save` -> `write_native_save` -> its background thread's
/// `upgrade_in_event_loop` hop -> [`save_finish::finish_save_native_success`])
/// would touch call sites this lane's file list does not include. Each guard
/// registers its own listener instead, closing over whatever it already has.
///
/// A listener that does not recognize the `after_save` value it is handed (it
/// belongs to the OTHER guard, or there is none right now) must leave it exactly
/// as found rather than dropping it via a plain `Option::take`/// `gui::window_close::setup_close_confirm_callbacks`'s and
/// `callbacks::tier_actions::lifecycle::setup_unsaved_guard_dispatch`'s matching
/// "put it back" comment for why: only one listener may ever actually consume a
/// given value, and a listener registered first must not silently steal a value
/// meant for the other.
pub
/// [`save_finish::finish_save_native_success`]'s own call into every
/// [`on_save_completed`] listener -- see that function's own doc comment.
pub
// Every symbol below is re-exported at exactly the visibility the pre-split
// `native_io.rs` gave it -- see each submodule's own item for why. A re-export
// can only match or narrow an item's own declared visibility, never widen it, so
// each item is declared `pub(in crate::gui::editor)` (or `pub(in crate::gui)` for
// `ask_write_confirm`) directly at its definition site.
pub use ;
pub use ask_write_confirm;
pub use ;
pub use ;
pub use setup_save_native_callback;
pub use resolve_solved_then;