summaryrefslogtreecommitdiffstats
path: root/GUI
diff options
context:
space:
mode:
Diffstat (limited to 'GUI')
-rw-r--r--GUI/GUI/GUI/Frame.cpp72
-rw-r--r--GUI/GUI/GUI/Frame.h2
-rw-r--r--GUI/GUI/GUI/GUI.vcxproj2
-rw-r--r--GUI/GUI/GUI/GUI.vcxproj.filters6
-rw-r--r--GUI/GUI/GUI/Logging.cpp17
-rw-r--r--GUI/GUI/GUI/Logging.h30
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp147
-rw-r--r--GUI/README.md10
8 files changed, 164 insertions, 122 deletions
diff --git a/GUI/GUI/GUI/Frame.cpp b/GUI/GUI/GUI/Frame.cpp
index 5c1fbeb..2ecc255 100644
--- a/GUI/GUI/GUI/Frame.cpp
+++ b/GUI/GUI/GUI/Frame.cpp
@@ -1,4 +1,5 @@
#include "Frame.h"
+#include "Logging.h"
#include "PythonWrapper.h"
#include <filesystem>
@@ -181,6 +182,8 @@ namespace {
constexpr int kModelDefault = 2; // base.en
} // namespace
+using ::Logging::Log;
+
Frame::Frame()
: wxFrame(nullptr, wxID_ANY, "TaSTT"),
py_app_(nullptr),
@@ -212,7 +215,7 @@ Frame::Frame()
transcribe_out->SetMinSize(transcribe_out_sz);
transcribe_out_ = transcribe_out;
- transcribe_out_->AppendText(PythonWrapper::GetVersion() + "\n");
+ Log(transcribe_out_, "{}\n", PythonWrapper::GetVersion());
auto* py_config_panel = new wxPanel(transcribe_panel, ID_PY_CONFIG_PANEL);
{
@@ -438,19 +441,15 @@ void Frame::OnNavbarUnity(wxCommandEvent& event)
void Frame::OnSetupPython(wxCommandEvent& event)
{
- transcribe_out_->AppendText("Setting up Python virtual environment\n");
- transcribe_out_->AppendText("This could take several minutes, please be patient!\n");
- transcribe_out_->AppendText("This will download ~5GB of dependencies.\n");
+ Log(transcribe_out_, "Setting up Python virtual environment\n");
+ Log(transcribe_out_, "This could take several minutes, please be patient!\n");
+ Log(transcribe_out_, "This will download ~5GB of dependencies.\n");
{
std::string transcribe_out;
- std::ostringstream transcribe_out_oss;
- transcribe_out_oss << " Installing pip" << std::endl;
- transcribe_out_->AppendText(transcribe_out_oss.str());
+ Log(transcribe_out_, " Installing pip\n");
if (!PythonWrapper::InstallPip(&transcribe_out)) {
- std::ostringstream transcribe_out_oss;
- transcribe_out_oss << "Failed to install pip: " << transcribe_out;
- transcribe_out_->AppendText(transcribe_out_oss.str());
+ Log(transcribe_out_, "Failed to install pip: {}\n", transcribe_out);
}
}
@@ -466,28 +465,21 @@ void Frame::OnSetupPython(wxCommandEvent& event)
};
for (const auto& pip_dep : pip_deps) {
- {
- std::ostringstream transcribe_out_oss;
- transcribe_out_oss << " Installing " << pip_dep << std::endl;
- transcribe_out_->AppendText(transcribe_out_oss.str());
- }
+ Log(transcribe_out_, " Installing {}\n", pip_dep);
std::string py_stdout, py_stderr;
bool res = PythonWrapper::InvokeWithArgs({ "-m", "pip", "install", pip_dep }, &py_stdout, &py_stderr);
if (!res) {
- std::ostringstream transcribe_out_oss;
- transcribe_out_oss << "Failed to install " << pip_dep << ": " << py_stderr << std::endl;
- transcribe_out_->AppendText(transcribe_out_oss.str());
+ Log(transcribe_out_, "Failed to install {}: {}\n", pip_dep, py_stderr);
return;
}
}
- transcribe_out_->AppendText("Python virtual environment successfully set up!\n");
+ Log(transcribe_out_, "Python virtual environment successfully set up!\n");
}
void Frame::OnDumpMics(wxCommandEvent& event)
{
- transcribe_out_->AppendText(PythonWrapper::DumpMics());
- transcribe_out_->AppendText("\n");
+ Log(transcribe_out_, "{}\n", PythonWrapper::DumpMics());
}
#define DEBUG
@@ -553,22 +545,18 @@ void Frame::OnGenerateFX(wxCommandEvent& event)
void Frame::OnAppStart(wxCommandEvent& event) {
if (py_app_) {
if (wxProcess::Exists(py_app_->GetPid())) {
- transcribe_out_->AppendText("Transcription engine already running\n");
+ Log(transcribe_out_, "Transcription engine already running\n");
return;
}
delete py_app_;
py_app_ = nullptr;
}
- transcribe_out_->AppendText("Launching transcription engine\n");
+ Log(transcribe_out_, "Launching transcription engine\n");
auto cb = [&](wxProcess* proc, int ret) -> void {
- std::ostringstream transcribe_out_oss;
- transcribe_out_oss << "Transcription engine exited with code " << ret << std::endl;
-
- DrainApp(proc, transcribe_out_oss);
-
- transcribe_out_->AppendText(transcribe_out_oss.str());
+ Log(transcribe_out_, "Transcription engine exited with code {}\n", ret);
+ DrainApp(proc, transcribe_out_);
return;
};
@@ -590,7 +578,7 @@ void Frame::OnAppStart(wxCommandEvent& event) {
kLangChoices[which_lang].ToStdString(),
kModelChoices[which_model].ToStdString());
if (!p) {
- transcribe_out_->AppendText("Failed to launch transcription engine\n");
+ Log(transcribe_out_, "Failed to launch transcription engine\n");
return;
}
@@ -601,7 +589,7 @@ void Frame::OnAppStop(wxCommandEvent& event) {
if (py_app_) {
const long pid = py_app_->GetPid();
- transcribe_out_->AppendText("Stopping transcription engine...\n");
+ Log(transcribe_out_, "Stopping transcription engine...\n");
// Closing stdout causes the app to exit. It takes it quite a while
// to exit gracefully; be patient.
@@ -615,11 +603,7 @@ void Frame::OnAppStop(wxCommandEvent& event) {
wxMilliSleep(10);
}
- {
- std::ostringstream oss;
- DrainApp(py_app_, oss);
- transcribe_out_->AppendText(oss.str());
- }
+ DrainApp(py_app_, transcribe_out_);
// Now shut it down.
bool first = true;
@@ -627,39 +611,37 @@ void Frame::OnAppStop(wxCommandEvent& event) {
while (wxProcess::Exists(pid)) {
wxProcess::Kill(pid, wxSIGKILL);
if (++loop_cnt % 100 == 0) {
- transcribe_out_->AppendText("Waiting for transcription engine to exit");
+ Log(transcribe_out_, "Waiting for transcription engine to exit\n");
}
wxMilliSleep(10);
}
// Since we don't process the termination event, py_app_ deletes itself!
py_app_ = nullptr;
- transcribe_out_->AppendText("Stopped transcription engine\n");
+ Log(transcribe_out_, "Stopped transcription engine\n");
}
else {
- transcribe_out_->AppendText("Transcription engine already stopped\n");
+ Log(transcribe_out_, "Transcription engine already stopped\n");
}
}
void Frame::OnAppDrain(wxTimerEvent& event) {
- std::ostringstream oss;
- DrainApp(py_app_, oss);
- transcribe_out_->AppendText(oss.str());
+ DrainApp(py_app_, transcribe_out_);
}
-void Frame::DrainApp(wxProcess* proc, std::ostringstream& oss) {
+void Frame::DrainApp(wxProcess* proc, wxTextCtrl* frame) {
if (!proc) {
return;
}
while (proc->IsInputAvailable()) {
wxTextInputStream iss(*(proc->GetInputStream()));
- oss << " " << iss.ReadLine() << std::endl;
+ Log(frame, " {}\n", iss.ReadLine());
}
while (proc->IsErrorAvailable()) {
wxTextInputStream iss(*(proc->GetErrorStream()));
- oss << " " << iss.ReadLine() << std::endl;
+ Log(frame, " {}\n", iss.ReadLine());
}
}
diff --git a/GUI/GUI/GUI/Frame.h b/GUI/GUI/GUI/Frame.h
index 1d847ca..9b94036 100644
--- a/GUI/GUI/GUI/Frame.h
+++ b/GUI/GUI/GUI/Frame.h
@@ -49,7 +49,7 @@ private:
void OnAppStart(wxCommandEvent& event);
void OnAppStop(wxCommandEvent& event);
void OnAppDrain(wxTimerEvent& event);
- void DrainApp(wxProcess* proc, std::ostringstream& oss);
+ void DrainApp(wxProcess* proc, wxTextCtrl *frame);
void OnGenerateFX(wxCommandEvent& event);
void LoadAndSetIcons();
diff --git a/GUI/GUI/GUI/GUI.vcxproj b/GUI/GUI/GUI/GUI.vcxproj
index cd0e5f0..8327365 100644
--- a/GUI/GUI/GUI/GUI.vcxproj
+++ b/GUI/GUI/GUI/GUI.vcxproj
@@ -137,12 +137,14 @@
<ItemGroup>
<ClCompile Include="App.cpp" />
<ClCompile Include="Frame.cpp" />
+ <ClCompile Include="Logging.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="PythonWrapper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="App.h" />
<ClInclude Include="Frame.h" />
+ <ClInclude Include="Logging.h" />
<ClInclude Include="PythonWrapper.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="ScopeGuard.h" />
diff --git a/GUI/GUI/GUI/GUI.vcxproj.filters b/GUI/GUI/GUI/GUI.vcxproj.filters
index 5118c26..348026a 100644
--- a/GUI/GUI/GUI/GUI.vcxproj.filters
+++ b/GUI/GUI/GUI/GUI.vcxproj.filters
@@ -27,6 +27,9 @@
<ClCompile Include="PythonWrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="Logging.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="PythonWrapper.h">
@@ -44,6 +47,9 @@
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="Logging.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="GUI.rc">
diff --git a/GUI/GUI/GUI/Logging.cpp b/GUI/GUI/GUI/Logging.cpp
new file mode 100644
index 0000000..6727ba1
--- /dev/null
+++ b/GUI/GUI/GUI/Logging.cpp
@@ -0,0 +1,17 @@
+#include "Logging.h"
+
+#include <regex>
+#include <string>
+
+std::string Logging::HidePII(const std::string&& str,
+ const std::string& replacement) {
+ try {
+ std::regex c_users("(C:\\\\Users\\\\)[a-zA-Z0-9_]+");
+ std::string real_replacement = "$1" + replacement;
+ return std::regex_replace(str, c_users, real_replacement);
+ }
+ catch (const std::regex_error& e) {
+ wxLogFatalError(e.what());
+ }
+ wxLogFatalError("Unhandled regex error (HidePII)");
+}
diff --git a/GUI/GUI/GUI/Logging.h b/GUI/GUI/GUI/Logging.h
new file mode 100644
index 0000000..95e7802
--- /dev/null
+++ b/GUI/GUI/GUI/Logging.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#pragma once
+
+#include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <format>
+#include <string>
+#include <string_view>
+
+namespace Logging {
+ // Remove personally identifying information (PII) from str.
+ //
+ // For example, this translates "C:/Users/foo/Desktop" to "C:/Users/*****/Desktop".
+ std::string HidePII(const std::string&& str, const std::string& replacement = "*****");
+
+ // Provides a simple Python format()-like interface to wxTextCtrl.
+ // Ex: Log(my_textctrl_, "{}\n", "Hello, world!");
+ template<typename... Args>
+ void Log(wxTextCtrl* frame, std::string_view format, Args&&... args) {
+ const std::string raw = std::vformat(format, std::make_format_args(args...));
+ const std::string masked = HidePII(std::move(raw));
+ frame->AppendText(masked);
+ }
+}
+
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp
index 972982f..2e37994 100644
--- a/GUI/GUI/GUI/PythonWrapper.cpp
+++ b/GUI/GUI/GUI/PythonWrapper.cpp
@@ -1,3 +1,4 @@
+#include "Logging.h"
#include "PythonWrapper.h"
#include <stdio.h>
@@ -5,6 +6,8 @@
#include <filesystem>
#include <sstream>
+using ::Logging::Log;
+
class PythonProcess : public wxProcess {
public:
PythonProcess(std::function<void(wxProcess* proc, int ret)>&& exit_callback) : exit_cb_(exit_callback) {
@@ -178,18 +181,14 @@ bool PythonWrapper::GenerateAnimator(
{
if (std::filesystem::exists(tastt_generated_dir_path)) {
- std::ostringstream oss;
- oss << "Erasing " << tastt_generated_dir_path << std::endl;
- out->AppendText(oss.str());
+ Log(out, "Erasing {}\n", tastt_generated_dir_path.string());
std::filesystem::remove_all(tastt_generated_dir_path);
}
- std::ostringstream oss;
- oss << "Creating " << tastt_generated_dir_path << std::endl;
- out->AppendText(oss.str());
+ Log(out, "Creating {}\n", tastt_generated_dir_path.string());
std::filesystem::create_directories(tastt_generated_dir_path);
}
{
- out->AppendText("Copying canned animations... ");
+ Log(out, "Copying canned animations... ");
auto opts = std::filesystem::copy_options();
opts |= std::filesystem::copy_options::overwrite_existing;
opts |= std::filesystem::copy_options::recursive;
@@ -197,13 +196,13 @@ bool PythonWrapper::GenerateAnimator(
std::filesystem::copy("Resources/Animations", tastt_animations_path, opts, error);
if (error.value()) {
wxLogError("Failed to copy animations: %s (%d)", error.message(), error.value());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
- out->AppendText("success!\n");
+ Log(out, "success!\n");
}
{
- out->AppendText("Copying canned assets... ");
+ Log(out, "Copying canned assets... ");
auto opts = std::filesystem::copy_options();
opts |= std::filesystem::copy_options::overwrite_existing;
opts |= std::filesystem::copy_options::recursive;
@@ -211,13 +210,13 @@ bool PythonWrapper::GenerateAnimator(
std::filesystem::copy("Resources/UnityAssets", tastt_assets_path, opts, error);
if (error.value()) {
wxLogError("Failed to copy animations: %s (%d)", error.message(), error.value());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
- out->AppendText("success!\n");
+ Log(out, "success!\n");
}
{
- out->AppendText("Copying canned shaders... ");
+ Log(out, "Copying canned shaders... ");
auto opts = std::filesystem::copy_options();
opts |= std::filesystem::copy_options::overwrite_existing;
opts |= std::filesystem::copy_options::recursive;
@@ -225,13 +224,13 @@ bool PythonWrapper::GenerateAnimator(
std::filesystem::copy("Resources/Shaders", tastt_shaders_path, opts, error);
if (error.value()) {
wxLogError("Failed to copy animations: %s (%d)", error.message(), error.value());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
- out->AppendText("success!\n");
+ Log(out, "success!\n");
}
{
- out->AppendText("Copying canned fonts... ");
+ Log(out, "Copying canned fonts... ");
auto opts = std::filesystem::copy_options();
opts |= std::filesystem::copy_options::overwrite_existing;
opts |= std::filesystem::copy_options::recursive;
@@ -239,83 +238,83 @@ bool PythonWrapper::GenerateAnimator(
std::filesystem::copy("Resources/Fonts", tastt_fonts_path, opts, error);
if (error.value()) {
wxLogError("Failed to copy animations: %s (%d)", error.message(), error.value());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
- out->AppendText("success!\n");
+ Log(out, "success!\n");
}
{
- out->AppendText("Generating guid.map... ");
+ Log(out, "Generating guid.map... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libunity_path, "guid_map",
"--project_root", unity_assets_path,
"--save_to", guid_map_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to generate guid.map: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Generating animations... ");
+ Log(out, "Generating animations... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libtastt_path, "gen_anims",
"--gen_anim_dir", tastt_animations_path.string(),
"--guid_map", guid_map_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to generate animations: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Generating FX layer... ");
+ Log(out, "Generating FX layer... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libtastt_path, "gen_fx",
"--fx_dest", tastt_fx0_path.string(),
"--gen_anim_dir", tastt_animations_path.string(),
"--guid_map", guid_map_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to generate FX layer: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Adding enable/disable toggle... ");
+ Log(out, "Adding enable/disable toggle... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libunity_path, "add_toggle",
"--fx0", tastt_fx0_path.string(),
@@ -323,48 +322,48 @@ bool PythonWrapper::GenerateAnimator(
"--gen_anim_dir", tastt_animations_path.string(),
"--guid_map", guid_map_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to add enable/disable toggle: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Merging with user animator... ");
+ Log(out, "Merging with user animator... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libunity_path, "merge",
"--fx0", unity_animator_path,
"--fx1", tastt_fx1_path.string(),
"--fx_dest", tastt_fx2_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to merge animators: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Setting noop animations... ");
+ Log(out, "Setting noop animations... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libunity_path, "set_noop_anim",
"--fx0", tastt_fx2_path.string(),
@@ -372,65 +371,65 @@ bool PythonWrapper::GenerateAnimator(
"--gen_anim_dir", tastt_animations_path.string(),
"--guid_map", guid_map_path.string() },
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to set noop animations: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Generating avatar parameters... ");
+ Log(out, "Generating avatar parameters... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ generate_params_path,
"--old_params", unity_parameters_path,
"--new_params", tastt_params_path.string()},
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to generate avatar parameters: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
{
- out->AppendText("Generating avatar menu... ");
+ Log(out, "Generating avatar menu... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ generate_menu_path,
"--old_menu", unity_menu_path,
"--new_menu", tastt_menu_path.string()},
&py_stdout, &py_stderr)) {
- out->AppendText("success!\n");
- out->AppendText(py_stdout.c_str());
+ Log(out, "success!\n");
+ Log(out, py_stdout.c_str());
if (!py_stdout.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
- out->AppendText(py_stderr.c_str());
+ Log(out, py_stderr.c_str());
if (!py_stderr.empty()) {
- out->AppendText("\n");
+ Log(out, "\n");
}
}
else {
wxLogError("Failed to generate avatar menu: %s", py_stderr.c_str());
- out->AppendText("failed!\n");
+ Log(out, "failed!\n");
return false;
}
}
diff --git a/GUI/README.md b/GUI/README.md
index 079474d..f8cc3a1 100644
--- a/GUI/README.md
+++ b/GUI/README.md
@@ -1,10 +1,16 @@
## Build instructions
0. Open Powershell.
-1. Execute Libraries/fetch.ps1.
-2. Install Visual Studio 2022.
+1. Make sure you've downloaded submodules:
+```
+$ git submodule init
+$ git submodule update
+```
+2. Execute Libraries/fetch.ps1.
3. Open Libraries/wx/build/msw/wx\_vc17.sln with Visual Studio 2022.
4. Build x64/Release.
+ 1. The build configuration is in the top. By default it's probably Debug/x64.
+ 2. To build: ctrl+shift+B
5. Open GUI/GUI.sln with Visual Studio 2022.
6. Build x64/Release.
7. Run package.ps1 from powershell.