From 8de8724660925c63dcf89724b954e393282e3a71 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sat, 22 Aug 2015 18:17:51 -0700 Subject: [PATCH] Support creating multiple main windows This is not yet actually exposed in any way in the UI. --- src/frame_main.cpp | 2 -- src/main.cpp | 63 ++++++++++++++++++++++++++++++---------------- src/main.h | 13 ++++++++-- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/frame_main.cpp b/src/frame_main.cpp index ba107d6c1..1a73dbf6c 100644 --- a/src/frame_main.cpp +++ b/src/frame_main.cpp @@ -161,8 +161,6 @@ FrameMain::FrameMain() } FrameMain::~FrameMain () { - wxGetApp().frame = nullptr; - context->project->CloseAudio(); context->project->CloseVideo(); diff --git a/src/main.cpp b/src/main.cpp index 6c87eaa4c..af299715e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -293,8 +293,7 @@ bool AegisubApp::OnInit() { // Open main frame StartupLog("Create main window"); - frame = new FrameMain; - SetTopWindow(frame); + NewProjectContext(); // Version checker StartupLog("Possibly perform automatic updates check"); @@ -318,11 +317,7 @@ bool AegisubApp::OnInit() { // Get parameter subs StartupLog("Parse command line"); - std::vector files; - for (int i = 1; i < argc; ++i) - files.push_back(from_wx(argv[i])); - if (!files.empty()) - frame->context->project->LoadList(files); + OpenFiles(argv.GetArguments()); } catch (agi::Exception const& e) { wxMessageBox(to_wx(e.GetMessage()), "Fatal error while initializing"); @@ -347,8 +342,9 @@ bool AegisubApp::OnInit() { } int AegisubApp::OnExit() { - if (frame) + for (auto frame : frames) delete frame; + frames.clear(); if (wxTheClipboard->Open()) { wxTheClipboard->Flush(); @@ -371,10 +367,27 @@ int AegisubApp::OnExit() { return wxApp::OnExit(); } -static void UnhandledExeception(bool stackWalk, agi::Context *c) { +agi::Context& AegisubApp::NewProjectContext() { + auto frame = new FrameMain; + frame->Bind(wxEVT_DESTROY, [=](wxWindowDestroyEvent&) { + frames.erase(remove(begin(frames), end(frames), frame), end(frames)); + if (frames.empty()) { + ExitMainLoop(); + } + }); + frames.push_back(frame); + return *frame->context; +} + +void AegisubApp::UnhandledException(bool stackWalk) { #if (!defined(_DEBUG) || defined(WITH_EXCEPTIONS)) && (wxUSE_ON_FATAL_EXCEPTION+0) - if (c && c->ass && c->subsController) { - auto path = config::path->Decode("?user/recovered"); + bool any = false; + agi::fs::path path; + for (auto& frame : frames) { + auto c = frame->context.get(); + if (!c || !c->ass || !c->subsController) continue; + + path = config::path->Decode("?user/recovered"); agi::fs::CreateDirectory(path); auto filename = c->subsController->Filename().stem(); @@ -382,26 +395,28 @@ static void UnhandledExeception(bool stackWalk, agi::Context *c) { path /= filename; c->subsController->Save(path); - if (stackWalk) - crash_writer::Write(); + any = true; + } + if (stackWalk) + crash_writer::Write(); + + if (any) { // Inform user of crash. wxMessageBox(agi::wxformat(exception_message, path), _("Program error"), wxOK | wxICON_ERROR | wxCENTER, nullptr); } else if (LastStartupState) { - if (stackWalk) - crash_writer::Write(); wxMessageBox(fmt_wx("Aegisub has crashed while starting up!\n\nThe last startup step attempted was: %s.", LastStartupState), _("Program error"), wxOK | wxICON_ERROR | wxCENTER); } #endif } void AegisubApp::OnUnhandledException() { - UnhandledExeception(false, frame ? frame->context.get() : nullptr); + UnhandledException(false); } void AegisubApp::OnFatalException() { - UnhandledExeception(true, frame ? frame->context.get() : nullptr); + UnhandledException(true); } #define SHOW_EXCEPTION(str) \ @@ -429,7 +444,6 @@ int AegisubApp::OnRun() { std::string error; try { - if (m_exitOnFrameDelete == Later) m_exitOnFrameDelete = Yes; return MainLoop(); } catch (const std::exception &e) { error = std::string("std::exception: ") + e.what(); } @@ -446,7 +460,14 @@ int AegisubApp::OnRun() { return 1; } -void AegisubApp::MacOpenFile(const wxString &filename) { - if (frame && !filename.empty()) - frame->context->project->LoadSubtitles(agi::fs::path(filename.wx_str())); +void AegisubApp::MacOpenFiles(wxArrayString const& filenames) { + OpenFiles(filenames); +} + +void AegisubApp::OpenFiles(wxArrayStringsAdapter filenames) { + std::vector files; + for (int i = 1; i < argc; ++i) + files.push_back(from_wx(argv[i])); + if (!files.empty()) + frames[0]->context->project->LoadList(files); } diff --git a/src/main.h b/src/main.h index 0ddc52175..d69dc2c1e 100644 --- a/src/main.h +++ b/src/main.h @@ -36,6 +36,9 @@ #endif class FrameMain; +namespace agi { + struct Context; +} class AegisubApp : public wxApp { friend class FrameMain; @@ -50,13 +53,19 @@ class AegisubApp : public wxApp { void OnAssertFailure(const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg) override; - FrameMain *frame = nullptr; + void UnhandledException(bool); + + void OpenFiles(wxArrayStringsAdapter filenames); + + std::vector frames; public: AegisubApp(); AegisubLocale locale; + agi::Context& NewProjectContext(); + // Apple events - void MacOpenFile(const wxString &filename) + void MacOpenFiles(wxArrayString const& filenames) #ifdef __APPLE__ override #endif