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/gui/action.cpp b/gui/action.cpp
index 46f4575..3e27dbb 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -197,6 +197,7 @@
 		ADD_ACTION(cancelbackup);
 		ADD_ACTION(checkpartitionlifetimewrites);
 		ADD_ACTION(mountsystemtoggle);
+		ADD_ACTION(setlanguage);
 
 		// remember actions that run in the caller thread
 		for (mapFunc::const_iterator it = mf.begin(); it != mf.end(); ++it)
@@ -340,12 +341,12 @@
 
 void GUIAction::simulate_progress_bar(void)
 {
-	gui_print("Simulating actions...\n");
+	gui_msg("simulating=Simulating actions...");
 	for (int i = 0; i < 5; i++)
 	{
 		if (PartitionManager.stop_backup.get_value()) {
 			DataManager::SetValue("tw_cancel_backup", 1);
-			gui_print("Backup Canceled.\n");
+			gui_msg("backup_cancel=Backup Canceled.");
 			DataManager::SetValue("ui_progress", 0);
 			PartitionManager.stop_backup.set_value(0);
 			return;
@@ -381,10 +382,10 @@
 		{
 			DataManager::SetValue("tw_operation", "Configuring TWRP");
 			DataManager::SetValue("tw_partition", "");
-			gui_print("Configuring TWRP...\n");
+			gui_msg("config_twrp=Configuring TWRP...");
 			if (TWFunc::Exec_Cmd("/sbin/installTwrp reinstall") < 0)
 			{
-				gui_print("Unable to configure TWRP with this kernel.\n");
+				gui_msg("config_twrp_err=Unable to configure TWRP with this kernel.");
 			}
 		}
 	}
@@ -587,12 +588,12 @@
 		if (!simulate)
 			PartitionManager.usb_storage_enable();
 		else
-			gui_print("Simulating actions...\n");
+			gui_msg("simulating=Simulating actions...");
 	} else if (!simulate) {
 		PartitionManager.Mount_By_Path(arg, true);
 		PartitionManager.Add_MTP_Storage(arg);
 	} else
-		gui_print("Simulating actions...\n");
+		gui_msg("simulating=Simulating actions...");
 	return 0;
 }
 
@@ -602,12 +603,12 @@
 		if (!simulate)
 			PartitionManager.usb_storage_disable();
 		else
-			gui_print("Simulating actions...\n");
+			gui_msg("simulating=Simulating actions...");
 		DataManager::SetValue(TW_ACTION_BUSY, 0);
 	} else if (!simulate) {
 		PartitionManager.UnMount_By_Path(arg, true);
 	} else
-		gui_print("Simulating actions...\n");
+		gui_msg("simulating=Simulating actions...");
 	return 0;
 }
 
@@ -615,7 +616,7 @@
 {
 	operation_start("Restore Defaults");
 	if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting
-		gui_print("Simulating actions...\n");
+		gui_msg("simulating=Simulating actions...");
 	else {
 		DataManager::ResetDefaults();
 		PartitionManager.Update_System_Details();
@@ -636,7 +637,7 @@
 		TWFunc::copy_file("/tmp/recovery.log", dst.c_str(), 0755);
 		tw_set_default_metadata(dst.c_str());
 		sync();
-		gui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str());
+		gui_msg(Msg("copy_log=Copied recovery log to {1}.")(DataManager::GetCurrentStoragePath()));
 	} else
 		simulate_progress_bar();
 	operation_end(0);
@@ -733,7 +734,7 @@
 int GUIAction::queuezip(std::string arg __unused)
 {
 	if (zip_queue_index >= 10) {
-		gui_print("Maximum zip queue reached!\n");
+		gui_msg("max_queue=Maximum zip queue reached!");
 		return 0;
 	}
 	DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]);
@@ -747,7 +748,7 @@
 int GUIAction::cancelzip(std::string arg __unused)
 {
 	if (zip_queue_index <= 0) {
-		gui_print("Minimum zip queue reached!\n");
+		gui_msg("min_queue=Minimum zip queue reached!");
 		return 0;
 	} else {
 		zip_queue_index--;
@@ -925,7 +926,7 @@
 		chmod(path, 0666);
 		chown(path, uid, gid);
 
-		gui_print("Screenshot was saved to %s\n", path);
+		gui_msg(Msg("screenshot_saved=Screenshot was saved to %s")(path));
 
 		// blink to notify that the screenshow was taken
 		gr_color(255, 255, 255, 255);
@@ -933,7 +934,7 @@
 		gr_flip();
 		gui_forceRender();
 	} else {
-		LOGERR("Failed to take a screenshot!\n");
+		gui_err("screenshot_err=Failed to take a screenshot!");
 	}
 	return 0;
 }
