Multiple Language Support

This is similar to https://gerrit.omnirom.org/#/c/14014

A lot of the features built in the older patch set have been split
out into separate patches, most of which have already been merged.
The remaining functionality here should all be directly related to
language selection and loading. We always load English as a base
before loading other languages over the top of the base. The idea
is that if another language is missing a translation, then we will
still display the English.

Maybe still to do: read the /cache/recovery/last_locale file and
load a language based on that. For me, this file contains just:
en_US
We probably won't bother with region specific translations so we
would have to look at either trimming off the _US or using some
other method like perhaps a symlink or a combination of the two.

Thanks to _that for twmsg.cpp class

Change-Id: I9647a22e47883a3ddd2de1da51f64aab7c328f74
diff --git a/partition.cpp b/partition.cpp
index f6adec9..df408e6 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -43,6 +43,7 @@
 #include "fixPermissions.hpp"
 #include "infomanager.hpp"
 #include "set_metadata.h"
+#include "gui/gui.hpp"
 extern "C" {
 	#include "mtdutils/mtdutils.h"
 	#include "mtdutils/mounts.h"
@@ -299,7 +300,7 @@
 						DataManager::SetValue(TW_CRYPTO_PASSWORD, "");
 						DataManager::SetValue("tw_crypto_display", "");
 					} else {
-						LOGERR("Could not mount /data and unable to find crypto footer.\n");
+						gui_err("mount_data_footer=Could not mount /data and unable to find crypto footer.");
 					}
 				} else {
 					LOGERR("Primary block device '%s' for mount point '%s' is not present!\n", Primary_Block_Device.c_str(), Mount_Point.c_str());
@@ -642,7 +643,7 @@
 	if (!TWFunc::Path_Exists(Path)) {
 		if (mkdir(Path.c_str(), 0777) == -1) {
 			if (Display_Error)
-				LOGERR("Can not create '%s' folder.\n", Path.c_str());
+				gui_msg(Msg(msg::kError, "create_folder_strerr=Can not create '{1}' folder ({2}).")(Path)(strerror(errno)));
 			else
 				LOGINFO("Can not create '%s' folder.\n", Path.c_str());
 			return false;
@@ -1011,7 +1012,7 @@
 		if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Fstab_File_System.c_str(), flags, NULL) < 0) {
 			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), Fstab_File_System.c_str(), flags | MS_RDONLY, NULL) < 0) {
 				if (Display_Error)
-					LOGERR("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
+					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
 				else
 					LOGINFO("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
 				return false;
@@ -1024,7 +1025,7 @@
 			string test_path = Mount_Point;
 			if (stat(test_path.c_str(), &st) < 0) {
 				if (Display_Error)
-					LOGERR("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
+					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
 				else
 					LOGINFO("Failed to mount '%s' (MTD)\n", Mount_Point.c_str());
 				return false;
@@ -1056,7 +1057,7 @@
 			LOGINFO("Mounting exfat failed, trying vfat...\n");
 			if (mount(Actual_Block_Device.c_str(), Mount_Point.c_str(), "vfat", 0, NULL) != 0) {
 				if (Display_Error)
-					LOGERR("Unable to mount '%s'\n", Mount_Point.c_str());
+					gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
 				else
 					LOGINFO("Unable to mount '%s'\n", Mount_Point.c_str());
 				LOGINFO("Actual block device: '%s', current file system: '%s', flags: 0x%8x, options: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str(), flags, Mount_Options.c_str());
@@ -1065,7 +1066,7 @@
 		} else {
 #endif
 			if (!Removable && Display_Error)
-				LOGERR("Unable to mount '%s'\n", Mount_Point.c_str());
+				gui_msg(Msg(msg::kError, "fail_mount=Failed to mount '{1}' ({2})")(Mount_Point)(strerror(errno)));
 			else
 				LOGINFO("Unable to mount '%s'\n", Mount_Point.c_str());
 			LOGINFO("Actual block device: '%s', current file system: '%s'\n", Actual_Block_Device.c_str(), Current_File_System.c_str());
@@ -1102,7 +1103,7 @@
 		umount(Mount_Point.c_str());
 		if (Is_Mounted()) {
 			if (Display_Error)
-				LOGERR("Unable to unmount '%s'\n", Mount_Point.c_str());
+				gui_msg(Msg(msg::kError, "fail_unmount=Failed to unmount '{1}' ({2})")(Mount_Point)(strerror(errno)));
 			else
 				LOGINFO("Unable to unmount '%s'\n", Mount_Point.c_str());
 			return false;
@@ -1120,7 +1121,7 @@
 	string Layout_Filename = Mount_Point + "/.layout_version";
 
 	if (!Can_Be_Wiped) {
-		LOGERR("Partition '%s' cannot be wiped.\n", Mount_Point.c_str());
+		gui_msg(Msg(msg::kError, "cannot_wipe=Partition {1} cannot be wiped.\n")(Display_Name));
 		return false;
 	}
 
@@ -1207,7 +1208,7 @@
 	if (!Mount(true))
 		return false;
 
-	gui_print("Wiping %s\n", Backup_Display_Name.c_str());
+	gui_msg(Msg("wiping=Wiping {1}")(Backup_Display_Name));
 	TWFunc::removeDir(Mount_Point + "/.android_secure/", true);
 	return true;
 }
@@ -1233,96 +1234,96 @@
 
 	if (Current_File_System == "vfat") {
 		if (!TWFunc::Path_Exists("/sbin/fsck.fat")) {
-			gui_print("fsck.fat does not exist! Cannot repair!\n");
+			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.fat"));
 			return false;
 		}
 		if (!UnMount(true))
 			return false;
-		gui_print("Repairing %s using fsck.fat...\n", Display_Name.c_str());
+		gui_msg(Msg("reparing=Repairing {1} using {2}...")(Display_Name)("fsck.fat"));
 		Find_Actual_Block_Device();
 		command = "/sbin/fsck.fat -y " + Actual_Block_Device;
 		LOGINFO("Repair command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
 			return false;
 		}
 	}
 	if (Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") {
 		if (!TWFunc::Path_Exists("/sbin/e2fsck")) {
-			gui_print("e2fsck does not exist! Cannot repair!\n");
+			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("e2fsck"));
 			return false;
 		}
 		if (!UnMount(true))
 			return false;
-		gui_print("Repairing %s using e2fsck...\n", Display_Name.c_str());
+		gui_msg(Msg("reparing=Repairing {1} using {2}...")(Display_Name)("e2fsck"));
 		Find_Actual_Block_Device();
 		command = "/sbin/e2fsck -fp " + Actual_Block_Device;
 		LOGINFO("Repair command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
 			return false;
 		}
 	}
 	if (Current_File_System == "exfat") {
 		if (!TWFunc::Path_Exists("/sbin/fsck.exfat")) {
-			gui_print("fsck.exfat does not exist! Cannot repair!\n");
+			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.exfat"));
 			return false;
 		}
 		if (!UnMount(true))
 			return false;
-		gui_print("Repairing %s using fsck.exfat...\n", Display_Name.c_str());
+		gui_msg(Msg("reparing=Repairing {1} using {2}...")(Display_Name)("fsck.exfat"));
 		Find_Actual_Block_Device();
 		command = "/sbin/fsck.exfat " + Actual_Block_Device;
 		LOGINFO("Repair command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
 			return false;
 		}
 	}
 	if (Current_File_System == "f2fs") {
 		if (!TWFunc::Path_Exists("/sbin/fsck.f2fs")) {
-			gui_print("fsck.f2fs does not exist! Cannot repair!\n");
+			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("fsck.f2fs"));
 			return false;
 		}
 		if (!UnMount(true))
 			return false;
-		gui_print("Repairing %s using fsck.f2fs...\n", Display_Name.c_str());
+		gui_msg(Msg("reparing=Repairing {1} using {2}...")(Display_Name)("fsck.f2fs"));
 		Find_Actual_Block_Device();
 		command = "/sbin/fsck.f2fs " + Actual_Block_Device;
 		LOGINFO("Repair command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
 			return false;
 		}
 	}
 	if (Current_File_System == "ntfs") {
 		if (!TWFunc::Path_Exists("/sbin/ntfsfix")) {
-			gui_print("ntfsfix does not exist! Cannot repair!\n");
+			gui_msg(Msg(msg::kError, "repair_not_exist={1} does not exist! Cannot repair!")("ntfsfix"));
 			return false;
 		}
 		if (!UnMount(true))
 			return false;
-		gui_print("Repairing %s using ntfsfix...\n", Display_Name.c_str());
+		gui_msg(Msg("reparing=Repairing {1} using {2}...")(Display_Name)("ntfsfix"));
 		Find_Actual_Block_Device();
 		command = "/sbin/ntfsfix " + Actual_Block_Device;
 		LOGINFO("Repair command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to repair '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_repair=Unable to repair {1}.")(Display_Name));
 			return false;
 		}
 	}
@@ -1342,18 +1343,20 @@
 
 	if (Current_File_System == "ext2" || Current_File_System == "ext3" || Current_File_System == "ext4") {
 		if (!Can_Repair()) {
-			LOGERR("Cannot resize %s because %s cannot be repaired before resizing.\n", Display_Name.c_str(), Display_Name.c_str());
+			LOGINFO("Cannot resize %s because %s cannot be repaired before resizing.\n", Display_Name.c_str(), Display_Name.c_str());
+			gui_msg(Msg(msg::kError, "cannot_resize=Cannot resize {1}.")(Display_Name));
 			return false;
 		}
 		if (!TWFunc::Path_Exists("/sbin/resize2fs")) {
-			gui_print("resize2fs does not exist! Cannot resize!\n");
+			LOGINFO("resize2fs does not exist! Cannot resize!\n");
+			gui_msg(Msg(msg::kError, "cannot_resize=Cannot resize {1}.")(Display_Name));
 			return false;
 		}
 		// Repair will unmount so no need to do it twice
-		gui_print("Repairing %s before resizing.\n", Display_Name.c_str());
+		gui_msg(Msg("repair_resize=Repairing {1} before resizing.")( Display_Name));
 		if (!Repair())
 			return false;
-		gui_print("Resizing %s using resize2fs...\n", Display_Name.c_str());
+		gui_msg(Msg("resizing=Resizing {1} using {2}...")(Display_Name)("resize2fs"));
 		Find_Actual_Block_Device();
 		command = "/sbin/resize2fs " + Actual_Block_Device;
 		if (Length != 0) {
@@ -1362,13 +1365,14 @@
 
 			fd = open(Actual_Block_Device.c_str(), O_RDONLY);
 			if (fd < 0) {
-				LOGERR("Resize: Failed to open '%s'\n", Actual_Block_Device.c_str());
+				gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Actual_Block_Device)(strerror(errno)));
 				return false;
 			}
 			ret = ioctl(fd, BLKGETSIZE, &block_device_size);
 			close(fd);
 			if (ret) {
-				LOGERR("Resize: ioctl error\n");
+				gui_msg(Msg(msg::kError, "unable_resize=Unable to resize {1}.")(Display_Name));
+				LOGINFO("Resize: ioctl error\n");
 				return false;
 			}
 			unsigned long long Actual_Size = (unsigned long long)(block_device_size) * 512LLU;
@@ -1389,11 +1393,11 @@
 		LOGINFO("Resize command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Update_Size(true);
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
 			Update_Size(true);
-			LOGERR("Unable to resize '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_resize=Unable to resize {1}.")(Display_Name));
 			return false;
 		}
 	}
@@ -1429,14 +1433,13 @@
 		md5file = split_filename;
 		md5file += ".md5";
 		if (!TWFunc::Path_Exists(md5file)) {
-			LOGERR("No md5 file found for '%s'.\n", split_filename);
-			LOGERR("Please unselect Enable MD5 verification to restore.\n");
+			gui_msg(Msg(msg::kError, "no_md5_found=No md5 file found for '{1}'. Please unselect Enable MD5 verification to restore.")(split_filename));
 			return false;
 		}
 		md5sum.setfn(split_filename);
 		while (index < 1000) {
 			if (TWFunc::Path_Exists(split_filename) && md5sum.verify_md5digest() != 0) {
-				LOGERR("MD5 failed to match on '%s'.\n", split_filename);
+				gui_msg(Msg(msg::kError, "md5_fail_match=MD5 failed to match on '{1}'.")(split_filename));
 				return false;
 			}
 			index++;
@@ -1448,13 +1451,12 @@
 		// Single file archive
 		md5file = Full_Filename + ".md5";
 		if (!TWFunc::Path_Exists(md5file)) {
-			LOGERR("No md5 file found for '%s'.\n", Full_Filename.c_str());
-			LOGERR("Please unselect Enable MD5 verification to restore.\n");
+			gui_msg(Msg(msg::kError, "no_md5_found=No md5 file found for '{1}'. Please unselect Enable MD5 verification to restore.")(split_filename));
 			return false;
 		}
 		md5sum.setfn(Full_Filename);
 		if (md5sum.verify_md5digest() != 0) {
-			LOGERR("MD5 failed to match on '%s'.\n", Full_Filename.c_str());
+			gui_msg(Msg(msg::kError, "md5_fail_match=MD5 failed to match on '{1}'.")(split_filename));
 			return false;
 		} else
 			return true;
@@ -1465,7 +1467,7 @@
 bool TWPartition::Restore(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size) {
 	string Restore_File_System;
 
-	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
+	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, gui_parse_text("{@restoring}"));
 	LOGINFO("Restore filename is: %s\n", Backup_FileName.c_str());
 
 	Restore_File_System = Get_Restore_File_System(restore_folder);
@@ -1591,12 +1593,12 @@
 		}
 		DataManager::SetValue(TW_IS_ENCRYPTED, 0);
 #ifndef TW_OEM_BUILD
-		gui_print("You may need to reboot recovery to be able to use /data again.\n");
+		gui_msg("format_data_msg=You may need to reboot recovery to be able to use /data again.");
 #endif
 		return true;
 	} else {
 		Has_Data_Media = Save_Data_Media;
-		LOGERR("Unable to format to remove encryption.\n");
+		gui_err("format_data_err=Unable to format to remove encryption.");
 		if (Has_Data_Media && Mount(false))
 			PartitionManager.Add_MTP_Storage(MTP_Storage_ID);
 		return false;
@@ -1639,17 +1641,17 @@
 	if (TWFunc::Path_Exists("/sbin/mke2fs")) {
 		string command;
 
-		gui_print("Formatting %s using mke2fs...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("mke2fs"));
 		Find_Actual_Block_Device();
 		command = "mke2fs -t " + File_System + " -m 0 " + Actual_Block_Device;
 		LOGINFO("mke2fs command: %s\n", command.c_str());
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Current_File_System = File_System;
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 	} else
@@ -1661,7 +1663,8 @@
 bool TWPartition::Wipe_EXT4() {
 	Find_Actual_Block_Device();
 	if (!Is_Present) {
-		LOGERR("Block device not present, cannot wipe %s.\n", Display_Name.c_str());
+		LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str());
+		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 		return false;
 	}
 	if (!UnMount(true))
@@ -1671,7 +1674,7 @@
 	int ret;
 	char *secontext = NULL;
 
-	gui_print("Formatting %s using make_ext4fs function.\n", Display_Name.c_str());
+	gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("make_ext4fs"));
 
 	if (!selinux_handle || selabel_lookup(selinux_handle, &secontext, Mount_Point.c_str(), S_IFDIR) < 0) {
 		LOGINFO("Cannot lookup security context for '%s'\n", Mount_Point.c_str());
@@ -1680,7 +1683,7 @@
 		ret = make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), selinux_handle);
 	}
 	if (ret != 0) {
-		LOGERR("Unable to wipe '%s' using function call.\n", Mount_Point.c_str());
+		gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 		return false;
 	} else {
 		string sedir = Mount_Point + "/lost+found";
@@ -1693,7 +1696,7 @@
 	if (TWFunc::Path_Exists("/sbin/make_ext4fs")) {
 		string Command;
 
-		gui_print("Formatting %s using make_ext4fs...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("make_ext4fs"));
 		Find_Actual_Block_Device();
 		Command = "make_ext4fs";
 		if (!Is_Decrypted && Length != 0) {
@@ -1711,10 +1714,10 @@
 		if (TWFunc::Exec_Cmd(Command) == 0) {
 			Current_File_System = "ext4";
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 	} else
@@ -1730,16 +1733,16 @@
 		if (!UnMount(true))
 			return false;
 
-		gui_print("Formatting %s using mkfs.fat...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("mkfs.fat"));
 		Find_Actual_Block_Device();
 		command = "mkfs.fat " + Actual_Block_Device;
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Current_File_System = "vfat";
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 		return true;
@@ -1757,15 +1760,15 @@
 		if (!UnMount(true))
 			return false;
 
-		gui_print("Formatting %s using mkexfatfs...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("mkexfatfs"));
 		Find_Actual_Block_Device();
 		command = "mkexfatfs " + Actual_Block_Device;
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 		return true;
@@ -1777,7 +1780,7 @@
 	if (!UnMount(true))
 		return false;
 
-	gui_print("MTD Formatting \"%s\"\n", MTD_Name.c_str());
+	gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("MTD"));
 
 	mtd_scan_partitions();
 	const MtdPartition* mtd = mtd_find_partition_by_name(MTD_Name.c_str());
@@ -1802,7 +1805,7 @@
 	}
 	Current_File_System = "yaffs2";
 	Recreate_AndSec_Folder();
-	gui_print("Done.\n");
+	gui_msg("done=Done.");
 	return true;
 }
 
@@ -1815,7 +1818,7 @@
 	if (Is_Storage)
 		PartitionManager.Remove_MTP_Storage(MTP_Storage_ID);
 
-	gui_print("Removing all files under '%s'\n", Mount_Point.c_str());
+	gui_msg(Msg("remove_all=Removing all files under '{1}'")(Mount_Point));
 	TWFunc::removeDir(Mount_Point, true);
 	Recreate_AndSec_Folder();
 	return true;
@@ -1828,7 +1831,7 @@
 		if (!UnMount(true))
 			return false;
 
-		gui_print("Formatting %s using mkfs.f2fs...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("mkfs.f2fs"));
 		Find_Actual_Block_Device();
 		command = "mkfs.f2fs -t 1";
 		if (!Is_Decrypted && Length != 0) {
@@ -1844,15 +1847,15 @@
 		command += " " + Actual_Block_Device;
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 		return true;
 	} else {
-		gui_print("mkfs.f2fs binary not found, using rm -rf to wipe.\n");
+		LOGINFO("mkfs.f2fs binary not found, using rm -rf to wipe.\n");
 		return Wipe_RMRF();
 	}
 	return false;
@@ -1865,15 +1868,15 @@
 		if (!UnMount(true))
 			return false;
 
-		gui_print("Formatting %s using mkntfs...\n", Display_Name.c_str());
+		gui_msg(Msg("formating_using=Formatting {1} using {2}...")(Display_Name)("mkntfs"));
 		Find_Actual_Block_Device();
 		command = "mkntfs " + Actual_Block_Device;
 		if (TWFunc::Exec_Cmd(command) == 0) {
 			Recreate_AndSec_Folder();
-			gui_print("Done.\n");
+			gui_msg("done=Done.");
 			return true;
 		} else {
-			LOGERR("Unable to wipe '%s'.\n", Mount_Point.c_str());
+			gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name));
 			return false;
 		}
 		return true;
@@ -1892,7 +1895,7 @@
 	if (!Mount(true))
 		return false;
 
-	gui_print("Wiping data without wiping /data/media ...\n");
+	gui_msg("wiping_data=Wiping data without wiping /data/media ...");
 
 	DIR* d;
 	d = opendir("/data");
@@ -1917,10 +1920,10 @@
 		}
 		closedir(d);
 
-		gui_print("Done.\n");
+		gui_msg("done=Done.");
 		return true;
 	}
