use std::sync::Arc;
use crate::app_context::AppContext;
use crate::commands::global_commands;
use crate::event_hub_client::EventHubClient;
use crate::{App, AppState, ProjectTabState};
use common::event::{DirectAccessEntity, EntityEvent, HandlingManifestEvent, Origin};
use slint::ComponentHandle;
fn create_new_undo_stack(app: &App, app_context: &Arc<AppContext>) {
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
if let Some(app) = app_weak.upgrade() {
let stack_id = ctx.undo_redo_manager.lock().unwrap().create_new_stack();
log::info!("New undo stack created with ID: {}", stack_id);
app.global::<ProjectTabState>()
.set_project_undo_stack_id(stack_id as i32);
}
}
fn delete_undo_stack(app: &App, app_context: &Arc<AppContext>) {
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
if let Some(app) = app_weak.upgrade() {
let stack_id = app.global::<ProjectTabState>().get_project_undo_stack_id() as u64;
let result = ctx.undo_redo_manager.lock().unwrap().delete_stack(stack_id);
match result {
Ok(()) => {
log::info!("Undo stack with ID {} deleted", stack_id);
app.global::<ProjectTabState>()
.set_project_undo_stack_id(-1);
}
Err(e) => {
log::error!("Failed to delete undo stack {}: {}", stack_id, e);
}
}
}
}
fn fill_project_tab(app: &App, app_context: &Arc<AppContext>) {
log::info!("Filling ProjectTabState with data from Global entity");
if let Some(global_id) = crate::tabs::common::get_global_id(app, app_context)
&& let Ok(Some(global)) = global_commands::get_global(app_context, &global_id)
{
log::info!("Filling ProjectTabState with global data: {:?}", global);
let language = match global.language.to_lowercase().as_str() {
"rust" => "Rust",
"cpp-qt" => "C++ / Qt",
_ => "Rust",
};
app.global::<ProjectTabState>()
.set_language(slint::SharedString::from(language));
app.global::<ProjectTabState>()
.set_application_name(slint::SharedString::from(&global.application_name));
app.global::<ProjectTabState>()
.set_organisation_name(slint::SharedString::from(&global.organisation_name));
app.global::<ProjectTabState>()
.set_organisation_domain(slint::SharedString::from(&global.organisation_domain));
app.global::<ProjectTabState>()
.set_prefix_path(slint::SharedString::from(&global.prefix_path));
}
}
fn clear_project_tab(app: &App) {
log::info!("Clearing ProjectTabState data");
app.global::<ProjectTabState>()
.set_language(slint::SharedString::from("Rust"));
app.global::<ProjectTabState>()
.set_application_name(slint::SharedString::from(""));
app.global::<ProjectTabState>()
.set_organisation_name(slint::SharedString::from(""));
app.global::<ProjectTabState>()
.set_organisation_domain(slint::SharedString::from(""));
app.global::<ProjectTabState>()
.set_prefix_path(slint::SharedString::from(""));
}
fn subscribe_close_manifest_event(
event_hub_client: &EventHubClient,
app: &App,
app_context: &Arc<AppContext>,
) {
event_hub_client.subscribe(Origin::HandlingManifest(HandlingManifestEvent::Close), {
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |event| {
log::info!("Manifest closed event received: {:?}", event);
let ctx = Arc::clone(&ctx);
let app_weak = app_weak.clone();
let _ = slint::invoke_from_event_loop(move || {
if let Some(app) = app_weak.upgrade()
&& app.global::<AppState>().get_manifest_is_open()
{
clear_project_tab(&app);
delete_undo_stack(&app, &ctx);
}
});
}
});
}
fn subscribe_new_manifest_event(
event_hub_client: &EventHubClient,
app: &App,
app_context: &Arc<AppContext>,
) {
event_hub_client.subscribe(Origin::HandlingManifest(HandlingManifestEvent::Create), {
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |_event| {
log::info!("New manifest created event received");
let ctx = Arc::clone(&ctx);
let app_weak = app_weak.clone();
let _ = slint::invoke_from_event_loop(move || {
if let Some(app) = app_weak.upgrade()
&& app.global::<AppState>().get_manifest_is_open()
{
fill_project_tab(&app, &ctx);
create_new_undo_stack(&app, &ctx);
}
});
}
});
}
fn subscribe_load_manifest_event(
event_hub_client: &EventHubClient,
app: &App,
app_context: &Arc<AppContext>,
) {
event_hub_client.subscribe(Origin::HandlingManifest(HandlingManifestEvent::Load), {
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |_event| {
log::info!("Manifest loaded event received");
let ctx = Arc::clone(&ctx);
let app_weak = app_weak.clone();
let _ = slint::invoke_from_event_loop(move || {
if let Some(app) = app_weak.upgrade()
&& app.global::<AppState>().get_manifest_is_open()
{
fill_project_tab(&app, &ctx);
create_new_undo_stack(&app, &ctx);
}
});
}
});
}
fn subscribe_global_created_event(
event_hub_client: &EventHubClient,
app: &App,
app_context: &Arc<AppContext>,
) {
event_hub_client.subscribe(
Origin::DirectAccess(DirectAccessEntity::Global(EntityEvent::Created)),
{
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |event| {
log::info!("Global created event received {:?}", event);
let ctx = Arc::clone(&ctx);
let app_weak = app_weak.clone();
let _ = slint::invoke_from_event_loop(move || {
if let Some(app) = app_weak.upgrade()
&& app.global::<AppState>().get_manifest_is_open()
{
fill_project_tab(&app, &ctx);
}
});
}
},
);
}
fn subscribe_global_updated_event(
event_hub_client: &EventHubClient,
app: &App,
app_context: &Arc<AppContext>,
) {
event_hub_client.subscribe(
Origin::DirectAccess(DirectAccessEntity::Global(EntityEvent::Updated)),
{
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |event| {
log::info!("Global updated event received {:?}", event);
let ctx = Arc::clone(&ctx);
let app_weak = app_weak.clone();
let _ = slint::invoke_from_event_loop(move || {
if let Some(app) = app_weak.upgrade()
&& app.global::<AppState>().get_manifest_is_open()
{
app.global::<AppState>().set_manifest_is_saved(false);
fill_project_tab(&app, &ctx);
}
});
}
},
);
}
fn update_global_helper<F>(app: &App, app_context: &Arc<AppContext>, update_fn: F)
where
F: FnOnce(&mut direct_access::GlobalDto),
{
if let Some(global_id) = crate::tabs::common::get_global_id(app, app_context) {
let global_res = global_commands::get_global(app_context, &global_id);
if let Ok(Some(mut global)) = global_res {
update_fn(&mut global);
match global_commands::update_global(
app_context,
Some(app.global::<ProjectTabState>().get_project_undo_stack_id() as u64),
&global.into(),
) {
Ok(_) => {
log::info!("Global updated successfully");
}
Err(e) => {
log::error!("Failed to update global: {}", e);
}
}
}
}
}
fn setup_language_callback(app: &App, app_context: &Arc<AppContext>) {
app.global::<ProjectTabState>().on_language_changed({
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |new_value| {
if let Some(app) = app_weak.upgrade() {
let value_str = new_value.to_string();
update_global_helper(&app, &ctx, |global| {
global.language = match value_str.as_str() {
"Rust" => "rust".to_string(),
"C++ / Qt" => "cpp-qt".to_string(),
_ => value_str.to_lowercase(),
};
});
}
}
});
}
fn setup_application_name_callback(app: &App, app_context: &Arc<AppContext>) {
app.global::<ProjectTabState>()
.on_application_name_changed({
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |new_value| {
if let Some(app) = app_weak.upgrade() {
let value_str = new_value.to_string();
update_global_helper(&app, &ctx, |global| {
global.application_name = value_str;
});
}
}
});
}
fn setup_organisation_name_callback(app: &App, app_context: &Arc<AppContext>) {
app.global::<ProjectTabState>()
.on_organisation_name_changed({
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |new_value| {
if let Some(app) = app_weak.upgrade() {
let value_str = new_value.to_string();
update_global_helper(&app, &ctx, |global| {
global.organisation_name = value_str;
});
}
}
});
}
fn setup_organisation_domain_callback(app: &App, app_context: &Arc<AppContext>) {
app.global::<ProjectTabState>()
.on_organisation_domain_changed({
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |new_value| {
if let Some(app) = app_weak.upgrade() {
let value_str = new_value.to_string();
update_global_helper(&app, &ctx, |global| {
global.organisation_domain = value_str;
});
}
}
});
}
fn setup_prefix_path_callback(app: &App, app_context: &Arc<AppContext>) {
app.global::<ProjectTabState>().on_prefix_path_changed({
let ctx = Arc::clone(app_context);
let app_weak = app.as_weak();
move |new_value| {
if let Some(app) = app_weak.upgrade() {
let value_str = new_value.to_string();
update_global_helper(&app, &ctx, |global| {
global.prefix_path = value_str;
});
}
}
});
}
pub fn init(event_hub_client: &EventHubClient, app: &App, app_context: &Arc<AppContext>) {
subscribe_global_created_event(event_hub_client, app, app_context);
subscribe_global_updated_event(event_hub_client, app, app_context);
subscribe_new_manifest_event(event_hub_client, app, app_context);
subscribe_close_manifest_event(event_hub_client, app, app_context);
subscribe_load_manifest_event(event_hub_client, app, app_context);
setup_language_callback(app, app_context);
setup_application_name_callback(app, app_context);
setup_organisation_name_callback(app, app_context);
setup_organisation_domain_callback(app, app_context);
setup_prefix_path_callback(app, app_context);
}