task_warrior.lua 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. -- @author cedlemo
  2. local helpers = require("blingbling.helpers")
  3. local awful = require("awful")
  4. local naughty = require("naughty")
  5. local wibox = require("wibox")
  6. local superproperties = require("blingbling.superproperties")
  7. local string = string
  8. local math = math
  9. local ipairs = ipairs
  10. local next = next
  11. local pairs = pairs
  12. local type = type
  13. local setmetatable = setmetatable
  14. local table = table
  15. local print = print
  16. ---Task warrior menu
  17. --@module blingbling.task_warrior
  18. local task_warrior = { mt = {} }
  19. local data = setmetatable( {}, { __mode = "k"})
  20. --Get projects list from task warrior
  21. local function get_projects(tw_menu)
  22. data[tw_menu].projects={}
  23. local my_projects=awful.util.pread("task projects")
  24. --remove first line
  25. my_projects=string.gsub(my_projects,
  26. "\nProject%s*Tasks%s*Pri%:None%s*Pri%:L%s*Pri%:M%s*Pri%:H%s*",
  27. "")
  28. --generate the list of projects
  29. --if string.find(my_projects,"No Projects") ~= nil then
  30. -- data[tw_menu].projects=nil
  31. --end
  32. for project, project_tasks in string.gmatch(my_projects,"\n([%w%(%)%-%_%.]*)%s%s+(%d*)","%1 %2") do
  33. project=string.gsub(project,"\n","")
  34. table.insert(data[tw_menu].projects, {name =project, nb_tasks = project_tasks} )
  35. end
  36. end
  37. local function generate_tasks_management_submenu(tw_menu, task_id)
  38. management_submenu={}
  39. table.insert(management_submenu,{ "Task "..task_id..": set done", "task "..task_id .. " done > /dev/null 2>&1", data[tw_menu].task_done_icon })
  40. return management_submenu
  41. end
  42. local function get_tasks(tw_menu, project)
  43. local tasks={}
  44. if project=="(none)" then
  45. project=""
  46. end
  47. local my_tasks=awful.util.pread("task rc.defaultwidth=0 project:\"".. project.."\" minimal ")
  48. --escape specific char ( need to be extended)
  49. project_pattern=string.gsub(project,"%-","%%-") or ""
  50. project_pattern=string.gsub(project_pattern,"%_","%%_") or ""
  51. project_pattern=string.gsub(project_pattern,"%.","%%.") or ""
  52. each_tasks={}
  53. each_tasks=helpers.split(my_tasks,"\n")
  54. for i,v in ipairs(each_tasks) do
  55. for my_task_id, my_task in string.gmatch(v,"%s*(%d*)%s+"..project_pattern.."%s+(.*)$","%1 %2") do
  56. table.insert(tasks, {my_task ,generate_tasks_management_submenu(tw_menu,my_task_id),data[tw_menu].task_icon})
  57. end
  58. end
  59. return tasks
  60. end
  61. local function generate_menu(tw_menu)
  62. my_menu={}
  63. my_submenu={}
  64. get_projects(tw_menu)
  65. if data[tw_menu].projects ~= {} then
  66. for i,v in ipairs(data[tw_menu].projects) do
  67. my_submenu=get_tasks(tw_menu,v.name)
  68. table.insert(my_menu,{v.name .. " (" ..v.nb_tasks ..")", my_submenu, data[tw_menu].project_icon })
  69. end
  70. data[tw_menu].menu= awful.menu({ items = my_menu, theme = {width = data[tw_menu].width }})
  71. else
  72. data[tw_menu].menu = awful.menu({ items = { {"No projects"}}, theme = {width = data[tw_menu].width }})
  73. end
  74. return tw_menu
  75. end
  76. local function display_menu(tw_menu)
  77. tw_menu:buttons(awful.util.table.join(
  78. awful.button({ }, 1, function()
  79. if data[tw_menu].menu_visible == "false" then
  80. data[tw_menu].menu_visible = "true"
  81. generate_menu(tw_menu )
  82. data[tw_menu].menu:show()
  83. else
  84. data[tw_menu].menu:hide()
  85. data[tw_menu].menu_visible = "false"
  86. end
  87. end),
  88. awful.button({ }, 3, function()
  89. data[tw_menu].menu:hide()
  90. data[tw_menu].menu_visible = "false"
  91. end)
  92. ))
  93. end
  94. ---Set the icon for "set task done" menu item.
  95. --@usage my_tasks:set_task_done_icon(an_image_file_name)
  96. --@param tw_menu a task warrior menu
  97. --@param an_image an image file name
  98. function task_warrior.set_task_done_icon(tw_menu,an_image)
  99. data[tw_menu].task_done_icon=an_image
  100. return tw_menu
  101. end
  102. ---Set the icon for project menu item.
  103. --@usage my_tasks:set_project_icon(an_image_file_name)
  104. --@param tw_menu a task warrior menu
  105. --@param an_image an image file name
  106. function set_project_icon(tw_menu,an_image)
  107. data[tw_menu].project_icon=an_image
  108. return tw_menu
  109. end
  110. ---Set the icon for task menu item.
  111. --@usage my_tasks:set_task_icon(an_image_file_name)
  112. --@param tw_menu a task warrior menu
  113. --@param an_image an image file name
  114. function set_task_icon(tw_menu,an_image)
  115. data[tw_menu].task_icon=an_image
  116. return tw_menu
  117. end
  118. ---Create new task warrior menu.
  119. --@usage my_tasks=blingbling.task_warrior.new({ menu_icon = an_icon_file, width = integer --[[optional--]], project_icon = an_icon_file --[[optional--]], task_icon = an_icon_file --[[optional--]], task_icon_done = an_icon_file --[[optional--]]} )
  120. --@param args a table
  121. --@return tw_menu a task warrior menu
  122. function task_warrior.new(args)
  123. local args = args or {}
  124. local tw_menu = wibox.widget.imagebox()
  125. tw_menu:set_image(args.menu_icon)
  126. data[tw_menu]={ projects= {},
  127. tasks={},
  128. menu_visible = "false",
  129. width = args.width or superproperties.menu_width,
  130. menu={},
  131. project_icon = args.project_icon or nil,
  132. task_icon = args.task_icon or nil,
  133. task_done_icon= args.task_done or nil,
  134. }
  135. tw_menu.set_task_done_icon = set_task_done_icon
  136. tw_menu.set_task_icon = set_task_icon
  137. tw_menu.set_project_icon = set_project_icon
  138. generate_menu(tw_menu)
  139. display_menu(tw_menu)
  140. return tw_menu
  141. end
  142. function task_warrior.mt:__call(...)
  143. return task_warrior.new(...)
  144. end
  145. return setmetatable(task_warrior, task_warrior.mt)