-	gui_print("Dirent failed to open /data, error!\n");
+	gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(Mount_Point)(strerror(errno)));
 	return false;
 #endif // ifdef TW_OEM_BUILD
 }
@@ -1938,7 +1941,7 @@
 		return false;
 
 	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Backup_Display_Name, "Backing Up");
-	gui_print("Backing up %s...\n", Backup_Display_Name.c_str());
+	gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name));
 
 	DataManager::GetValue(TW_USE_COMPRESSION_VAR, use_compression);
 	tar.use_compression = use_compression;
@@ -1989,8 +1992,8 @@
 	sprintf(block_size, "%llu", DD_Block_Size);
 	DD_BS = block_size;
 
-	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
-	gui_print("Backing up %s...\n", Display_Name.c_str());
+	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, gui_parse_text("{@backing}"));
+	gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name));
 
 	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
 	Backup_FileName = back_name;
@@ -2002,7 +2005,7 @@
 	TWFunc::Exec_Cmd(Command);
 	tw_set_default_metadata(Full_FileName.c_str());
 	if (TWFunc::Get_File_Size(Full_FileName) == 0) {
-		LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
+		gui_msg(Msg(msg::kError, "backup_size=Backup file size for '{1}' is 0 bytes.")(Full_FileName));
 		return false;
 	}
 	return true;
