aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/datetime/utils.h5
-rw-r--r--src/utils.cpp89
-rw-r--r--tests/state-fixture.h1
-rw-r--r--tests/test-utils.cc79
4 files changed, 82 insertions, 92 deletions
diff --git a/include/datetime/utils.h b/include/datetime/utils.h
index fbc80d7..10e881f 100644
--- a/include/datetime/utils.h
+++ b/include/datetime/utils.h
@@ -34,9 +34,12 @@ void split_settings_location (const char * location,
char ** zone,
char ** name);
-gchar * get_current_zone_name (const char * location,
+gchar * get_timezone_name (const char * timezone,
GSettings * settings);
+gchar * get_beautified_timezone_name (const char * timezone,
+ const char * saved_location);
+
gchar * generate_full_format_string_at_time (GDateTime * now,
GDateTime * time);
diff --git a/src/utils.cpp b/src/utils.cpp
index acd9796..bef8c2e 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -25,10 +25,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <datetime/clock.h>
#include <datetime/clock-mock.h>
#include <datetime/formatter.h>
-#include <datetime/settings-shared.h>
+#include <datetime/settings-live.h>
-#include <glib/gi18n-lib.h>
-#include <gio/gio.h>
+#include <glib.h>
#include <locale.h>
#include <langinfo.h>
@@ -53,16 +52,15 @@ void
split_settings_location(const gchar* location, gchar** zone, gchar** name)
{
auto location_dup = g_strdup(location);
- g_strstrip(location_dup);
+ if(location_dup != nullptr)
+ g_strstrip(location_dup);
gchar* first;
- if((first = strchr(location_dup, ' ')))
+ if(location_dup && (first = strchr(location_dup, ' ')))
*first = '\0';
if(zone)
- {
*zone = location_dup;
- }
if(name != nullptr)
{
@@ -72,7 +70,7 @@ split_settings_location(const gchar* location, gchar** zone, gchar** name)
{
*name = g_strdup(after);
}
- else // make the name from zone
+ else if (location_dup) // make the name from zone
{
gchar * chr = strrchr(location_dup, '/');
after = g_strdup(chr ? chr + 1 : location_dup);
@@ -84,54 +82,73 @@ split_settings_location(const gchar* location, gchar** zone, gchar** name)
*name = after;
}
+ else
+ {
+ *name = nullptr;
+ }
}
}
+/**
+ * Our Locations come from two places: (1) direct user input and (2) ones
+ * guessed by the system, such as from geoclue or timedate1.
+ *
+ * Since the latter only have a timezone (eg, "America/Chicago") and the
+ * former have a descriptive name provided by the end user (eg,
+ * "America/Chicago Oklahoma City"), this function tries to make a
+ * more human-readable name by using the user-provided name if the guessed
+ * timezone matches the last one the user manually clicked on.
+ *
+ * In the example above, this allows the menuitem for the system-guessed
+ * timezone ("America/Chicago") to read "Oklahoma City" after the user clicks
+ * on the "Oklahoma City" menuitem.
+ */
gchar*
-get_current_zone_name(const gchar* location, GSettings* settings)
+get_beautified_timezone_name(const char* timezone, const char* saved_location)
{
- gchar* new_zone;
- gchar* new_name;
- split_settings_location(location, &new_zone, &new_name);
-
- auto tz_name = g_settings_get_string(settings, SETTINGS_TIMEZONE_NAME_S);
- gchar* old_zone;
- gchar* old_name;
- split_settings_location(tz_name, &old_zone, &old_name);
- g_free(tz_name);
+ gchar* zone;
+ gchar* name;
+ split_settings_location(timezone, &zone, &name);
- /* new_name is always just a sanitized version of a timezone.
- old_name is potentially a saved "pretty" version of a timezone name from
- geonames. So we prefer to use it if available and the zones match. */
+ gchar* saved_zone;
+ gchar* saved_name;
+ split_settings_location(saved_location, &saved_zone, &saved_name);
gchar* rv;
- if (g_strcmp0(old_zone, new_zone) == 0)
+ if (g_strcmp0(zone, saved_zone) == 0)
{
- rv = old_name;
- old_name = nullptr;
+ rv = saved_name;
+ saved_name = nullptr;
}
else
{
- rv = new_name;
- new_name = nullptr;
+ rv = name;
+ name = nullptr;
}
- g_free(new_zone);
- g_free(old_zone);
- g_free(new_name);
- g_free(old_name);
+ g_free(zone);
+ g_free(name);
+ g_free(saved_zone);
+ g_free(saved_name);
return rv;
}
-gchar* generate_full_format_string_at_time(GDateTime* now, GDateTime* then)
+gchar*
+get_timezone_name(const gchar* timezone, GSettings* settings)
{
- using unity::indicator::datetime::Clock;
- using unity::indicator::datetime::DateTime;
- using unity::indicator::datetime::MockClock;
- using unity::indicator::datetime::DesktopFormatter;
+ auto saved_location = g_settings_get_string(settings, SETTINGS_TIMEZONE_NAME_S);
+ auto rv = get_beautified_timezone_name(timezone, saved_location);
+ g_free(saved_location);
+ return rv;
+}
+using namespace unity::indicator::datetime;
+
+gchar* generate_full_format_string_at_time(GDateTime* now, GDateTime* then)
+{
std::shared_ptr<Clock> clock(new MockClock(DateTime(now)));
- DesktopFormatter formatter(clock);
+ std::shared_ptr<Settings> settings(new LiveSettings);
+ DesktopFormatter formatter(clock, settings);
return g_strdup(formatter.getRelativeFormat(then).c_str());
}
diff --git a/tests/state-fixture.h b/tests/state-fixture.h
index 0286ea9..3c6ecd5 100644
--- a/tests/state-fixture.h
+++ b/tests/state-fixture.h
@@ -50,6 +50,7 @@ protected:
const DateTime now = DateTime::NowLocal();
m_clock.reset(new MockClock(now));
m_state.reset(new State);
+ m_state->settings.reset(new Settings);
m_state->timezones.reset(new Timezones);
m_state->clock = std::dynamic_pointer_cast<Clock>(m_clock);
m_state->planner.reset(new MockPlanner);
diff --git a/tests/test-utils.cc b/tests/test-utils.cc
index 8246396..2fe6a2e 100644
--- a/tests/test-utils.cc
+++ b/tests/test-utils.cc
@@ -17,22 +17,16 @@
* Charles Kerr <charles.kerr@canonical.com>
*/
-#include <gtest/gtest.h>
-
-#include <glib-object.h>
-
-#include "utils.h"
+#include <datetime/utils.h>
-/***
-****
-***/
+#include <gtest/gtest.h>
TEST(UtilsTest, SplitSettingsLocation)
{
struct {
- const char * location;
- const char * expected_zone;
- const char * expected_name;
+ const char* location;
+ const char* expected_zone;
+ const char* expected_name;
} test_cases[] = {
{ "America/Chicago Chicago", "America/Chicago", "Chicago" },
{ "America/Chicago Oklahoma City", "America/Chicago", "Oklahoma City" },
@@ -43,63 +37,38 @@ TEST(UtilsTest, SplitSettingsLocation)
{ "UTC UTC", "UTC", "UTC" }
};
- for(guint i=0, n=G_N_ELEMENTS(test_cases); i<n; i++)
+ for(const auto& test_case : test_cases)
{
- char * zone = NULL;
- char * name = NULL;
+ char * zone = nullptr;
+ char * name = nullptr;
- split_settings_location(test_cases[i].location, &zone, &name);
- ASSERT_STREQ(test_cases[i].expected_zone, zone);
- ASSERT_STREQ(test_cases[i].expected_name, name);
+ split_settings_location(test_case.location, &zone, &name);
+ ASSERT_STREQ(test_case.expected_zone, zone);
+ ASSERT_STREQ(test_case.expected_name, name);
g_free(zone);
g_free(name);
}
}
-/***
-****
-***/
-
-#define EM_SPACE "\xE2\x80\x82"
-
-TEST(UtilsTest, GenerateTerseFormatString)
+TEST(UtilsTest, BeautifulTimezoneName)
{
- auto arbitrary_day = g_date_time_new_local(2013, 6, 25, 12, 34, 56);
- auto on_the_hour = g_date_time_new_local(2013, 6, 25, 12, 0, 0);
-
struct {
- GDateTime * now;
- GDateTime * time;
- const char * expected_format_string;
+ const char* timezone;
+ const char* location;
+ const char* expected_name;
} test_cases[] = {
- { g_date_time_ref(arbitrary_day), g_date_time_ref(arbitrary_day), "%l:%M %p" }, /* identical time */
- { g_date_time_ref(arbitrary_day), g_date_time_add_hours(arbitrary_day,1), "%l:%M %p" }, /* later today */
- { g_date_time_ref(arbitrary_day), g_date_time_add_days(arbitrary_day,1), "Tomorrow" EM_SPACE "%l:%M %p" }, /* tomorrow */
- { g_date_time_ref(arbitrary_day), g_date_time_add_days(arbitrary_day,2), "%a" EM_SPACE "%l:%M %p" },
- { g_date_time_ref(arbitrary_day), g_date_time_add_days(arbitrary_day,6), "%a" EM_SPACE "%l:%M %p" },
- { g_date_time_ref(arbitrary_day), g_date_time_add_days(arbitrary_day,7), "%d %b" EM_SPACE "%l:%M %p" }, /* over one week away */
-
- { g_date_time_ref(on_the_hour), g_date_time_ref(on_the_hour), "%l %p" }, /* identical time */
- { g_date_time_ref(on_the_hour), g_date_time_add_hours(on_the_hour,1), "%l %p" }, /* later today */
- { g_date_time_ref(on_the_hour), g_date_time_add_days(on_the_hour,1), "Tomorrow" EM_SPACE "%l %p" }, /* tomorrow */
- { g_date_time_ref(on_the_hour), g_date_time_add_days(on_the_hour,2), "%a" EM_SPACE "%l %p" },
- { g_date_time_ref(on_the_hour), g_date_time_add_days(on_the_hour,6), "%a" EM_SPACE "%l %p" },
- { g_date_time_ref(on_the_hour), g_date_time_add_days(on_the_hour,7), "%d %b" EM_SPACE "%l %p" }, /* over one week away */
+ { "America/Chicago", NULL, "Chicago" },
+ { "America/Chicago", "America/Chicago", "Chicago" },
+ { "America/Chicago", "America/Chigago Chicago", "Chicago" },
+ { "America/Chicago", "America/Chicago Oklahoma City", "Oklahoma City" },
+ { "America/Chicago", "Europe/London London", "Chicago" }
};
- for(guint i=0, n=G_N_ELEMENTS(test_cases); i<n; i++)
+ for(const auto& test_case : test_cases)
{
- auto format_string = generate_terse_format_string_at_time(test_cases[i].now,
- test_cases[i].time);
-
- ASSERT_STREQ(test_cases[i].expected_format_string, format_string);
-
- g_free(format_string);
- g_date_time_unref(test_cases[i].now);
- g_date_time_unref(test_cases[i].time);
+ auto name = get_beautified_timezone_name(test_case.timezone, test_case.location);
+ EXPECT_STREQ(test_case.expected_name, name);
+ g_free(name);
}
-
- g_date_time_unref(arbitrary_day);
- g_date_time_unref(on_the_hour);
}