simple_notepad_6.e 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. class SIMPLE_NOTEPAD_6
  2. insert
  3. IUP_INTERFACE
  4. create {ANY}
  5. make
  6. feature {ANY}
  7. ml: IUP_MULTILINE
  8. str_find (str, str_to_find, casesensitive: STRING; pos: INTEGER): INTEGER
  9. do
  10. if str.count.is_equal(0) or str_to_find.count.is_equal(0) then
  11. Result := -1
  12. elseif casesensitive.is_equal("OFF") then
  13. str.to_lower
  14. str_to_find.to_lower
  15. end
  16. Result := str.substring_index(str_to_find, pos)
  17. end
  18. read_file (file_name: STRING): STRING
  19. local
  20. tfr: TEXT_FILE_READ
  21. str: STRING
  22. ms: IUP_MESSAGE
  23. do
  24. create str.make_empty
  25. create tfr.connect_to(file_name)
  26. if tfr.is_connected then
  27. from
  28. tfr.read_line
  29. until
  30. tfr.end_of_input
  31. loop
  32. str.append(tfr.last_string)
  33. str.append_character('%N')
  34. tfr.read_line
  35. end
  36. str.append(tfr.last_string)
  37. tfr.disconnect
  38. else
  39. str.append("Fail when reading from file: ")
  40. str.append(file_name)
  41. create ms.message("Error", str)
  42. end
  43. Result := str
  44. end
  45. write_file (file_name, text: STRING)
  46. local
  47. tfw: TEXT_FILE_WRITE
  48. ms: IUP_MESSAGE
  49. str: STRING
  50. do
  51. create tfw.connect_to(file_name)
  52. if tfw.is_connected then
  53. tfw.put_string(text)
  54. tfw.disconnect
  55. else
  56. str.make_empty
  57. str.append("Fail when writing to file: ")
  58. str.append(file_name)
  59. create ms.message("Error", str)
  60. end
  61. end
  62. --********************************** Callbacks *****************************************
  63. multitext_caret_cb (m: IUP_TEXT; lin, col, pos: INTEGER): STRING
  64. local
  65. lbl_statusbar: IUP_LABEL
  66. str: STRING
  67. do
  68. if lbl_statusbar ?:= m.get_dialog_child("STATUSBAR") then
  69. lbl_statusbar ::= m.get_dialog_child("STATUSBAR")
  70. str := "Line "
  71. str.append(lin.to_string)
  72. str.append(", Col ")
  73. str.append(col.to_string)
  74. lbl_statusbar.set_title(str)
  75. end
  76. Result := "IUP_DEFAULT"
  77. end
  78. item_open_action_cb (widget: IUP_WIDGET): STRING
  79. local
  80. status: INTEGER
  81. rv, name, text: STRING
  82. fd: IUP_FILE_DIALOG
  83. do
  84. create fd.file_dialog
  85. fd.set_dialog_type("OPEN")
  86. fd.set_ext_filter("Text files|*.txt|All Files|*.*|")
  87. fd.set_title("Select a text file")
  88. rv := fd.popup_predefined_xy("IUP_CENTER", "IUP_CENTER")
  89. if rv.is_equal("IUP_NOERROR") then
  90. status := fd.get_status
  91. if status.is_equal(0) then
  92. name := fd.get_value
  93. text := read_file(name)
  94. ml.set_value(text)
  95. end
  96. end
  97. fd.destroy
  98. Result := "IUP_DEFAULT"
  99. end
  100. item_saveas_action_cb (widget: IUP_WIDGET): STRING
  101. local
  102. status: INTEGER
  103. rv, name, text: STRING
  104. fd: IUP_FILE_DIALOG
  105. do
  106. create fd.file_dialog
  107. fd.set_dialog_type("SAVE")
  108. fd.set_ext_filter("Text files|*.txt|All Files|*.*|")
  109. fd.set_title("Select a text file")
  110. rv := fd.popup_predefined_xy("IUP_CENTER", "IUP_CENTER")
  111. if rv.is_equal("IUP_NOERROR") then
  112. status := fd.get_status
  113. if not status.is_equal(-1) then
  114. name := fd.get_value
  115. text := ml.get_value
  116. write_file(name, text)
  117. end
  118. end
  119. fd.destroy
  120. Result := "IUP_DEFAULT"
  121. end
  122. item_font_action_cb (widget: IUP_MENU_ITEM): STRING
  123. local
  124. status: INTEGER
  125. rv, ft, selected: STRING
  126. fd: IUP_FONT_DIALOG
  127. do
  128. create fd.font_dialog
  129. ft := ml.get_font
  130. fd.set_value(ft)
  131. rv := fd.popup_predefined_xy("IUP_CENTER", "IUP_CENTER")
  132. if rv.is_equal("IUP_NOERROR") then
  133. status := fd.get_status
  134. if status.is_equal(1) then
  135. selected := fd.get_value
  136. ml.set_font(selected)
  137. end
  138. end
  139. fd.destroy
  140. Result := "IUP_DEFAULT"
  141. end
  142. item_about_action_cb (widget: IUP_MENU_ITEM): STRING
  143. local
  144. ms: IUP_MESSAGE
  145. do
  146. create ms.message("About"," Simple Notepad%N%NAutors:%N Gustavo Lyrio%N Antonio Scuri")
  147. Result := "IUP_DEFAULT"
  148. end
  149. item_exit_action_cb (widget: IUP_MENU_ITEM): STRING
  150. do
  151. Result := "IUP_CLOSE"
  152. end
  153. goto_ok_action_cb(widget: IUP_BUTTON): STRING
  154. local
  155. line_count, line: INTEGER
  156. txt: IUP_TEXT
  157. ms: IUP_MESSAGE
  158. do
  159. if txt ?:= widget.get_dialog_child("LINE_TEXT") then
  160. txt ::= widget.get_dialog_child("LINE_TEXT")
  161. line_count := widget.get_attribute_integer("TEXT_LINECOUNT")
  162. line := txt.get_value.to_integer
  163. if line < 1 and line >= line_count then
  164. create ms.message("Error", "Invalid line number.")
  165. Result := "IUP_DEFAULT"
  166. end
  167. widget.get_dialog.set_attribute_integer("STATUS", 1)
  168. Result := "IUP_CLOSE"
  169. end
  170. end
  171. goto_cancel_action_cb(widget: IUP_BUTTON): STRING
  172. do
  173. widget.get_dialog.set_attribute_integer("STATUS", 0)
  174. Result := "IUP_CLOSE"
  175. end
  176. item_goto_action_cb (widget: IUP_WIDGET): STRING
  177. local
  178. dlg, d: IUP_DIALOG
  179. vbox: IUP_VBOX
  180. hbox: IUP_HBOX
  181. bt_ok, bt_cancel: IUP_BUTTON
  182. f: IUP_FILL
  183. lbl: IUP_LABEL
  184. txt: IUP_TEXT
  185. str, s: STRING
  186. line_count, line, pos: INTEGER
  187. item: IUP_MENU_ITEM
  188. do
  189. line_count := ml.get_line_count
  190. str := "Line Number [1-"
  191. str.append_string(ml.get_line_count.to_string)
  192. str.append_string("]:")
  193. create lbl.label(str)
  194. create txt.text
  195. txt.set_mask("IUP_MASK_UINT") -- unsigned integer numbers only
  196. txt.set_name("LINE_TEXT")
  197. txt.set_visible_columns(20)
  198. create bt_ok.button("OK")
  199. bt_ok.set_attribute_integer("TEXT_LINECOUNT", line_count)
  200. bt_ok.set_padding(10, 2)
  201. bt_ok.set_cb_action(agent goto_ok_action_cb(?))
  202. create bt_cancel.button("Cancel")
  203. bt_cancel.set_padding(10, 2)
  204. bt_cancel.set_cb_action(agent goto_cancel_action_cb(?))
  205. create f.fill
  206. create hbox.hbox({ARRAY[IUP_WIDGET] 1, << f, bt_ok, bt_cancel >>})
  207. hbox.set_normalize_size("HORIZONTAL")
  208. create vbox.vbox({ARRAY[IUP_WIDGET] 1, << lbl, txt, hbox >>})
  209. vbox.set_margin(10, 10)
  210. vbox.set_gap(5)
  211. create dlg.dialog(vbox)
  212. dlg.set_title("Go To Line")
  213. dlg.set_modal_dialog_frame(True)
  214. dlg.set_default_enter_widget(bt_ok)
  215. dlg.set_default_escape_widget(bt_cancel)
  216. if {IUP_MENU_ITEM} ?:= widget then
  217. item ::= widget
  218. dlg.set_parent_dialog_widget(item.get_dialog)
  219. elseif {IUP_DIALOG} ?:= widget then
  220. d ::= widget
  221. dlg.set_parent_dialog_widget(d)
  222. end
  223. s := dlg.popup_predefined_xy ("IUP_CENTERPARENT", "IUP_CENTERPARENT")
  224. if s.is_equal("IUP_NOERROR") and dlg.get_attribute_integer("STATUS").is_equal(1) then
  225. line := txt.get_value.to_integer
  226. pos := ml.text_convert_lin_col_to_pos(line, 0)
  227. ml.set_multiline_caret_pos(pos)
  228. ml.scroll_to_pos(pos)
  229. end
  230. dlg.destroy
  231. Result := "IUP_DEFAULT"
  232. end
  233. find_next_action_cb (widget: IUP_BUTTON): STRING
  234. local
  235. str, str_to_find, casesensitive: STRING
  236. find_pos, pos, end_pos: INTEGER
  237. txt: IUP_TEXT
  238. find_case: IUP_TOGGLE
  239. tup: TUPLE[INTEGER, INTEGER]
  240. pw: IUP_WIDGET
  241. ms: IUP_MESSAGE
  242. do
  243. str := ml.get_value
  244. find_pos := ml.get_attribute_integer("FIND_POS")
  245. if find_pos = 0 then
  246. find_pos := 1
  247. end
  248. if txt ?:= widget.get_dialog_child("FIND_TEXT") then
  249. txt ::= widget.get_dialog_child("FIND_TEXT")
  250. str_to_find := txt.get_value
  251. if find_case ?:= widget.get_dialog_child("FIND_CASE") then
  252. find_case ::= widget.get_dialog_child("FIND_CASE")
  253. casesensitive := find_case.get_value
  254. -- Rest 1 since the string start at 1, but multiline position
  255. -- start at 0.
  256. pos := str_find(str, str_to_find, casesensitive, find_pos) - 1
  257. if pos < 0 and find_pos > 0 then
  258. -- try again from the start
  259. pos := str_find(str, str_to_find, casesensitive, 1) - 1
  260. end
  261. if pos > 0 then
  262. end_pos := pos + str_to_find.count
  263. ml.set_attribute_integer("FIND_POS", end_pos)
  264. pw := ml.set_focus
  265. ml.set_multiline_selection_pos(pos, end_pos)
  266. tup := ml.text_convert_pos_to_lin_col(pos)
  267. -- position at col=0, just scroll lines
  268. pos := ml.text_convert_lin_col_to_pos(tup.item_1, 0)
  269. ml.scroll_to_pos(pos)
  270. else
  271. create ms.message("Warning", "Text not found.")
  272. end
  273. end
  274. end
  275. Result := "IUP_DEFAULT"
  276. end
  277. find_close_action_cb (widget: IUP_BUTTON): STRING
  278. do
  279. widget.get_dialog.hide
  280. Result := "IUP_DEFAULT"
  281. end
  282. item_find_action_cb (widget: IUP_WIDGET): STRING
  283. local
  284. dlg, main_dlg: IUP_DIALOG
  285. lbl: IUP_LABEL
  286. txt: IUP_TEXT
  287. btn, bt_next, bt_close: IUP_BUTTON
  288. find_case: IUP_TOGGLE
  289. f: IUP_FILL
  290. hbox: IUP_HBOX
  291. vbox: IUP_VBOX
  292. s: STRING
  293. item: IUP_MENU_ITEM
  294. do
  295. if btn ?:= widget then
  296. btn ::= widget
  297. main_dlg := btn.get_dialog
  298. elseif item ?:= widget then
  299. item ::= widget
  300. main_dlg := item.get_dialog
  301. elseif main_dlg ?:= widget then
  302. main_dlg ::= widget
  303. end
  304. if dlg ?:= main_dlg.get_attribute_widget("FIND_DIALOG") then
  305. dlg ::= main_dlg.get_attribute_widget("FIND_DIALOG")
  306. end
  307. if dlg = Void then
  308. create lbl.label("Find What:")
  309. create txt.text
  310. txt.set_name("FIND_TEXT")
  311. txt.set_visible_columns(20)
  312. create find_case.toggle("Case Sensitive")
  313. find_case.set_name("FIND_CASE")
  314. create bt_next.button("Find Next")
  315. bt_next.set_padding(10, 2)
  316. bt_next.set_cb_action(agent find_next_action_cb(?))
  317. create bt_close.button("Close")
  318. bt_close.set_padding(10, 2)
  319. bt_close.set_cb_action(agent find_close_action_cb(?))
  320. create f.fill
  321. create hbox.hbox({ARRAY[IUP_WIDGET] 1, << f, bt_next, bt_close >>})
  322. hbox.set_normalize_size("HORIZONTAL")
  323. create vbox.vbox({ARRAY[IUP_WIDGET] 1, << lbl, txt, find_case, hbox >>})
  324. vbox.set_margin(10, 10)
  325. vbox.set_gap(10)
  326. create dlg.dialog(vbox)
  327. dlg.set_title("Find")
  328. dlg.set_modal_dialog_frame(True)
  329. dlg.set_default_enter_widget(bt_next)
  330. dlg.set_default_escape_widget(bt_close)
  331. dlg.set_parent_dialog_widget(main_dlg)
  332. -- Save the dialog to reuse it
  333. main_dlg.set_attribute_widget("FIND_DIALOG", dlg)
  334. end
  335. -- center parent first time, next time reuse the last position
  336. s := dlg.show_predefined_xy("IUP_CURRENT", "IUP_CURRENT")
  337. Result := "IUP_DEFAULT"
  338. end
  339. key_pressed (dlg: IUP_DIALOG; k: INTEGER): STRING
  340. do
  341. if k.is_equal(iup_open.x_key_ctrl('O')) then
  342. Result := item_open_action_cb(dlg)
  343. elseif k.is_equal(iup_open.x_key_ctrl('S')) then
  344. Result := item_saveas_action_cb(dlg)
  345. elseif k.is_equal(iup_open.x_key_ctrl('F')) then
  346. Result := item_find_action_cb(dlg)
  347. elseif k.is_equal(iup_open.x_key_ctrl('G')) then
  348. Result := item_goto_action_cb(dlg)
  349. else
  350. Result := "IUP_DEFAULT"
  351. end
  352. end
  353. --********************************** Make *****************************************
  354. make
  355. local
  356. i: STRING
  357. gui: IUP
  358. v: IUP_VBOX
  359. w: IUP_DIALOG
  360. item_exit, item_open, item_saveas, item_font, item_about: IUP_MENU_ITEM
  361. item_find, item_goto: IUP_MENU_ITEM
  362. sep: IUP_MENU_SEPARATOR
  363. file_menu, edit_menu, format_menu, help_menu, menu: IUP_MENU
  364. sub_menu_file, sub_menu_edit, sub_menu_format, sub_menu_help: IUP_SUBMENU
  365. btn_open, btn_save, btn_find: IUP_BUTTON
  366. lbl_statusbar, toolbar_sep: IUP_LABEL
  367. toolbar_hb: IUP_HBOX
  368. do
  369. gui := iup_open
  370. gui.load_images
  371. create ml.multiline
  372. ml.set_expand("YES")
  373. ml.set_cb_caret(agent multitext_caret_cb(?,?,?,?))
  374. create item_open.item("&Open... %TCtrl+O")
  375. item_open.set_hide_mark(True)
  376. item_open.set_cb_action(agent item_open_action_cb(?))
  377. create btn_open.button("")
  378. btn_open.set_image("IUP_FileOpen")
  379. btn_open.set_flat(True)
  380. btn_open.set_can_focus(False)
  381. btn_open.set_tip("Open (Ctrl+O)")
  382. btn_open.set_cb_action(agent item_open_action_cb(?))
  383. create item_saveas.item("Save &As...%TCtrl+S")
  384. item_saveas.set_hide_mark(True)
  385. item_saveas.set_cb_action(agent item_saveas_action_cb(?))
  386. create btn_save.button("")
  387. btn_save.set_image("IUP_FileSave")
  388. btn_save.set_flat(True)
  389. btn_save.set_can_focus(False)
  390. btn_save.set_tip("Save (Ctrl+S)")
  391. btn_save.set_cb_action(agent item_saveas_action_cb(?))
  392. create item_exit.item("E&xit")
  393. item_exit.set_hide_mark(True)
  394. item_exit.set_cb_action(agent item_exit_action_cb(?))
  395. create item_find.item("&Find...%TCtrl+F")
  396. item_find.set_hide_mark(True)
  397. item_find.set_cb_action(agent item_find_action_cb(?))
  398. create btn_find.button("")
  399. btn_find.set_image("IUP_EditFind")
  400. btn_find.set_flat(True)
  401. btn_find.set_can_focus(False)
  402. btn_find.set_tip("Find (Ctrl+F)")
  403. btn_find.set_cb_action(agent item_find_action_cb(?))
  404. create item_goto.item("&Go To...%TCtrl+G")
  405. item_goto.set_hide_mark(True)
  406. item_goto.set_cb_action(agent item_goto_action_cb(?))
  407. create item_font.item("&Font...%TCtrl+F")
  408. item_font.set_hide_mark(True)
  409. item_font.set_cb_action(agent item_font_action_cb(?))
  410. create item_about.item("&About...")
  411. item_about.set_hide_mark(True)
  412. item_about.set_cb_action(agent item_about_action_cb(?))
  413. create sep.separator
  414. create toolbar_sep.label_empty
  415. toolbar_sep.set_vertical_separator
  416. create file_menu.menu({ARRAY[IUP_MENU_ELEMENT] 1, << item_open, item_saveas, sep, item_exit >>})
  417. create edit_menu.menu({ARRAY[IUP_MENU_ELEMENT] 1, << item_find, item_goto >>})
  418. create format_menu.menu({ARRAY[IUP_MENU_ELEMENT] 1, << item_font >>})
  419. create help_menu.menu({ARRAY[IUP_MENU_ELEMENT] 1, << item_about >>})
  420. create sub_menu_file.submenu("&File", file_menu)
  421. create sub_menu_edit.submenu("&Edit", edit_menu)
  422. create sub_menu_format.submenu("F&ormat", format_menu)
  423. create sub_menu_help.submenu("&Help", help_menu)
  424. create menu.menu({ARRAY[IUP_MENU_ELEMENT] 1, << sub_menu_file, sub_menu_edit, sub_menu_format, sub_menu_help >>})
  425. create toolbar_hb.hbox({ARRAY[IUP_WIDGET] 1, << btn_open, btn_save, toolbar_sep, btn_find >>})
  426. toolbar_hb.set_margin(5, 5)
  427. toolbar_hb.set_gap(2)
  428. create lbl_statusbar.label("Lin 1, Col 1")
  429. lbl_statusbar.set_name("STATUSBAR")
  430. lbl_statusbar.set_expand("HORIZONTAL")
  431. lbl_statusbar.set_padding(10, 5)
  432. create v.vbox({ARRAY[IUP_WIDGET] 1, << toolbar_hb, ml, lbl_statusbar >>})
  433. create w.dialog(v)
  434. w.set_menu_widget(menu)
  435. w.set_cb_k_any(agent key_pressed(?, ?))
  436. w.set_title("Simple Notepad")
  437. w.set_predefined_size("HALF", "HALF")
  438. -- parent for some pre-defined dialogs in callbak functions
  439. gui.set_global_parent_dialog_widget(w)
  440. i := w.show_predefined_xy("IUP_CENTER", "IUP_CENTER")
  441. w.set_user_size(0, 0)
  442. gui.main_loop
  443. gui.close
  444. end
  445. end