menus.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. // Copyright (C) 2003 Mooffie <mooffie@typo.co.il>
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  16. #include <config.h>
  17. #if HAVE_DIRENT_H
  18. # include <dirent.h> // for population the 'color scheme' sub menu.
  19. # define NAMLEN(dirent) strlen((dirent)->d_name)
  20. #else
  21. # define dirent direct
  22. # define NAMLEN(dirent) (dirent)->d_namlen
  23. # if HAVE_SYS_NDIR_H
  24. # include <sys/ndir.h>
  25. # endif
  26. # if HAVE_SYS_DIR_H
  27. # include <sys/dir.h>
  28. # endif
  29. # if HAVE_NDIR_H
  30. # include <ndir.h>
  31. # endif
  32. #endif
  33. #include <unistd.h>
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36. #include <algorithm> // sort
  37. #include "io.h" // get_cfg_filename
  38. #include "pathnames.h"
  39. #include "menus.h"
  40. #define STT_AUTOINDENT 1001
  41. #define STT_AUTOJUSTIFY 1002
  42. #define STT_ALTKBD 1003
  43. #define STT_SMRT 1004
  44. #define STT_ARABICSHAPING 1005
  45. #define STT_FORMATMARKS 1006
  46. #define STT_CURSORREPORT 1007
  47. #define STT_SPELLERLOADED 1008
  48. #define STT_READONLY 1009
  49. #define STT_BIGCURSOR 1010
  50. #define STT_GRAPHBOXES 1011
  51. #define STT_KEYFORKEYUNDO 1012
  52. #define STT_BIDI 1013
  53. #define STT_UNDERLINE 1014
  54. #define STT_SYNAUTO 1015
  55. #define STT_EOPUNIX 5001
  56. #define STT_EOPDOS 5002
  57. #define STT_EOPMAC 5003
  58. #define STT_EOPUNICODE 5004
  59. #define STT_RTLNSMASCII 5010
  60. #define STT_RTLNSMASIS 5011
  61. #define STT_RTLNSMHIDE 5012
  62. #define STT_MQFASCII 5020
  63. #define STT_MQFHIGHLIGHT 5021
  64. #define STT_MQFASIS 5022
  65. #define STT_WRAPWSPACE 5030
  66. #define STT_WRAPBREAK 5031
  67. #define STT_WRAPOFF 5032
  68. #define STT_DIRALGOUNICODE 5040
  69. #define STT_DIRALGOCTXSTRNG 5041
  70. #define STT_DIRALGOCTXRTL 5042
  71. #define STT_DIRALGOFLTR 5043
  72. #define STT_DIRALGOFRTL 5044
  73. #define STT_SCRLBRNONE 5060
  74. #define STT_SCRLBRLEFT 5061
  75. #define STT_SCRLBRRIGHT 5062
  76. #define STT_SYNNONE 5070
  77. #define STT_SYNHTML 5071
  78. #define STT_SYNEMAIL 5072
  79. #define STT_CRSVIS 5080
  80. #define STT_CRSLOG 5081
  81. #define STT_THEME_START 6000
  82. #define STT_THEME_END 6999
  83. #define CMD_CHR 100
  84. #define CMD_CRSVIS 101
  85. #define CMD_CRSLOG 102
  86. #define CMD_SETTHEME 103
  87. #define CMD_SETFLAG 104
  88. #define CMD_ENC 105
  89. #define CMD_INTERACTIVEENC 106
  90. #define CMD_HELP 120
  91. #define FLAG_FILE_ENCODING 1
  92. #define FLAG_DEFAULT_ENCODING 2
  93. #define HELP_ITEM N_("Get a detailed explanation for the above")
  94. #define HELP_TOPIC_ALGO_STR "\xD7\x90\xD7\x9C\xD7\x92\xD7\x95\xD7\xA8\xD7\x99\xD7\xAA\xD7\x9D\x20\xD7\x9C\xD7\xA7\xD7\x91\xD7\x99\xD7\xA2\xD7"
  95. #define HELP_TOPIC_POINTS_STR "\xD7\xA0\xD7\x99\xD7\xA7\xD7\x95\xD7\x93\x20\xD7\xA2\xD7\x91\xD7\xA8\xD7\x99"
  96. #define HELP_TOPIC_MAQAF_STR "\xD7\x9E\xD7\xA7\xD7\xA3"
  97. #define HELP_TOPIC_EOL_STR "\xD7\xA1\xD7\x95\xD7\xA4\xD7\x99\x20\xD7\xA9\xD7\x95\xD7\xA8\xD7\x95\xD7\xAA"
  98. #define HELP_TOPIC_CRSLV_STR "\xD7\xAA\xD7\xA0\xD7\x95\xD7\xA2\xD7\xAA\x20\xD7\xA1\xD7\x9E\xD7\x9F"
  99. #define HELP_TOPIC_SYNHLT_STR "\xD7\xA6\xD7\x91\xD7\x99\xD7\xA2\xD7\x94\x20\xD7\xAA\xD7\x97\xD7\x91\xD7\x99\xD7\xA8\xD7\x99\xD7\xAA"
  100. #define HELP_TOPIC_WRAP_STR "\xD7\xA7\xD7\x99\xD7\xA4\xD7\x95\xD7\x9C\x20\xD7\xA4\xD7\xA1\xD7\xA7\xD7\x90\xD7\x95\xD7\xAA"
  101. #define HELP_TOPIC_COLORS_STR "\xD7\xA2\xD7\xA8\xD7\x9B\xD7\x95\xD7\xAA\x20\xD7\xA6\xD7\x91\xD7\xA2\xD7\x99\xD7\x9D"
  102. #define HELP_TOPIC_ENCODING_STR "\xD7\xA7\xD7\x99\xD7\x93\xD7\x95\xD7\x93\x20\xD7\x94\xD7\xA7\xD7\x91\xD7\xA6\xD7\x99\xD7\x9D"
  103. #define HELP_TOPIC_EXTED_STR "\xD7\x94\xD7\xA4\xD7\xA2\xD7\x9C\xD7\xAA\x20\xD7\xA2\xD7\x95\xD7\xA8\xD7\x9A\x20\xD7\x97\xD7\x99\xD7\xA6\xD7\x95\xD7\xA0\xD7\x99"
  104. PulldownMenu FileMenu = {
  105. { "load_file", N_("~Open...") },
  106. { "insert_file", N_("~Insert file...") },
  107. { "-----------" },
  108. { "save_file", N_("~Save") },
  109. { "save_file_as", N_("Save ~As...") },
  110. { "write_selection_to_file", N_("~Write selection to...") },
  111. { "-----------" },
  112. { "external_edit_prompt", N_("Launch external ~editor...") },
  113. { "external_edit_no_prompt", N_("Launch external editor") },
  114. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_EXTED_STR },
  115. { "-----------" },
  116. { "change_directory", N_("Ch~dir...") },
  117. { "quit", N_("~Quit") },
  118. { NULL }
  119. };
  120. PulldownMenu MovementMenu = {
  121. { "move_beginning_of_buffer", N_("Move to the ~beginning of the buffer") },
  122. { "move_end_of_buffer", N_("Move to the ~end of the buffer") },
  123. { "go_to_line", N_("Go to a specific ~line") },
  124. { "move_last_modification", N_("Jump to the last ~modification point") },
  125. { "-----------" },
  126. { "key_left", N_("Move a character left") },
  127. { "key_right", N_("Move a character right") },
  128. { "move_previous_line", N_("Move to the previous line") },
  129. { "move_next_line", N_("Move to the next line") },
  130. { "move_backward_page", N_("Move to the previous page") },
  131. { "move_forward_page", N_("Move to the next page") },
  132. { "move_backward_char", N_("Move back a character") },
  133. { "move_forward_char", N_("Move forward a character") },
  134. //{ "move_beginning_of_line", N_("Move to the beginning of the current line") },
  135. { "key_home", N_("Move to the beginning of the current line") },
  136. { "move_end_of_line", N_("Move to the end of the current line") },
  137. { NULL }
  138. };
  139. PulldownMenu DeletionMenu = {
  140. { "delete_backward_char", N_("Delete the previous character") },
  141. { "delete_forward_char", N_("Delete the character the cursor is on") },
  142. { "delete_backward_word", N_("Delete to the start of the current or previous word") },
  143. { "delete_forward_word", N_("Delete to the end of the current or next word") },
  144. { "delete_paragraph", N_("Delete the current paragraph") },
  145. { "cut_end_of_paragraph", N_("Cut [to] end of paragraph") },
  146. { NULL }
  147. };
  148. PulldownMenu EditMenu = {
  149. { "undo", N_("~Undo") },
  150. { "redo", N_("~Redo") },
  151. { "toggle_key_for_key_undo", N_("Toggle ~key-for-key undo"), STT_KEYFORKEYUNDO },
  152. { "-----------" },
  153. { "copy", N_("~Copy") },
  154. { "cut", N_("Cu~t") },
  155. { "paste",N_("~Paste") },
  156. { "toggle_primary_mark", N_("Start/cancel selection") },
  157. { "-----------" },
  158. { "", N_("~Movement"), 0, MovementMenu },
  159. { "", N_("~Deletion"), 0, DeletionMenu },
  160. { "toggle_read_only", N_("Toggle read-only status of buffer"), STT_READONLY },
  161. { "-----------" },
  162. { "search_forward", N_("~Search...") },
  163. { "search_forward_next", N_("Search ~next") },
  164. { "-----------" },
  165. { "toggle_auto_justify", N_("Toggle auto-~justify"), STT_AUTOJUSTIFY },
  166. { "justify", N_("Justify the current or next paragraph") },
  167. { "change_justification_column", N_("Change justify column...") },
  168. { "-----------" },
  169. { "toggle_auto_indent", N_("Toggle auto-~indent"), STT_AUTOINDENT },
  170. { "change_tab_width", N_("Change the TAB character size...") },
  171. { NULL }
  172. };
  173. PulldownMenu EolMenu = {
  174. { "set_eops_unix", N_("~Unix (LF)"), STT_EOPUNIX },
  175. { "set_eops_dos", N_("~DOS/Windows (CR,LF)"), STT_EOPDOS },
  176. { "set_eops_mac", N_("~Macintosh (CR)"), STT_EOPMAC },
  177. { "set_eops_unicode", N_("U~nicode PS (U+2029)"), STT_EOPUNICODE },
  178. { "-----------" },
  179. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_EOL_STR },
  180. { NULL }
  181. };
  182. #define ICONVREQ N_("(requires iconv)")
  183. PulldownMenu CyrillicEncodingsMenu = {
  184. { "xxx", N_("(Cyrillic) ~Windows-1251"), 0, 0, CMD_ENC, 0, "CP1251", ICONVREQ },
  185. { "xxx", N_("(Cyrillic) ~ISO-8859-5"), 0, 0, CMD_ENC, 0, "ISO-8859-5", ICONVREQ },
  186. { "xxx", N_("(Cyrillic) KOI8-~R"), 0, 0, CMD_ENC, 0, "KOI8-R", ICONVREQ },
  187. { "xxx", N_("(Cyrillic) KOI8-~U"), 0, 0, CMD_ENC, 0, "KOI8-U", ICONVREQ },
  188. { "xxx", N_("(Cyrillic) IBM-866"), 0, 0, CMD_ENC, 0, "CP866", ICONVREQ },
  189. { "xxx", N_("(Cyrillic) IBM-855"), 0, 0, CMD_ENC, 0, "CP855", ICONVREQ },
  190. { "xxx", N_("(Cyrillic) ISO-IR-111"), 0, 0, CMD_ENC, 0, "ISO-IR-111", ICONVREQ },
  191. { "xxx", N_("(Cyrillic) ~MacCyrillic"), 0, 0, CMD_ENC, 0, "MACCYRILLIC", ICONVREQ },
  192. { NULL }
  193. };
  194. PulldownMenu UnicodeEncodingsMenu = {
  195. { "xxx", N_("UTF-1~6"), 0, 0, CMD_ENC, 0, "UTF-16", ICONVREQ },
  196. { "xxx", N_("UTF-16 Big Endian"), 0, 0, CMD_ENC, 0, "UTF-16BE", ICONVREQ },
  197. { "xxx", N_("UTF-16 Little Endian"), 0, 0, CMD_ENC, 0, "UTF-16LE", ICONVREQ },
  198. { "xxx", N_("UTF-~32"), 0, 0, CMD_ENC, 0, "UTF-32", ICONVREQ },
  199. { "xxx", N_("UTF-32 Big Endian"), 0, 0, CMD_ENC, 0, "UTF-32BE", ICONVREQ },
  200. { "xxx", N_("UTF-32 Little Endian"), 0, 0, CMD_ENC, 0, "UTF-32LE", ICONVREQ },
  201. { "xxx", N_("UTF-~7"), 0, 0, CMD_ENC, 0, "UTF-7", ICONVREQ },
  202. { "-----------" },
  203. { "xxx", N_("UCS-2"), 0, 0, CMD_ENC, 0, "UCS-2", ICONVREQ },
  204. { "xxx", N_("UCS-2 Big Endian"), 0, 0, CMD_ENC, 0, "UCS-2BE", ICONVREQ },
  205. { "xxx", N_("UCS-2 Little Endian"), 0, 0, CMD_ENC, 0, "UCS-2BE", ICONVREQ },
  206. { "xxx", N_("UCS-4"), 0, 0, CMD_ENC, 0, "UCS-4", ICONVREQ },
  207. { "xxx", N_("UCS-4 Big Endian"), 0, 0, CMD_ENC, 0, "UCS-4BE", ICONVREQ },
  208. { "xxx", N_("UCS-4 Little Endian"), 0, 0, CMD_ENC, 0, "UCS-4LE", ICONVREQ },
  209. { NULL }
  210. };
  211. PulldownMenu EncodingsMenu = {
  212. { "xxx", N_("~UTF-8"), 0, 0, CMD_ENC, 0, "UTF-8" },
  213. { "-----------" },
  214. { "xxx", N_("(Hebrew) ~ISO-8859-8"), 0, 0, CMD_ENC, 0, "ISO-8859-8" },
  215. { "xxx", N_("(Hebrew) ~Windows-1255"), 0, 0, CMD_ENC, 0, "CP1255", ICONVREQ },
  216. { "xxx", N_("(Hebrew) MacHebrew"), 0, 0, CMD_ENC, 0, "MACHEBREW", ICONVREQ },
  217. { "xxx", N_("(Hebrew) IBM-862 (~Dos)"), 0, 0, CMD_ENC, 0, "CP862", ICONVREQ },
  218. { "-----------" },
  219. { "xxx", N_("(Arabic) ISO-8859-6"), 0, 0, CMD_ENC, 0, "ISO-8859-6", ICONVREQ },
  220. { "xxx", N_("(~Arabic) Windows-1256"), 0, 0, CMD_ENC, 0, "CP1256", ICONVREQ },
  221. { "xxx", N_("(Arabic) MacArabic"), 0, 0, CMD_ENC, 0, "MACARABIC", ICONVREQ },
  222. { "xxx", N_("(Arabic) IBM-864 (Dos)"), 0, 0, CMD_ENC, 0, "CP864", ICONVREQ },
  223. { "xxx", N_("(Farsi) MacFarsi"), 0, 0, CMD_ENC, 0, "MACFARSI", ICONVREQ },
  224. { "xxx", N_("~Cyrillic"), 0, CyrillicEncodingsMenu },
  225. { "xxx", N_("~More Unicodes"), 0, UnicodeEncodingsMenu },
  226. { "-----------" },
  227. { "xxx", N_("Other..."), 0, 0, CMD_INTERACTIVEENC },
  228. { NULL }
  229. };
  230. PulldownMenu CantillationsCharMenu = {
  231. { "xxx", N_("ETNAHTA (U+0591)"), 0, 0, CMD_CHR, 0x0591 },
  232. { "xxx", N_("SEGOL (U+0592)"), 0, 0, CMD_CHR, 0x0592 },
  233. { "xxx", N_("SHALSHELET (U+0593)"), 0, 0, CMD_CHR, 0x0593 },
  234. { "xxx", N_("ZAQEF QATAN (U+0594)"), 0, 0, CMD_CHR, 0x0594 },
  235. { "xxx", N_("ZAQEF GADOL (U+0595)"), 0, 0, CMD_CHR, 0x0595 },
  236. { "xxx", N_("TIPEHA (U+0596)"), 0, 0, CMD_CHR, 0x0596 },
  237. { "xxx", N_("REVIA (U+0597)"), 0, 0, CMD_CHR, 0x0597 },
  238. { "xxx", N_("ZARQA (U+0598)"), 0, 0, CMD_CHR, 0x0598 },
  239. { "xxx", N_("PASHTA (U+0599)"), 0, 0, CMD_CHR, 0x0599 },
  240. { "xxx", N_("YETIV (U+059A)"), 0, 0, CMD_CHR, 0x059A },
  241. { "xxx", N_("TEVIR (U+059B)"), 0, 0, CMD_CHR, 0x059B },
  242. { "xxx", N_("GERESH (U+059C)"), 0, 0, CMD_CHR, 0x059C },
  243. { "xxx", N_("GERESH MUQDAM (U+059D)"), 0, 0, CMD_CHR, 0x059D },
  244. { "xxx", N_("GERSHAYIM (U+059E)"), 0, 0, CMD_CHR, 0x059E },
  245. { "xxx", N_("QARNEY PARA (U+059F)"), 0, 0, CMD_CHR, 0x059F },
  246. { "xxx", N_("TELISHA GEDOLA (U+05A0)"), 0, 0, CMD_CHR, 0x05A0 },
  247. { "xxx", N_("PAZER (U+05A1)"), 0, 0, CMD_CHR, 0x05A1 },
  248. { "xxx", N_("MUNAH (U+05A3)"), 0, 0, CMD_CHR, 0x05A3 },
  249. { "xxx", N_("MAHAPAKH (U+05A4)"), 0, 0, CMD_CHR, 0x05A4 },
  250. { "xxx", N_("MERKHA (U+05A5)"), 0, 0, CMD_CHR, 0x05A5 },
  251. { "xxx", N_("MERKHA KEFULA (U+05A6)"), 0, 0, CMD_CHR, 0x05A6 },
  252. { "xxx", N_("DARGA (U+05A7)"), 0, 0, CMD_CHR, 0x05A7 },
  253. { "xxx", N_("QADMA (U+05A8)"), 0, 0, CMD_CHR, 0x05A8 },
  254. { "xxx", N_("TELISHA QETANA (U+05A9)"), 0, 0, CMD_CHR, 0x05A9 },
  255. { "xxx", N_("YERAH BEN YOMO (U+05AA)"), 0, 0, CMD_CHR, 0x05AA },
  256. { "xxx", N_("OLE (U+05AB)"), 0, 0, CMD_CHR, 0x05AB },
  257. { "xxx", N_("ILUY (U+05AC)"), 0, 0, CMD_CHR, 0x05AC },
  258. { "xxx", N_("DEHI (U+05AD)"), 0, 0, CMD_CHR, 0x05AD },
  259. { "xxx", N_("ZINOR (U+05AE)"), 0, 0, CMD_CHR, 0x05AE },
  260. { "xxx", N_("MASORA CIRCLE (U+05AF)"), 0, 0, CMD_CHR, 0x05AF },
  261. { "-----------" },
  262. { "xxx", N_("METEG (U+05BD)"), 0, 0, CMD_CHR, UNI_HEB_METEG },
  263. { "xxx", N_("PASEQ (U+05C0)"), 0, 0, CMD_CHR, UNI_HEB_PASEQ },
  264. { "xxx", N_("SOF PASUQ (U+05C3)"), 0, 0, CMD_CHR, UNI_HEB_SOF_PASUQ },
  265. { NULL }
  266. };
  267. PulldownMenu ArabicCharMenu = {
  268. { "xxx", N_("~FATHATAN (U+064B)"), 0, 0, CMD_CHR, 0x064B },
  269. { "xxx", N_("DAMMATAN (U+064C)"), 0, 0, CMD_CHR, 0x064C },
  270. { "xxx", N_("~KASRATAN (U+064D)"), 0, 0, CMD_CHR, 0x064D },
  271. { "xxx", N_("FATHA (U+064E)"), 0, 0, CMD_CHR, 0x064E },
  272. { "xxx", N_("~DAMMA (U+064F)"), 0, 0, CMD_CHR, 0x064F },
  273. { "xxx", N_("KASRA (U+0650)"), 0, 0, CMD_CHR, 0x0650 },
  274. { "xxx", N_("~SHADDA (U+0651)"), 0, 0, CMD_CHR, 0x0651 },
  275. { "xxx", N_("SUKUN (U+0652)"), 0, 0, CMD_CHR, 0x0652 },
  276. { "xxx", N_("SUPERSCRIPT ALEF (U+0670)"), 0, 0, CMD_CHR, 0x0670 },
  277. { "-----------" },
  278. { "xxx", N_("ZWJ, ZERO WIDTH JOINER (U+200D)"), 0, 0, CMD_CHR, 0x200D },
  279. { "xxx", N_("ZWNJ, ZERO WIDTH NON-JOINER (U+200C)"), 0, 0, CMD_CHR, 0x200C },
  280. { NULL }
  281. };
  282. PulldownMenu InsertCharMenu = {
  283. { "insert_maqaf", N_("Hebrew ~maqaf (U+05BE)") },
  284. { "-----------" },
  285. { "xxx", N_("~LRM, LEFT-TO-RIGHT MARK (U+200E)"), 0, 0, CMD_CHR, UNI_LRM },
  286. { "xxx", N_("~RLM, RIGHT-TO-LEFT MARK (U+200F)"), 0, 0, CMD_CHR, UNI_RLM },
  287. { "xxx", N_("LRE, LEFT-TO-RIGHT EMBEDDING (U+202A)"), 0, 0, CMD_CHR, UNI_LRE },
  288. { "xxx", N_("RLE, RIGHT-TO-LEFT EMBEDDING (U+202B)"), 0, 0, CMD_CHR, UNI_RLE },
  289. { "xxx", N_("PDF, POP DIRECTIONAL FORMATTING (U+202C)"), 0, 0, CMD_CHR, UNI_PDF },
  290. { "xxx", N_("LRO, LEFT-TO-RIGHT OVERRIDE (U+202D)"), 0, 0, CMD_CHR, UNI_LRO },
  291. { "xxx", N_("RLO, RIGHT-TO-LEFT OVERRIDE (U+202E)"), 0, 0, CMD_CHR, UNI_RLO },
  292. { "-----------" },
  293. { "xxx", N_("~SHEVA (U+05B0)"), 0, 0, CMD_CHR, UNI_HEB_SHEVA },
  294. { "xxx", N_("HATAF SEGOL (U+05B~1)"), 0, 0, CMD_CHR, UNI_HEB_HATAF_SEGOL },
  295. { "xxx", N_("HATAF PATAH (U+05B~2)"), 0, 0, CMD_CHR, UNI_HEB_HATAF_PATAH },
  296. { "xxx", N_("HATAF QAMATS (U+05B~3)"), 0, 0, CMD_CHR, UNI_HEB_HATAF_QAMATS },
  297. { "xxx", N_("~HIRIQ (U+05B4)"), 0, 0, CMD_CHR, UNI_HEB_HIRIQ },
  298. { "xxx", N_("TS~ERE (U+05B5)"), 0, 0, CMD_CHR, UNI_HEB_TSERE },
  299. { "xxx", N_("SE~GOL (U+05B6)"), 0, 0, CMD_CHR, UNI_HEB_SEGOL },
  300. { "xxx", N_("~PATAH (U+05B7)"), 0, 0, CMD_CHR, UNI_HEB_PATAH },
  301. { "xxx", N_("~QAMATS (U+05B8)"), 0, 0, CMD_CHR, UNI_HEB_QAMATS },
  302. { "xxx", N_("H~OLAM (U+05B9)"), 0, 0, CMD_CHR, UNI_HEB_HOLAM },
  303. { "xxx", N_("Q~UBUTS (U+05BB)"), 0, 0, CMD_CHR, UNI_HEB_QUBUTS },
  304. { "xxx", N_("~DAGESH OR MAPIQ (U+05BC)"), 0, 0, CMD_CHR, UNI_HEB_DAGESH_OR_MAPIQ },
  305. { "xxx", N_("~RAFE (U+05BF)"), 0, 0, CMD_CHR, UNI_HEB_RAFE },
  306. { "xxx", N_("SHIN DOT (U+05C1)"), 0, 0, CMD_CHR, UNI_HEB_SHIN_DOT },
  307. { "xxx", N_("SIN DOT (U+05C2)"), 0, 0, CMD_CHR, UNI_HEB_SIN_DOT },
  308. { "-----------" },
  309. { "xxx", N_("GERESH (U+05F3)"), 0, 0, CMD_CHR, UNI_HEB_GERESH },
  310. { "xxx", N_("GERSHAYIM (U+05F4)"), 0, 0, CMD_CHR, UNI_HEB_GERSHAYIM },
  311. { "xxx", N_("NO-BREAK SPACE (U+00A0)"), 0, 0, CMD_CHR, 0x00A0 },
  312. { "xxx", N_("ZERO WIDTH SPACE(U+200B)"), 0, 0, CMD_CHR, 0x200B },
  313. { "-----------" },
  314. { "xxx", N_("~Cantillations"), 0, CantillationsCharMenu },
  315. { "xxx", N_("~Arabic"), 0, ArabicCharMenu },
  316. };
  317. PulldownMenu CharactersUtilsMenu = {
  318. { "show_character_code", N_("Print ~Unicode and UTF-8 value") },
  319. { "show_character_info", N_("Print the corresponding Unicode~Data.txt line") },
  320. { "xxx", N_("~Insert a Unicode character from the list"), 0, InsertCharMenu },
  321. { "insert_unicode_char", N_("Insert a Unicode character using its ~code") },
  322. { "-----------" },
  323. { "xxx", N_("Set the ~encoding used for saving this file"), 0, EncodingsMenu, CMD_SETFLAG, FLAG_FILE_ENCODING },
  324. { "xxx", N_("Set the de~fault encoding"), 0, EncodingsMenu, CMD_SETFLAG, FLAG_DEFAULT_ENCODING, 0,
  325. N_("The \"default encoding\" is used when loading files and when creating new files.") },
  326. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_ENCODING_STR },
  327. { "-----------" },
  328. { "toggle_alt_kbd", N_("Toogle ~Hebrew keyboard emulation"), STT_ALTKBD },
  329. { "toggle_smart_typing", N_("Toggle ~smart-typing mode"), STT_SMRT },
  330. { "set_translate_next_char", N_("~Translate next character") },
  331. { "-----------" },
  332. { "toggle_eops", N_("Change end-of-~line type"), 0, EolMenu },
  333. { NULL }
  334. };
  335. PulldownMenu DirAlgoMenu = {
  336. { "set_dir_algo_unicode", N_("~Unicode's TR #9"), STT_DIRALGOUNICODE },
  337. { "set_dir_algo_context_strong", N_("Contextual-~strong"), STT_DIRALGOCTXSTRNG },
  338. { "set_dir_algo_context_rtl", N_("~Contextual-rtl"), STT_DIRALGOCTXRTL },
  339. { "set_dir_algo_force_ltr", N_("Force ~LTR"), STT_DIRALGOFLTR },
  340. { "set_dir_algo_force_rtl", N_("Force ~RTL"), STT_DIRALGOFRTL },
  341. { "-----------" },
  342. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_ALGO_STR },
  343. { NULL }
  344. };
  345. PulldownMenu CursorMovementMenu = {
  346. { "toggle_visual_cursor_movement", N_("~Logical"), STT_CRSLOG, 0, CMD_CRSLOG, 0,
  347. N_("Logical movement: cursor follows the buffer order") },
  348. { "toggle_visual_cursor_movement", N_("~Visual"), STT_CRSVIS, 0, CMD_CRSVIS, 0,
  349. N_("Visual movement: cursor follows what you see on screen") },
  350. { "-----------" },
  351. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_CRSLV_STR },
  352. { NULL }
  353. };
  354. PulldownMenu BiDiMenu = {
  355. { "toggle_bidi", N_("Toggle the ~BiDi algorithm"), STT_BIDI },
  356. { "toggle_dir_algo", N_("Select base-directionality ~algorithm"), 0, DirAlgoMenu },
  357. { "toggle_visual_cursor_movement", N_("~Cursor movement"), 0, CursorMovementMenu },
  358. { NULL }
  359. };
  360. PulldownMenu SpellerMenu = {
  361. { "spell_check_all", N_("Spell check all ~document") },
  362. { "spell_check_forward", N_("Spell check ~from cursor onward") },
  363. { "spell_check_word", N_("Spell check ~word under cursor") },
  364. { "-----------" },
  365. { "load_unload_speller", N_("Explicitly ~load/unload the speller process..."), STT_SPELLERLOADED },
  366. { NULL }
  367. };
  368. PulldownMenu WrapMenu = {
  369. { "set_wrap_type_at_white_space",
  370. N_("Wrap lines, do not break ~words"), STT_WRAPWSPACE },
  371. { "set_wrap_type_anywhere",
  372. N_("Wrap lines, ~break words"), STT_WRAPBREAK },
  373. { "set_wrap_type_off",
  374. N_("Do ~not wrap lines"), STT_WRAPOFF },
  375. { "-----------" },
  376. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_WRAP_STR },
  377. { NULL }
  378. };
  379. PulldownMenu rtlnsmMenu = {
  380. { "set_rtl_nsm_transliterated",
  381. N_("Display Hebrew/Arabic points as highlighted ~ASCII characters"), STT_RTLNSMASCII },
  382. { "set_rtl_nsm_asis",
  383. N_("Display Hebrew/Arabic points as-~is (for capable terminals)"), STT_RTLNSMASIS },
  384. { "set_rtl_nsm_off",
  385. N_("~Hide Hebrew/Arabic points"), STT_RTLNSMHIDE },
  386. { "-----------" },
  387. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_POINTS_STR },
  388. { NULL }
  389. };
  390. PulldownMenu MaqafMenu = {
  391. { "set_maqaf_display_transliterated",
  392. N_("Display the maqaf as ~ASCII dash"), STT_MQFASCII },
  393. { "set_maqaf_display_asis",
  394. N_("Display the maqaf as-~is (for capable terminals)"),
  395. STT_MQFASIS },
  396. { "set_maqaf_display_highlighted",
  397. N_("~Highlight the maqaf"), STT_MQFHIGHLIGHT },
  398. { "-----------" },
  399. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_MAQAF_STR },
  400. { NULL }
  401. };
  402. PulldownMenu ScrollbarMenu = {
  403. { "menu_set_scrollbar_none", N_("~Off"), STT_SCRLBRNONE },
  404. { "menu_set_scrollbar_left", N_("~Left"), STT_SCRLBRLEFT },
  405. { "menu_set_scrollbar_right", N_("~Right"), STT_SCRLBRRIGHT },
  406. { NULL }
  407. };
  408. PulldownMenu HighlightMenu = {
  409. { "toggle_syntax_auto_detection", N_("Syntax ~Auto-Detection"), STT_SYNAUTO },
  410. { "-----------" },
  411. { "menu_set_syn_hlt_none", N_("~None"), STT_SYNNONE },
  412. { "menu_set_syn_hlt_html", N_("~HTML"), STT_SYNHTML },
  413. { "menu_set_syn_hlt_email", N_("~Email"), STT_SYNEMAIL },
  414. { "-----------" },
  415. { "toggle_underline", N_("Highlight *~text* and _text_"), STT_UNDERLINE },
  416. { "-----------" },
  417. { "xxx", HELP_ITEM, 0, 0, CMD_HELP, 0, HELP_TOPIC_SYNHLT_STR },
  418. { NULL }
  419. };
  420. #define MAX_COLOR_SCHEMES 100
  421. MenuItem ColorScheme[MAX_COLOR_SCHEMES] = {
  422. { "set_default_theme", N_("~Default (transparent)"), STT_THEME_START, 0, 0, 0, "default.thm" },
  423. { "-----------" },
  424. };
  425. PulldownMenu DisplayMenu = {
  426. { "toggle_formatting_marks", N_("Toggle display of ~formatting marks"), STT_FORMATMARKS },
  427. { "toggle_arabic_shaping", N_("Toggle ~Arabic shaping"), STT_ARABICSHAPING },
  428. { "xxx_toggle_rtl_nsm", N_("Change display of Hebrew/Arabic ~points"), 0, rtlnsmMenu },
  429. { "xxx_toggle_maqaf", N_("Change display of the Hebrew ~maqaf"), 0, MaqafMenu },
  430. { "-----------" },
  431. { "toggle_wrap", N_("Change ~wrap style"), 0, WrapMenu },
  432. { "xxx", N_("~Scrollbar"), 0, ScrollbarMenu },
  433. { "toggle_cursor_position_report", N_("Toggle display of cursor p~osition"), STT_CURSORREPORT },
  434. { "change_scroll_step", N_("Change the scroll step...") },
  435. { "-----------" },
  436. { "xxx", N_("~Color scheme"), 0, ColorScheme },
  437. { "-----------" },
  438. { "xxx", N_("Syntax ~Highlighting"), 0, HighlightMenu },
  439. { "-----------" },
  440. { "refresh_and_center", N_("~Repaint the screen and center the line") },
  441. { "toggle_graphical_boxes", N_("Toggle use of ~graphical characters for frames"), STT_GRAPHBOXES },
  442. { "toggle_big_cursor", N_("Toggle ~big cursor"), STT_BIGCURSOR },
  443. { NULL }
  444. };
  445. PulldownMenu HelpMenu = {
  446. { "help", N_("User ~Manual") },
  447. { "describe_key", N_("~Describe key...") },
  448. { NULL }
  449. };
  450. MenubarMenu mainMenu = {
  451. { "File", FileMenu },
  452. { "Edit", EditMenu },
  453. { "Characters", CharactersUtilsMenu },
  454. { "Display", DisplayMenu },
  455. { "BiDi", BiDiMenu },
  456. { "Speller", SpellerMenu },
  457. { "Help", HelpMenu },
  458. { NULL }
  459. };
  460. ////////////////////////////// MMPopupMenu /////////////////////////////////
  461. class MMPopupMenu : public PopupMenu {
  462. Editor *editor;
  463. EditBox *editbox;
  464. public:
  465. MMPopupMenu(Editor *aEditor, EditBox *aEditbox,
  466. PopupMenu *aParent, PulldownMenu aMnu);
  467. protected:
  468. virtual void show_hint(const char *hint);
  469. virtual void clear_other_popups();
  470. virtual Dispatcher *get_primary_target();
  471. virtual Dispatcher *get_secondary_target();
  472. virtual PopupMenu *create_popupmenu(PopupMenu *aParent, PulldownMenu mnu);
  473. virtual bool get_item_state(int id);
  474. virtual void do_command(unsigned long parameter1, unsigned long parameter2,
  475. const char *parameter3);
  476. };
  477. MMPopupMenu::MMPopupMenu(Editor *aEditor, EditBox *aEditbox,
  478. PopupMenu *aParent, PulldownMenu aMnu)
  479. : PopupMenu(aParent, NULL)
  480. {
  481. editor = aEditor;
  482. editbox = aEditbox;
  483. init(aMnu);
  484. }
  485. void MMPopupMenu::show_hint(const char *hint)
  486. {
  487. editor->show_hint(hint);
  488. }
  489. void MMPopupMenu::clear_other_popups()
  490. {
  491. editor->refresh(true);
  492. }
  493. Dispatcher *MMPopupMenu::get_primary_target()
  494. {
  495. return editor;
  496. }
  497. Dispatcher *MMPopupMenu::get_secondary_target()
  498. {
  499. return editbox;
  500. }
  501. PopupMenu *MMPopupMenu::create_popupmenu(PopupMenu *aParent, PulldownMenu mnu)
  502. {
  503. return new MMPopupMenu(editor, editbox, aParent, mnu);
  504. }
  505. bool MMPopupMenu::get_item_state(int id)
  506. {
  507. switch (id) {
  508. case STT_AUTOINDENT: return editbox->is_auto_indent();
  509. case STT_AUTOJUSTIFY: return editbox->is_auto_justify();
  510. case STT_ALTKBD: return editbox->get_alt_kbd();
  511. case STT_SMRT: return editbox->is_smart_typing();
  512. case STT_ARABICSHAPING: return terminal::do_arabic_shaping;
  513. case STT_FORMATMARKS: return editbox->has_formatting_marks();
  514. case STT_CURSORREPORT: return editor->is_cursor_position_report();
  515. case STT_READONLY: return editbox->is_read_only();
  516. case STT_BIGCURSOR: return editor->is_big_cursor();
  517. case STT_GRAPHBOXES: return terminal::graphical_boxes;
  518. case STT_KEYFORKEYUNDO: return editbox->is_key_for_key_undo();
  519. case STT_BIDI: return editbox->is_bidi_enabled();
  520. case STT_EOPUNIX: return editbox->get_dominant_eop() == eopUnix;
  521. case STT_EOPDOS: return editbox->get_dominant_eop() == eopDOS;
  522. case STT_EOPMAC: return editbox->get_dominant_eop() == eopMac;
  523. case STT_EOPUNICODE: return editbox->get_dominant_eop() == eopUnicode;
  524. case STT_RTLNSMASCII: return editbox->get_rtl_nsm_display() == EditBox::rtlnsmTransliterated;
  525. case STT_RTLNSMASIS: return editbox->get_rtl_nsm_display() == EditBox::rtlnsmAsis;
  526. case STT_RTLNSMHIDE: return editbox->get_rtl_nsm_display() == EditBox::rtlnsmOff;
  527. case STT_MQFASCII: return editbox->get_maqaf_display() == EditBox::mqfTransliterated;
  528. case STT_MQFHIGHLIGHT: return editbox->get_maqaf_display() == EditBox::mqfHighlighted;
  529. case STT_MQFASIS: return editbox->get_maqaf_display() == EditBox::mqfAsis;
  530. case STT_WRAPOFF: return editbox->get_wrap_type() == EditBox::wrpOff;
  531. case STT_WRAPBREAK: return editbox->get_wrap_type() == EditBox::wrpAnywhere;
  532. case STT_WRAPWSPACE: return editbox->get_wrap_type() == EditBox::wrpAtWhiteSpace;
  533. case STT_DIRALGOUNICODE: return editbox->get_dir_algo() == algoUnicode;
  534. case STT_DIRALGOCTXSTRNG: return editbox->get_dir_algo() == algoContextStrong;
  535. case STT_DIRALGOCTXRTL: return editbox->get_dir_algo() == algoContextRTL;
  536. case STT_DIRALGOFLTR: return editbox->get_dir_algo() == algoForceLTR;
  537. case STT_DIRALGOFRTL: return editbox->get_dir_algo() == algoForceRTL;
  538. case STT_SPELLERLOADED: return editor->is_speller_loaded();
  539. case STT_SCRLBRNONE: return editor->get_scrollbar_pos() == Editor::scrlbrNone;
  540. case STT_SCRLBRLEFT: return editor->get_scrollbar_pos() == Editor::scrlbrLeft;
  541. case STT_SCRLBRRIGHT: return editor->get_scrollbar_pos() == Editor::scrlbrRight;
  542. case STT_SYNNONE: return editbox->get_syn_hlt() == EditBox::synhltOff;
  543. case STT_SYNHTML: return editbox->get_syn_hlt() == EditBox::synhltHTML;
  544. case STT_SYNEMAIL: return editbox->get_syn_hlt() == EditBox::synhltEmail;
  545. case STT_UNDERLINE: return editbox->get_underline();
  546. case STT_SYNAUTO: return editor->get_syntax_auto_detection();
  547. case STT_CRSVIS: return editbox->get_visual_cursor_movement();
  548. case STT_CRSLOG: return !editbox->get_visual_cursor_movement();
  549. default:
  550. if (id >= STT_THEME_START && id <= STT_THEME_END) {
  551. int i = 0;
  552. while (ColorScheme[i].action) {
  553. if (ColorScheme[i].state_id == id)
  554. return STREQ(ColorScheme[i].command_parameter3, editor->get_theme_name());
  555. i++;
  556. }
  557. return false;
  558. }
  559. else {
  560. return false;
  561. }
  562. }
  563. }
  564. void MMPopupMenu::do_command(unsigned long parameter1, unsigned long parameter2,
  565. const char *parameter3)
  566. {
  567. static int flag;
  568. switch (parameter1) {
  569. case CMD_SETTHEME:
  570. editor->set_theme(parameter3);
  571. break;
  572. case CMD_CHR:
  573. editbox->insert_char((unichar)parameter2);
  574. break;
  575. case CMD_CRSVIS:
  576. editbox->set_visual_cursor_movement(true);
  577. break;
  578. case CMD_CRSLOG:
  579. editbox->set_visual_cursor_movement(false);
  580. break;
  581. case CMD_HELP:
  582. editor->show_help_topic(parameter3);
  583. break;
  584. case CMD_ENC:
  585. if (flag == FLAG_DEFAULT_ENCODING)
  586. editor->set_default_encoding(parameter3);
  587. else
  588. editor->set_encoding(parameter3);
  589. break;
  590. case CMD_INTERACTIVEENC:
  591. editor->menu_set_encoding(flag == FLAG_DEFAULT_ENCODING);
  592. break;
  593. case CMD_SETFLAG:
  594. flag = parameter2;
  595. break;
  596. }
  597. }
  598. /////////////////////////////// MMMenubar //////////////////////////////////
  599. class MMMenubar : public Menubar {
  600. Editor *editor;
  601. EditBox *editbox;
  602. void populate_color_scheme_menu();
  603. public:
  604. MMMenubar(Editor *, EditBox *);
  605. virtual void refresh_screen();
  606. virtual PopupMenu *create_popupmenu(PulldownMenu mnu);
  607. };
  608. MMMenubar::MMMenubar(Editor *aEditor, EditBox *aEditbox)
  609. : Menubar()
  610. {
  611. editor = aEditor;
  612. editbox = aEditbox;
  613. populate_color_scheme_menu();
  614. init(mainMenu);
  615. }
  616. void MMMenubar::refresh_screen()
  617. {
  618. editor->refresh(true);
  619. }
  620. PopupMenu *MMMenubar::create_popupmenu(PulldownMenu mnu)
  621. {
  622. return new MMPopupMenu(editor, editbox, NULL, mnu);
  623. }
  624. //////////////////// Populate the ColorScheme Menu /////////////////////////
  625. bool operator<(const MenuItem &a, const MenuItem &b)
  626. {
  627. u8string as = a.label, bs = b.label;
  628. return strcmp(as.erase_char('~').toupper_ascii().c_str(),
  629. bs.erase_char('~').toupper_ascii().c_str()) < 0;
  630. }
  631. static u8string get_color_scheme_title(const char *filename)
  632. {
  633. #define MAX_LINE_LEN 1024
  634. FILE *fp;
  635. if ((fp = fopen(filename, "r")) != NULL) {
  636. char line[MAX_LINE_LEN];
  637. int line_no = 0;
  638. while (fgets(line, MAX_LINE_LEN, fp) && line_no++ < 5) {
  639. const char *pos;
  640. if ((pos = strstr(line, "Title:")) != NULL) {
  641. fclose(fp);
  642. return u8string(pos + strlen("Title:")).trim();
  643. }
  644. }
  645. fclose(fp);
  646. }
  647. return "";
  648. #undef MAX_LINE_LEN
  649. }
  650. static bool theme_already_listed(const char *theme_name)
  651. {
  652. int i = 0;
  653. while (ColorScheme[i].action) {
  654. if (ColorScheme[i].command_parameter3 &&
  655. STREQ(ColorScheme[i].command_parameter3, theme_name))
  656. return true;
  657. i++;
  658. }
  659. return false;
  660. }
  661. void MMMenubar::populate_color_scheme_menu()
  662. {
  663. int menu_pos = 0;
  664. while (ColorScheme[menu_pos].action) menu_pos++;
  665. int menu_start = menu_pos;
  666. for (int i = 0; i < 2; i++) {
  667. DIR *dir;
  668. dirent *ent;
  669. const char *dirstr = get_cfg_filename((i == 0) ? USER_THEMES_DIR : SYSTEM_THEMES_DIR);
  670. if ((dir = opendir(dirstr)) == NULL)
  671. continue;
  672. while ((ent = readdir(dir)) != NULL) {
  673. const char *d_name = ent->d_name;
  674. u8string desc;
  675. desc.cformat("File: %s%s", dirstr, d_name);
  676. if (STREQ(d_name, "default.thm") && !ColorScheme[0].desc)
  677. ColorScheme[0].desc = strdup(desc.c_str());
  678. if (strstr(d_name, ".thm") && !strchr(d_name, '~')
  679. && !theme_already_listed(d_name)) {
  680. ColorScheme[menu_pos].action = "xxx";
  681. ColorScheme[menu_pos].command_parameter1 = CMD_SETTHEME;
  682. ColorScheme[menu_pos].command_parameter3 = strdup(d_name);
  683. ColorScheme[menu_pos].state_id = STT_THEME_START + menu_pos;
  684. ColorScheme[menu_pos].desc = strdup(desc.c_str());
  685. u8string filepath = dirstr; filepath += d_name;
  686. u8string title = get_color_scheme_title(filepath.c_str());
  687. if (title.empty()) {
  688. char *label = strdup(d_name);
  689. // cut the file extension
  690. if (strchr(label, '.'))
  691. *strchr(label, '.') = '\0';
  692. ColorScheme[menu_pos].label = label;
  693. } else {
  694. ColorScheme[menu_pos].label = strdup(title.c_str());
  695. }
  696. menu_pos++;
  697. }
  698. }
  699. closedir(dir);
  700. }
  701. std::sort(&ColorScheme[menu_start], &ColorScheme[menu_pos]);
  702. ColorScheme[menu_pos++].action = "---";
  703. ColorScheme[menu_pos].action = "xxx";
  704. ColorScheme[menu_pos].label = HELP_ITEM;
  705. ColorScheme[menu_pos].command_parameter1 = CMD_HELP;
  706. ColorScheme[menu_pos].command_parameter3 = HELP_TOPIC_COLORS_STR;
  707. }
  708. ////////////////////////////////////////////////////////////////////////////
  709. Menubar *create_main_menubar(Editor *aEdtr, EditBox *aEdtbx)
  710. {
  711. return new MMMenubar(aEdtr, aEdtbx);
  712. }