@@ -959,7 +960,7 @@
 void GUIAction::reinject_after_flash()
 {
 	if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) {
-		gui_print("Injecting TWRP into boot image...\n");
+		gui_msg("injecttwrp=Injecting TWRP into boot image...");
 		if (simulate) {
 			simulate_progress_bar();
 		} else {
@@ -970,7 +971,7 @@
 				string injectcmd = "injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash bd=" + Boot->Actual_Block_Device;
 				TWFunc::Exec_Cmd(injectcmd);
 			}
-			gui_print("TWRP injection complete.\n");
+			gui_msg("done=Done.");
 		}
 	}
 }
@@ -993,7 +994,7 @@
 		ret_val = flash_zip(zip_path, &wipe_cache);
 		TWFunc::SetPerformanceMode(false);
 		if (ret_val != 0) {
-			gui_print("Error flashing zip '%s'\n", zip_path.c_str());
+			gui_msg(Msg(msg::kError, "zip_err=Error installing zip file '{1}'")(zip_path));
 			ret_val = 1;
 			break;
 		}
@@ -1001,7 +1002,7 @@
 	zip_queue_index = 0;
 
 	if (wipe_cache) {
-		gui_print("One or more zip requested a cache wipe\nWiping cache now.\n");
+		gui_msg("zip_wipe_cache=One or more zip requested a cache wipe -- Wiping cache now.");
 		PartitionManager.Wipe_By_Path("/cache");
 	}
 
@@ -1063,7 +1064,7 @@
 					LOGINFO("wipe_path '%s'\n", wipe_path.c_str());
 					if (wipe_path == "/and-sec") {
 						if (!PartitionManager.Wipe_Android_Secure()) {
-							LOGERR("Unable to wipe android secure\n");
+							gui_msg("and_sec_wipe_err=Unable to wipe android secure");
 							ret_val = false;
 							break;
 						} else {
@@ -1071,7 +1072,7 @@
 						}
 					} else if (wipe_path == "DALVIK") {
 						if (!PartitionManager.Wipe_Dalvik_Cache()) {
-							LOGERR("Failed to wipe dalvik\n");
+							gui_err("dalvik_wipe_err=Failed to wipe dalvik");
 							ret_val = false;
 							break;
 						} else {
@@ -1087,7 +1088,7 @@
 					}
 					if (!skip) {
 						if (!PartitionManager.Wipe_By_Path(wipe_path)) {
-							LOGERR("Unable to wipe '%s'\n", wipe_path.c_str());
+							gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(wipe_path));
 							ret_val = false;
 							break;
 						} else if (wipe_path == DataManager::GetSettingsStoragePath()) {
@@ -1152,6 +1153,8 @@
 		if (arg == "backup") {
 			string Backup_Name;
 			DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
+			string auto_gen = gui_lookup("auto_gen", "(Auto Generate)");
+			string curr_date = gui_lookup("curr_date", "(Current Date)");
 			if (Backup_Name == "(Auto Generate)" || Backup_Name == "(Current Date)" || Backup_Name == "0" || Backup_Name == "(" || PartitionManager.Check_Backup_Name(true) == 0) {
 				ret = PartitionManager.Run_Backup();
 			}
@@ -1159,7 +1162,7 @@
 				operation_end(1);
 				return -1;
 			}
-			DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)");
+			DataManager::SetValue(TW_BACKUP_NAME, auto_gen);
 		} else if (arg == "restore") {
 			string Restore_Name;
 			DataManager::GetValue("tw_restore", Restore_Name);
@@ -1178,7 +1181,7 @@
 		}
 		else {
 			DataManager::SetValue("tw_cancel_backup", 1);
-			gui_print("Backup Canceled.\n");
+			gui_msg("backup_cancel=Backup Canceled.");
 			ret = 0;
 		}
 		operation_end(ret);
