diff --git a/espanso-modulo/build.rs b/espanso-modulo/build.rs
index 740d424..85adb6e 100644
--- a/espanso-modulo/build.rs
+++ b/espanso-modulo/build.rs
@@ -117,6 +117,8 @@ fn build_native() {
.file("src/sys/wizard/wizard_gui.cpp")
.file("src/sys/welcome/welcome.cpp")
.file("src/sys/welcome/welcome_gui.cpp")
+ .file("src/sys/troubleshooting/troubleshooting.cpp")
+ .file("src/sys/troubleshooting/troubleshooting_gui.cpp")
.flag("/EHsc")
.include(wx_include_dir)
.include(wx_include_msvc_dir)
@@ -215,6 +217,8 @@ fn build_native() {
.file("src/sys/wizard/wizard_gui.cpp")
.file("src/sys/welcome/welcome.cpp")
.file("src/sys/welcome/welcome_gui.cpp")
+ .file("src/sys/troubleshooting/troubleshooting.cpp")
+ .file("src/sys/troubleshooting/troubleshooting_gui.cpp")
.file("src/sys/common/mac.mm");
build.flag("-std=c++17");
@@ -353,7 +357,9 @@ fn build_native() {
.file("src/sys/wizard/wizard.cpp")
.file("src/sys/wizard/wizard_gui.cpp")
.file("src/sys/welcome/welcome.cpp")
- .file("src/sys/welcome/welcome_gui.cpp");
+ .file("src/sys/welcome/welcome_gui.cpp")
+ .file("src/sys/troubleshooting/troubleshooting.cpp")
+ .file("src/sys/troubleshooting/troubleshooting_gui.cpp");
build.flag("-std=c++17");
for flag in cpp_flags {
diff --git a/espanso-modulo/src/lib.rs b/espanso-modulo/src/lib.rs
index 2eb870a..b139690 100644
--- a/espanso-modulo/src/lib.rs
+++ b/espanso-modulo/src/lib.rs
@@ -22,6 +22,7 @@ extern crate lazy_static;
pub mod form;
pub mod search;
+pub mod troubleshooting;
pub mod welcome;
pub mod wizard;
mod sys;
\ No newline at end of file
diff --git a/espanso-modulo/src/sys/interop/interop.h b/espanso-modulo/src/sys/interop/interop.h
index 351646a..1fd0e9f 100644
--- a/espanso-modulo/src/sys/interop/interop.h
+++ b/espanso-modulo/src/sys/interop/interop.h
@@ -120,6 +120,8 @@ typedef struct WizardMetadata {
void (*on_completed)();
} WizardMetadata;
+// WELCOME
+
typedef struct WelcomeMetadata {
const char *window_icon_path;
const char *tray_image_path;
@@ -128,3 +130,30 @@ typedef struct WelcomeMetadata {
int (*dont_show_again_changed)(int);
} WelcomeMetadata;
+// TROUBLESHOOTING
+
+const int ERROR_METADATA_LEVEL_ERROR = 1;
+const int ERROR_METADATA_LEVEL_WARNING = 2;
+typedef struct ErrorMetadata {
+ const int level;
+ const char *message;
+} ErrorMetadata;
+
+typedef struct ErrorSetMetadata {
+ const char *file_path;
+ const ErrorMetadata * errors;
+ const int errors_count;
+} ErrorSetMetadata;
+
+typedef struct TroubleshootingMetadata {
+ const char *window_icon_path;
+
+ const int is_fatal_error;
+
+ const ErrorSetMetadata * error_sets;
+ const int error_sets_count;
+
+ // METHODS
+ int (*dont_show_again_changed)(int);
+ int (*open_file)(const char * file_name);
+} TroubleshootingMetadata;
diff --git a/espanso-modulo/src/sys/interop/mod.rs b/espanso-modulo/src/sys/interop/mod.rs
index 07f4e08..7d8b06d 100644
--- a/espanso-modulo/src/sys/interop/mod.rs
+++ b/espanso-modulo/src/sys/interop/mod.rs
@@ -146,6 +146,38 @@ pub struct WelcomeMetadata {
pub dont_show_again_changed: extern fn(c_int),
}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct TroubleshootingMetadata {
+ pub window_icon_path: *const c_char,
+ pub is_fatal_error: c_int,
+
+ pub error_sets: *const ErrorSetMetadata,
+ pub error_sets_count: c_int,
+
+ pub dont_show_again_changed: extern fn(c_int),
+ pub open_file: extern fn(*const c_char),
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct ErrorSetMetadata {
+ pub file_path: *const c_char,
+
+ pub errors: *const ErrorMetadata,
+ pub errors_count: c_int,
+}
+
+pub const ERROR_METADATA_LEVEL_ERROR: c_int = 1;
+pub const ERROR_METADATA_LEVEL_WARNING: c_int = 2;
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct ErrorMetadata {
+ pub level: c_int,
+ pub message: *const c_char,
+}
+
// Native bindings
#[allow(improper_ctypes)]
@@ -174,4 +206,7 @@ extern "C" {
// WELCOME
pub(crate) fn interop_show_welcome(metadata: *const WelcomeMetadata);
+
+ // TROUBLESHOOTING
+ pub(crate) fn interop_show_troubleshooting(metadata: *const TroubleshootingMetadata);
}
diff --git a/espanso-modulo/src/sys/mod.rs b/espanso-modulo/src/sys/mod.rs
index dc479ff..3ac74cc 100644
--- a/espanso-modulo/src/sys/mod.rs
+++ b/espanso-modulo/src/sys/mod.rs
@@ -19,6 +19,7 @@
pub mod form;
pub mod search;
+pub mod troubleshooting;
pub mod wizard;
pub mod welcome;
diff --git a/espanso-modulo/src/sys/troubleshooting/mod.rs b/espanso-modulo/src/sys/troubleshooting/mod.rs
new file mode 100644
index 0000000..f8c27e6
--- /dev/null
+++ b/espanso-modulo/src/sys/troubleshooting/mod.rs
@@ -0,0 +1,176 @@
+/*
+ * This file is part of modulo.
+ *
+ * Copyright (C) 2020-2021 Federico Terzi
+ *
+ * modulo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * modulo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with modulo. If not, see .
+ */
+
+use std::ffi::CStr;
+use std::os::raw::{c_char, c_int};
+use std::path::PathBuf;
+use std::sync::Mutex;
+
+use crate::sys::interop::{ErrorSetMetadata, TroubleshootingMetadata};
+use crate::sys::troubleshooting::interop::{OwnedErrorSet};
+use crate::sys::util::convert_to_cstring_or_null;
+use crate::troubleshooting::{TroubleshootingHandlers, TroubleshootingOptions};
+use anyhow::Result;
+
+lazy_static! {
+ static ref HANDLERS: Mutex