dialogs.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. Internal file viewer for the Midnight Commander
  3. Function for paint dialogs
  4. Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
  5. 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
  6. Written by: 1994, 1995, 1998 Miguel de Icaza
  7. 1994, 1995 Janne Kukonlehto
  8. 1995 Jakub Jelinek
  9. 1996 Joseph M. Hinkle
  10. 1997 Norbert Warmuth
  11. 1998 Pavel Machek
  12. 2004 Roland Illig <roland.illig@gmx.de>
  13. 2005 Roland Illig <roland.illig@gmx.de>
  14. 2009 Slava Zanko <slavazanko@google.com>
  15. 2009 Andrew Borodin <aborodin@vmail.ru>
  16. 2009 Ilia Maslakov <il.smind@gmail.com>
  17. This file is part of the Midnight Commander.
  18. The Midnight Commander is free software; you can redistribute it
  19. and/or modify it under the terms of the GNU General Public License as
  20. published by the Free Software Foundation; either version 2 of the
  21. License, or (at your option) any later version.
  22. The Midnight Commander is distributed in the hope that it will be
  23. useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  24. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  25. General Public License for more details.
  26. You should have received a copy of the GNU General Public License
  27. along with this program; if not, write to the Free Software
  28. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  29. MA 02110-1301, USA.
  30. */
  31. #include <config.h>
  32. #include <stdlib.h>
  33. #include <sys/types.h>
  34. #include "lib/global.h"
  35. #include "lib/search.h"
  36. #include "lib/strutil.h"
  37. #include "src/wtools.h"
  38. #include "src/history.h"
  39. #include "src/charsets.h"
  40. #include "internal.h"
  41. /*** global variables ****************************************************************************/
  42. mcview_search_options_t mcview_search_options = {
  43. .type = MC_SEARCH_T_NORMAL,
  44. .case_sens = FALSE,
  45. .backwards = FALSE,
  46. .whole_words = FALSE,
  47. .all_codepages = FALSE
  48. };
  49. /*** file scope macro definitions ****************************************************************/
  50. /*** file scope type declarations ****************************************************************/
  51. /*** file scope variables ************************************************************************/
  52. /*** file scope functions ************************************************************************/
  53. /*** public functions ****************************************************************************/
  54. /* --------------------------------------------------------------------------------------------- */
  55. gboolean
  56. mcview_dialog_search (mcview_t * view)
  57. {
  58. int SEARCH_DLG_MIN_HEIGHT = 12;
  59. int SEARCH_DLG_HEIGHT_SUPPLY = 3;
  60. int SEARCH_DLG_WIDTH = 58;
  61. char *exp = NULL;
  62. int qd_result;
  63. size_t num_of_types;
  64. gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types);
  65. int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY;
  66. QuickWidget quick_widgets[] = {
  67. QUICK_BUTTON (6, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL,
  68. NULL),
  69. QUICK_BUTTON (2, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL),
  70. #ifdef HAVE_CHARSET
  71. QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 8, SEARCH_DLG_HEIGHT,
  72. N_("All charsets"), &mcview_search_options.all_codepages),
  73. #endif
  74. QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 7, SEARCH_DLG_HEIGHT,
  75. N_("&Whole words"), &mcview_search_options.whole_words),
  76. QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 6, SEARCH_DLG_HEIGHT,
  77. N_("&Backwards"), &mcview_search_options.backwards),
  78. QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
  79. N_("Case &sensitive"), &mcview_search_options.case_sens),
  80. QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT,
  81. num_of_types, (const char **) list_of_types,
  82. (int *) &mcview_search_options.type),
  83. QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT,
  84. INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, &exp),
  85. QUICK_LABEL (3, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_("Enter search string:")),
  86. QUICK_END
  87. };
  88. QuickDialog Quick_input = {
  89. SEARCH_DLG_WIDTH, SEARCH_DLG_HEIGHT, -1, -1,
  90. N_("Search"), "[Input Line Keys]",
  91. quick_widgets, NULL, FALSE
  92. };
  93. qd_result = quick_dialog (&Quick_input);
  94. g_strfreev (list_of_types);
  95. if ((qd_result == B_CANCEL) || (exp == NULL) || (exp[0] == '\0'))
  96. {
  97. g_free (exp);
  98. return FALSE;
  99. }
  100. #ifdef HAVE_CHARSET
  101. {
  102. GString *tmp = str_convert_to_input (exp);
  103. if (tmp)
  104. {
  105. g_free (exp);
  106. exp = g_string_free (tmp, FALSE);
  107. }
  108. }
  109. #endif
  110. g_free (view->last_search_string);
  111. view->last_search_string = exp;
  112. mcview_nroff_seq_free (&view->search_nroff_seq);
  113. mc_search_free (view->search);
  114. view->search = mc_search_new (view->last_search_string, -1);
  115. view->search_nroff_seq = mcview_nroff_seq_new (view);
  116. if (view->search != NULL)
  117. {
  118. view->search->search_type = mcview_search_options.type;
  119. view->search->is_all_charsets = mcview_search_options.all_codepages;
  120. view->search->is_case_sensitive = mcview_search_options.case_sens;
  121. view->search->whole_words = mcview_search_options.whole_words;
  122. view->search->search_fn = mcview_search_cmd_callback;
  123. view->search->update_fn = mcview_search_update_cmd_callback;
  124. }
  125. return (view->search != NULL);
  126. }
  127. /* --------------------------------------------------------------------------------------------- */
  128. gboolean
  129. mcview_dialog_goto (mcview_t * view, off_t * offset)
  130. {
  131. typedef enum
  132. {
  133. MC_VIEW_GOTO_LINENUM = 0,
  134. MC_VIEW_GOTO_PERCENT = 1,
  135. MC_VIEW_GOTO_OFFSET_DEC = 2,
  136. MC_VIEW_GOTO_OFFSET_HEX = 3
  137. } mcview_goto_type_t;
  138. const char *mc_view_goto_str[] = {
  139. N_("&Line number (decimal)"),
  140. N_("Pe&rcents"),
  141. N_("&Decimal offset"),
  142. N_("He&xadecimal offset")
  143. };
  144. const int goto_dlg_height = 12;
  145. int goto_dlg_width = 40;
  146. static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;
  147. size_t i;
  148. size_t num_of_types = sizeof (mc_view_goto_str) / sizeof (mc_view_goto_str[0]);
  149. char *exp = NULL;
  150. int qd_result;
  151. gboolean res = FALSE;
  152. QuickWidget quick_widgets[] = {
  153. QUICK_BUTTON (6, 10, goto_dlg_height - 3, goto_dlg_height, N_("&Cancel"), B_CANCEL, NULL),
  154. QUICK_BUTTON (2, 10, goto_dlg_height - 3, goto_dlg_height, N_("&OK"), B_ENTER, NULL),
  155. QUICK_RADIO (3, goto_dlg_width, 4, goto_dlg_height,
  156. num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type),
  157. QUICK_INPUT (3, goto_dlg_width, 2, goto_dlg_height,
  158. INPUT_LAST_TEXT, goto_dlg_width - 6, 0, MC_HISTORY_VIEW_GOTO, &exp),
  159. QUICK_END
  160. };
  161. QuickDialog Quick_input = {
  162. goto_dlg_width, goto_dlg_height, -1, -1,
  163. N_("Goto"), "[Input Line Keys]",
  164. quick_widgets, NULL, FALSE
  165. };
  166. #ifdef ENABLE_NLS
  167. for (i = 0; i < num_of_types; i++)
  168. mc_view_goto_str[i] = _(mc_view_goto_str[i]);
  169. quick_widgets[0].u.button.text = _(quick_widgets[0].u.button.text);
  170. quick_widgets[1].u.button.text = _(quick_widgets[1].u.button.text);
  171. #endif
  172. /* calculate widget coordinates */
  173. {
  174. int b0_len, b1_len, len;
  175. const int button_gap = 2;
  176. /* preliminary dialog width */
  177. goto_dlg_width = max (goto_dlg_width, str_term_width1 (Quick_input.title) + 4);
  178. /* length of radiobuttons */
  179. for (i = 0; i < num_of_types; i++)
  180. goto_dlg_width = max (goto_dlg_width, str_term_width1 (mc_view_goto_str[i]) + 10);
  181. /* length of buttons */
  182. b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
  183. b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 5; /* default button */
  184. len = b0_len + b1_len + button_gap * 2;
  185. /* dialog width */
  186. Quick_input.xlen = max (goto_dlg_width, len + 6);
  187. /* correct widget coordinates */
  188. for (i = sizeof (quick_widgets) / sizeof (quick_widgets[0]); i > 0; i--)
  189. quick_widgets[i - 1].x_divisions = Quick_input.xlen;
  190. /* input length */
  191. quick_widgets[3].u.input.len = Quick_input.xlen - 6;
  192. /* button positions */
  193. quick_widgets[1].relative_x = Quick_input.xlen / 2 - len / 2;
  194. quick_widgets[0].relative_x = quick_widgets[1].relative_x + b1_len + button_gap;
  195. }
  196. /* run dialog */
  197. qd_result = quick_dialog (&Quick_input);
  198. *offset = -1;
  199. /* check input line value */
  200. if ((qd_result != B_CANCEL) && (exp != NULL) && (exp[0] != '\0'))
  201. {
  202. int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
  203. off_t addr;
  204. char *error;
  205. res = TRUE;
  206. addr = strtoll (exp, &error, base);
  207. if ((*error == '\0') && (addr >= 0))
  208. {
  209. switch (current_goto_type)
  210. {
  211. case MC_VIEW_GOTO_LINENUM:
  212. mcview_coord_to_offset (view, offset, addr, 0);
  213. break;
  214. case MC_VIEW_GOTO_PERCENT:
  215. if (addr > 100)
  216. addr = 100;
  217. *offset = addr * mcview_get_filesize (view) / 100;
  218. break;
  219. case MC_VIEW_GOTO_OFFSET_DEC:
  220. *offset = addr;
  221. break;
  222. case MC_VIEW_GOTO_OFFSET_HEX:
  223. *offset = addr;
  224. break;
  225. default:
  226. break;
  227. }
  228. *offset = mcview_bol (view, *offset, 0);
  229. }
  230. }
  231. g_free (exp);
  232. return res;
  233. }