Skip to content

Commit ca56889

Browse files
committed
Implemented Import/Export All Open MyMod Actions.
1 parent e9abb33 commit ca56889

9 files changed

Lines changed: 131 additions & 20 deletions

File tree

2.88 KB
Binary file not shown.

3rdparty/src/qt_rpfm_extensions/src/kshortcuts_dialog.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ extern "C" void shortcut_collection_init(QWidget* parent, QList<QObject*>* short
3535
new_action(mymod_menu_actions, "delete_mymod", "Delete Open MyMod", Qt::ShortcutContext::ApplicationShortcut, QKeySequence::listFromString(""), "draw-eraser-delete-objects");
3636
new_action(mymod_menu_actions, "import_mymod", "Import MyMod", Qt::ShortcutContext::ApplicationShortcut, QKeySequence::listFromString("Ctrl+Alt+I"), "document-import");
3737
new_action(mymod_menu_actions, "export_mymod", "Export MyMod", Qt::ShortcutContext::ApplicationShortcut, QKeySequence::listFromString("Ctrl+Alt+E"), "document-export");
38+
new_action(mymod_menu_actions, "import_all_mymod", "Import All Open MyMods", Qt::ShortcutContext::ApplicationShortcut, QKeySequence::listFromString("Ctrl+Alt+Shift+I"), "document-import");
39+
new_action(mymod_menu_actions, "export_all_mymod", "Export All Open MyMods", Qt::ShortcutContext::ApplicationShortcut, QKeySequence::listFromString("Ctrl+Alt+Shift+E"), "document-export");
3840
mymod_menu_actions->readSettings();
3941

4042
// View Menu actions.

locale/English_en.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ mymod_new = New MyMod
103103
mymod_delete_selected = Delete Selected MyMod
104104
mymod_import = Import
105105
mymod_export = Export
106+
mymod_import_all = Import All Open MyMods
107+
mymod_export_all = Export All Open MyMods
106108
107109
mymod_name = Name of the Mod:
108110
mymod_name_default = For example: one_ring_for_me
@@ -224,6 +226,8 @@ tt_mymod_delete_selected = Delete the currently selected MyMod.
224226
225227
tt_mymod_import = Move all of the contents of the MyMod folder into the .pack file. If any files have been removed in the MyMod folder, they will be deleted in the .pack file.
226228
tt_mymod_export = Move all of the contents from the .pack file into the MyMod folder. If any files have been removed from the .pack, they will be deleted in the MyMod folder.
229+
tt_mymod_import_all = Run <i>Import</i> on every open MyMod pack.
230+
tt_mymod_export_all = Run <i>Export</i> on every open MyMod pack.
227231
228232
## GameSelected menu tips
229233

rpfm_ui/src/app_ui/connections.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ pub unsafe fn set_connections(app_ui: &Rc<AppUI>, slots: &AppUISlots) {
5252
app_ui.menu_bar_mymod.about_to_show().connect(&slots.mymod_open_menu);
5353
app_ui.mymod_open_mymod_folder.triggered().connect(&slots.mymod_open_mymod_folder);
5454
app_ui.mymod_new.triggered().connect(&slots.mymod_new);
55+
app_ui.mymod_import_all.triggered().connect(&slots.mymod_import_all);
56+
app_ui.mymod_export_all.triggered().connect(&slots.mymod_export_all);
5557

5658
//-----------------------------------------------//
5759
// `View` menu connections.

rpfm_ui/src/app_ui/mod.rs

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ pub struct AppUI {
201201
//-------------------------------------------------------------------------------//
202202
mymod_open_mymod_folder: QPtr<QAction>,
203203
mymod_new: QPtr<QAction>,
204+
mymod_import_all: QPtr<QAction>,
205+
mymod_export_all: QPtr<QAction>,
204206

205207
mymod_open_pharaoh_dynasties: QPtr<QMenu>,
206208
mymod_open_pharaoh: QPtr<QMenu>,
@@ -466,6 +468,8 @@ impl AppUI {
466468
//-----------------------------------------------//
467469
let mymod_open_mymod_folder = add_action_to_menu(&menu_bar_mymod, shortcuts.as_ref(), "mymod_menu", "open_mymod_folder", "mymod_open_mymod_folder", Some(main_window.static_upcast::<qt_widgets::QWidget>()));
468470
let mymod_new = add_action_to_menu(&menu_bar_mymod, shortcuts.as_ref(), "mymod_menu", "new_mymod", "mymod_new", Some(main_window.static_upcast::<qt_widgets::QWidget>()));
471+
let mymod_import_all = add_action_to_menu(&menu_bar_mymod, shortcuts.as_ref(), "mymod_menu", "import_all_mymod", "mymod_import_all", Some(main_window.static_upcast::<qt_widgets::QWidget>()));
472+
let mymod_export_all = add_action_to_menu(&menu_bar_mymod, shortcuts.as_ref(), "mymod_menu", "export_all_mymod", "mymod_export_all", Some(main_window.static_upcast::<qt_widgets::QWidget>()));
469473

470474
menu_bar_mymod.add_separator();
471475

@@ -486,6 +490,8 @@ impl AppUI {
486490
menu_bar_mymod.insert_separator(&mymod_new);
487491

488492
mymod_new.set_enabled(false);
493+
mymod_import_all.set_enabled(false);
494+
mymod_export_all.set_enabled(false);
489495

490496
mymod_open_pharaoh_dynasties.menu_action().set_visible(false);
491497
mymod_open_pharaoh.menu_action().set_visible(false);
@@ -686,6 +692,8 @@ impl AppUI {
686692
//-------------------------------------------------------------------------------//
687693
mymod_open_mymod_folder,
688694
mymod_new,
695+
mymod_import_all,
696+
mymod_export_all,
689697

690698
mymod_open_pharaoh_dynasties,
691699
mymod_open_pharaoh,
@@ -1338,6 +1346,8 @@ impl AppUI {
13381346

13391347
// This one too, though we had to deal with it specially later on.
13401348
app_ui.mymod_new.set_enabled(false);
1349+
app_ui.mymod_import_all.set_enabled(false);
1350+
app_ui.mymod_export_all.set_enabled(false);
13411351
}
13421352

13431353
// Otherwise...
@@ -1353,8 +1363,10 @@ impl AppUI {
13531363

13541364
// If there is a "MyMod" path set in the settings...
13551365
let path = settings_path_buf(MYMOD_BASE_PATH);
1356-
if path.is_dir() { app_ui.mymod_new.set_enabled(true); }
1357-
else { app_ui.mymod_new.set_enabled(false); }
1366+
let mymod_path_ok = path.is_dir();
1367+
app_ui.mymod_new.set_enabled(mymod_path_ok);
1368+
app_ui.mymod_import_all.set_enabled(enable && mymod_path_ok);
1369+
app_ui.mymod_export_all.set_enabled(enable && mymod_path_ok);
13581370
}
13591371

13601372
// If we are disabling...
@@ -3840,8 +3852,7 @@ impl AppUI {
38403852
paths_packedfile.push(ContainerPath::File(filtered_path.to_string_lossy().to_string()));
38413853
}
38423854

3843-
let pack_key = pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default();
3844-
let settings = send_ipc_command(Command::GetPackSettings(pack_key), response_extractor!(Response::PackSettings));
3855+
let settings = send_ipc_command(Command::GetPackSettings(pack_key.to_string()), response_extractor!(Response::PackSettings));
38453856

38463857
let files_to_ignore = settings.setting_text("import_files_to_ignore").map(|files_to_ignore| {
38473858
if files_to_ignore.is_empty() { vec![] } else {
@@ -3852,7 +3863,7 @@ impl AppUI {
38523863
}
38533864
});
38543865

3855-
PackFileContentsUI::add_files(app_ui, pack_file_contents_ui, &paths, &paths_packedfile, files_to_ignore);
3866+
PackFileContentsUI::add_files(app_ui, pack_file_contents_ui, &paths, &paths_packedfile, files_to_ignore, Some(pack_key));
38563867
}
38573868

38583869
// If there is no MyMod path configured, report it.
@@ -3868,9 +3879,70 @@ impl AppUI {
38683879
pub unsafe fn export_mymod(
38693880
app_ui: &Rc<Self>,
38703881
pack_file_contents_ui: &Rc<PackFileContentsUI>,
3871-
paths_to_extract: Option<Vec<ContainerPath>>
3882+
paths_to_extract: Option<Vec<ContainerPath>>,
3883+
target_pack_key: Option<&str>,
3884+
) {
3885+
PackFileContentsUI::extract_packed_files(app_ui, pack_file_contents_ui, paths_to_extract, true, target_pack_key)
3886+
}
3887+
3888+
/// This function runs MyMod imports for every open MyMod pack.
3889+
pub unsafe fn import_all_mymod(
3890+
app_ui: &Rc<Self>,
3891+
pack_file_contents_ui: &Rc<PackFileContentsUI>,
3892+
) {
3893+
let mymod_keys = AppUI::open_mymod_pack_keys(pack_file_contents_ui);
3894+
if mymod_keys.is_empty() {
3895+
return show_dialog(&app_ui.main_window, "There are no open MyMod packs to import.", false);
3896+
}
3897+
3898+
for pack_key in &mymod_keys {
3899+
AppUI::import_mymod(app_ui, pack_file_contents_ui, pack_key);
3900+
}
3901+
}
3902+
3903+
/// This function runs MyMod exports for every open MyMod pack.
3904+
pub unsafe fn export_all_mymod(
3905+
app_ui: &Rc<Self>,
3906+
pack_file_contents_ui: &Rc<PackFileContentsUI>,
38723907
) {
3873-
PackFileContentsUI::extract_packed_files(app_ui, pack_file_contents_ui, paths_to_extract, true)
3908+
let mymod_keys = AppUI::open_mymod_pack_keys(pack_file_contents_ui);
3909+
if mymod_keys.is_empty() {
3910+
return show_dialog(&app_ui.main_window, "There are no open MyMod packs to export.", false);
3911+
}
3912+
3913+
for pack_key in &mymod_keys {
3914+
AppUI::export_mymod(app_ui, pack_file_contents_ui, Some(vec![ContainerPath::Folder("".to_owned())]), Some(pack_key));
3915+
}
3916+
}
3917+
3918+
/// Collect the pack keys of every open pack that is in MyMod operational mode.
3919+
pub unsafe fn open_mymod_pack_keys(pack_file_contents_ui: &Rc<PackFileContentsUI>) -> Vec<String> {
3920+
let model = pack_file_contents_ui.packfile_contents_tree_model();
3921+
let mut keys = Vec::new();
3922+
for row in 0..model.row_count_0a() {
3923+
let item = model.item_1a(row);
3924+
let root_type = item.data_1a(rpfm_ui_common::ROOT_NODE_TYPE).to_int_0a();
3925+
if root_type != rpfm_ui_common::ROOT_NODE_TYPE_EDITABLE_PACKFILE && root_type != rpfm_ui_common::ROOT_NODE_TYPE_MYMOD_PACKFILE {
3926+
continue;
3927+
}
3928+
3929+
let variant = item.data_1a(rpfm_ui_common::ITEM_PACK_KEY);
3930+
if !variant.is_valid() || variant.is_null() {
3931+
continue;
3932+
}
3933+
3934+
let key = variant.to_string().to_std_string();
3935+
if key.is_empty() {
3936+
continue;
3937+
}
3938+
3939+
let mode = send_ipc_command(Command::GetPackOperationalMode(key.clone()), response_extractor!(Response::OperationalMode));
3940+
if matches!(mode, OperationalMode::MyMod(..)) {
3941+
keys.push(key);
3942+
}
3943+
}
3944+
3945+
keys
38743946
}
38753947

38763948
/// This function is used to build a snowman.

rpfm_ui/src/app_ui/slots.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ pub struct AppUISlots {
120120
pub mymod_open_menu: QBox<SlotNoArgs>,
121121
pub mymod_open_mymod_folder: QBox<SlotOfBool>,
122122
pub mymod_new: QBox<SlotOfBool>,
123+
pub mymod_import_all: QBox<SlotOfBool>,
124+
pub mymod_export_all: QBox<SlotOfBool>,
123125

124126
//-----------------------------------------------//
125127
// `View` menu slots.
@@ -789,6 +791,24 @@ impl AppUISlots {
789791
}
790792
));
791793

794+
// This slot is used for the "Import All Open MyMods" action.
795+
let mymod_import_all = SlotOfBool::new(&app_ui.main_window, clone!(
796+
app_ui,
797+
pack_file_contents_ui => move |_| {
798+
info!("Triggering `Import All MyMods` By Slot");
799+
AppUI::import_all_mymod(&app_ui, &pack_file_contents_ui);
800+
}
801+
));
802+
803+
// This slot is used for the "Export All Open MyMods" action.
804+
let mymod_export_all = SlotOfBool::new(&app_ui.main_window, clone!(
805+
app_ui,
806+
pack_file_contents_ui => move |_| {
807+
info!("Triggering `Export All MyMods` By Slot");
808+
AppUI::export_all_mymod(&app_ui, &pack_file_contents_ui);
809+
}
810+
));
811+
792812
//-----------------------------------------------//
793813
// `View` menu logic.
794814
//-----------------------------------------------//
@@ -1708,6 +1728,8 @@ impl AppUISlots {
17081728
mymod_open_menu,
17091729
mymod_open_mymod_folder,
17101730
mymod_new,
1731+
mymod_import_all,
1732+
mymod_export_all,
17111733

17121734
//-----------------------------------------------//
17131735
// `View` menu slots.

rpfm_ui/src/app_ui/tips.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub unsafe fn set_tips(app_ui: &Rc<AppUI>) {
3131
// `MyMod` menu tips.
3232
//-----------------------------------------------//
3333
app_ui.mymod_new.set_status_tip(&qtr("tt_mymod_new"));
34+
app_ui.mymod_import_all.set_status_tip(&qtr("tt_mymod_import_all"));
35+
app_ui.mymod_export_all.set_status_tip(&qtr("tt_mymod_export_all"));
3436

3537
//-----------------------------------------------//
3638
// `Game Selected` menu tips.

rpfm_ui/src/packfile_contents_ui/mod.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -516,13 +516,17 @@ impl PackFileContentsUI {
516516
paths: &[PathBuf],
517517
paths_in_container: &[ContainerPath],
518518
paths_to_ignore: Option<Vec<PathBuf>>,
519+
target_pack_key: Option<&str>,
519520
) {
520521
let window_was_disabled = !app_ui.main_window().is_enabled();
521522
if !window_was_disabled {
522523
app_ui.toggle_main_window(false);
523524
}
524525

525-
let pack_key = pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default();
526+
let pack_key = match target_pack_key {
527+
Some(key) => key.to_owned(),
528+
None => pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default(),
529+
};
526530
match send_ipc_command_result(Command::AddPackedFiles(pack_key.clone(), paths.to_vec(), paths_in_container.to_vec(), paths_to_ignore), response_extractor!(Response::VecContainerPathOptionString, paths, error)) {
527531
Ok((paths, error)) => {
528532
if !paths.is_empty() {
@@ -662,6 +666,7 @@ impl PackFileContentsUI {
662666
pack_file_contents_ui: &Rc<Self>,
663667
paths_to_extract: Option<Vec<ContainerPath>>,
664668
extract_tables_as_tsv: bool,
669+
target_pack_key: Option<&str>,
665670
) {
666671

667672
// Get the currently selected paths (and visible) paths, or the ones received from the function.
@@ -670,9 +675,12 @@ impl PackFileContentsUI {
670675
None => <QPtr<QTreeView> as PackTree>::get_item_types_from_main_treeview_selection(pack_file_contents_ui),
671676
};
672677

673-
// Query the selected pack's operational mode for extraction path logic.
674-
let selected_pack_key = pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default();
675-
let pack_mode = send_ipc_command(Command::GetPackOperationalMode(selected_pack_key), response_extractor!(Response::OperationalMode));
678+
// Resolve the pack key to operate on: explicit target, or the selected/first editable pack.
679+
let selected_pack_key = match target_pack_key {
680+
Some(key) => key.to_owned(),
681+
None => pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default(),
682+
};
683+
let pack_mode = send_ipc_command(Command::GetPackOperationalMode(selected_pack_key.clone()), response_extractor!(Response::OperationalMode));
676684

677685
let extraction_path = match pack_mode {
678686

@@ -724,9 +732,8 @@ impl PackFileContentsUI {
724732
else {
725733
let mut paths_by_source = BTreeMap::new();
726734
paths_by_source.insert(DataSource::PackFile, items_to_extract);
727-
let pack_key = pack_file_contents_ui.pack_key_from_selection_or_first().unwrap_or_default();
728735
app_ui.toggle_main_window(false);
729-
match send_ipc_command_result_async(Command::ExtractPackedFiles(pack_key, paths_by_source, extraction_path, extract_tables_as_tsv), response_extractor!(Response::StringVecPathBuf, result, _paths)) {
736+
match send_ipc_command_result_async(Command::ExtractPackedFiles(selected_pack_key, paths_by_source, extraction_path, extract_tables_as_tsv), response_extractor!(Response::StringVecPathBuf, result, _paths)) {
730737
Ok((result, _)) => show_message_info(app_ui.message_widget(), result),
731738
Err(error) => show_dialog(app_ui.main_window(), error, false),
732739
}

rpfm_ui/src/packfile_contents_ui/slots.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ impl PackFileContentsSlots {
784784
};
785785

786786
app_ui.toggle_main_window(false);
787-
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None);
787+
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None, None);
788788
app_ui.toggle_main_window(true);
789789
}
790790
}
@@ -815,7 +815,7 @@ impl PackFileContentsSlots {
815815
}
816816

817817
app_ui.toggle_main_window(false);
818-
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None);
818+
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None, None);
819819
app_ui.toggle_main_window(true);
820820
}
821821
}
@@ -918,15 +918,15 @@ impl PackFileContentsSlots {
918918
let filtered_path = path.strip_prefix(&assets_folder).unwrap();
919919
paths_packedfile.push(ContainerPath::File(filtered_path.to_string_lossy().to_string()));
920920
}
921-
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None);
921+
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &paths, &paths_packedfile, None, None);
922922
}
923923

924924
// Otherwise, they are added like normal files.
925925
else if let Some(selection) = pack_file_contents_ui.packfile_contents_tree_view.get_path_from_selection().first() {
926926
let destination_paths = (0..folder_paths.len()).map(|_| ContainerPath::Folder(selection.to_string())).collect::<Vec<_>>();
927927

928928
app_ui.toggle_main_window(false);
929-
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &folder_paths, &destination_paths, None);
929+
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &folder_paths, &destination_paths, None, None);
930930
app_ui.toggle_main_window(true);
931931
}
932932
}
@@ -973,7 +973,7 @@ impl PackFileContentsSlots {
973973
let destination_paths = (0..folder_paths.len()).map(|_| ContainerPath::Folder(selection.to_string())).collect::<Vec<_>>();
974974

975975
app_ui.toggle_main_window(false);
976-
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &folder_paths, &destination_paths, None);
976+
PackFileContentsUI::add_files(&app_ui, &pack_file_contents_ui, &folder_paths, &destination_paths, None, None);
977977
app_ui.toggle_main_window(true);
978978
}
979979
}
@@ -1115,7 +1115,7 @@ impl PackFileContentsSlots {
11151115
app_ui,
11161116
pack_file_contents_ui => move |_| {
11171117
info!("Triggering `Extract` By Slot");
1118-
PackFileContentsUI::extract_packed_files(&app_ui, &pack_file_contents_ui, None, true);
1118+
PackFileContentsUI::extract_packed_files(&app_ui, &pack_file_contents_ui, None, true, None);
11191119
}
11201120
));
11211121

@@ -2109,7 +2109,7 @@ impl PackFileContentsSlots {
21092109
let context_menu_mymod_export = SlotOfBool::new(&pack_file_contents_ui.packfile_contents_dock_widget, clone!(
21102110
app_ui,
21112111
pack_file_contents_ui => move |_| {
2112-
AppUI::export_mymod(&app_ui, &pack_file_contents_ui, Some(vec![ContainerPath::Folder("".to_owned())]));
2112+
AppUI::export_mymod(&app_ui, &pack_file_contents_ui, Some(vec![ContainerPath::Folder("".to_owned())]), None);
21132113
}
21142114
));
21152115

0 commit comments

Comments
 (0)