Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set 24h format based on language #84

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c0a0114
Add option for 24 h format languages
meisenzahl Jun 25, 2020
13867ee
Read option for 24 h format languages
meisenzahl Jun 25, 2020
57ac175
Add logic to set time format for user
meisenzahl Jun 25, 2020
cc826a0
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Aug 29, 2020
d2c5ab6
Add view to set timezone
meisenzahl Sep 17, 2020
4e3f81c
Satisfy linter
meisenzahl Sep 17, 2020
00e498a
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Sep 17, 2020
83aaa9f
Set timezone on system
meisenzahl Sep 17, 2020
3507df5
Set clock format for user based on countrycode found by timezone
meisenzahl Sep 17, 2020
a2ad4dd
Satisfy linter
meisenzahl Sep 17, 2020
0f74982
Set clock format based on Posix.NLItem.T_FMT
meisenzahl Sep 19, 2020
9014707
Satisfy linter
meisenzahl Sep 19, 2020
2f8f245
Refactor
meisenzahl Sep 19, 2020
9e0e8a6
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Sep 21, 2020
9dc9cb7
Set clock format for created user
meisenzahl Sep 23, 2020
b1b1471
Satisfy linter
meisenzahl Sep 23, 2020
0be493c
Write clock format to accounts service
meisenzahl Sep 26, 2020
49787b4
Change to owned get accessor
meisenzahl Sep 26, 2020
a5ece22
Delete unused function
meisenzahl Sep 26, 2020
ccaf1b4
Chain async methods
meisenzahl Sep 27, 2020
8621955
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Oct 21, 2020
51212f8
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Oct 25, 2020
0c8c1e6
Merge branch 'master' into set-24h-format-based-on-language
cassidyjames Nov 5, 2020
1e08b1a
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Nov 14, 2020
44c7b17
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Dec 16, 2020
955c877
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Dec 28, 2020
9633a9c
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Jan 30, 2021
bbecc89
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Feb 15, 2021
33ea61f
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Apr 6, 2021
be6cefa
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl May 2, 2021
61f31f1
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl May 28, 2021
4dc28c3
Merge branch 'master' into set-24h-format-based-on-language
cassidyjames Jun 7, 2021
1c5221d
Merge branch 'master' into set-24h-format-based-on-language
Jun 29, 2021
44362a8
Merge branch 'master' into set-24h-format-based-on-language
cassidyjames Jul 8, 2021
60f2cd1
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Jul 17, 2021
8dace65
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Aug 11, 2021
a3150cd
Merge branch 'master' into set-24h-format-based-on-language
cassidyjames Aug 20, 2021
b57c037
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Oct 17, 2021
47e5d68
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Dec 7, 2021
f6623e9
Merge branch 'master' into set-24h-format-based-on-language
Dec 10, 2021
c6dd136
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Feb 3, 2022
4475971
Merge branch 'master' into set-24h-format-based-on-language
kgrubb Feb 23, 2022
cb1fc0d
Merge branch 'master' into set-24h-format-based-on-language
meisenzahl Feb 26, 2022
852a68f
Merge branch 'master' into set-24h-format-based-on-language
danirabbit Apr 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/Config.vala.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace Build {
public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@";
public const string LANG_LIST = "@LANG_LIST@";
public const string PREFERRED_LANG_LIST = "@PREFERRED_LANG_LIST@";
public const string XKB_BASE = "@XKB_BASE@";
public const string ISO_CODES_LOCATION = "@ISO_CODES_LOCATION@";
public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@";
public const string LANG_LIST = "@LANG_LIST@";
public const string PREFERRED_LANG_LIST = "@PREFERRED_LANG_LIST@";
public const string XKB_BASE = "@XKB_BASE@";
public const string ISO_CODES_LOCATION = "@ISO_CODES_LOCATION@";
}
1 change: 1 addition & 0 deletions src/Helpers/AccountsServiceInterface.vala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public interface Installer.AccountsService : Object {

public abstract KeyboardLayout[] keyboard_layouts { owned get; set; }
public abstract uint active_keyboard_layout { get; set; }
public abstract string clock_format { owned get; set; }
public abstract bool left_handed { get; set; }
}

Expand Down
164 changes: 164 additions & 0 deletions src/Helpers/LocationHelper.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
/*-
* Copyright (c) 2014 Pantheon Developers (http://launchpad.net/switchboard-plug-datetime)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Corentin Noël <corentin@elementaryos.org>
*/

