2020-10-12 03:06:04 +00:00
--[[--
2020-10-12 15:20:16 +00:00
This module is responsible for dispatching events .
To add a new action an entry must be added to ` settingsList ` & ` dispatcher_menu_order `
This can also be done at runtime via @ { registerAction } ( ) .
` settingsList ` contains the list of dispatchable settings .
Each setting contains :
* category : one of :
* none : a direct event call
* arg : a event that expects a gesture object or an argument
* absolutenumber : event that sets a number
* incrementalnumber : event that increments a number & accepts a gesture object
* string : event with a list of arguments to chose from
2021-05-14 22:13:27 +00:00
* configurable : like string but instead of an event it updates the configurable ( used by kopt )
2020-10-12 15:20:16 +00:00
* event : what to call .
* title : for use in ui .
2021-09-10 20:11:24 +00:00
* section : under which menu to display ( currently : general , device , screen , filemanager , reader , rolling , paging )
2020-10-12 15:20:16 +00:00
and optionally
* min / max : for number
2021-05-05 18:48:42 +00:00
* step : for number
2020-10-12 15:20:16 +00:00
* default
* args : allowed values for string .
* toggle : display name for args
* separator : put a separator after in the menu list
2021-05-13 15:57:48 +00:00
* configurable : can be parsed from cre / kopt and used to set ` document.configurable ` . Should not be set manually
2020-10-12 03:06:04 +00:00
--]]--
2020-06-19 21:38:53 +00:00
local CreOptions = require ( " ui/data/creoptions " )
2021-05-14 22:13:27 +00:00
local KoptOptions = require ( " ui/data/koptoptions " )
2020-07-14 21:39:03 +00:00
local Device = require ( " device " )
2020-06-19 21:38:53 +00:00
local Event = require ( " ui/event " )
2021-05-20 21:14:11 +00:00
local Notification = require ( " ui/widget/notification " )
2020-11-28 16:18:57 +00:00
local ReaderZooming = require ( " apps/reader/modules/readerzooming " )
2020-06-19 21:38:53 +00:00
local UIManager = require ( " ui/uimanager " )
2021-09-10 20:14:07 +00:00
local util = require ( " util " )
2020-06-19 21:38:53 +00:00
local _ = require ( " gettext " )
2020-08-17 07:55:03 +00:00
local C_ = _.pgettext
local T = require ( " ffi/util " ) . template
2020-06-19 21:38:53 +00:00
local Dispatcher = {
initialized = false ,
}
2020-10-12 15:20:16 +00:00
-- See above for description.
2020-06-19 21:38:53 +00:00
local settingsList = {
2021-09-10 20:11:24 +00:00
-- Screen & Lights
show_frontlight_dialog = { category = " none " , event = " ShowFlDialog " , title = _ ( " Show frontlight dialog " ) , screen = true , condition = Device : hasFrontlight ( ) } ,
toggle_frontlight = { category = " none " , event = " ToggleFrontlight " , title = _ ( " Toggle frontlight " ) , screen = true , condition = Device : hasFrontlight ( ) } ,
set_frontlight = { category = " absolutenumber " , event = " SetFlIntensity " , min = 0 , max = Device : getPowerDevice ( ) . fl_max , title = _ ( " Set frontlight brightness to %1 " ) , screen = true , condition = Device : hasFrontlight ( ) } ,
increase_frontlight = { category = " incrementalnumber " , event = " IncreaseFlIntensity " , min = 1 , max = Device : getPowerDevice ( ) . fl_max , title = _ ( " Increase frontlight brightness by %1 " ) , screen = true , condition = Device : hasFrontlight ( ) } ,
decrease_frontlight = { category = " incrementalnumber " , event = " DecreaseFlIntensity " , min = 1 , max = Device : getPowerDevice ( ) . fl_max , title = _ ( " Decrease frontlight brightness by %1 " ) , screen = true , condition = Device : hasFrontlight ( ) } ,
set_frontlight_warmth = { category = " absolutenumber " , event = " SetFlWarmth " , min = 0 , max = 100 , title = _ ( " Set frontlight warmth to %1 " ) , screen = true , condition = Device : hasNaturalLight ( ) } ,
increase_frontlight_warmth = { category = " incrementalnumber " , event = " IncreaseFlWarmth " , min = 1 , max = Device : getPowerDevice ( ) . fl_warmth_max , title = _ ( " Increase frontlight warmth by %1 " ) , screen = true , condition = Device : hasNaturalLight ( ) } ,
decrease_frontlight_warmth = { category = " incrementalnumber " , event = " DecreaseFlWarmth " , min = 1 , max = Device : getPowerDevice ( ) . fl_warmth_max , title = _ ( " Decrease frontlight warmth by %1 " ) , screen = true , condition = Device : hasNaturalLight ( ) , separator = true } ,
full_refresh = { category = " none " , event = " FullRefresh " , title = _ ( " Full screen refresh " ) , screen = true } ,
night_mode = { category = " none " , event = " ToggleNightMode " , title = _ ( " Toggle night mode " ) , screen = true } ,
set_night_mode = { category = " string " , event = " SetNightMode " , title = _ ( " Set night mode " ) , screen = true , args = { true , false } , toggle = { _ ( " On " ) , _ ( " Off " ) } , separator = true } ,
set_refresh_rate = { category = " absolutenumber " , event = " SetBothRefreshRates " , min =- 1 , max = 200 , title = _ ( " Flash every %1 pages (always) " ) , screen = true , condition = Device : hasEinkScreen ( ) } ,
set_day_refresh_rate = { category = " absolutenumber " , event = " SetDayRefreshRate " , min =- 1 , max = 200 , title = _ ( " Flash every %1 pages (not in night mode) " ) , screen = true , condition = Device : hasEinkScreen ( ) } ,
set_night_refresh_rate = { category = " absolutenumber " , event = " SetNightRefreshRate " , min =- 1 , max = 200 , title = _ ( " Flash every %1 pages (in night mode) " ) , screen = true , condition = Device : hasEinkScreen ( ) } ,
set_flash_on_chapter_boundaries = { category = " string " , event = " SetFlashOnChapterBoundaries " , title = _ ( " Always flash on chapter boundaries " ) , screen = true , condition = Device : hasEinkScreen ( ) , args = { true , false } , toggle = { _ ( " On " ) , _ ( " Off " ) } } ,
toggle_flash_on_chapter_boundaries = { category = " none " , event = " ToggleFlashOnChapterBoundaries " , title = _ ( " Toggle flashing on chapter boundaries " ) , screen = true , condition = Device : hasEinkScreen ( ) } ,
set_no_flash_on_second_chapter_page = { category = " string " , event = " SetNoFlashOnSecondChapterPage " , title = _ ( " Never flash on chapter's 2nd page " ) , screen = true , condition = Device : hasEinkScreen ( ) , args = { true , false } , toggle = { _ ( " On " ) , _ ( " Off " ) } } ,
toggle_no_flash_on_second_chapter_page = { category = " none " , event = " ToggleNoFlashOnSecondChapterPage " , title = _ ( " Toggle flashing on chapter's 2nd page " ) , screen = true , condition = Device : hasEinkScreen ( ) , separator = true } ,
2020-07-14 21:39:03 +00:00
-- Device settings
2021-05-10 10:44:55 +00:00
toggle_gsensor = { category = " none " , event = " ToggleGSensor " , title = _ ( " Toggle accelerometer " ) , device = true , condition = Device : canToggleGSensor ( ) } ,
wifi_on = { category = " none " , event = " InfoWifiOn " , title = _ ( " Turn on Wi-Fi " ) , device = true , condition = Device : hasWifiToggle ( ) } ,
wifi_off = { category = " none " , event = " InfoWifiOff " , title = _ ( " Turn off Wi-Fi " ) , device = true , condition = Device : hasWifiToggle ( ) } ,
2022-05-06 17:19:55 +00:00
toggle_wifi = { category = " none " , event = " ToggleWifi " , title = _ ( " Toggle Wi-Fi " ) , device = true , condition = Device : hasWifiToggle ( ) } ,
2022-06-24 21:19:38 +00:00
toggle_fullscreen = { category = " none " , event = " ToggleFullscreen " , title = _ ( " Toggle Fullscreen " ) , device = true , condition = not Device : isAlwaysFullscreen ( ) } ,
2022-05-06 17:19:55 +00:00
show_network_info = { category = " none " , event = " ShowNetworkInfo " , title = _ ( " Show network info " ) , device = true , separator = true } ,
2022-07-11 11:50:28 +00:00
exit_screensaver = { category = " none " , event = " ExitScreensaver " , title = _ ( " Exit screensaver " ) , device = true } ,
2021-05-10 10:44:55 +00:00
suspend = { category = " none " , event = " SuspendEvent " , title = _ ( " Suspend " ) , device = true } ,
exit = { category = " none " , event = " Exit " , title = _ ( " Exit KOReader " ) , device = true } ,
restart = { category = " none " , event = " Restart " , title = _ ( " Restart KOReader " ) , device = true , condition = Device : canRestart ( ) } ,
reboot = { category = " none " , event = " Reboot " , title = _ ( " Reboot the device " ) , device = true , condition = Device : canReboot ( ) } ,
poweroff = { category = " none " , event = " PowerOff " , title = _ ( " Power off " ) , device = true , condition = Device : canPowerOff ( ) , separator = true } ,
toggle_hold_corners = { category = " none " , event = " IgnoreHoldCorners " , title = _ ( " Toggle hold corners " ) , device = true , separator = true } ,
toggle_rotation = { category = " none " , event = " SwapRotation " , title = _ ( " Toggle orientation " ) , device = true } ,
invert_rotation = { category = " none " , event = " InvertRotation " , title = _ ( " Invert rotation " ) , device = true } ,
iterate_rotation = { category = " none " , event = " IterateRotation " , title = _ ( " Rotate by 90° CW " ) , device = true , separator = true } ,
2021-09-10 20:11:24 +00:00
-- General
reading_progress = { category = " none " , event = " ShowReaderProgress " , title = _ ( " Reading progress " ) , general = true } ,
history = { category = " none " , event = " ShowHist " , title = _ ( " History " ) , general = true } ,
open_previous_document = { category = " none " , event = " OpenLastDoc " , title = _ ( " Open previous document " ) , general = true } ,
filemanager = { category = " none " , event = " Home " , title = _ ( " File browser " ) , general = true , separator = true } ,
dictionary_lookup = { category = " none " , event = " ShowDictionaryLookup " , title = _ ( " Dictionary lookup " ) , general = true } ,
wikipedia_lookup = { category = " none " , event = " ShowWikipediaLookup " , title = _ ( " Wikipedia lookup " ) , general = true } ,
fulltext_search = { category = " none " , event = " ShowFulltextSearchInput " , title = _ ( " Fulltext search " ) , general = true } ,
file_search = { category = " none " , event = " ShowFileSearch " , title = _ ( " File search " ) , general = true , separator = true } ,
show_menu = { category = " none " , event = " ShowMenu " , title = _ ( " Show menu " ) , general = true } ,
favorites = { category = " none " , event = " ShowColl " , arg = " favorites " , title = _ ( " Favorites " ) , general = true } ,
screenshot = { category = " none " , event = " Screenshot " , title = _ ( " Screenshot " ) , general = true , separator = true } ,
2020-07-14 21:39:03 +00:00
-- filemanager settings
2021-05-10 10:44:55 +00:00
folder_up = { category = " none " , event = " FolderUp " , title = _ ( " Folder up " ) , filemanager = true } ,
show_plus_menu = { category = " none " , event = " ShowPlusMenu " , title = _ ( " Show plus menu " ) , filemanager = true } ,
2021-12-16 11:12:25 +00:00
toggle_select_mode = { category = " none " , event = " ToggleSelectMode " , title = _ ( " Toggle select mode " ) , filemanager = true } ,
2021-05-10 10:44:55 +00:00
refresh_content = { category = " none " , event = " RefreshContent " , title = _ ( " Refresh content " ) , filemanager = true } ,
folder_shortcuts = { category = " none " , event = " ShowFolderShortcutsDialog " , title = _ ( " Folder shortcuts " ) , filemanager = true , separator = true } ,
2020-07-14 21:39:03 +00:00
-- reader settings
2021-09-10 20:11:24 +00:00
toggle_status_bar = { category = " none " , event = " TapFooter " , title = _ ( " Toggle status bar " ) , reader = true , separator = true } ,
prev_chapter = { category = " none " , event = " GotoPrevChapter " , title = _ ( " Previous chapter " ) , reader = true } ,
next_chapter = { category = " none " , event = " GotoNextChapter " , title = _ ( " Next chapter " ) , reader = true } ,
first_page = { category = " none " , event = " GoToBeginning " , title = _ ( " First page " ) , reader = true } ,
last_page = { category = " none " , event = " GoToEnd " , title = _ ( " Last page " ) , reader = true } ,
prev_bookmark = { category = " none " , event = " GotoPreviousBookmarkFromPage " , title = _ ( " Previous bookmark " ) , reader = true } ,
next_bookmark = { category = " none " , event = " GotoNextBookmarkFromPage " , title = _ ( " Next bookmark " ) , reader = true } ,
go_to = { category = " none " , event = " ShowGotoDialog " , title = _ ( " Go to page " ) , filemanager = true , reader = true } ,
skim = { category = " none " , event = " ShowSkimtoDialog " , title = _ ( " Skim document " ) , reader = true } ,
back = { category = " none " , event = " Back " , title = _ ( " Back " ) , reader = true } ,
previous_location = { category = " none " , event = " GoBackLink " , arg = true , title = _ ( " Back to previous location " ) , reader = true } ,
latest_bookmark = { category = " none " , event = " GoToLatestBookmark " , title = _ ( " Go to latest bookmark " ) , reader = true } ,
follow_nearest_link = { category = " arg " , event = " GoToPageLink " , arg = { pos = { x = 0 , y = 0 } } , title = _ ( " Follow nearest link " ) , reader = true } ,
follow_nearest_internal_link = { category = " arg " , event = " GoToInternalPageLink " , arg = { pos = { x = 0 , y = 0 } } , title = _ ( " Follow nearest internal link " ) , reader = true } ,
clear_location_history = { category = " none " , event = " ClearLocationStack " , arg = true , title = _ ( " Clear location history " ) , reader = true , separator = true } ,
toc = { category = " none " , event = " ShowToc " , title = _ ( " Table of contents " ) , reader = true } ,
2022-01-04 20:58:56 +00:00
book_map = { category = " none " , event = " ShowBookMap " , title = _ ( " Book map " ) , reader = true , condition = Device : isTouchDevice ( ) } ,
page_browser = { category = " none " , event = " ShowPageBrowser " , title = _ ( " Page browser " ) , reader = true , condition = Device : isTouchDevice ( ) } ,
2021-09-10 20:11:24 +00:00
bookmarks = { category = " none " , event = " ShowBookmark " , title = _ ( " Bookmarks " ) , reader = true } ,
2021-12-04 17:37:00 +00:00
bookmark_search = { category = " none " , event = " SearchBookmark " , title = _ ( " Bookmark search " ) , reader = true } ,
2021-09-10 20:11:24 +00:00
book_status = { category = " none " , event = " ShowBookStatus " , title = _ ( " Book status " ) , reader = true } ,
book_info = { category = " none " , event = " ShowBookInfo " , title = _ ( " Book information " ) , reader = true } ,
book_description = { category = " none " , event = " ShowBookDescription " , title = _ ( " Book description " ) , reader = true } ,
book_cover = { category = " none " , event = " ShowBookCover " , title = _ ( " Book cover " ) , reader = true , separator = true } ,
show_config_menu = { category = " none " , event = " ShowConfigMenu " , title = _ ( " Show bottom menu " ) , reader = true } ,
toggle_bookmark = { category = " none " , event = " ToggleBookmark " , title = _ ( " Toggle bookmark " ) , reader = true } ,
2022-06-02 21:59:29 +00:00
toggle_page_change_animation = { category = " none " , event = " TogglePageChangeAnimation " , title = _ ( " Toggle page turn animations " ) , reader = true , condition = Device : canDoSwipeAnimation ( ) } ,
2021-09-10 20:11:24 +00:00
toggle_inverse_reading_order = { category = " none " , event = " ToggleReadingOrder " , title = _ ( " Toggle page turn direction " ) , reader = true , separator = true } ,
cycle_highlight_action = { category = " none " , event = " CycleHighlightAction " , title = _ ( " Cycle highlight action " ) , reader = true } ,
cycle_highlight_style = { category = " none " , event = " CycleHighlightStyle " , title = _ ( " Cycle highlight style " ) , reader = true } ,
page_jmp = { category = " absolutenumber " , event = " GotoViewRel " , min =- 100 , max = 100 , title = _ ( " Go %1 pages " ) , reader = true } ,
2021-05-10 10:44:55 +00:00
panel_zoom_toggle = { category = " none " , event = " TogglePanelZoomSetting " , title = _ ( " Toggle panel zoom " ) , paging = true , separator = true } ,
2020-07-14 21:39:03 +00:00
-- rolling reader settings
2021-12-16 20:31:22 +00:00
set_font = { category = " string " , event = " SetFont " , title = _ ( " Set font " ) , rolling = true , args_func = require ( " fontlist " ) . getFontArgFunc , } ,
2021-05-10 10:44:55 +00:00
increase_font = { category = " incrementalnumber " , event = " IncreaseFontSize " , min = 0.5 , max = 255 , step = 0.5 , title = _ ( " Increase font size by %1 " ) , rolling = true } ,
decrease_font = { category = " incrementalnumber " , event = " DecreaseFontSize " , min = 0.5 , max = 255 , step = 0.5 , title = _ ( " Decrease font size by %1 " ) , rolling = true } ,
2020-07-14 21:39:03 +00:00
-- paging reader settings
2021-05-10 10:44:55 +00:00
toggle_page_flipping = { category = " none " , event = " TogglePageFlipping " , title = _ ( " Toggle page flipping " ) , paging = true } ,
toggle_reflow = { category = " none " , event = " ToggleReflow " , title = _ ( " Toggle reflow " ) , paging = true } ,
zoom = { category = " string " , event = " SetZoomMode " , title = _ ( " Zoom mode " ) , args = ReaderZooming.available_zoom_modes , toggle = ReaderZooming.available_zoom_modes , paging = true } ,
2020-11-28 16:18:57 +00:00
zoom_factor_change = { category = " none " , event = " ZoomFactorChange " , title = _ ( " Change zoom factor " ) , paging = true , separator = true } ,
2020-07-14 21:39:03 +00:00
-- parsed from CreOptions
-- the rest of the table elements are built from their counterparts in CreOptions
2021-09-10 20:11:24 +00:00
rotation_mode = { category = " string " , device = true } ,
2021-05-10 10:44:55 +00:00
visible_pages = { category = " string " , rolling = true , separator = true } ,
2021-10-19 09:50:31 +00:00
h_page_margins = { category = " string " , rolling = true } ,
2020-07-14 21:39:03 +00:00
sync_t_b_page_margins = { category = " string " , rolling = true } ,
t_page_margin = { category = " absolutenumber " , rolling = true } ,
2021-05-10 10:44:55 +00:00
b_page_margin = { category = " absolutenumber " , rolling = true , separator = true } ,
2020-07-14 21:39:03 +00:00
view_mode = { category = " string " , rolling = true } ,
block_rendering_mode = { category = " string " , rolling = true } ,
render_dpi = { category = " string " , rolling = true } ,
2021-05-10 10:44:55 +00:00
line_spacing = { category = " absolutenumber " , rolling = true , separator = true } ,
2021-05-05 18:48:42 +00:00
font_size = { category = " absolutenumber " , title = _ ( " Set font size to %1 " ) , rolling = true , step = 0.5 } ,
2021-12-16 15:48:53 +00:00
font_base_weight = { category = " string " , rolling = true } ,
font_gamma = { category = " string " , rolling = true } ,
2020-07-14 21:39:03 +00:00
font_hinting = { category = " string " , rolling = true } ,
2021-05-10 10:44:55 +00:00
font_kerning = { category = " string " , rolling = true , separator = true } ,
2020-07-14 21:39:03 +00:00
status_line = { category = " string " , rolling = true } ,
embedded_css = { category = " string " , rolling = true } ,
embedded_fonts = { category = " string " , rolling = true } ,
smooth_scaling = { category = " string " , rolling = true } ,
nightmode_images = { category = " string " , rolling = true } ,
2021-05-14 22:13:27 +00:00
-- parsed from KoptOptions
kopt_trim_page = { category = " string " , paging = true } ,
kopt_page_margin = { category = " string " , paging = true } ,
2021-10-01 21:06:59 +00:00
kopt_zoom_overlap_h = { category = " absolutenumber " , paging = true } ,
kopt_zoom_overlap_v = { category = " absolutenumber " , paging = true } ,
2021-05-14 22:13:27 +00:00
kopt_zoom_mode_type = { category = " string " , paging = true } ,
kopt_zoom_range_number = { category = " string " , paging = true } ,
kopt_zoom_factor = { category = " string " , paging = true } ,
kopt_zoom_mode_genus = { category = " string " , paging = true } ,
kopt_zoom_direction = { category = " string " , paging = true } ,
kopt_page_scroll = { category = " string " , paging = true } ,
kopt_page_gap_height = { category = " string " , paging = true } ,
kopt_full_screen = { category = " string " , paging = true } ,
kopt_line_spacing = { category = " configurable " , paging = true } ,
kopt_justification = { category = " configurable " , paging = true } ,
kopt_font_size = { category = " string " , paging = true , title = _ ( " Font Size " ) } ,
kopt_font_fine_tune = { category = " string " , paging = true } ,
kopt_word_spacing = { category = " configurable " , paging = true } ,
kopt_text_wrap = { category = " string " , paging = true } ,
2021-10-01 21:06:59 +00:00
kopt_contrast = { category = " absolutenumber " , paging = true } ,
2021-05-14 22:13:27 +00:00
kopt_page_opt = { category = " configurable " , paging = true } ,
kopt_hw_dithering = { category = " configurable " , paging = true , condition = Device : hasEinkScreen ( ) and Device : canHWDither ( ) } ,
2022-02-05 19:20:15 +00:00
kopt_sw_dithering = { category = " configurable " , paging = true , condition = Device : hasEinkScreen ( ) and not Device : canHWDither ( ) and Device.screen . fb_bpp == 8 } ,
2021-05-14 22:13:27 +00:00
kopt_quality = { category = " configurable " , paging = true } ,
kopt_doc_language = { category = " string " , paging = true } ,
kopt_forced_ocr = { category = " configurable " , paging = true } ,
kopt_writing_direction = { category = " configurable " , paging = true } ,
kopt_defect_size = { category = " string " , paging = true , condition = false } ,
2021-10-01 21:06:59 +00:00
kopt_auto_straighten = { category = " absolutenumber " , paging = true } ,
2021-05-14 22:13:27 +00:00
kopt_detect_indent = { category = " configurable " , paging = true , condition = false } ,
kopt_max_columns = { category = " configurable " , paging = true } ,
2020-07-14 21:39:03 +00:00
}
-- array for item order in menu
local dispatcher_menu_order = {
-- device
" reading_progress " ,
" open_previous_document " ,
2021-09-10 20:11:24 +00:00
" history " ,
2020-07-14 21:39:03 +00:00
" favorites " ,
" filemanager " ,
" dictionary_lookup " ,
" wikipedia_lookup " ,
" fulltext_search " ,
" file_search " ,
2021-09-10 20:11:24 +00:00
" show_menu " ,
" screenshot " ,
2022-07-11 11:50:28 +00:00
" exit_screensaver " ,
2020-07-14 21:39:03 +00:00
" suspend " ,
" exit " ,
" restart " ,
" reboot " ,
" poweroff " ,
2021-09-10 20:11:24 +00:00
" toggle_hold_corners " ,
" toggle_gsensor " ,
" rotation_mode " ,
" toggle_rotation " ,
" invert_rotation " ,
" iterate_rotation " ,
" wifi_on " ,
" wifi_off " ,
" toggle_wifi " ,
2022-06-24 21:19:38 +00:00
" toggle_fullscreen " ,
2022-05-06 17:19:55 +00:00
" show_network_info " ,
2021-09-10 20:11:24 +00:00
2020-07-14 21:39:03 +00:00
" show_frontlight_dialog " ,
" toggle_frontlight " ,
2020-07-29 21:48:28 +00:00
" set_frontlight " ,
2020-07-14 21:39:03 +00:00
" increase_frontlight " ,
" decrease_frontlight " ,
2020-07-29 21:48:28 +00:00
" set_frontlight_warmth " ,
2020-07-14 21:39:03 +00:00
" increase_frontlight_warmth " ,
" decrease_frontlight_warmth " ,
2021-09-10 20:11:24 +00:00
" night_mode " ,
" set_night_mode " ,
2020-07-14 21:39:03 +00:00
2021-09-10 20:11:24 +00:00
" full_refresh " ,
2020-08-21 12:33:08 +00:00
" set_refresh_rate " ,
" set_day_refresh_rate " ,
" set_night_refresh_rate " ,
" set_flash_on_chapter_boundaries " ,
" toggle_flash_on_chapter_boundaries " ,
" set_no_flash_on_second_chapter_page " ,
" toggle_no_flash_on_second_chapter_page " ,
2020-07-14 21:39:03 +00:00
-- filemanager
" folder_up " ,
" show_plus_menu " ,
2021-12-16 11:12:25 +00:00
" toggle_select_mode " ,
2021-05-05 18:43:43 +00:00
" refresh_content " ,
2020-07-14 21:39:03 +00:00
" folder_shortcuts " ,
-- reader
2021-09-10 20:11:24 +00:00
" show_config_menu " ,
2021-04-26 19:45:34 +00:00
" toggle_status_bar " ,
2020-07-14 21:39:03 +00:00
" prev_chapter " ,
" next_chapter " ,
" first_page " ,
" last_page " ,
2021-05-10 10:44:55 +00:00
" page_jmp " ,
2020-07-14 21:39:03 +00:00
" go_to " ,
" skim " ,
2021-05-10 10:44:55 +00:00
" prev_bookmark " ,
" next_bookmark " ,
" latest_bookmark " ,
2020-07-14 21:39:03 +00:00
" back " ,
" previous_location " ,
" follow_nearest_link " ,
" follow_nearest_internal_link " ,
" clear_location_history " ,
" toc " ,
2022-01-04 20:58:56 +00:00
" book_map " ,
" page_browser " ,
2020-07-14 21:39:03 +00:00
" bookmarks " ,
2021-12-04 17:37:00 +00:00
" bookmark_search " ,
2020-07-14 21:39:03 +00:00
" book_status " ,
" book_info " ,
" book_description " ,
" book_cover " ,
2021-12-16 20:31:22 +00:00
" set_font " ,
2020-07-14 21:39:03 +00:00
" increase_font " ,
" decrease_font " ,
" font_size " ,
2020-09-21 21:51:12 +00:00
" font_gamma " ,
2021-04-28 23:37:53 +00:00
" font_base_weight " ,
2020-07-14 21:39:03 +00:00
" font_hinting " ,
" font_kerning " ,
" toggle_bookmark " ,
2022-06-02 21:59:29 +00:00
" toggle_page_change_animation " ,
2020-07-14 21:39:03 +00:00
" toggle_page_flipping " ,
" toggle_reflow " ,
" toggle_inverse_reading_order " ,
" zoom " ,
2020-11-28 16:18:57 +00:00
" zoom_factor_change " ,
2020-07-14 21:39:03 +00:00
" cycle_highlight_action " ,
" cycle_highlight_style " ,
2020-09-24 13:17:37 +00:00
" panel_zoom_toggle " ,
2020-07-14 21:39:03 +00:00
" visible_pages " ,
" h_page_margins " ,
" sync_t_b_page_margins " ,
" t_page_margin " ,
" b_page_margin " ,
" view_mode " ,
" block_rendering_mode " ,
" render_dpi " ,
" line_spacing " ,
" status_line " ,
" embedded_css " ,
" embedded_fonts " ,
" smooth_scaling " ,
" nightmode_images " ,
2021-05-14 22:13:27 +00:00
" kopt_trim_page " ,
" kopt_page_margin " ,
" kopt_zoom_overlap_h " ,
" kopt_zoom_overlap_v " ,
" kopt_zoom_mode_type " ,
--"kopt_zoom_range_number", -- can't figure out how this name text func works
" kopt_zoom_factor " ,
" kopt_zoom_mode_genus " ,
" kopt_zoom_direction " ,
" kopt_page_scroll " ,
" kopt_page_gap_height " ,
" kopt_full_screen " ,
" kopt_line_spacing " ,
" kopt_justification " ,
" kopt_font_size " ,
" kopt_font_fine_tune " ,
" kopt_word_spacing " ,
" kopt_text_wrap " ,
" kopt_contrast " ,
" kopt_page_opt " ,
" kopt_hw_dithering " ,
2022-02-05 18:49:13 +00:00
" kopt_sw_dithering " ,
2021-05-14 22:13:27 +00:00
" kopt_quality " ,
" kopt_doc_language " ,
" kopt_forced_ocr " ,
" kopt_writing_direction " ,
" kopt_defect_size " ,
" kopt_auto_straighten " ,
" kopt_detect_indent " ,
" kopt_max_columns " ,
2020-06-19 21:38:53 +00:00
}
--[[--
add settings from CreOptions / KoptOptions
--]]--
function Dispatcher : init ( )
2020-09-22 00:05:02 +00:00
if Dispatcher.initialized then return end
2021-05-14 22:13:27 +00:00
local parseoptions = function ( base , i , prefix )
for y = 1 , # base [ i ] . options do
2020-06-19 21:38:53 +00:00
local option = base [ i ] . options [ y ]
2021-05-14 22:13:27 +00:00
local name = prefix and prefix .. option.name or option.name
if settingsList [ name ] ~= nil then
2021-01-07 22:19:23 +00:00
if option.name ~= nil and option.values ~= nil then
2021-05-14 22:13:27 +00:00
settingsList [ name ] . configurable = { name = option.name , values = option.values }
2021-01-07 22:19:23 +00:00
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . event == nil then
settingsList [ name ] . event = option.event
2020-06-19 21:38:53 +00:00
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . title == nil then
settingsList [ name ] . title = option.name_text
2020-06-19 21:38:53 +00:00
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . category == " string " or settingsList [ name ] . category == " configurable " then
if settingsList [ name ] . toggle == nil then
settingsList [ name ] . toggle = option.toggle or option.labels
if settingsList [ name ] . toggle == nil then
settingsList [ name ] . toggle = { }
2020-06-28 10:18:45 +00:00
for z = 1 , # option.values do
if type ( option.values [ z ] ) == " table " then
2021-05-14 22:13:27 +00:00
settingsList [ name ] . toggle [ z ] = option.values [ z ] [ 1 ]
else
settingsList [ name ] . toggle [ z ] = option.values [ z ]
2020-06-28 10:18:45 +00:00
end
2020-06-19 21:38:53 +00:00
end
end
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . args == nil then
settingsList [ name ] . args = option.args or option.values
2020-06-19 21:38:53 +00:00
end
2021-05-14 22:13:27 +00:00
elseif settingsList [ name ] . category == " absolutenumber " then
if settingsList [ name ] . min == nil then
2021-10-01 21:06:59 +00:00
settingsList [ name ] . min = option.args and option.args [ 1 ] or option.values [ 1 ]
2020-06-19 21:38:53 +00:00
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . max == nil then
2021-10-01 21:06:59 +00:00
settingsList [ name ] . max = option.args and option.args [ # option.args ] or option.values [ # option.values ]
2020-06-19 21:38:53 +00:00
end
2021-05-14 22:13:27 +00:00
if settingsList [ name ] . default == nil then
settingsList [ name ] . default = option.default_value
2020-06-19 21:38:53 +00:00
end
end
end
end
end
for i = 1 , # CreOptions do
parseoptions ( CreOptions , i )
end
2021-05-14 22:13:27 +00:00
for i = 1 , # KoptOptions do
parseoptions ( KoptOptions , i , " kopt_ " )
end
2020-10-12 03:06:04 +00:00
UIManager : broadcastEvent ( Event : new ( " DispatcherRegisterActions " ) )
2020-06-19 21:38:53 +00:00
Dispatcher.initialized = true
end
2020-10-12 03:06:04 +00:00
--[[--
2020-10-12 15:20:16 +00:00
Adds settings at runtime .
@ usage
function Hello : onDispatcherRegisterActions ( )
2021-09-10 20:11:24 +00:00
Dispatcher : registerAction ( " helloworld_action " , { category = " none " , event = " HelloWorld " , title = _ ( " Hello World " ) , general = true } )
2020-10-12 15:20:16 +00:00
end
function Hello : init ( )
self : onDispatcherRegisterActions ( )
end
@ param name the key to use in the table
@ param value a table per settingsList above
2020-10-12 03:06:04 +00:00
--]]--
function Dispatcher : registerAction ( name , value )
if settingsList [ name ] == nil then
settingsList [ name ] = value
table.insert ( dispatcher_menu_order , name )
end
return true
end
2021-09-10 20:14:07 +00:00
--[[--
Removes settings at runtime .
@ param name the key to use in the table
--]]--
function Dispatcher : removeAction ( name )
local k = util.arrayContains ( dispatcher_menu_order , name )
if k then
table.remove ( dispatcher_menu_order , k )
settingsList [ name ] = nil
end
return true
end
2020-07-28 18:49:55 +00:00
-- Returns a display name for the item.
function Dispatcher : getNameFromItem ( item , location , settings )
2020-10-12 03:06:04 +00:00
if settingsList [ item ] == nil then
return _ ( " Unknown item " )
end
2020-07-28 18:49:55 +00:00
local amount
if location [ settings ] ~= nil and location [ settings ] [ item ] ~= nil then
amount = location [ settings ] [ item ]
end
2020-08-17 07:55:03 +00:00
if amount == nil
or ( amount == 0 and settingsList [ item ] . category == " incrementalnumber " )
then
amount = C_ ( " Number placeholder " , " # " )
2020-07-28 18:49:55 +00:00
end
return T ( settingsList [ item ] . title , amount )
end
2020-08-04 22:19:28 +00:00
function Dispatcher : addItem ( caller , menu , location , settings , section )
2020-07-14 21:39:03 +00:00
for _ , k in ipairs ( dispatcher_menu_order ) do
if settingsList [ k ] [ section ] == true and
( settingsList [ k ] . condition == nil or settingsList [ k ] . condition )
then
if settingsList [ k ] . category == " none " or settingsList [ k ] . category == " arg " then
2020-06-19 21:38:53 +00:00
table.insert ( menu , {
2021-05-25 14:12:16 +00:00
text = settingsList [ k ] . title ,
checked_func = function ( )
return location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil
end ,
callback = function ( touchmenu_instance )
if location [ settings ] == nil then
location [ settings ] = { }
end
if location [ settings ] [ k ] then
location [ settings ] [ k ] = nil
else
location [ settings ] [ k ] = true
end
caller.updated = true
if touchmenu_instance then touchmenu_instance : updateItems ( ) end
2020-06-19 21:38:53 +00:00
end ,
2021-05-25 14:12:16 +00:00
separator = settingsList [ k ] . separator ,
} )
2020-06-19 21:38:53 +00:00
elseif settingsList [ k ] . category == " absolutenumber " then
table.insert ( menu , {
text_func = function ( )
2020-07-28 18:49:55 +00:00
return Dispatcher : getNameFromItem ( k , location , settings )
2020-06-19 21:38:53 +00:00
end ,
checked_func = function ( )
2020-07-28 01:26:56 +00:00
return location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil
2020-06-19 21:38:53 +00:00
end ,
callback = function ( touchmenu_instance )
local SpinWidget = require ( " ui/widget/spinwidget " )
2021-05-13 02:38:52 +00:00
local precision
2021-05-05 18:48:42 +00:00
if settingsList [ k ] . step and math.floor ( settingsList [ k ] . step ) ~= settingsList [ k ] . step then
2021-05-13 02:38:52 +00:00
precision = " %0.1f "
2021-05-05 18:48:42 +00:00
end
2020-06-19 21:38:53 +00:00
local items = SpinWidget : new {
2020-07-28 18:49:55 +00:00
value = location [ settings ] ~= nil and location [ settings ] [ k ] or settingsList [ k ] . default or 0 ,
2020-06-19 21:38:53 +00:00
value_min = settingsList [ k ] . min ,
2021-05-05 18:48:42 +00:00
value_step = settingsList [ k ] . step or 1 ,
2021-05-13 02:38:52 +00:00
precision = precision ,
2021-01-11 17:14:10 +00:00
value_hold_step = 5 ,
2020-06-19 21:38:53 +00:00
value_max = settingsList [ k ] . max ,
2021-05-05 18:48:42 +00:00
default_value = settingsList [ k ] . default ,
2020-07-28 18:49:55 +00:00
title_text = Dispatcher : getNameFromItem ( k , location , settings ) ,
2021-12-16 11:55:05 +00:00
ok_always_enabled = true ,
2020-06-19 21:38:53 +00:00
callback = function ( spin )
2020-07-28 18:49:55 +00:00
if location [ settings ] == nil then
location [ settings ] = { }
end
2020-07-28 01:26:56 +00:00
location [ settings ] [ k ] = spin.value
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-06-19 21:38:53 +00:00
if touchmenu_instance then
touchmenu_instance : updateItems ( )
end
end
}
UIManager : show ( items )
end ,
hold_callback = function ( touchmenu_instance )
2020-07-28 18:49:55 +00:00
if location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil then
location [ settings ] [ k ] = nil
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-07-28 18:49:55 +00:00
end
2020-06-19 21:38:53 +00:00
if touchmenu_instance then touchmenu_instance : updateItems ( ) end
end ,
2020-07-14 21:39:03 +00:00
separator = settingsList [ k ] . separator ,
2020-06-19 21:38:53 +00:00
} )
elseif settingsList [ k ] . category == " incrementalnumber " then
table.insert ( menu , {
text_func = function ( )
2020-07-28 18:49:55 +00:00
return Dispatcher : getNameFromItem ( k , location , settings )
2020-06-19 21:38:53 +00:00
end ,
checked_func = function ( )
2020-07-28 01:26:56 +00:00
return location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil
2020-06-19 21:38:53 +00:00
end ,
callback = function ( touchmenu_instance )
2020-07-14 21:39:03 +00:00
local _ = require ( " gettext " )
2021-05-13 02:38:52 +00:00
local precision
2021-05-05 18:48:42 +00:00
if settingsList [ k ] . step and math.floor ( settingsList [ k ] . step ) ~= settingsList [ k ] . step then
2021-05-13 02:38:52 +00:00
precision = " %0.1f "
2021-05-05 18:48:42 +00:00
end
2020-06-19 21:38:53 +00:00
local SpinWidget = require ( " ui/widget/spinwidget " )
local items = SpinWidget : new {
2020-07-28 18:49:55 +00:00
value = location [ settings ] ~= nil and location [ settings ] [ k ] or 0 ,
2020-06-19 21:38:53 +00:00
value_min = settingsList [ k ] . min ,
2021-05-05 18:48:42 +00:00
value_step = settingsList [ k ] . step or 1 ,
2021-05-13 02:38:52 +00:00
precision = precision ,
2021-01-11 17:14:10 +00:00
value_hold_step = 5 ,
2020-06-19 21:38:53 +00:00
value_max = settingsList [ k ] . max ,
default_value = 0 ,
2020-07-28 18:49:55 +00:00
title_text = Dispatcher : getNameFromItem ( k , location , settings ) ,
2020-07-14 21:39:03 +00:00
info_text = _ ( [[If called by a gesture the amount of the gesture will be used]] ) ,
2021-12-16 11:55:05 +00:00
ok_always_enabled = true ,
2020-06-19 21:38:53 +00:00
callback = function ( spin )
2020-07-28 18:49:55 +00:00
if location [ settings ] == nil then
location [ settings ] = { }
end
2020-07-28 01:26:56 +00:00
location [ settings ] [ k ] = spin.value
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-06-19 21:38:53 +00:00
if touchmenu_instance then
touchmenu_instance : updateItems ( )
end
end
}
UIManager : show ( items )
end ,
hold_callback = function ( touchmenu_instance )
2020-07-28 18:49:55 +00:00
if location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil then
location [ settings ] [ k ] = nil
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-07-28 18:49:55 +00:00
end
2020-06-19 21:38:53 +00:00
if touchmenu_instance then
touchmenu_instance : updateItems ( )
end
end ,
2020-07-14 21:39:03 +00:00
separator = settingsList [ k ] . separator ,
2020-06-19 21:38:53 +00:00
} )
2021-05-14 22:13:27 +00:00
elseif settingsList [ k ] . category == " string " or settingsList [ k ] . category == " configurable " then
2020-06-19 21:38:53 +00:00
local sub_item_table = { }
2021-12-16 20:30:48 +00:00
if settingsList [ k ] . args_func then
settingsList [ k ] . args , settingsList [ k ] . toggle = settingsList [ k ] . args_func ( )
end
2020-06-19 21:38:53 +00:00
for i = 1 , # settingsList [ k ] . args do
table.insert ( sub_item_table , {
text = tostring ( settingsList [ k ] . toggle [ i ] ) ,
checked_func = function ( )
2020-07-28 01:26:56 +00:00
return location [ settings ] ~= nil
and location [ settings ] [ k ] ~= nil
and location [ settings ] [ k ] == settingsList [ k ] . args [ i ]
2020-06-19 21:38:53 +00:00
end ,
callback = function ( )
2020-07-28 18:49:55 +00:00
if location [ settings ] == nil then
location [ settings ] = { }
end
2020-07-28 01:26:56 +00:00
location [ settings ] [ k ] = settingsList [ k ] . args [ i ]
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-06-19 21:38:53 +00:00
end ,
} )
end
table.insert ( menu , {
text_func = function ( )
2020-07-28 18:49:55 +00:00
return Dispatcher : getNameFromItem ( k , location , settings )
2020-06-19 21:38:53 +00:00
end ,
checked_func = function ( )
2020-07-28 18:49:55 +00:00
return location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil
2020-06-19 21:38:53 +00:00
end ,
sub_item_table = sub_item_table ,
keep_menu_open = true ,
hold_callback = function ( touchmenu_instance )
2020-07-28 18:49:55 +00:00
if location [ settings ] ~= nil and location [ settings ] [ k ] ~= nil then
location [ settings ] [ k ] = nil
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-07-28 18:49:55 +00:00
end
2020-06-19 21:38:53 +00:00
if touchmenu_instance then
touchmenu_instance : updateItems ( )
end
end ,
2020-07-14 21:39:03 +00:00
separator = settingsList [ k ] . separator ,
2021-05-25 14:16:53 +00:00
menu_item_id = k ,
2020-06-19 21:38:53 +00:00
} )
end
end
2020-07-14 21:39:03 +00:00
end
end
--[[--
Add a submenu to edit which items are dispatched
arguments are :
2020-08-04 22:19:28 +00:00
1 ) the caller so dispatcher can set the updated flag
2 ) the table representing the submenu ( can be empty )
3 ) the object ( table ) in which the settings table is found
4 ) the name of the settings table
2020-07-14 21:39:03 +00:00
example usage :
2021-09-10 20:14:07 +00:00
Dispatcher : addSubMenu ( self , sub_items , self.data , " profile1 " )
2020-07-14 21:39:03 +00:00
--]]--
2020-08-04 22:19:28 +00:00
function Dispatcher : addSubMenu ( caller , menu , location , settings )
2020-09-22 00:05:02 +00:00
Dispatcher : init ( )
2020-07-14 21:39:03 +00:00
table.insert ( menu , {
2020-07-28 18:49:55 +00:00
text = _ ( " Nothing " ) ,
2020-07-14 21:39:03 +00:00
separator = true ,
checked_func = function ( )
2020-07-28 18:49:55 +00:00
return location [ settings ] ~= nil and next ( location [ settings ] ) == nil
2020-07-14 21:39:03 +00:00
end ,
callback = function ( touchmenu_instance )
2020-07-28 01:26:56 +00:00
location [ settings ] = { }
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-07-14 21:39:03 +00:00
if touchmenu_instance then touchmenu_instance : updateItems ( ) end
end ,
} )
local section_list = {
2021-09-10 20:11:24 +00:00
{ " general " , _ ( " General " ) } ,
2020-07-14 21:39:03 +00:00
{ " device " , _ ( " Device " ) } ,
2021-09-14 07:22:43 +00:00
{ " screen " , _ ( " Screen and lights " ) } ,
2020-07-17 07:57:46 +00:00
{ " filemanager " , _ ( " File browser " ) } ,
2021-09-10 20:11:24 +00:00
{ " reader " , _ ( " Reader " ) } ,
2020-07-14 21:39:03 +00:00
{ " rolling " , _ ( " Reflowable documents (epub, fb2, txt…) " ) } ,
{ " paging " , _ ( " Fixed layout documents (pdf, djvu, pics…) " ) } ,
}
for _ , section in ipairs ( section_list ) do
local submenu = { }
2020-08-04 22:19:28 +00:00
Dispatcher : addItem ( caller , submenu , location , settings , section [ 1 ] )
2020-07-14 21:39:03 +00:00
table.insert ( menu , {
text = section [ 2 ] ,
2020-07-28 18:49:55 +00:00
checked_func = function ( )
if location [ settings ] ~= nil then
for k , _ in pairs ( location [ settings ] ) do
2020-10-12 03:06:04 +00:00
if settingsList [ k ] ~= nil and settingsList [ k ] [ section [ 1 ] ] == true and
2020-07-28 18:49:55 +00:00
( settingsList [ k ] . condition == nil or settingsList [ k ] . condition )
then return true end
end
end
end ,
hold_callback = function ( touchmenu_instance )
if location [ settings ] ~= nil then
for k , _ in pairs ( location [ settings ] ) do
2020-10-12 03:06:04 +00:00
if settingsList [ k ] ~= nil and settingsList [ k ] [ section [ 1 ] ] == true then
2020-07-28 18:49:55 +00:00
location [ settings ] [ k ] = nil
2020-08-04 22:19:28 +00:00
caller.updated = true
2020-07-28 18:49:55 +00:00
end
end
if touchmenu_instance then touchmenu_instance : updateItems ( ) end
end
end ,
2020-07-14 21:39:03 +00:00
sub_item_table = submenu ,
} )
end
2020-06-19 21:38:53 +00:00
end
2020-07-28 01:26:56 +00:00
--[[--
Calls the events in a settings list
arguments are :
1 ) a reference to the uimanager
2 ) the settings table
3 ) optionally a ` gestures ` object
--]]--
2021-07-23 11:27:12 +00:00
function Dispatcher : execute ( settings , gesture )
2020-06-19 21:38:53 +00:00
for k , v in pairs ( settings ) do
2020-10-12 03:06:04 +00:00
if settingsList [ k ] ~= nil and ( settingsList [ k ] . conditions == nil or settingsList [ k ] . conditions == true ) then
2021-07-23 11:27:12 +00:00
Notification : setNotifySource ( Notification.SOURCE_DISPATCHER )
2021-08-30 15:01:46 +00:00
if settingsList [ k ] . configurable then
local value = v
if type ( v ) ~= " number " then
for i , r in ipairs ( settingsList [ k ] . args ) do
if v == r then value = settingsList [ k ] . configurable.values [ i ] break end
end
end
UIManager : sendEvent ( Event : new ( " ConfigChange " , settingsList [ k ] . configurable.name , value ) )
end
2021-07-23 11:27:12 +00:00
if settingsList [ k ] . category == " none " then
if settingsList [ k ] . arg ~= nil then
UIManager : sendEvent ( Event : new ( settingsList [ k ] . event , settingsList [ k ] . arg ) )
else
UIManager : sendEvent ( Event : new ( settingsList [ k ] . event ) )
2021-05-20 17:23:34 +00:00
end
2021-07-23 11:27:12 +00:00
end
if settingsList [ k ] . category == " absolutenumber "
or settingsList [ k ] . category == " string "
then
UIManager : sendEvent ( Event : new ( settingsList [ k ] . event , v ) )
end
-- the event can accept a gesture object or an argument
if settingsList [ k ] . category == " arg " then
local arg = gesture or settingsList [ k ] . arg
UIManager : sendEvent ( Event : new ( settingsList [ k ] . event , arg ) )
end
-- the event can accept a gesture object or a number
if settingsList [ k ] . category == " incrementalnumber " then
local arg = v ~= 0 and v or gesture or 0
UIManager : sendEvent ( Event : new ( settingsList [ k ] . event , arg ) )
end
2020-06-19 21:38:53 +00:00
end
2021-07-23 11:27:12 +00:00
Notification : resetNotifySource ( )
2020-06-19 21:38:53 +00:00
end
end
return Dispatcher