@@ -2013,8 +2016,8 @@
 	string Full_FileName, Command;
 	int use_compression;
 
-	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, "Backing Up");
-	gui_print("Backing up %s...\n", Display_Name.c_str());
+	TWFunc::GUI_Operation_Text(TW_BACKUP_TEXT, Display_Name, gui_parse_text("{@backing}"));
+	gui_msg(Msg("backing_up=Backing up {1}...")(Backup_Display_Name));
 
 	sprintf(back_name, "%s.%s.win", Backup_Name.c_str(), Current_File_System.c_str());
 	Backup_FileName = back_name;
@@ -2027,7 +2030,7 @@
 	tw_set_default_metadata(Full_FileName.c_str());
 	if (TWFunc::Get_File_Size(Full_FileName) == 0) {
 		// Actual size may not match backup size due to bad blocks on MTD devices so just check for 0 bytes
-		LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str());
+		gui_msg(Msg(msg::kError, "backup_size=Backup file size for '%s' is 0 bytes.")(Full_FileName));
 		return false;
 	}
 	return true;
@@ -2076,10 +2079,9 @@
 		if (!Wipe_AndSec())
 			return false;
 	} else {
-		gui_print("Wiping %s...\n", Display_Name.c_str());
+		gui_msg(Msg("wiping=Wiping {1}")(Backup_Display_Name));
 		if (Has_Data_Media && Mount_Point == "/data" && Restore_File_System != Current_File_System) {
-			gui_print("WARNING: This /data backup was made with %s file system!\n", Restore_File_System.c_str());
-			gui_print("The backup may not boot unless you change back to %s.\n", Restore_File_System.c_str());
+			gui_msg(Msg(msg::kWarning, "datamedia_fs_restore=WARNING: This /data backup was made with {1} file system! The backup may not boot unless you change back to {1}.")(Restore_File_System));
 			if (!Wipe_Data_Without_Wiping_Media())
 				return false;
 		} else {
@@ -2087,8 +2089,8 @@
 				return false;
 		}
 	}