public class LocationHelper : GLib.Object {
[DBus (name = "org.freedesktop.timedate1")]
public interface DateTime1 : Object {
public abstract string Timezone {public owned get;}
public abstract bool LocalRTC {public get;}
public abstract bool CanNTP {public get;}
public abstract bool NTP {public get;}

//usec_utc expects number of microseconds since 1 Jan 1970 UTC
public abstract void set_time (int64 usec_utc, bool relative, bool user_interaction) throws GLib.Error;
public abstract void set_timezone (string timezone, bool user_interaction) throws GLib.Error;
public abstract void SetLocalRTC (bool local_rtc, bool fix_system, bool user_interaction) throws GLib.Error; //vala-lint=naming-convention
public abstract void SetNTP (bool use_ntp, bool user_interaction) throws GLib.Error; //vala-lint=naming-convention
}

private static List<string> lines;
private static LocationHelper? helper = null;

public static LocationHelper get_default () {
if (helper == null)
helper = new LocationHelper ();
return helper;
}
private LocationHelper () {
var file = File.new_for_path ("/usr/share/zoneinfo/zone.tab");
if (!file.query_exists ()) {
critical ("/usr/share/zoneinfo/zone.tab doesn't exist !");
return;
}

lines = new List<string> ();
try {
var dis = new DataInputStream (file.read ());
string line;
while ((line = dis.read_line (null)) != null) {
if (line.has_prefix ("#")) {
continue;
}

lines.append (line);
}
} catch (Error e) {
critical (e.message);
}
#if GENERATE
generate_translation_template ();
#endif
}

public HashTable<string, string> get_timezones_from_continent (string continent) {
var timezones = new HashTable<string, string> (str_hash, str_equal);
foreach (var line in lines) {
var items = line.split ("\t", 4);
string value = items[2];
if (value.has_prefix (continent) == false)
continue;

string tz_name_field;
// Take the original English string if there is something wrong with the translation
if (_(items[2]) == null || _(items[2]) == "") {
tz_name_field = items[2];
} else {
tz_name_field = _(items[2]);
}

string city = tz_name_field.split ("/", 2)[1];
if (city != null && city != "") {
string key = format_city (city);
if (items[3] != null && items[3] != "") {
if (items[3] != "mainland" && items[3] != "most locations" && _(items[3]) != key) {
key = "%s - %s".printf (key, format_city (_(items[3])));
}
}

timezones.set (key, value);
}
}

return timezones;
}

public string? get_countrycode_from_timezone (string timezone) {
foreach (var line in lines) {
var items = line.split ("\t", 4);
string value = items[2];

if (value == timezone) {
return items[0];
}
}

return null;
}

public HashTable<string, string> get_locations () {
var locations = new HashTable<string, string> (str_hash, str_equal);
foreach (var line in lines) {
var items = line.split ("\t", 4);
string key = items[1];
string value = items[2];
locations.set (key, value);
}

return locations;
}

public static string format_city (string city) {
return city.replace ("_", " ").replace ("/", ", ");
}

public static string get_clock_format () {
var t_fmt = Posix.nl_langinfo (Posix.NLItem.T_FMT);

if (t_fmt.contains ("%r") || t_fmt.contains ("%l") || t_fmt.contains ("%I")) {
return "12h";
}

return "24h";
}

#if GENERATE
public void generate_translation_template () {
var file = GLib.File.new_for_path (GLib.Environment.get_home_dir () + "/Translations.vala");
try {
var dos = new GLib.DataOutputStream (file.create (GLib.FileCreateFlags.REPLACE_DESTINATION));
dos.put_string ("#if 0\n");
foreach (var line in lines) {
var items = line.split ("\t", 4);
string key = items[2];
string comment = items[3];
dos.put_string ("///Translators: Secondary \"/\" and all \"_\" will be replaced by \", \" and \" \".\n");
dos.put_string ("_(\""+ key + "\");\n");
if (comment != null && comment != "") {
dos.put_string ("///Translators: Comment for Timezone %s\n".printf (key));
dos.put_string ("_(\""+ comment + "\");\n");
}
}
dos.put_string ("#endif\n");
} catch (Error e) {
critical (e.message);
}
}
#endif
}
56 changes: 53 additions & 3 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Installer.MainWindow : Hdy.Window {

private AccountView account_view;
private LanguageView language_view;
private LocationView location_view;
private KeyboardLayoutView keyboard_layout_view;
private NetworkView network_view;

Expand Down Expand Up @@ -82,20 +83,69 @@ public class Installer.MainWindow : Hdy.Window {
deck.add (network_view);
deck.visible_child = network_view;

network_view.next_step.connect (load_account_view);
network_view.next_step.connect (load_location_view);
} else {
load_account_view ();
load_location_view ();
}
}

