← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/bug-566729 into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-566729 into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #566729 in widelands: "Add gametime display to replays"
  https://bugs.launchpad.net/widelands/+bug/566729

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-566729/+merge/229302

Added gametime to replays & debug screen on the top left.

Also removed leading 0s from gametime (hours only), except for the in-game messages where we need the 0s for table sorting.

Internationalized the display of datetime strings in filenames.
-- 
https://code.launchpad.net/~widelands-dev/widelands/bug-566729/+merge/229302
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-566729 into lp:widelands.
=== modified file 'src/base/time_string.cc'
--- src/base/time_string.cc	2014-07-05 14:22:44 +0000
+++ src/base/time_string.cc	2014-08-01 22:44:21 +0000
@@ -19,11 +19,16 @@
 
 #include "base/time_string.h"
 
+#include <algorithm>
 #include <cassert>
 #include <ctime>
+#include <string>
 
+#include <boost/format.hpp>
 #include <stdint.h>
 
+#include "base/i18n.h"
+
 namespace  {
 char timestring_buffer[] = "YYYY-MM-DDThh.mm.ss"; //  ':' is not a valid file name character for FAT FS
 char gamestringbuffer[] = "000:00:00";
@@ -82,7 +87,104 @@
 	return timestring_buffer;
 }
 
-char * gametimestring(uint32_t gametime)
+namespace  {
+std::string localize_month(int8_t month) {
+	std::string fallback = std::to_string(month);
+	switch (month) {
+		case 1:
+			/** TRANSLATORS: January */
+			return _("Jan");
+		case 2:
+			/** TRANSLATORS: February */
+			return _("Feb");
+		case 3:
+			/** TRANSLATORS: March */
+			return _("Mar");
+		case 4:
+			/** TRANSLATORS: April */
+			return _("Apr");
+		case 5:
+			/** TRANSLATORS: May */
+			return _("May");
+		case 6:
+			/** TRANSLATORS: June */
+			return _("Jun");
+		case 7:
+			/** TRANSLATORS: July */
+			return _("Jul");
+		case 8:
+			/** TRANSLATORS: August */
+			return _("Aug");
+		case 9:
+			/** TRANSLATORS: September */
+			return _("Sep");
+		case 10:
+			/** TRANSLATORS: October */
+			return _("Oct");
+		case 11:
+			/** TRANSLATORS: November */
+			return _("Nov");
+		case 12:
+			/** TRANSLATORS: December */
+			return _("Dec");
+		default:
+			return fallback;
+	}
+}
+}
+
+
+// Locale-dependent formatting for datetime-based filenames.
+std::string format_timestring(std::string timestring) {
+
+	std::string result = "";
+
+	// Do some formatting if this is a string of the type "YYYY-MM-DDThh.mm.ss"
+	// check separators
+	if (timestring.length() >= sizeof(timestring_buffer) - 1 &&
+		 timestring.compare(4, 1, "-") == 0 &&
+		 timestring.compare(7, 1, "-") == 0 &&
+		 timestring.compare(10, 1, "T") == 0 &&
+		 timestring.compare(13, 1, ".") == 0 &&
+		 timestring.compare(16, 1, ".") == 0) {
+
+		std::string year = timestring.substr(0, 4);
+		std::string month = timestring.substr(5, 2);
+		std::string day = timestring.substr(8, 2);
+		std::string hour = timestring.substr(11, 2);
+		std::string minute = timestring.substr(14, 2);
+		std::string second = timestring.substr(17, 2);
+
+		// check digits
+		if (std::all_of(year.begin(), year.end(), ::isdigit) &&
+			 std::all_of(month.begin(), month.end(), ::isdigit) &&
+			 std::all_of(day.begin(), day.end(), ::isdigit) &&
+			 std::all_of(hour.begin(), hour.end(), ::isdigit) &&
+			 std::all_of(minute.begin(), minute.end(), ::isdigit) &&
+			 std::all_of(second.begin(), second.end(), ::isdigit)) {
+
+			month = localize_month(stoi(month));
+
+			/** TRANSLATORS: Date format for filenames on load game screens. YYYY Mon DD hh:mm:ss */
+			result = (boost::format(_("%1% %2% %3% %4%:%5%:%6%"))
+						 % day % month % year
+						 % hour % minute % second).str();
+
+			if (timestring.length() > sizeof(timestring_buffer) - 1) {
+				result.append(timestring.substr(19));
+			}
+
+		} else {
+				result = timestring;
+		}
+	} else {
+		result = timestring;
+	}
+	return result;
+}
+
+
+char * gametimestring_leading_zeros(uint32_t gametime)
 {
 	uint32_t time = gametime / 1000;
 	gamestringbuffer[8] = '0' +  time        % 10;
@@ -94,3 +196,25 @@
 	gamestringbuffer[0] = '0' + (time /= 10);
 	return gamestringbuffer;
 }
