feat: profiles can be editable or not; forbid editing non editable profiles and prompt to duplicate the profile

This commit is contained in:
Gabriele Musco 2023-06-22 21:46:00 +02:00
parent 50a89399e2
commit d44e0815a0
No known key found for this signature in database
GPG key ID: 1068D795C80E51DE
6 changed files with 67 additions and 7 deletions

View file

@ -28,6 +28,7 @@ pub struct Profile {
/** Install prefix */
pub prefix: String,
pub can_be_built: bool,
pub editable: bool,
}
impl Display for Profile {
@ -121,6 +122,7 @@ mod tests {
environment: env,
prefix: String::from("/home/user/rex2prefix"),
can_be_built: true,
editable: true,
};
let fpath = String::from("./target/testout/testprofile.json");
p.dump_profile(&fpath);

View file

@ -21,5 +21,6 @@ pub fn system_valve_index_profile() -> Profile {
environment,
prefix: SYSTEM_PREFIX.into(),
can_be_built: false,
editable: false,
}
}

View file

@ -24,5 +24,6 @@ pub fn valve_index_profile() -> Profile {
environment,
prefix,
can_be_built: true,
editable: false,
}
}

View file

@ -21,5 +21,6 @@ pub fn wivrn_profile() -> Profile {
environment,
prefix,
can_be_built: true,
editable: false,
}
}

View file

@ -12,6 +12,8 @@ use crate::ui::app::{
};
use crate::ui::profile_editor::ProfileEditorInit;
use gtk::prelude::*;
use relm4::adw::traits::MessageDialogExt;
use relm4::adw::ResponseAppearance;
use relm4::prelude::*;
use relm4::{ComponentParts, ComponentSender, SimpleComponent};
use relm4_icons::icon_name;
@ -32,6 +34,8 @@ pub struct MainView {
runtime_switcher_box: Controller<RuntimeSwitcherBox>,
#[tracker::do_not_track]
profile_editor: Controller<ProfileEditor>,
#[tracker::do_not_track]
profile_not_editable_dialog: adw::MessageDialog,
}
#[derive(Debug)]
@ -45,6 +49,7 @@ pub enum MainViewMsg {
ProfileSelected(u32),
UpdateSelectedProfile(Profile),
EditProfile,
DuplicateProfile,
}
#[derive(Debug)]
@ -231,7 +236,15 @@ impl SimpleComponent for MainView {
));
}
Self::Input::EditProfile => {
self.profile_editor.emit(ProfileEditorMsg::Present(self.selected_profile.clone()));
if self.selected_profile.editable {
self.profile_editor
.emit(ProfileEditorMsg::Present(self.selected_profile.clone()));
} else {
self.profile_not_editable_dialog.present();
}
}
Self::Input::DuplicateProfile => {
println!("dup")
}
}
}
@ -241,6 +254,30 @@ impl SimpleComponent for MainView {
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let profile_not_editable_dialog = adw::MessageDialog::builder()
.modal(true)
// .transient_for(root.root().unwrap().upcast_ref::<gtk::Window>())
.heading("This profile is not editable")
.body(concat!(
"You can duplicate it and edit the new copy. ",
"Do you want to duplicate the current profile?"
))
.hide_on_close(true)
.build();
profile_not_editable_dialog.add_response("no", "_No");
profile_not_editable_dialog.add_response("yes", "_Yes");
profile_not_editable_dialog.set_response_appearance("no", ResponseAppearance::Destructive);
profile_not_editable_dialog.set_response_appearance("yes", ResponseAppearance::Suggested);
{
let pne_sender = sender.clone();
profile_not_editable_dialog.connect_response(None, move |_, res| {
if res == "yes" {
pne_sender.input(Self::Input::DuplicateProfile);
}
});
}
let mut model = Self {
xrservice_active: false,
enable_debug_view: init.config.debug_view_enabled,
@ -257,8 +294,11 @@ impl SimpleComponent for MainView {
selected_profile: init.selected_profile.clone(),
})
.detach(),
profile_editor: ProfileEditor::builder().launch(ProfileEditorInit {}).detach(),
profile_editor: ProfileEditor::builder()
.launch(ProfileEditorInit {})
.detach(),
selected_profile: init.selected_profile.clone(),
profile_not_editable_dialog,
tracker: 0,
};
let widgets = view_output!();

View file

@ -5,13 +5,20 @@ use gtk::prelude::*;
use relm4::{factory::FactoryVecDeque, prelude::*};
use relm4_icons::icon_name;
#[tracker::track]
pub struct ProfileEditor {
profile: Option<Profile>,
#[tracker::do_not_track]
win: Option<adw::PreferencesWindow>,
#[tracker::do_not_track]
name_row: adw::EntryRow,
#[tracker::do_not_track]
env_rows: FactoryVecDeque<EntryModel>,
#[tracker::do_not_track]
switch_rows: FactoryVecDeque<SwitchModel>,
#[tracker::do_not_track]
path_rows: FactoryVecDeque<PathModel>,
}
@ -36,6 +43,11 @@ impl SimpleComponent for ProfileEditor {
adw::PreferencesWindow {
set_hide_on_close: true,
set_modal: true,
#[track = "model.changed(Self::profile())"]
set_title: match model.profile.as_ref() {
Some(p) => Some(p.name.as_str()),
None => None,
},
add: mainpage = &adw::PreferencesPage {
add: maingrp = &adw::PreferencesGroup {
set_title: "Profile Info",
@ -49,13 +61,14 @@ impl SimpleComponent for ProfileEditor {
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
self.reset();
match message {
Self::Input::Present(prof) => {
let win = self.win.as_ref().unwrap();
let p = prof.clone();
win.set_title(Some(p.name.as_str()));
self.name_row.set_text(p.name.as_str());
self.env_rows.guard().clear();
for (k, v) in p.environment.iter() {
self.env_rows.guard().push_back(EntryModelInit {
@ -111,8 +124,9 @@ impl SimpleComponent for ProfileEditor {
value: p.mercury_path
});
self.profile = Some(prof);
win.present();
self.set_profile(Some(prof.clone()));
self.win.as_ref().unwrap().present();
}
Self::Input::SaveProfile => {}
Self::Input::EntryChanged(name, value) => {
@ -173,7 +187,8 @@ impl SimpleComponent for ProfileEditor {
// .description("")
.build(),
sender.input_sender(),
)
),
tracker: 0,
};
let widgets = view_output!();