diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index d9b332553..136b41cd9 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -205,6 +205,10 @@ function Device:retrieveNetworkInfo() end end +function Device:setTime(hour, min) + return false +end + -- Return an integer value to indicate the brightness of the environment. The value should be in -- range [0, 4]. -- 0: dark. diff --git a/frontend/device/kindle/device.lua b/frontend/device/kindle/device.lua index 79216dce8..9f25f295c 100644 --- a/frontend/device/kindle/device.lua +++ b/frontend/device/kindle/device.lua @@ -66,6 +66,16 @@ function Kindle:supportsScreensaver() end end +function Kindle:setTime(hour, min) + if hour == nil or min == nil then return true end + if os.execute(string.format("date -s '%d:%d'", hour, min)) == 0 then + os.execute('hwclock -u -w') + return true + else + return false + end +end + function Kindle:usbPlugIn() if self.charging_mode == false and self.screen_saver_mode == false then -- On FW >= 5.7.2, we sigstop awesome, but we need it to show stuff... diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 54d618000..2967e5b7b 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -184,6 +184,16 @@ function Kobo:init() end end +function Kobo:setTime(hour, min) + if hour == nil or min == nil then return true end + if os.execute(string.format("date -s '%d:%d'", hour, min)) == 0 then + os.execute('hwclock -u -w') + return true + else + return false + end +end + function Kobo:initNetworkManager(NetworkMgr) function NetworkMgr:turnOffWifi(complete_callback) koboEnableWifi(0) diff --git a/frontend/device/pocketbook/device.lua b/frontend/device/pocketbook/device.lua index 4a89f876b..378f8acb2 100644 --- a/frontend/device/pocketbook/device.lua +++ b/frontend/device/pocketbook/device.lua @@ -77,6 +77,16 @@ function PocketBook:init() Generic.init(self) end +function PocketBook:setTime(hour, min) + if hour == nil or min == nil then return true end + if os.execute(string.format("date -s '%d:%d'", hour, min)) == 0 then + os.execute('hwclock -u -w') + return true + else + return false + end +end + function PocketBook:initNetworkManager(NetworkMgr) NetworkMgr.turnOnWifi = function() pocketbookEnableWifi(1) diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index aa4581b40..b5ea316b0 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -59,6 +59,16 @@ function Device:init() Generic.init(self) end +function Device:setTime(hour, min) + if hour == nil or min == nil then return true end + if os.execute(string.format("date -s '%d:%d'", hour, min)) == 0 then + os.execute('hwclock -u -w') + return true + else + return false + end +end + function Device:simulateSuspend() local InfoMessage = require("ui/widget/infomessage") local UIManager = require("ui/uimanager") diff --git a/frontend/ui/elements/common_settings_menu_table.lua b/frontend/ui/elements/common_settings_menu_table.lua index 09e1e6506..3a8f39aa2 100644 --- a/frontend/ui/elements/common_settings_menu_table.lua +++ b/frontend/ui/elements/common_settings_menu_table.lua @@ -1,9 +1,12 @@ local Device = require("device") +local InfoMessage = require("ui/widget/infomessage") local Language = require("ui/language") local NetworkMgr = require("ui/network/manager") local UIManager = require("ui/uimanager") -local Screen = require("device").screen +local TimeWidget = require("ui/widget/timewidget") local _ = require("gettext") +local Screen = Device.screen +local T = require("ffi/util").template local common_settings = {} @@ -17,6 +20,37 @@ if Device:hasFrontlight() then } end +if Device:setTime() then + common_settings.time = { + text = _("Set time"), + callback = function() + local now_t = os.date("*t") + local curr_hour = now_t.hour + local curr_min = now_t.min + local time_widget = TimeWidget:new{ + hour = curr_hour, + min = curr_min, + ok_text = _("Set time"), + title_text = _("Set time"), + callback = function(time) + if Device:setTime(time.hour, time.min) then + now_t = os.date("*t") + UIManager:show(InfoMessage:new{ + text = T(_("Current time: %1:%2"), string.format("%02d", now_t.hour), + string.format("%02d", now_t.min)) + }) + else + UIManager:show(InfoMessage:new{ + text = _("Time couldn't be set"), + }) + end + end + } + UIManager:show(time_widget) + end, + } +end + common_settings.night_mode = { text = _("Night mode"), checked_func = function() return G_reader_settings:readSetting("night_mode") end, diff --git a/frontend/ui/elements/filemanager_menu_order.lua b/frontend/ui/elements/filemanager_menu_order.lua index 1aa67d0c6..3fa47a20c 100644 --- a/frontend/ui/elements/filemanager_menu_order.lua +++ b/frontend/ui/elements/filemanager_menu_order.lua @@ -24,6 +24,7 @@ local order = { "save_document", "----------------------------", "language", + "time", -- end common settings }, tools = { diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index a2179b82e..bbaa7d261 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -43,6 +43,7 @@ local order = { "save_document", "----------------------------", "language", + "time", "----------------------------", "djvu_render_mode", "status_bar", diff --git a/frontend/ui/widget/timewidget.lua b/frontend/ui/widget/timewidget.lua new file mode 100644 index 000000000..494fb7744 --- /dev/null +++ b/frontend/ui/widget/timewidget.lua @@ -0,0 +1,356 @@ +local Blitbuffer = require("ffi/blitbuffer") +local Button = require("ui/widget/button") +local ButtonTable = require("ui/widget/buttontable") +local CenterContainer = require("ui/widget/container/centercontainer") +local CloseButton = require("ui/widget/closebutton") +local Device = require("device") +local FrameContainer = require("ui/widget/container/framecontainer") +local Geom = require("ui/geometry") +local GestureRange = require("ui/gesturerange") +local Font = require("ui/font") +local HorizontalGroup = require("ui/widget/horizontalgroup") +local HorizontalSpan = require("ui/widget/horizontalspan") +local InputContainer = require("ui/widget/container/inputcontainer") +local LineWidget = require("ui/widget/linewidget") +local OverlapGroup = require("ui/widget/overlapgroup") +local TextBoxWidget = require("ui/widget/textboxwidget") +local TextWidget = require("ui/widget/textwidget") +local UIManager = require("ui/uimanager") +local VerticalGroup = require("ui/widget/verticalgroup") +local VerticalSpan = require("ui/widget/verticalspan") +local WidgetContainer = require("ui/widget/container/widgetcontainer") +local _ = require("gettext") +local Screen = Device.screen + +local TimeWidget = InputContainer:new{ + title_face = Font:getFace("x_smalltfont"), + width = nil, + height = nil, + hour = 0, + min = 0, + ok_text = _("OK"), + cancel_text = _("Cancel"), +} + +function TimeWidget:init() + self.medium_font_face = Font:getFace("ffont") + self.light_bar = {} + self.screen_width = Screen:getSize().w + self.screen_height = Screen:getSize().h + self.width = self.screen_width * 0.95 + if Device:hasKeys() then + self.key_events = { + Close = { {"Back"}, doc = "close time" } + } + end + if Device:isTouchDevice() then + self.ges_events = { + TapCloseFL = { + GestureRange:new{ + ges = "tap", + range = Geom:new{ + x = 0, y = 0, + w = self.screen_width, + h = self.screen_height, + } + }, + }, + } + end + + self:update() +end + +function TimeWidget:changeHours(hour, change) + hour = hour + change + if hour > 23 then + hour = hour - 24 + elseif hour < 0 then + hour = 24 + hour + end + return hour +end + +function TimeWidget:changeMin(min, change) + min = min + change + if min > 59 then + min = min - 60 + elseif min < 0 then + min = 60 + min + end + return min +end + +function TimeWidget:paintContainer() + local padding_span = VerticalSpan:new{ width = math.ceil(self.screen_height * 0.01) } + local padding_span_top_bottom = VerticalSpan:new{ width = math.ceil(self.screen_height * 0.20) } + local button_group_down = HorizontalGroup:new{ align = "center" } + local button_group_up = HorizontalGroup:new{ align = "center" } + local vertical_group = VerticalGroup:new{ align = "center" } + + local button_up_hours = Button:new{ + text = "▲", + bordersize = 2, + margin = 2, + radius = 0, + text_font_size = 24, + width = self.screen_width * 0.20, + show_parent = self, + callback = function() + self.hour = self:changeHours(self.hour, 1) + self:update() + end, + hold_callback = function() + self.hour = self:changeHours(self.hour, 6) + self:update() + end + } + local button_down_hours = Button:new{ + text = "▼", + bordersize = 2, + margin = 2, + radius = 0, + text_font_size = 24, + width = self.screen_width * 0.20, + show_parent = self, + callback = function() + self.hour = self:changeHours(self.hour, -1) + self:update() + end, + hold_callback = function() + self.hour = self:changeHours(self.hour, -6) + self:update() + end + } + + local button_up_minutes = Button:new{ + text = "▲", + bordersize = 2, + margin = 2, + radius = 0, + text_font_size = 24, + width = self.screen_width * 0.20, + show_parent = self, + callback = function() + self.min = self:changeMin(self.min, 1) + self:update() + end, + hold_callback = function() + self.min = self:changeMin(self.min, 15) + self:update() + end + } + local button_down_minutes = Button:new{ + text = "▼", + bordersize = 2, + margin = 2, + radius = 0, + text_font_size = 24, + width = self.screen_width * 0.20, + show_parent = self, + callback = function() + self.min = self:changeMin(self.min, -1) + self:update() + end, + hold_callback = function() + self.min = self:changeMin(self.min, -15) + self:update() + end + } + local empty_space = HorizontalSpan:new{ + width = self.screen_width * 0.20 + } + + local text_hours = TextBoxWidget:new{ + text = string.format("%02d", self.hour), + alignment = "center", + face = self.title_face, + text_font_size = 24, + bold = true, + width = self.screen_width * 0.20, + } + local text_minutes = TextBoxWidget:new{ + text = string.format("%02d", self.min), + alignment = "center", + face = self.title_face, + text_font_size = 24, + bold = true, + width = self.screen_width * 0.20, + } + + local colon_space = TextBoxWidget:new{ + text = ":", + alignment = "center", + face = self.title_face, + bold = true, + width = self.screen_width * 0.20 + 2 * button_up_hours.bordersize + 2 * button_up_minutes.bordersize + } + + local button_table_up = HorizontalGroup:new{ + align = "center", + button_up_hours, + empty_space, + button_up_minutes, + } + local time_text_table = HorizontalGroup:new{ + align = "center", + text_hours, + colon_space, + text_minutes, + } + local button_table_down = HorizontalGroup:new{ + align = "center", + button_down_hours, + empty_space, + button_down_minutes, + } + + table.insert(button_group_up, button_table_up) + table.insert(button_group_down, button_table_down) + table.insert(vertical_group, padding_span_top_bottom) + table.insert(vertical_group, button_group_up) + table.insert(vertical_group, padding_span) + table.insert(vertical_group, time_text_table) + table.insert(vertical_group, padding_span) + table.insert(vertical_group, button_group_down) + table.insert(vertical_group, padding_span_top_bottom) + + return CenterContainer:new{ + dimen = Geom:new{ + w = self.screen_width * 0.95, + h = vertical_group:getSize().h + }, + vertical_group + } +end + +function TimeWidget:update() + local time_title = FrameContainer:new{ + padding = Screen:scaleBySize(5), + margin = Screen:scaleBySize(2), + bordersize = 0, + TextWidget:new{ + text = self.title_text, + face = self.title_face, + bold = true, + width = self.screen_width * 0.95, + }, + } + local time_container = FrameContainer:new{ + padding = Screen:scaleBySize(2), + margin = Screen:scaleBySize(2), + bordersize = 0, + self:paintContainer() + } + local time_line = LineWidget:new{ + dimen = Geom:new{ + w = self.width, + h = Screen:scaleBySize(2), + } + } + local time_bar = OverlapGroup:new{ + dimen = { + w = self.width, + h = time_title:getSize().h + }, + time_title, + CloseButton:new{ window = self, }, + } + local buttons = { + { + { + text = self.cancel_text, + callback = function() + self:onClose() + end, + }, + { + text = self.ok_text, + callback = function() + if self.callback then + self:callback(self) + end + self:onClose() + end, + }, + } + } + + local ok_cancel_buttons = ButtonTable:new{ + width = Screen:getWidth()*0.9, + buttons = buttons, + show_parent = self, + } + + self.time_frame = FrameContainer:new{ + radius = 5, + bordersize = 3, + padding = 0, + margin = 0, + background = Blitbuffer.COLOR_WHITE, + VerticalGroup:new{ + align = "left", + time_bar, + time_line, + CenterContainer:new{ + dimen = Geom:new{ + w = self.screen_width * 0.95, + h = self.screen_height * 0.25 + }, + time_container, + }, + time_line, + ok_cancel_buttons + } + } + self[1] = WidgetContainer:new{ + align = "center", + dimen =Geom:new{ + x = 0, y = 0, + w = self.screen_width, + h = self.screen_height, + }, + FrameContainer:new{ + bordersize = 0, + padding = Screen:scaleBySize(5), + self.time_frame, + } + } + + UIManager:setDirty(self, function() + return "ui", self.time_frame.dimen + end) +end + +function TimeWidget:onCloseWidget() + UIManager:setDirty(nil, function() + return "partial", self.time_frame.dimen + end) + return true +end + +function TimeWidget:onShow() + UIManager:setDirty(self, function() + return "ui", self.time_frame.dimen + end) + return true +end + +function TimeWidget:onAnyKeyPressed() + UIManager:close(self) + return true +end + +function TimeWidget:onTapCloseFL(arg, ges_ev) + if ges_ev.pos:notIntersectWith(self.time_frame.dimen) then + self:onClose() + end + return true +end + +function TimeWidget:onClose() + UIManager:close(self) + return true +end + +return TimeWidget