Skip to content

Commit 7039889

Browse files
authored
QtFRED - wire up file and edit menu controls (#7347)
* wire up file and edit menu controls * linux * more linux * backup files don't go into the recent files list
1 parent 57eec4d commit 7039889

21 files changed

Lines changed: 394 additions & 52 deletions

qtfred/src/mission/Editor.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,68 @@ void Editor::update() {
133133
}
134134
}
135135

136+
int Editor::autosave(const char* /*desc*/) {
137+
if (autosaveDisabled || !_lastActiveViewport)
138+
return 0;
139+
140+
Fred_mission_save save;
141+
save.set_always_save_display_names(_lastActiveViewport->Always_save_display_names);
142+
save.set_view_pos(_lastActiveViewport->view_pos);
143+
save.set_view_orient(_lastActiveViewport->view_orient);
144+
save.set_fred_alt_names(Fred_alt_names);
145+
save.set_fred_callsigns(Fred_callsigns);
146+
147+
// autosave_mission_file() needs a mutable buffer because it reads but doesn't write through it
148+
char backup_name_buf[] = MISSION_BACKUP_NAME;
149+
if (save.autosave_mission_file(backup_name_buf)) {
150+
undoCount = undoAvailable = 0;
151+
return -1;
152+
}
153+
154+
undoCount++;
155+
checkUndo();
156+
return 0;
157+
}
158+
159+
int Editor::checkUndo() {
160+
undoAvailable = 0;
161+
if (undoCount == 0)
162+
return 0;
163+
164+
// Undo is available when Backup.002 exists (Backup.001 is the current, .002 is what we load)
165+
CFileLocation loc = cf_find_file_location("Backup.002", CF_TYPE_MISSIONS);
166+
if (loc.found) {
167+
undoAvailable = 1;
168+
return 1;
169+
}
170+
return 0;
171+
}
172+
173+
bool Editor::autoload() {
174+
if (!undoAvailable || !_lastActiveViewport)
175+
return false;
176+
177+
// Load the previous state from Backup.002
178+
if (!loadMission("Backup.002", MPF_FAST_RELOAD))
179+
return false;
180+
181+
// Delete Backup.001 (the state we just replaced)
182+
cf_delete("Backup.001", CF_TYPE_MISSIONS);
183+
184+
// Rotate backups back one slot: .003->.002, .004->.003, etc, .009->.008
185+
char old_name[256], new_name[256];
186+
for (int i = 1; i < MISSION_BACKUP_DEPTH; i++) {
187+
sprintf(old_name, "Backup.%.3d", i + 1);
188+
sprintf(new_name, "Backup.%.3d", i);
189+
cf_rename(old_name, new_name, CF_TYPE_MISSIONS);
190+
}
191+
192+
if (undoCount > 0)
193+
undoCount--;
194+
checkUndo();
195+
return true;
196+
}
197+
136198
void Editor::maybeUseAutosave(std::string& filepath)
137199
{
138200
// first, just grab the info of this mission
@@ -431,6 +493,11 @@ bool Editor::loadMission(const std::string& mission_name, int flags) {
431493
scripting::hooks::FredOnMissionLoad->run();
432494
}
433495

496+
if (!(flags & MPF_FAST_RELOAD)) {
497+
undoCount = undoAvailable = 0;
498+
autosave("nothing");
499+
}
500+
434501
return true;
435502
}
436503
void Editor::clean_up_selections() {
@@ -824,6 +891,8 @@ void Editor::createNewMission() {
824891
clearMission();
825892
create_player(&vmd_zero_vector, &vmd_identity_matrix);
826893
stars_post_level_init();
894+
undoCount = undoAvailable = 0;
895+
autosave("nothing");
827896
}
828897
void Editor::hideMarkedObjects() {
829898
object* ptr;

qtfred/src/mission/Editor.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,32 @@ class Editor : public QObject {
135135
void objectMarkingChanged(int obj, bool marked);
136136

137137
public:
138+
// --- Undo / autosave state ---
139+
int undoAvailable = 0; ///< Whether an undo state (Backup.002) is available
140+
int autosaveDisabled = 0; ///< When non-zero, autosave writes are suppressed
141+
142+
/**
143+
* @brief Rotate the backup stack and save the current mission state.
144+
*
145+
* Equivalent to CFREDDoc::autosave() in old FRED2. Should be called after
146+
* any significant edit operation. Does nothing when @c autosaveDisabled is set.
147+
*
148+
* @param desc Optional human-readable description of the operation being saved.
149+
* @return 0 on success, -1 if the backup write failed.
150+
*/
151+
int autosave(const char* desc = nullptr);
152+
153+
/**
154+
* @brief Restore the previous mission state from the backup stack.
155+
*
156+
* Equivalent to CFREDDoc::autoload() in old FRED2.
157+
* Caller is responsible for preserving and restoring the camera state and
158+
* @c saveName around this call.
159+
*
160+
* @return true on success, false if no undo state was available.
161+
*/
162+
bool autoload();
163+
138164
int Id_select_type_jump_node = 0;
139165
int Id_select_type_waypoint = 0;
140166

@@ -234,6 +260,11 @@ class Editor : public QObject {
234260
SCP_vector<std::unique_ptr<EditorViewport>> _viewports;
235261
EditorViewport* _lastActiveViewport = nullptr;
236262

263+
int undoCount = 0; ///< Number of autosave operations performed since last reset
264+
265+
/** @brief Check whether Backup.002 exists and update @c undoAvailable accordingly. */
266+
int checkUndo();
267+
237268
int numMarked = 0;
238269

239270
SCP_vector<GlobalShieldStatus> Shield_sys_teams;

qtfred/src/mission/EditorViewport.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,8 @@ void EditorViewport::level_controlled() {
614614
level_object(&Objects[view_obj].orient);
615615
object_moved(&Objects[view_obj]);
616616
///! \todo Notify.
617+
editor->autosave("level object");
617618
editor->missionChanged();
618-
//FREDDoc_ptr->autosave("level object");
619619
}
620620
break;
621621

@@ -641,13 +641,7 @@ void EditorViewport::level_controlled() {
641641

642642
///! \todo Notify.
643643
if (count) {
644-
/*
645-
if (count > 1)
646-
FREDDoc_ptr->autosave("level objects");
647-
else
648-
FREDDoc_ptr->autosave("level object");
649-
*/
650-
644+
editor->autosave(count > 1 ? "level objects" : "level object");
651645
editor->missionChanged();
652646
}
653647

@@ -676,7 +670,7 @@ void EditorViewport::verticalize_controlled() {
676670
verticalize_object(&Objects[view_obj].orient);
677671
object_moved(&Objects[view_obj]);
678672
///! \todo notify.
679-
//FREDDoc_ptr->autosave("align object");
673+
editor->autosave("align object");
680674
editor->missionChanged();
681675
}
682676
break;
@@ -703,13 +697,7 @@ void EditorViewport::verticalize_controlled() {
703697

704698
///! \todo Notify.
705699
if (count) {
706-
/*
707-
if (count > 1)
708-
FREDDoc_ptr->autosave("align objects");
709-
else
710-
FREDDoc_ptr->autosave("align object");
711-
*/
712-
700+
editor->autosave(count > 1 ? "align objects" : "align object");
713701
editor->missionChanged();
714702
}
715703

@@ -1152,8 +1140,7 @@ int EditorViewport::create_object_on_grid(int x, int y, int waypoint_instance, b
11521140
if (obj >= 0) {
11531141
editor->markObject(obj);
11541142

1155-
// TODO: Add autosave here
1156-
// FREDDoc_ptr->autosave("object create");
1143+
editor->autosave("object create");
11571144

11581145
} else if (obj == -1) {
11591146
dialogProvider->showButtonDialog(DialogType::Error, "Error", "Maximum ship limit reached. Can't add any more ships.", { DialogButton::Ok });

0 commit comments

Comments
 (0)