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

Expose clock format as granite setting #528

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
10 changes: 7 additions & 3 deletions demo/Views/DateTimePickerView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ public class DateTimePickerView : Gtk.Grid {
current_time_label.halign = Gtk.Align.END;

var now = new DateTime.now_local ();
var settings = new Settings ("org.gnome.desktop.interface");
var time_format = Granite.DateTime.get_default_time_format (settings.get_enum ("clock-format") == 1, false);
var settings = Granite.Settings.get_default ();
var time_format = Granite.DateTime.get_default_time_format (settings.clock_format == Granite.Settings.ClockFormat.12H, false);

var current_time = new Gtk.Label (now.format (time_format));
var current_time = new Gtk.Label (Granite.DateTime.format_time (now, false));
current_time.tooltip_text = time_format;
current_time.xalign = 0;

settings.notify["clock-format"].connect (() => {
current_time.label = Granite.DateTime.format_time (now, false);
});

var current_date_label = new Gtk.Label ("Localized date:");
current_date_label.halign = Gtk.Align.END;

Expand Down
40 changes: 22 additions & 18 deletions lib/DateTime.vala
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@
* getting the default translated format for either date and time.
*/
namespace Granite.DateTime {

/**
* Gets a default translated time format.
* The function constructs a new string interpreting the //is_12h// and //with_second// parameters
* so that it can be used with formatting functions like {@link GLib.DateTime.format}.
*
* The returned string is formatted and translated. This function is mostly used to display
* The returned format string is formatted and translated. This function is mostly used to display
* the time in various user interfaces like the time displayed in the top panel.
*
* @param is_12h if the returned string should be formatted in 12h format
* @param with_second if the returned string should include seconds
*
* @return the formatted and located time string.
* @return the formatted and located time format string.
*/
public static string get_default_time_format (bool is_12h = false, bool with_second = false) {
if (is_12h == true) {
Expand All @@ -41,6 +42,22 @@ namespace Granite.DateTime {
}
}

/**
* Formats a {@link GLib.DateTime} using defaults from desktop settings
*
* The returned string is formatted and translated. This function is mostly used to display
* the time in various user interfaces like the time displayed in the top panel.
*
* @param date_time a {@link GLib.DateTime} to format using the desktop settings
* @param with_second if the returned string should include seconds
* @return the formatted and located time string.
*/
public static string format_time (GLib.DateTime date_time, bool with_second = false) {
var is_12h = is_clock_format_12h ();
var time_format = get_default_time_format (is_12h, with_second);
return date_time.format (time_format);
}

/**
* Compares a {@link GLib.DateTime} to {@link GLib.DateTime.now_local} and returns a location, relative date and
* time string. Results appear as natural-language strings like "Now", "5m ago", "Yesterday"
Expand Down Expand Up @@ -75,7 +92,7 @@ namespace Granite.DateTime {
}
}

return date_time.format (get_default_time_format (is_clock_format_12h (), false));
return format_time (date_time, false);
} else if (is_same_day (date_time.add_days (1), now)) {
return _("Yesterday");
} else if (is_same_day (date_time.add_days (-1), now)) {
Expand All @@ -96,21 +113,8 @@ namespace Granite.DateTime {
* @return true if the clock format is 12h based, false otherwise.
*/
private static bool is_clock_format_12h () {
string format = null;
try {
var portal = Portal.Settings.get ();
var variant = portal.read ("org.gnome.desktop.interface", "clock-format").get_variant ();
format = variant.get_string ();
} catch (Error e) {
debug ("cannot use portal, using GSettings: %s", e.message);
}

if (format == null) {
var h24_settings = new GLib.Settings ("org.gnome.desktop.interface");
format = h24_settings.get_string ("clock-format");
}

return (format.contains ("12h"));
var settings = Granite.Settings.get_default ();
return settings.clock_format == Granite.Settings.ClockFormat.12H;
}

/**
Expand Down
84 changes: 83 additions & 1 deletion lib/Widgets/Settings.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ namespace Granite {
* Granite.Settings provides a way to share Pantheon desktop settings with applications.
*/
public class Settings : Object {

private const string GNOME_DESKTOP_INTERFACE = "org.gnome.desktop.interface";
private const string CLOCK_FORMAT_KEY = "clock-format";

/**
* Possible color scheme preferences expressed by the user
*/
Expand Down Expand Up @@ -69,6 +73,36 @@ namespace Granite {
}
}

/**
* Possible clock format preferences expressed by the user
*/
public enum ClockFormat {
ryonakano marked this conversation as resolved.
Show resolved Hide resolved
/**
* The user prefers a 12 hour clock
*/
12H,
/**
* The user prefers a 24 hour clock
*/
24H
}

private ClockFormat? _clock_format = null;
/**
* Whether the user would prefer a 12 hour or 24 hour clock
*/
public ClockFormat clock_format {
get {
if (_clock_format == null) {
setup_clock_format ();
}
return _clock_format;
Copy link
Member

@tintou tintou Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return _clock_format;
return _clock_format;

_clock_format might be null, so we need to explicitly do/
return _clock_format ?? ClockFormat.24H

}
private set {
_clock_format = value;
}
}

private static GLib.Once<Granite.Settings> instance;
public static unowned Granite.Settings get_default () {
return instance.once (() => {
Expand Down Expand Up @@ -96,9 +130,15 @@ namespace Granite {
}
}

private void setup_portal () {
if (portal == null) {
portal = Portal.Settings.get ();
}
}

private void setup_prefers_color_scheme () {
try {
portal = Portal.Settings.get ();
setup_portal ();

prefers_color_scheme = (ColorScheme) portal.read (
"org.freedesktop.appearance",
Expand Down Expand Up @@ -139,5 +179,47 @@ namespace Granite {
// Set a default in case we can't get from system
prefers_color_scheme = ColorScheme.NO_PREFERENCE;
}

private void setup_clock_format () {
try {
setup_portal ();

var clock_format_variant = portal.read (GNOME_DESKTOP_INTERFACE, CLOCK_FORMAT_KEY).get_variant ();
var format = clock_format_variant.get_string ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var format = clock_format_variant.get_string ();
unowned var format = clock_format_variant.get_string ();


set_clock_format_from_nick (format);

portal.setting_changed.connect ((@namespace, key, @value) => {
if (@namespace == GNOME_DESKTOP_INTERFACE && key == CLOCK_FORMAT_KEY) {
var updated_format = @value.get_string ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var updated_format = @value.get_string ();
unowned var updated_format = @value.get_string ();

set_clock_format_from_nick (updated_format);
}
});
} catch (Error e) {
debug ("Unable to connect to desktop portal (%s), using GSettings", e.message);

var interface_settings = new GLib.Settings (GNOME_DESKTOP_INTERFACE);
var format = interface_settings.get_string (CLOCK_FORMAT_KEY);
set_clock_format_from_nick (format);

interface_settings.changed.connect ((key) => {
if (key == CLOCK_FORMAT_KEY) {
var updated_format = interface_settings.get_string (CLOCK_FORMAT_KEY);
set_clock_format_from_nick (updated_format);
}
});
}
}

private void set_clock_format_from_nick (string format) {
EnumClass clock_format_enum_class = (EnumClass) typeof (ClockFormat).class_ref ();
unowned EnumValue? eval = clock_format_enum_class.get_value_by_nick (format);

if (eval == null) {
_clock_format = null;
} else {
clock_format = (ClockFormat) eval.value;
}
}
}
}
23 changes: 18 additions & 5 deletions lib/Widgets/TimePicker.vala
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ namespace Granite.Widgets {
activate.connect (is_unfocused);

update_text ();

var granite_settings = Granite.Settings.get_default ();

granite_settings.notify["clock-format"].connect (() => {
update_text ();
set_popover_clock_format ();
});
}

private void update_time (bool is_hour) {
Expand Down Expand Up @@ -222,6 +229,14 @@ namespace Granite.Widgets {
private void on_icon_press (Gtk.EntryIconPosition position, Gdk.Event event) {
// If the mode is changed from 12h to 24h or visa versa, the entry updates on icon press
update_text ();

set_popover_clock_format ();

popover.pointing_to = get_icon_area (Gtk.EntryIconPosition.SECONDARY);
popover.show_all ();
}

private void set_popover_clock_format () {
changing_time = true;

if (Granite.DateTime.is_clock_format_12h () && time.get_hour () > 12) {
Expand All @@ -245,18 +260,16 @@ namespace Granite.Widgets {
// Make sure that bounds are set correctly
hours_spinbutton.set_range (1, 12);
} else {

hours_spinbutton.set_range (0, 23);

am_pm_modebutton.no_show_all = true;
am_pm_modebutton.hide ();
hours_spinbutton.set_value (time.get_hour ());

hours_spinbutton.set_range (0, 23);
}

minutes_spinbutton.set_value (time.get_minute ());
changing_time = false;

popover.pointing_to = get_icon_area (Gtk.EntryIconPosition.SECONDARY);
popover.show_all ();
}

[Version (deprecated = true, deprecated_since = "5.2.0")]
Expand Down