cal-menu.el 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. ;;; cal-menu.el --- calendar functions for menu bar and popup menu support
  2. ;; Copyright (C) 1994-1995, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
  4. ;; Lara Rios <lrios@coewl.cen.uiuc.edu>
  5. ;; Maintainer: Glenn Morris <rgm@gnu.org>
  6. ;; Keywords: calendar
  7. ;; Human-Keywords: calendar, popup menus, menu bar
  8. ;; Package: calendar
  9. ;; This file is part of GNU Emacs.
  10. ;; GNU Emacs is free software: you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation, either version 3 of the License, or
  13. ;; (at your option) any later version.
  14. ;; GNU Emacs is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;; GNU General Public License for more details.
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  20. ;;; Commentary:
  21. ;; See calendar.el.
  22. ;;; Code:
  23. (require 'calendar)
  24. (defconst cal-menu-sunmoon-menu
  25. '("Sun/Moon"
  26. ["Lunar Phases" calendar-lunar-phases]
  27. ["Sunrise/sunset for cursor date" calendar-sunrise-sunset]
  28. ["Sunrise/sunset for cursor month" calendar-sunrise-sunset-month])
  29. "Key map for \"Sun/Moon\" menu in the calendar.")
  30. (defconst cal-menu-diary-menu
  31. '("Diary"
  32. ["Other File" diary-view-other-diary-entries]
  33. ["Cursor Date" diary-view-entries]
  34. ["Mark All" diary-mark-entries]
  35. ["Show All" diary-show-all-entries]
  36. ["Insert Diary Entry" diary-insert-entry]
  37. ["Insert Weekly" diary-insert-weekly-entry]
  38. ["Insert Monthly" diary-insert-monthly-entry]
  39. ["Insert Yearly" diary-insert-yearly-entry]
  40. ["Insert Anniversary" diary-insert-anniversary-entry]
  41. ["Insert Block" diary-insert-block-entry]
  42. ["Insert Cyclic" diary-insert-cyclic-entry]
  43. ("Insert Bahá'í"
  44. ["One time" diary-bahai-insert-entry]
  45. ["Monthly" diary-bahai-insert-monthly-entry]
  46. ["Yearly" diary-bahai-insert-yearly-entry])
  47. ("Insert Islamic"
  48. ["One time" diary-islamic-insert-entry]
  49. ["Monthly" diary-islamic-insert-monthly-entry]
  50. ["Yearly" diary-islamic-insert-yearly-entry])
  51. ("Insert Hebrew"
  52. ["One time" diary-hebrew-insert-entry]
  53. ["Monthly" diary-hebrew-insert-monthly-entry]
  54. ["Yearly" diary-hebrew-insert-yearly-entry]))
  55. "Key map for \"Diary\" menu in the calendar.")
  56. (defun cal-menu-holiday-window-suffix ()
  57. "Return a string suffix for the \"Window\" entry in `cal-menu-holidays-menu'."
  58. (let ((my1 (calendar-increment-month-cons -1))
  59. (my2 (calendar-increment-month-cons 1)))
  60. ;; Mon1-Mon2, Year or Mon1, Year1-Mon2, Year2.
  61. (format "%s%s-%s, %d"
  62. (calendar-month-name (car my1) 'abbrev)
  63. (if (= (cdr my1) (cdr my2))
  64. ""
  65. (format ", %d" (cdr my1)))
  66. (calendar-month-name (car my2) 'abbrev)
  67. (cdr my2))))
  68. (defvar displayed-year) ; from calendar-generate
  69. (defconst cal-menu-holidays-menu
  70. `("Holidays"
  71. ["For Cursor Date -" calendar-cursor-holidays
  72. :suffix (calendar-date-string (calendar-cursor-to-date) t t)
  73. :visible (calendar-cursor-to-date)]
  74. ["For Window -" calendar-list-holidays
  75. :suffix (cal-menu-holiday-window-suffix)]
  76. ["For Today -" (calendar-cursor-holidays (calendar-current-date))
  77. :suffix (calendar-date-string (calendar-current-date) t t)]
  78. "--"
  79. ,@(let ((l ()))
  80. ;; Show 11 years--5 before, 5 after year of middle month.
  81. ;; We used to use :suffix rather than :label and bumped into
  82. ;; an easymenu bug:
  83. ;; http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01813.html
  84. ;; The bug has since been fixed.
  85. (dotimes (i 11)
  86. (push (vector (format "hol-year-%d" i)
  87. `(lambda ()
  88. (interactive)
  89. (holiday-list (+ displayed-year ,(- i 5))))
  90. :label `(format "For Year %d"
  91. (+ displayed-year ,(- i 5))))
  92. l))
  93. (nreverse l))
  94. "--"
  95. ["Unmark Calendar" calendar-unmark]
  96. ["Mark Holidays" calendar-mark-holidays])
  97. "Key map for \"Holidays\" menu in the calendar.")
  98. (defconst cal-menu-goto-menu
  99. '("Goto"
  100. ["Today" calendar-goto-today]
  101. ["Beginning of Week" calendar-beginning-of-week]
  102. ["End of Week" calendar-end-of-week]
  103. ["Beginning of Month" calendar-beginning-of-month]
  104. ["End of Month" calendar-end-of-month]
  105. ["Beginning of Year" calendar-beginning-of-year]
  106. ["End of Year" calendar-end-of-year]
  107. ["Other Date" calendar-goto-date]
  108. ["Day of Year" calendar-goto-day-of-year]
  109. ["ISO Week" calendar-iso-goto-week]
  110. ["ISO Date" calendar-iso-goto-date]
  111. ["Astronomical Date" calendar-astro-goto-day-number]
  112. ["Hebrew Date" calendar-hebrew-goto-date]
  113. ["Persian Date" calendar-persian-goto-date]
  114. ["Bahá'í Date" calendar-bahai-goto-date]
  115. ["Islamic Date" calendar-islamic-goto-date]
  116. ["Julian Date" calendar-julian-goto-date]
  117. ["Chinese Date" calendar-chinese-goto-date]
  118. ["Coptic Date" calendar-coptic-goto-date]
  119. ["Ethiopic Date" calendar-ethiopic-goto-date]
  120. ("Mayan Date"
  121. ["Next Tzolkin" calendar-mayan-next-tzolkin-date]
  122. ["Previous Tzolkin" calendar-mayan-previous-tzolkin-date]
  123. ["Next Haab" calendar-mayan-next-haab-date]
  124. ["Previous Haab" calendar-mayan-previous-haab-date]
  125. ["Next Round" calendar-mayan-next-round-date]
  126. ["Previous Round" calendar-mayan-previous-round-date])
  127. ["French Date" calendar-french-goto-date])
  128. "Key map for \"Goto\" menu in the calendar.")
  129. (defconst cal-menu-scroll-menu
  130. '("Scroll"
  131. ["Scroll Commands" nil :help "Commands that scroll the visible window"]
  132. ["Forward 1 Month" calendar-scroll-left]
  133. ["Forward 3 Months" calendar-scroll-left-three-months]
  134. ["Forward 1 Year" (calendar-scroll-left 12) :keys "4 C-v"]
  135. ["Backward 1 Month" calendar-scroll-right]
  136. ["Backward 3 Months" calendar-scroll-right-three-months]
  137. ["Backward 1 Year" (calendar-scroll-right 12) :keys "4 M-v"]
  138. "--"
  139. ["Motion Commands" nil :help "Commands that move point"]
  140. ["Forward 1 Day" calendar-forward-day]
  141. ["Forward 1 Week" calendar-forward-week]
  142. ["Forward 1 Month" calendar-forward-month]
  143. ["Forward 1 Year" calendar-forward-year]
  144. ["Backward 1 Day" calendar-backward-day]
  145. ["Backward 1 Week" calendar-backward-week]
  146. ["Backward 1 Month" calendar-backward-month]
  147. ["Backward 1 Year" calendar-backward-year])
  148. "Key map for \"Scroll\" menu in the calendar.")
  149. (declare-function x-popup-menu "menu.c" (position menu))
  150. (defmacro cal-menu-x-popup-menu (event title &rest body)
  151. "Call `x-popup-menu' at position EVENT, with TITLE and contents BODY.
  152. Signals an error if popups are unavailable."
  153. (declare (indent 2))
  154. `(if (display-popup-menus-p)
  155. (x-popup-menu ,event (list ,title (append (list ,title) ,@body)))
  156. (error "Popup menus are not available on this system")))
  157. (autoload 'diary-list-entries "diary-lib")
  158. ;; Autoloaded in diary-lib.
  159. (declare-function calendar-check-holidays "holidays" (date))
  160. (defun calendar-mouse-view-diary-entries (&optional date diary event)
  161. "Pop up menu of diary entries for mouse-selected date.
  162. Use optional DATE and alternative file DIARY. EVENT is the event
  163. that invoked this command. Shows holidays if `diary-show-holidays-flag'
  164. is non-nil."
  165. (interactive "i\ni\ne")
  166. (let* ((date (or date (calendar-cursor-to-date nil event)))
  167. (diary-file (or diary diary-file))
  168. (diary-list-include-blanks nil)
  169. (diary-entries (mapcar (lambda (x) (split-string (cadr x) "\n"))
  170. (diary-list-entries date 1 'list-only)))
  171. (holidays (if diary-show-holidays-flag
  172. (calendar-check-holidays date)))
  173. (title (format "Diary entries%s for %s"
  174. (if diary (format " from %s" diary) "")
  175. (calendar-date-string date)))
  176. (selection (cal-menu-x-popup-menu event title
  177. (mapcar (lambda (x) (list (concat " " x))) holidays)
  178. (if holidays
  179. (list "--shadow-etched-in" "--shadow-etched-in"))
  180. (if diary-entries
  181. (mapcar 'list (apply 'append diary-entries))
  182. '("None")))))
  183. (and selection (call-interactively selection))))
  184. (defun calendar-mouse-view-other-diary-entries (&optional event)
  185. "Pop up menu of diary entries from alternative file on mouse-selected date."
  186. (interactive "e")
  187. (calendar-mouse-view-diary-entries
  188. (calendar-cursor-to-date nil event)
  189. (read-file-name "Enter diary file name: " default-directory nil t)
  190. event))
  191. ;; In 22, the equivalent code gave an error when not called on a date,
  192. ;; but easymenu does not seem to allow this (?).
  193. ;; The ignore-errors is because `documentation' can end up calling
  194. ;; this in a non-calendar buffer where displayed-month is unbound. (Bug#3862)
  195. ;; This still has issues - bug#9976, so added derived-mode-p call.
  196. (defun cal-menu-set-date-title (menu)
  197. "Convert date of last event to title suitable for MENU."
  198. (when (derived-mode-p 'calendar-mode)
  199. (let ((date (ignore-errors (calendar-cursor-to-date nil last-input-event))))
  200. (if date
  201. (easy-menu-filter-return menu (calendar-date-string date t nil))
  202. (message "Not on a date!")
  203. nil))))
  204. (easy-menu-define cal-menu-context-mouse-menu nil
  205. "Pop up mouse menu for selected date in the calendar window."
  206. '("cal-menu-context-mouse-menu" :filter cal-menu-set-date-title
  207. "--"
  208. ["Holidays" calendar-cursor-holidays]
  209. ["Mark date" calendar-set-mark]
  210. ["Sunrise/sunset" calendar-sunrise-sunset]
  211. ["Other calendars" calendar-print-other-dates]
  212. ;; There was a bug (#447; fixed) with last-nonmenu-event and submenus.
  213. ;; These did not work if called without calendar window selected.
  214. ("Prepare LaTeX buffer"
  215. ["Daily (1 page)" cal-tex-cursor-day]
  216. ["Weekly (1 page)" cal-tex-cursor-week]
  217. ["Weekly (2 pages)" cal-tex-cursor-week2]
  218. ["Weekly (other style; 1 page)" cal-tex-cursor-week-iso]
  219. ["Weekly (yet another style; 1 page)" cal-tex-cursor-week-monday]
  220. ["Monthly" cal-tex-cursor-month]
  221. ["Monthly (landscape)" cal-tex-cursor-month-landscape]
  222. ["Yearly" cal-tex-cursor-year]
  223. ["Yearly (landscape)" cal-tex-cursor-year-landscape]
  224. ("Filofax styles"
  225. ["Filofax Daily (one-day-per-page)" cal-tex-cursor-filofax-daily]
  226. ["Filofax Weekly (2-weeks-at-a-glance)" cal-tex-cursor-filofax-2week]
  227. ["Filofax Weekly (week-at-a-glance)" cal-tex-cursor-filofax-week]
  228. ["Filofax Yearly" cal-tex-cursor-filofax-year]))
  229. ("Write HTML calendar"
  230. ["For selected month" cal-html-cursor-month]
  231. ["For selected year" cal-html-cursor-year])
  232. ["Diary entries" calendar-mouse-view-diary-entries :keys "d"]
  233. ["Insert diary entry" diary-insert-entry]
  234. ["Other diary file entries" calendar-mouse-view-other-diary-entries
  235. :keys "D"]))
  236. (easy-menu-define cal-menu-global-mouse-menu nil
  237. "Menu bound to a mouse event, not specific to the mouse-click location."
  238. '("Calendar"
  239. ["Scroll forward" calendar-scroll-left-three-months]
  240. ["Scroll backward" calendar-scroll-right-three-months]
  241. ["Mark diary entries" diary-mark-entries]
  242. ["List holidays" calendar-list-holidays]
  243. ["Mark holidays" calendar-mark-holidays]
  244. ["Unmark" calendar-unmark]
  245. ["Lunar phases" calendar-lunar-phases]
  246. ["Sunrise times for month" calendar-sunrise-sunset-month]
  247. ["Show diary" diary-show-all-entries]
  248. ["Exit calendar" calendar-exit]))
  249. ;; Undocumented and probably useless.
  250. (defvar cal-menu-load-hook nil
  251. "Hook run on loading of the `cal-menu' package.")
  252. (make-obsolete-variable 'cal-menu-load-hook
  253. "it will be removed in future." "23.1")
  254. (run-hooks 'cal-menu-load-hook)
  255. (provide 'cal-menu)
  256. ;; Local Variables:
  257. ;; coding: utf-8
  258. ;; End:
  259. ;;; cal-menu.el ends here