1---------------------------------------------------------------------------
2--- Text clock widget.
3--
4-- @author Julien Danjou <julien@danjou.info>
5-- @copyright 2009 Julien Danjou
6-- @classmod wibox.widget.textclock
7---------------------------------------------------------------------------
8
9local setmetatable = setmetatable
10local os = os
11local textbox = require("wibox.widget.textbox")
12local timer = require("gears.timer")
13local gtable = require("gears.table")
14local glib = require("lgi").GLib
15local DateTime = glib.DateTime
16local TimeZone = glib.TimeZone
17
18local textclock = { mt = {} }
19
20--- Set the clock's format
21-- @property format
22-- @tparam string format The new time format.  This can contain pango markup
23
24function textclock:set_format(format)
25    self._private.format = format
26    self:force_update()
27end
28
29function textclock:get_format()
30    return self._private.format
31end
32
33--- Set the clock's timezone
34-- @property timezone
35-- @tparam string timezone
36
37function textclock:set_timezone(tzid)
38    self._private.tzid = tzid
39    self._private.timezone = tzid and TimeZone.new(tzid)
40    self:force_update()
41end
42
43function textclock:get_timezone()
44    return self._private.tzid
45end
46
47--- Set the clock's refresh rate
48-- @property refresh
49-- @tparam number How often the clock is updated, in seconds
50
51function textclock:set_refresh(refresh)
52    self._private.refresh = refresh or self._private.refresh
53    self:force_update()
54end
55
56function textclock:get_refresh()
57    return self._private.refresh
58end
59
60--- Force a textclock to update now.
61function textclock:force_update()
62    self._timer:emit_signal("timeout")
63end
64
65--- This lowers the timeout so that it occurs "correctly". For example, a timeout
66-- of 60 is rounded so that it occurs the next time the clock reads ":00 seconds".
67local function calc_timeout(real_timeout)
68    return real_timeout - os.time() % real_timeout
69end
70
71--- Create a textclock widget. It draws the time it is in a textbox.
72--
73-- @tparam[opt=" %a %b %d, %H:%M "] string format The time format.
74-- @tparam[opt=60] number refresh How often to update the time (in seconds).
75-- @tparam[opt=local timezone] string timezone The timezone to use,
76--   e.g. "Z" for UTC, "±hh:mm" or "Europe/Amsterdam". See
77--   https://developer.gnome.org/glib/stable/glib-GTimeZone.html#g-time-zone-new.
78-- @treturn table A textbox widget.
79-- @function wibox.widget.textclock
80local function new(format, refresh, tzid)
81    local w = textbox()
82    gtable.crush(w, textclock, true)
83
84    w._private.format = format or " %a %b %d, %H:%M "
85    w._private.refresh = refresh or 60
86    w._private.tzid = tzid
87    w._private.timezone = tzid and TimeZone.new(tzid)
88
89    function w._private.textclock_update_cb()
90        local str = DateTime.new_now(w._private.timezone or TimeZone.new_local()):format(w._private.format)
91        if str == nil then
92            require("gears.debug").print_warning("textclock: "
93                    .. "g_date_time_format() failed for format "
94                    .. "'" .. w._private.format .. "'")
95        end
96        w:set_markup(str)
97        w._timer.timeout = calc_timeout(w._private.refresh)
98        w._timer:again()
99        return true -- Continue the timer
100    end
101
102    w._timer = timer.weak_start_new(refresh, w._private.textclock_update_cb)
103    w:force_update()
104    return w
105end
106
107function textclock.mt:__call(...)
108    return new(...)
109end
110
111--@DOC_widget_COMMON@
112
113--@DOC_object_COMMON@
114
115return setmetatable(textclock, textclock.mt)
116
117-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
118