2 -- ion/mod_statusbar/mod_statusbar.lua
4 -- Copyright (c) Tuomo Valkonen 2004-2007.
6 -- Ion is free software; you can redistribute it and/or modify it under
7 -- the terms of the GNU Lesser General Public License as published by
8 -- the Free Software Foundation; either version 2.1 of the License, or
9 -- (at your option) any later version.
12 -- This is a slight abuse of the package.loaded variable perhaps, but
13 -- library-like packages should handle checking if they're loaded instead of
14 -- confusing the user with require/include differences.
15 if package.loaded["mod_statusbar"] then return end
17 if not ioncore.load_module("mod_statusbar") then
21 local mod_statusbar=_G["mod_statusbar"]
31 function mod_statusbar.inform(name, value)
38 -- Template processing {{{
40 local function process_template(template, meter_f, text_f, stretch_f)
41 local st, en, b, c, r, p, tmp
45 st, en, b, r=string.find(template, '^(.-)%%(.*)')
53 -- Add preciding text as normal text element
58 -- Check for '% ' and '%%'
59 st, en, c, r=string.find(template, '^([ %%])(.*)')
69 -- Extract [alignment][zero padding]<meter name>
70 local pat='([<|>]?)(0*[0-9]*)([a-zA-Z0-9_]+)'
72 st, en, c, p, b, r=string.find(template, '^{'..pat..'}(.*)')
75 st, en, c, p, b, r=string.find(template, '^'..pat..'(.*)')
78 meter_f(b, c, tonumber(p))
88 function mod_statusbar.template_to_table(template)
90 local m=meters --set_date(stng, meters)
91 local aligns={["<"]=0, ["|"]=1, [">"]=2}
93 process_template(template,
97 table.insert(res, {type=4})
98 elseif (string.find(s, "^systray$") or
99 string.find(s, "^systray_")) then
110 tmpl=meters[s.."_template"],
133 mod_statusbar._set_template_parser(mod_statusbar.template_to_table)
141 -- Update statusbar contents. To be called after series
142 -- of \fnref{mod_statusbar.inform} calls.
143 function mod_statusbar.update(update_templates)
144 for _, sb in pairs(mod_statusbar.statusbars()) do
145 if update_templates then
146 local t=sb:get_template_table()
147 for _, v in pairs(t) do
149 v.tmpl=meters[v.meter.."_template"]
152 sb:set_template_table(t)
161 -- ion-statusd support {{{
165 function mod_statusbar.rcv_statusd(str)
170 local function doline(i)
172 mod_statusbar.update(updatenw)
175 local _, _, m, v=string.find(i, "^([^:]+):%s*(.*)")
177 mod_statusbar.inform(m, v)
178 updatenw=updatenw or string.find(m, "_template")
186 data=string.gsub(data..str, "([^\n]*)\n", doline)
187 str=coroutine.yield(updated)
190 ioncore.warn(TR("ion-statusd quit."))
193 mod_statusbar.update(updatenw)
197 local function get_modules()
199 local specials={["filler"]=true, ["systray"]=true}
201 for _, sb in pairs(mod_statusbar.statusbars()) do
202 for _, item in pairs(sb:get_template_table()) do
203 if item.type==2 and not specials[item.meter] then
204 local _, _, m=string.find(item.meter, "^([^_]*)");
216 function mod_statusbar.cfg_statusd(cfg)
217 if date_format_backcompat_kludge then
219 cfg=table.copy(cfg, false)
220 cfg.date={date_format=date_format_backcompat_kludge}
221 elseif not cfg.date.date_format then
222 cfg=table.copy(cfg, true)
223 cfg.date.date_format=date_format_backcompat_kludge
227 --TODO: don't construct file name twice.
228 ioncore.write_savefile("cfg_statusd", cfg)
229 return ioncore.get_savefile("cfg_statusd")
233 function mod_statusbar.rcv_statusd_err(str)
241 -- Load modules and launch ion-statusd with configuration table \var{cfg}.
242 function mod_statusbar.launch_statusd(cfg)
243 if statusd_pid>0 then
247 local mods=get_modules()
250 for m in pairs(mods) do
251 if dopath("statusbar_"..m, true) then
256 -- Lookup ion-statusd
257 local statusd=ioncore.lookup_script("ion-statusd")
259 ioncore.warn(TR("Could not find %s", script))
264 local function initrcverr(str)
265 statusd_errors=(statusd_errors or "")..str
268 local cfg=mod_statusbar.cfg_statusd(cfg or {})
270 table.foreach(mods, function(k) params=params.." -m "..k end)
271 local cmd=statusd.." -q -c "..cfg..params
273 local rcv=coroutine.wrap(mod_statusbar.rcv_statusd)
274 local rcverr=mod_statusbar.rcv_statusd_err
276 statusd_pid=mod_statusbar._launch_statusd(cmd,
280 if statusd_errors then
281 warn(TR("Errors starting ion-statusd:\n")..statusd_errors)
284 if statusd_pid<=0 then
285 warn(TR("Failed to start ion-statusd."))
292 -- Initialisation and default settings {{{
295 -- Create a statusbar.
296 function mod_statusbar.create(param)
297 local scr=ioncore.find_screen_id(param.screen or 0)
299 error(TR("Screen not found."))
302 if not param.force then
303 local stdisp=scr:get_stdisp()
304 if stdisp and stdisp.reg then
305 error(TR("Screen already has an stdisp. Refusing to create a "..
310 local sb=scr:set_stdisp({
312 pos=(param.pos or "bl"),
313 fullsize=param.fullsize,
315 template=param.template,
316 template_table=param.template_table,
317 systray=param.systray,
321 error(TR("Failed to create statusbar."))
330 -- Mark ourselves loaded.
331 package.loaded["mod_statusbar"]=true
334 -- Load user configuration file
335 dopath('cfg_statusbar', true)
337 -- Launch statusd if the user didn't launch it.
338 if statusd_pid<=0 then
339 mod_statusbar.launch_statusd()