Coverage Report

Created: 2025-04-22 06:17

/src/neomutt/menu/menu.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * GUI present the user with a selectable list
4
 *
5
 * @authors
6
 * Copyright (C) 2017-2023 Richard Russon <rich@flatcap.org>
7
 * Copyright (C) 2020 R Primus <rprimus@gmail.com>
8
 *
9
 * @copyright
10
 * This program is free software: you can redistribute it and/or modify it under
11
 * the terms of the GNU General Public License as published by the Free Software
12
 * Foundation, either version 2 of the License, or (at your option) any later
13
 * version.
14
 *
15
 * This program is distributed in the hope that it will be useful, but WITHOUT
16
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18
 * details.
19
 *
20
 * You should have received a copy of the GNU General Public License along with
21
 * this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
/**
25
 * @page menu_menu GUI present the user with a selectable list
26
 *
27
 * GUI present the user with a selectable list
28
 */
29
30
#include "config.h"
31
#include <stdio.h>
32
#include "private.h"
33
#include "mutt/lib.h"
34
#include "gui/lib.h"
35
#include "lib.h"
36
#include "color/lib.h"
37
#include "expando/lib.h" // IWYU pragma: keep
38
#include "type.h"
39
40
struct ConfigSubset;
41
42
/// Previous search string, one for each #MenuType
43
char *SearchBuffers[MENU_MAX];
44
45
/**
46
 * default_color - Get the default colour for a line of the menu - Implements Menu::color() - @ingroup menu_color
47
 */
48
static const struct AttrColor *default_color(struct Menu *menu, int line)
49
0
{
50
0
  return simple_color_get(MT_COLOR_NORMAL);
51
0
}
52
53
/**
54
 * generic_search - Search a menu for a item matching a regex - Implements Menu::search() - @ingroup menu_search
55
 */
56
static int generic_search(struct Menu *menu, regex_t *rx, int line)
57
0
{
58
0
  struct Buffer *buf = buf_pool_get();
59
60
0
  menu->make_entry(menu, line, -1, buf);
61
0
  int rc = regexec(rx, buf->data, 0, NULL, 0);
62
0
  buf_pool_release(&buf);
63
64
0
  return rc;
65
0
}
66
67
/**
68
 * menu_cleanup - Free the saved Menu searches
69
 */
70
void menu_cleanup(void)
71
0
{
72
0
  for (int i = 0; i < MENU_MAX; i++)
73
0
    FREE(&SearchBuffers[i]);
74
0
}
75
76
/**
77
 * menu_init - Initialise all the Menus
78
 */
79
void menu_init(void)
80
0
{
81
0
  for (int i = 0; i < MENU_MAX; i++)
82
0
    SearchBuffers[i] = NULL;
83
0
}
84
85
/**
86
 * menu_get_current_type - Get the type of the current Window
87
 * @retval enum Menu Type, e.g. #MENU_PAGER
88
 */
89
enum MenuType menu_get_current_type(void)
90
0
{
91
0
  struct MuttWindow *win = window_get_focus();
92
93
  // This should only happen before the first window is created
94
0
  if (!win)
95
0
    return MENU_INDEX;
96
97
0
  if ((win->type == WT_CUSTOM) && (win->parent->type == WT_PAGER))
98
0
    return MENU_PAGER;
99
100
0
  if (win->type != WT_MENU)
101
0
    return MENU_GENERIC;
102
103
0
  struct Menu *menu = win->wdata;
104
0
  if (!menu)
105
0
    return MENU_GENERIC;
106
107
0
  return menu->type;
108
0
}
109
110
/**
111
 * menu_free - Free a Menu
112
 * @param ptr Menu to free
113
 */
114
void menu_free(struct Menu **ptr)
115
0
{
116
0
  if (!ptr || !*ptr)
117
0
    return;
118
119
0
  struct Menu *menu = *ptr;
120
121
0
  notify_free(&menu->notify);
122
123
0
  if (menu->mdata_free && menu->mdata)
124
0
    menu->mdata_free(menu, &menu->mdata); // Custom function to free private data
125
126
0
  FREE(ptr);
127
0
}
128
129
/**
130
 * menu_new - Create a new Menu
131
 * @param type Menu type, e.g. #MENU_ALIAS
132
 * @param win  Parent Window
133
 * @param sub  Config items
134
 * @retval ptr New Menu
135
 */
136
struct Menu *menu_new(enum MenuType type, struct MuttWindow *win, struct ConfigSubset *sub)
137
0
{
138
0
  struct Menu *menu = MUTT_MEM_CALLOC(1, struct Menu);
139
140
0
  menu->type = type;
141
0
  menu->redraw = MENU_REDRAW_FULL;
142
0
  menu->color = default_color;
143
0
  menu->search = generic_search;
144
0
  menu->notify = notify_new();
145
0
  menu->win = win;
146
0
  menu->page_len = win->state.rows;
147
0
  menu->sub = sub;
148
149
0
  notify_set_parent(menu->notify, win->notify);
150
0
  menu_add_observers(menu);
151
152
0
  return menu;
153
0
}
154
155
/**
156
 * menu_get_index - Get the current selection in the Menu
157
 * @param menu Menu
158
 * @retval num Index of selection
159
 */
160
int menu_get_index(struct Menu *menu)
161
0
{
162
0
  if (!menu)
163
0
    return -1;
164
165
0
  return menu->current;
166
0
}
167
168
/**
169
 * menu_set_index - Set the current selection in the Menu
170
 * @param menu  Menu
171
 * @param index Item to select
172
 * @retval enum #MenuRedrawFlags, e.g. #MENU_REDRAW_INDEX
173
 */
174
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
175
0
{
176
0
  return menu_move_selection(menu, index);
177
0
}
178
179
/**
180
 * menu_queue_redraw - Queue a request for a redraw
181
 * @param menu  Menu
182
 * @param redraw Item to redraw, e.g. #MENU_REDRAW_CURRENT
183
 */
184
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
185
0
{
186
0
  if (!menu)
187
0
    return;
188
189
0
  menu->redraw |= redraw;
190
0
  menu->win->actions |= WA_RECALC;
191
0
}