+
+char * gametimestring(uint32_t gametime)
+{
+	// update buffer
+	gametimestring_leading_zeros(gametime);
+
+	// remove leading 0s
+	int8_t returnindex = 0;
+	if (gamestringbuffer[0] == '0')
+	{
+		returnindex++;
+		if (gamestringbuffer[1] == '0')
+		{
+			returnindex++;
+			if (gamestringbuffer[2] == '0')
+			{
+				returnindex = returnindex + 2;
+			}
+		}
+	}
+	return &gamestringbuffer[returnindex];
+}

=== modified file 'src/base/time_string.h'
--- src/base/time_string.h	2014-07-05 16:41:51 +0000
+++ src/base/time_string.h	2014-08-01 22:44:21 +0000
@@ -20,6 +20,8 @@
 #ifndef WL_BASE_TIME_STRING_H
 #define WL_BASE_TIME_STRING_H
 
+#include <string>
+
 #include <stdint.h>
 
 /// Get a string representation conforming to ISO 8601 of the current time (in
@@ -27,9 +29,22 @@
 /// string which might be overwritten by subsequent calls.
 char * timestring();
 
+/// Format a localized timestring for display on screen for the user,
+/// so it is more easily read.
+/// If the string starts with the datetime format "YYYY-MM-DDThh.mm.ss",
+/// that part of the string is transformed to a localized datetime string.
+/// Any other parts of the string remain as is.
+std::string format_timestring(std::string timestring);
+
 /// Get a string representation of the game time
 /// as hhh:mm:ss. If Time represents more than
 /// 999 hours, it wraps around
+/// Use this in table columns for easy sorting
+char * gametimestring_leading_zeros(uint32_t gametime);
+
+/// Get a string representation of the game time
+/// as [hhh:]mm:ss. If Time represents more than
+/// 999 hours, it wraps around
 char * gametimestring(uint32_t gametime);
 
 #endif  // end of include guard: WL_BASE_TIME_STRING_H

=== modified file 'src/ui_fsmenu/loadgame.cc'
--- src/ui_fsmenu/loadgame.cc	2014-07-14 10:45:44 +0000
+++ src/ui_fsmenu/loadgame.cc	2014-08-01 22:44:21 +0000
@@ -311,7 +311,7 @@
 				Widelands::Game_Loader gl(name, m_game);
 				gl.preload_game(gpdp);
 
-				m_list.add(FileSystem::FS_FilenameWoExt(name).c_str(), name);
+				m_list.add(format_timestring(FileSystem::FS_FilenameWoExt(name)).c_str(), name);
 			} catch (const _wexception &) {
 				//  we simply skip illegal entries
 			}

=== modified file 'src/ui_fsmenu/loadreplay.cc'
--- src/ui_fsmenu/loadreplay.cc	2014-07-05 14:22:44 +0000
+++ src/ui_fsmenu/loadreplay.cc	2014-08-01 22:44:21 +0000
@@ -237,7 +237,7 @@
 			gl.preload_game(gpdp);
 
 			m_list.add