-	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, "Restoring");
-	gui_print("Restoring %s...\n", Backup_Display_Name.c_str());
+	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, gui_parse_text("{@restore}"));
+	gui_msg(Msg("restoring=Restoring {1}...")(Backup_Display_Name));
 
 	if (!Mount(true))
 		return false;
@@ -2135,7 +2137,8 @@
 	double display_percent, progress_percent;
 	char size_progress[1024];
 
-	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, "Restoring");
+	TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Backup_Display_Name, gui_parse_text("{@restore}"));
+	gui_msg(Msg("restoring=Restoring {1}...")(Backup_Display_Name));
 	Full_FileName = restore_folder + "/" + Backup_FileName;
 
 	if (Restore_File_System == "emmc") {
@@ -2226,7 +2229,7 @@
 	string Command;
 
 	if (!Mount(true)) {
-		LOGERR("Unable to recreate /data/media folder.\n");
+		gui_msg(Msg(msg::kError, "recreate_folder_err=Unable to recreate {1} folder.")("/data/media"));
 	} else if (!TWFunc::Path_Exists("/data/media")) {
 		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
 		LOGINFO("Recreating /data/media folder.\n");
@@ -2258,7 +2261,7 @@
 		return;
 	LOGINFO("Creating %s: %s\n", Backup_Display_Name.c_str(), Symlink_Path.c_str());
 	if (!Mount(true)) {
-		LOGERR("Unable to recreate %s folder.\n", Backup_Name.c_str());
+		gui_msg(Msg(msg::kError, "recreate_folder_err=Unable to recreate {1} folder.")(Backup_Name));
 	} else if (!TWFunc::Path_Exists(Symlink_Path)) {
 		LOGINFO("Recreating %s folder.\n", Backup_Name.c_str());
 		PartitionManager.Mount_By_Path(Symlink_Mount_Point, true);
@@ -2308,8 +2311,9 @@
 		}
 		unsigned long long image_size = TWFunc::Get_File_Size(Filename);
 		if (image_size > Size) {
-			LOGERR("Size (%llu bytes) of image '%s' is larger than target device '%s' (%llu bytes)\n",
+			LOGINFO("Size (%llu bytes) of image '%s' is larger than target device '%s' (%llu bytes)\n",
 				image_size, Filename.c_str(), Actual_Block_Device.c_str(), Size);
+			gui_err("img_size_err=Size of image is larger than target device");
 			return false;
 		}
 		if (Backup_Method == DD)
@@ -2325,7 +2329,7 @@
 bool TWPartition::Flash_Image_DD(string Filename) {
 	string Command;
 
-	gui_print("Flashing %s...\n", Display_Name.c_str());
+	gui_msg(Msg("flashing=Flashing {1}...")(Display_Name));
 	Command = "dd bs=8388608 if='" + Filename + "' of=" + Actual_Block_Device;
 	LOGINFO("Flash command: '%s'\n", Command.c_str());
 	TWFunc::Exec_Cmd(Command);
@@ -2335,7 +2339,7 @@
 bool TWPartition::Flash_Image_FI(string Filename) {
 	string Command;
 
-	gui_print("Flashing %s...\n", Display_Name.c_str());
+	gui_msg(Msg("flashing=Flashing {1}...")(Display_Name));
 	// Sometimes flash image doesn't like to flash due to the first 2KB matching, so we erase first to ensure that it flashes
 	Command = "erase_image " + MTD_Name;
 	LOGINFO("Erase command: '%s'\n", Command.c_str());