diff --git a/extension.json b/extension.json index ade46b7..f2d5e1b 100644 --- a/extension.json +++ b/extension.json @@ -2,6 +2,8 @@ "extension": "datetime-format", "domain": "Daniel-Khodabakhsh.github.com", "description": "Allow users to customise the datetime format on the clock panel and lock screen.", - "gnomeShellVersions": ["3.20.4"], + "gnomeShellVersions": [ + "40", "42", "43" + ], "url": "https://github.com/Daniel-Khodabakhsh/datetime-format" -} \ No newline at end of file +} diff --git a/src/EditWindow.js b/src/EditWindow.js index 76b3858..9531a7d 100644 --- a/src/EditWindow.js +++ b/src/EditWindow.js @@ -10,14 +10,15 @@ /// @param {Settings} settings - Settings object. /// @param {Object} language - Language map. /// -const Class = function (parent, gladeFile, settings, language) { +var Class = function (parent, gladeFile, settings, language) { const GLib = imports.gi.GLib; const Utilities = imports.misc.extensionUtils.getCurrentExtension().imports.Utilities; const builder = Utilities.getBuilder(gladeFile); const window = builder.get_object("editWindow"); - const header = builder.get_object("editWindowHeaderBar"); + const title = builder.get_object("editWindowTitle"); const applyButton = builder.get_object("editWindowApplyButton"); + const closeButton = builder.get_object("editWindowCloseButton"); const formatEntry = builder.get_object("editWindowFormatEntry"); const preview = builder.get_object("editWindowPreviewLabel"); const notebook = builder.get_object("editWindowFormatOptionsNotebook"); @@ -68,9 +69,15 @@ const Class = function (parent, gladeFile, settings, language) { }; formatEntry.connect("changed", updatePreview); + formatEntry.connect("notify::text", () => { + applyButton.get_style_context().add_class("suggested-action"); + applyButton.set_sensitive(true); + applyButton.set_receives_default(true); + }); + // Hide window and disconnect elements. - const hide = function () { + const hideWindow = function () { // Stop updatePreview() if (updateTimeoutID != 0) { GLib.Source.remove(updateTimeoutID); @@ -87,7 +94,8 @@ const Class = function (parent, gladeFile, settings, language) { }; // Close button - builder.get_object("editWindowCloseButton").connect("clicked", hide); + closeButton.connect("clicked", hideWindow); + //builder.get_object("editWindowCloseButton").connect_swapped(window, "response", hide, window); /// /// Show the edit window. @@ -98,23 +106,26 @@ const Class = function (parent, gladeFile, settings, language) { /// @param {function(): boolean} updateParentPreview - Callback to update the parent preview label. /// @param {string} name - Format target name. /// - this.show = function (formatTarget, formatTargetObject, updateParentPreview, name) { - header.set_title(name + " - " + language.format); - window.set_transient_for(parent.get_parent().get_parent()); + this.showWindow = function (formatTarget, formatTargetObject, updateParentPreview, name) { + title.set_text(name + " - " + language.format); + window.set_transient_for(parent.get_root()); formatEntry.set_text(settings.getFormat(formatTarget)); formatEntry.select_region(0, -1); formatEntry.grab_focus(); + applyButton.get_style_context().remove_class("suggested-action"); + applyButton.set_sensitive(false); + closeButton.set_receives_default(true); defaultFormat = formatTargetObject.defaultFormat; // Click apply button, hide window, save settings, and update parent applyButtonClickID = applyButton.connect("clicked", function () { - hide(); + hideWindow(); settings.setFormat(formatTarget, formatEntry.get_text()); updateParentPreview(); }); updateTimeoutID = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 1000, updatePreview); updatePreview(); - window.show_all(); + window.show(); }; -}; \ No newline at end of file +}; diff --git a/src/FormatTarget.js b/src/FormatTarget.js index 6e01b3d..5d9b6a5 100644 --- a/src/FormatTarget.js +++ b/src/FormatTarget.js @@ -11,7 +11,7 @@ /// @param {Settings} settings - Settings object. /// @param {EditWindow} editWindow - Edit window to show when the settings button is pressed. /// -const create = function (container, formatTarget, builder, settings, editWindow) { +var create = function (container, formatTarget, builder, settings, editWindow) { const GLib = imports.gi.GLib; const extension = imports.misc.extensionUtils.getCurrentExtension(); const formatTargetObject = extension.imports.formatTargets[formatTarget]; @@ -56,8 +56,8 @@ const create = function (container, formatTarget, builder, settings, editWindow) // Edit button click -> show edit window builder.get_object("formatTargetEditButton").connect("clicked", function () { - editWindow.show(formatTarget, formatTargetObject, updatePreview, name); + editWindow.showWindow(formatTarget, formatTargetObject, updatePreview, name); }); - container.pack_start(builder.get_object("formatTargetBox"), false, true, 0); -}; \ No newline at end of file + container.append(builder.get_object("formatTargetBox")); +}; diff --git a/src/Settings.js b/src/Settings.js index dd4d303..bec3259 100644 --- a/src/Settings.js +++ b/src/Settings.js @@ -5,7 +5,7 @@ /// /// Settings constructor. /// -const Class = function () { +var Class = function () { const Gio = imports.gi.Gio; const extension = imports.misc.extensionUtils.getCurrentExtension(); @@ -64,4 +64,4 @@ const Class = function () { this.setToggle = function (formatTarget, value) { settings.set_boolean(toggleKey(formatTarget), value); }; -}; \ No newline at end of file +}; diff --git a/src/Utilities.js b/src/Utilities.js index beb4070..6a66816 100644 --- a/src/Utilities.js +++ b/src/Utilities.js @@ -2,8 +2,8 @@ /// Common Utilities /// -const Gtk = imports.gi.Gtk; - +const { GLib, Gtk } = imports.gi; +let _localTimeZone = null; /// /// Convert string to datetime format. /// @@ -23,4 +23,19 @@ function dateTimeFormat(format, defaultFormat) { /// function getBuilder(gladeContent) { return Gtk.Builder.new_from_string(gladeContent, gladeContent.length); -} \ No newline at end of file +} +// Code from https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/master/js/ui/environment.js +// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783 +Date.prototype.toLocaleFormat = function (format) { + if (_localTimeZone === null) + _localTimeZone = GLib.TimeZone.new_local(); + + let dt = GLib.DateTime.new(_localTimeZone, + this.getFullYear(), + this.getMonth() + 1, + this.getDate(), + this.getHours(), + this.getMinutes(), + this.getSeconds()); + return dt?.format(format) ?? ''; +}; diff --git a/src/formatTargets/DateMenuDate.js b/src/formatTargets/DateMenuDate.js index e57f873..e3461b1 100644 --- a/src/formatTargets/DateMenuDate.js +++ b/src/formatTargets/DateMenuDate.js @@ -1,10 +1,10 @@ -const name = { +var name = { en: "Date Menu: Date", fr: "Menu de date: Date", ja: "日付メニュー:日付" }; -const defaultFormat = "%B %e %Y"; +var defaultFormat = "%B %e %Y"; let dateLabel; let dateTimeDisplay; @@ -28,4 +28,4 @@ function disable() { function update(format) { dateTimeDisplay.set_text(format); -} \ No newline at end of file +} diff --git a/src/formatTargets/DateMenuDay.js b/src/formatTargets/DateMenuDay.js index 61a5a9d..2a50058 100644 --- a/src/formatTargets/DateMenuDay.js +++ b/src/formatTargets/DateMenuDay.js @@ -1,10 +1,10 @@ -const name = { +var name = { en: "Date Menu: Day", fr: "Menu de date: Jour", ja: "日付メニュー:日" }; -const defaultFormat = "%A"; +var defaultFormat = "%A"; let dayLabel; let dateTimeDisplay; @@ -29,4 +29,4 @@ function disable() { function update(format) { dateTimeDisplay.set_text(format); -} \ No newline at end of file +} diff --git a/src/formatTargets/StatusBar.js b/src/formatTargets/StatusBar.js index db3a102..6e1785e 100644 --- a/src/formatTargets/StatusBar.js +++ b/src/formatTargets/StatusBar.js @@ -1,10 +1,10 @@ -const name = { +var name = { en: "Status Bar", fr: "Barre d'état", ja: "ステータスバー" }; -const defaultFormat = "%c"; +var defaultFormat = "%c"; let clockDisplay; let dateTimeDisplay; @@ -28,4 +28,4 @@ function disable() { function update(format) { dateTimeDisplay.set_text(format); -} \ No newline at end of file +} diff --git a/src/preferences.css b/src/preferences.css index cd669f0..f1f9da5 100644 --- a/src/preferences.css +++ b/src/preferences.css @@ -1,8 +1,4 @@ .formatTargetBox { - border-bottom: solid 1px rgba(0, 0, 0, 0.25); - padding: 10px 0 10px; + padding: 14px; } -.formatTargetBox:last-child { - border: 0; -} \ No newline at end of file diff --git a/src/preferences.glade b/src/preferences.glade index 82f2fae..2ef3578 100644 --- a/src/preferences.glade +++ b/src/preferences.glade @@ -1,132 +1,105 @@ - - - - True - False - window-close-symbolic - - - True - False - applications-system-symbolic - + + - True - False + 0 + 0 + vertical + 12 + 30 + 0 + 36 + 36 center - True - 10 - - True - True - center + + 0 + start + 0 + <title> + + + - - False - True - 0 - - True - False - True - vertical + 1 + center + 1 + 12 + horizontal - - True - False - <title> - - - + + 0 + center + start + 1 + <preview> - - True - True - 0 - - - True - False - <preview> + + 1 + 1 + center + 0 + emblem-system-symbolic + - - False - True - 1 - + + + 1 + center + 0 + + + - - False - True - 1 - - - - - True - True - True - center - editImage - True - - - False - True - 2 - - + - True - False + 0 start - True + 1 <format option description> - True + 1 0 + - True - False + 0 start <format option> + - True - True - True + 1 never - False + 0 - True - False - none + 0 - True - False - 10 - 10 + 0 + 10 + 10 10 10 - True + 1 15 10 @@ -134,26 +107,22 @@ + - True - False + 0 <page label> + - True - True - True + 1 - True - False - none + 0 - True - False - 20 - 20 + 0 + 20 + 20 10 10 vertical @@ -165,178 +134,137 @@ - - True - False - gtk-apply - - + + 700 - False - True - dialog - + 700 + 1 + 1 + 1 + - False - 20 - 20 + 1 + 1 + 20 + 20 10 20 vertical 10 - - - False - - - False - False - 0 - - + 1 + 1 + - True - False - 0 - in + 1 - True - True - 10 - 10 + 1 + 10 + 10 10 - True - False + 0 Format + + + - - False - True - 0 - + - True - False - 0 - in + 0 - True - False - 10 - 10 + 0 + 10 + 10 10 - <preview> - True + <preview> + 1 - True - False + 0 Preview + + + - - False - True - 2 - + - True - False - True - 0 - in + 1 + 1 - True - True - 10 - 10 + 10 + 10 10 left - True - False + 0 Format options + + + - - False - True - 3 - + - - True - False - <title> - - - True - False - 5 - - - True - True - True - True - center - center - saveImage - True - - - - False - True - 0 - - - - - True - True - True - closeImage - True - - - False - True - 1 - - - - - end - - - + + 0 + + + Title + True + end + 10 + + + + + + Apply + 1 + False + + + + + Cancel + 1 + + + + + + horizontal + + + + + + diff --git a/src/prefs.js b/src/prefs.js index 38f8ed0..574c605 100644 --- a/src/prefs.js +++ b/src/prefs.js @@ -4,6 +4,7 @@ const Gtk = imports.gi.Gtk; const GLib = imports.gi.GLib; +const ByteArray = imports.byteArray; const extension = imports.misc.extensionUtils.getCurrentExtension(); const Utilities = extension.imports.Utilities; @@ -83,7 +84,7 @@ function fileExists(file) { /// @return {string} File contents. /// function readFile(file) { - return String(GLib.file_get_contents(filePath(file))[1]); + return ByteArray.toString(GLib.file_get_contents(filePath(file))[1]); } /// @@ -103,6 +104,10 @@ function buildPrefsWidget() { const builder = Utilities.getBuilder(gladeFile); const preferencesBox = builder.get_object("preferences"); const formatTargetsBox = builder.get_object("preferencesFormatTargetsBox"); + GLib.idle_add(GLib.PRIORITY_DEFAULT, ()=> { + let prefsWindow = preferencesBox.get_root(); + prefsWindow.default_height = 480; + }); // Load language const language = JSON.parse( @@ -114,7 +119,7 @@ function buildPrefsWidget() { .reduce((accumulator, currentValue) => accumulator || GLib .get_locale_variants(currentValue) - .find((languageCode) => + .find((languageCode) => fileExists(languageFolder + "/" + languageCode + ".json") ), "" @@ -125,15 +130,16 @@ function buildPrefsWidget() { ); // Set stylesheet - const cssProvider = new Gtk.CssProvider(); + let cssProvider = new Gtk.CssProvider(); cssProvider.load_from_path(filePath("preferences.css")); - Gtk.StyleContext.add_provider_for_screen(imports.gi.Gdk.Screen.get_default(), cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + Gtk.StyleContext.add_provider_for_display(imports.gi.Gdk.Display.get_default(), cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); // Create edit window const editWindow = new extension.imports.EditWindow.Class(preferencesBox, gladeFile, settings, language); // Generate format options - extension.metadata.formatTargets.forEach((formatTarget) => extension.imports.FormatTarget.create(formatTargetsBox, formatTarget, Utilities.getBuilder(gladeFile), settings, editWindow)); + //extension.metadata.formatTargets.forEach((formatTarget) => extension.imports.FormatTarget.create(formatTargetsBox, formatTarget, Utilities.getBuilder(gladeFile), settings, editWindow)); + ["DateMenuDate", "DateMenuDay", "StatusBar"].forEach((formatTarget) => extension.imports.FormatTarget.create(formatTargetsBox, formatTarget, Utilities.getBuilder(gladeFile), settings, editWindow)); return preferencesBox; -} \ No newline at end of file +}