@@ -1242,7 +1245,7 @@
 		int allow_partition;
 		DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition);
 		if (allow_partition == 0) {
-			gui_print("This device does not have a real SD Card!\nAborting!\n");
+			gui_err("no_real_sdcard=This device does not have a real SD Card! Aborting!");
 		} else {
 			if (!PartitionManager.Partition_SDCard())
 				ret_val = 1; // failed
@@ -1332,7 +1335,7 @@
 
 		fp = popen(command.c_str(), "r");
 		if (fp == NULL) {
-			LOGERR("Error opening command to run.\n");
+			LOGERR("Error opening command to run (%s).\n", strerror(errno));
 		} else {
 			int fd = fileno(fp), has_data = 0, check = 0, keep_going = -1, bytes_read = 0;
 			struct timeval timeout;
@@ -1391,12 +1394,12 @@
 {
 	int op_status = 0;
 	operation_start("ReinjectTWRP");
-	gui_print("Injecting TWRP into boot image...\n");
+	gui_msg("injecttwrp=Injecting TWRP into boot image...");
 	if (simulate) {
 		simulate_progress_bar();
 	} else {
 		TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash");
-		gui_print("TWRP injection complete.\n");
+		gui_msg("done=Done.");
 	}
 
 	operation_end(op_status);
@@ -1462,7 +1465,7 @@
 		simulate_progress_bar();
 		operation_end(0);
 	} else {
-		gui_print("Starting ADB sideload feature...\n");
+		gui_msg("start_sideload=Starting ADB sideload feature...");
 		bool mtp_was_enabled = TWFunc::Toggle_MTP(false);
 
 		// wait for the adb connection
@@ -1471,7 +1474,7 @@
 
 		if (ret != 0) {
 			if (ret == -2)
-				gui_print("You need adb 1.0.32 or newer to sideload to this device.\n");
+				gui_msg("need_new_adb=You need adb 1.0.32 or newer to sideload to this device.");
 			ret = 1; // failure
 		} else {
 			int wipe_cache = 0;
@@ -1509,7 +1512,7 @@
 {
 	struct stat st;
 	DataManager::SetValue("tw_has_cancel", 0); // Remove cancel button from gui
-	gui_print("Cancelling ADB sideload...\n");
+	gui_msg("cancel_sideload=Cancelling ADB sideload...");
 	LOGINFO("Signaling child sideload process to exit.\n");
 	// Calling stat() on this magic filename signals the minadbd
 	// subprocess to shut down.
@@ -1543,7 +1546,7 @@
 		// Run those first.
 		int reboot = 0;
 		if (TWFunc::Path_Exists(SCRIPT_FILE_TMP)) {
-			gui_print("Processing AOSP recovery commands...\n");
+			gui_msg("running_recovery_commands=Running Recovery Commands");
 			if (OpenRecoveryScript::run_script_file() == 0) {
 				reboot = 1;
 				op_status = 0;
@@ -1551,7 +1554,7 @@
 		}
 		// Check for the ORS file in /cache and attempt to run those commands.
 		if (OpenRecoveryScript::check_for_script_file()) {
-			gui_print("Processing OpenRecoveryScript file...\n");
+			gui_msg("running_ors=Running OpenRecoveryScript");
 			if (OpenRecoveryScript::run_script_file() == 0) {
 				reboot = 1;
 				op_status = 0;
@@ -1640,7 +1643,6 @@
 		if (PartitionManager.Repair_By_Path(part_path, true)) {
 			op_status = 0; // success
 		} else {
-			LOGERR("Error repairing file system.\n");
 			op_status = 1; // fail
 		}
 	}
@@ -1662,7 +1664,6 @@
 		if (PartitionManager.Resize_By_Path(part_path, true)) {
 			op_status = 0; // success
 		} else {
-			LOGERR("Error resizing file system.\n");
 			op_status = 1; // fail
 		}
 	}
@@ -1685,7 +1686,7 @@
 		if (PartitionManager.Wipe_By_Path(part_path, file_system)) {
 			op_status = 0; // success
 		} else {
-			LOGERR("Error changing file system.\n");
+			gui_err("change_fs_err=Error changing file system.");
 			op_status = 1; // fail
 		}
 	}
@@ -1826,3 +1827,16 @@
 	operation_end(op_status);
 	return 0;
 }
+
+int GUIAction::setlanguage(std::string arg __unused)
+{
+	int op_status = 0;
+
+	operation_start("Set Language");
+	PageManager::LoadLanguage(DataManager::GetStrValue("tw_language"));
+	PageManager::RequestReload();
+	op_status = 0; // success
+
+	operation_end(op_status);
+	return 0;
+}