-				(FileSystem::FS_FilenameWoExt(pname->c_str()).c_str(), *pname);
+				(format_timestring(FileSystem::FS_FilenameWoExt(pname->c_str())).c_str(), *pname);
 		} catch (const _wexception &) {} //  we simply skip illegal entries
 	}
 

=== modified file 'src/wui/game_main_menu_save_game.cc'
--- src/wui/game_main_menu_save_game.cc	2014-07-22 09:54:49 +0000
+++ src/wui/game_main_menu_save_game.cc	2014-08-01 22:44:21 +0000
@@ -134,8 +134,6 @@
 		m_gametime.set_text(gametimestring(gametime));
 
 		int player_nr = parent.game().player_manager()->get_number_of_players();
-		// TODO(GunChleoc): This should be ngettext(" %i player" etc. with boost::format, but it refuses to work
-		/** TRANSLATORS: This is preceded by a number */
 		m_players_label.set_text(
 		   (boost::format(ngettext("%i player", "%i players", player_nr)) % player_nr).str());
 		m_win_condition.set_text(parent.game().get_win_condition_displayname());
@@ -157,7 +155,7 @@
 	gl.preload_game(gpdp); //  This has worked before, no problem
 
 	{
-		m_editbox->setText(FileSystem::FS_FilenameWoExt(name.c_str()));
+		m_editbox->setText(format_timestring(FileSystem::FS_FilenameWoExt(name.c_str())));
 	}
 	m_button_ok->set_enabled(true);
 
@@ -215,7 +213,7 @@
 		try {
 			Widelands::Game_Loader gl(name, igbase().game());
 			gl.preload_game(gpdp);
-			m_ls.add(FileSystem::FS_FilenameWoExt(name).c_str(), name);
+			m_ls.add(format_timestring(FileSystem::FS_FilenameWoExt(name).c_str()).c_str(), name);
 		} catch (const _wexception &) {} //  we simply skip illegal entries
 	}
 }

=== modified file 'src/wui/game_message_menu.cc'
--- src/wui/game_message_menu.cc	2014-07-25 22:17:48 +0000
+++ src/wui/game_message_menu.cc	2014-08-01 22:44:21 +0000
@@ -205,7 +205,7 @@
 	er.set_string(ColTitle, message.title());
 
 	const uint32_t time = message.sent();
-	er.set_string(ColTimeSent, gametimestring(time));
+	er.set_string(ColTimeSent, gametimestring_leading_zeros(time));
 }
 
 /*

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2014-07-28 14:23:03 +0000
+++ src/wui/interactive_base.cc	2014-08-01 22:44:21 +0000
@@ -26,6 +26,7 @@
 #include <boost/format.hpp>
 
 #include "base/macros.h"
+#include "base/time_string.h"
 #include "economy/flag.h"
 #include "economy/road.h"
 #include "graphic/default_resolution.h"
@@ -404,6 +405,17 @@
 
 	// Blit node information when in debug mode.
 	if (get_display_flag(dfDebug) || !dynamic_cast<const Game*>(&egbase())) {
+
+		std::string gametime(gametimestring(static_cast<uint32_t>(egbase().get_gametime())));
+
+		const std::string gametime_text = as_uifont
+			(gametime.c_str(), UI_FONT_SIZE_SMALL);
+		dst.blit(
+			Point(5, 5),
+			UI::g_fh1->render(gametime_text),
+			CM_Normal,
+			UI::Align_TopLeft
+		);
 		static format node_format("(%i, %i)");
 
 		const std::string node_text = as_uifont
@@ -423,7 +435,7 @@
 			((fps_format %
 			  (1000.0 / m_frametime) % (1000.0 / (m_avg_usframetime / 1000)))
 			 .str(), UI_FONT_SIZE_SMALL);
-		dst.blit(Point(5, 5), UI::g_fh1->render(fps_text), CM_Normal, UI::Align_Left);
+		dst.blit(Point(5, 25), UI::g_fh1->render(fps_text), CM_Normal, UI::Align_Left);
 	}
 }
 


Follow ups