private void load_location_view () {
if (location_view != null) {
location_view.destroy ();
}

location_view = new LocationView ();
deck.add (location_view);
deck.visible_child = location_view;

location_view.next_step.connect (() => load_account_view ());
}

private void load_account_view () {
if (account_view != null) {
account_view.destroy ();
}

account_view = new AccountView ();

deck.add (account_view);
deck.visible_child = account_view;
}

private async void set_timezone () {
try {
LocationHelper.DateTime1 datetime1 = yield Bus.get_proxy (BusType.SYSTEM, "org.freedesktop.timedate1", "/org/freedesktop/timedate1");
unowned Configuration configuration = Configuration.get_default ();
datetime1.set_timezone (configuration.timezone, true);
} catch (Error e) {
warning (e.message);
}
}

private async void set_clock_format () {
AccountsService accounts_service = null;

try {
var act_service = yield GLib.Bus.get_proxy<FDO.Accounts> (GLib.BusType.SYSTEM,
"org.freedesktop.Accounts",
"/org/freedesktop/Accounts");
var user_path = act_service.find_user_by_name (account_view.created.user_name);

accounts_service = yield GLib.Bus.get_proxy (GLib.BusType.SYSTEM,
"org.freedesktop.Accounts",
user_path,
GLib.DBusProxyFlags.GET_INVALIDATED_PROPERTIES);
} catch (Error e) {
warning ("Unable to get AccountsService proxy, clock format on new user may be incorrect: %s", e.message);
}

if (accounts_service != null) {
accounts_service.clock_format = Configuration.get_default ().clock_format;
}
}

private async void set_settings () {
yield set_accounts_service_settings ();
yield set_timezone ();
yield set_clock_format ();
}
}
2 changes: 2 additions & 0 deletions src/Objects/Configuration.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ public class Configuration : GLib.Object {
public string? country { get; set; default = null; }
public InitialSetup.KeyboardLayout keyboard_layout { get; set; }
public InitialSetup.KeyboardVariant? keyboard_variant { get; set; default = null; }
public string timezone { get; set; }
public string clock_format { get; set; default = "24h"; }
public bool left_handed { get; set; }
}
87 changes: 87 additions & 0 deletions src/Objects/LocationLayout.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*-
* Copyright 2019 elementary, Inc (https://elementary.io)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Corentin Noël <corentin@elementary.io>
*/

public class InitialSetup.LocationLayout : GLib.Object {
public string name { get; construct; }
public string original_name { get; construct; }
public string display_name {
get {
return name;
}
}

private GLib.ListStore variants_store;

public LocationLayout (string name, string original_name) {
Object (name: name, original_name: original_name);
}

construct {
variants_store = new GLib.ListStore (typeof (LocationVariant));
variants_store.append (new LocationVariant (this, null, null));
}

public void add_variant (string name, string original_name) {
var variant = new LocationVariant (this, name, original_name);
variants_store.insert_sorted (variant, (GLib.CompareDataFunc<GLib.Object>) LocationVariant.compare);
}

public bool has_variants () {
return variants_store.get_n_items () > 1;
}

public unowned GLib.ListStore get_variants () {
return variants_store;
}

public GLib.Variant to_gsd_variant () {
return new GLib.Variant ("(ss)", "xkb", name);
}

public static int compare (LocationLayout a, LocationLayout b) {
return a.display_name.collate (b.display_name);
}

public static GLib.ListStore get_all () {
var layout_store = new GLib.ListStore (typeof (LocationLayout));

var continents = new List<string> ();
continents.append ("Africa");
continents.append ("America");
continents.append ("Antarctica");
continents.append ("Asia");
continents.append ("Atlantic");
continents.append ("Australia");
continents.append ("Europe");
continents.append ("Indian");
continents.append ("Pacific");

continents.foreach ((continent) => {
var layout = new LocationLayout (_(continent), continent);
layout_store.insert_sorted (layout, (GLib.CompareDataFunc<GLib.Object>) LocationLayout.compare);

var timezones = LocationHelper.get_default ().get_timezones_from_continent (continent);
timezones.foreach ((city, timezone) => {
layout.add_variant (_(city), timezone);
});
});

return layout_store;
}
}
Loading