Coverage Report

Created: 2025-04-22 06:17

/src/neomutt/postpone/functions.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * Postponed Emails Functions
4
 *
5
 * @authors
6
 * Copyright (C) 2022-2023 Richard Russon <rich@flatcap.org>
7
 * Copyright (C) 2023 Dennis Schön <mail@dennis-schoen.de>
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 postpone_functions Postponed Emails Functions
26
 *
27
 * Postponed Emails Functions
28
 */
29
30
#include "config.h"
31
#ifdef _MAKEDOC
32
#include "docs/makedoc_defs.h"
33
#else
34
#include <stddef.h>
35
#include "mutt/lib.h"
36
#include "config/lib.h"
37
#include "core/lib.h"
38
#include "gui/lib.h"
39
#include "mutt.h"
40
#include "key/lib.h"
41
#include "menu/lib.h"
42
#include "pattern/lib.h"
43
#include "functions.h"
44
#include "mview.h"
45
#include "protos.h"
46
#endif
47
48
// clang-format off
49
/**
50
 * OpPostponed - Functions for the Postpone Menu
51
 */
52
const struct MenuFuncOp OpPostponed[] = { /* map: postpone */
53
  { "exit",                          OP_EXIT },
54
  { "delete-entry",                  OP_DELETE },
55
  { "undelete-entry",                OP_UNDELETE },
56
  { NULL, 0 },
57
};
58
59
/**
60
 * PostponedDefaultBindings - Key bindings for the Postpone Menu
61
 */
62
const struct MenuOpSeq PostponedDefaultBindings[] = { /* map: postpone */
63
  { OP_DELETE,                             "d" },
64
  { OP_EXIT,                               "q" },
65
  { OP_UNDELETE,                           "u" },
66
  { 0, NULL },
67
};
68
// clang-format on
69
70
/**
71
 * op_delete - Delete the current entry - Implements ::postpone_function_t - @ingroup postpone_function_api
72
 */
73
static int op_delete(struct PostponeData *pd, int op)
74
{
75
  struct Menu *menu = pd->menu;
76
  struct MailboxView *mv = pd->mailbox_view;
77
  struct Mailbox *m = mv->mailbox;
78
79
  const int index = menu_get_index(menu);
80
  /* should deleted draft messages be saved in the trash folder? */
81
  mutt_set_flag(m, m->emails[index], MUTT_DELETE, (op == OP_DELETE), true);
82
  PostCount = m->msg_count - m->msg_deleted;
83
  const bool c_resolve = cs_subset_bool(NeoMutt->sub, "resolve");
84
  if (c_resolve && (index < (menu->max - 1)))
85
  {
86
    menu_set_index(menu, index + 1);
87
    if (index >= (menu->top + menu->page_len))
88
    {
89
      menu->top = index;
90
      menu_queue_redraw(menu, MENU_REDRAW_INDEX);
91
    }
92
  }
93
  else
94
  {
95
    menu_queue_redraw(menu, MENU_REDRAW_CURRENT);
96
  }
97
98
  return FR_SUCCESS;
99
}
100
101
/**
102
 * op_exit - Exit this menu - Implements ::postpone_function_t - @ingroup postpone_function_api
103
 */
104
static int op_exit(struct PostponeData *pd, int op)
105
{
106
  pd->done = true;
107
  return FR_SUCCESS;
108
}
109
110
/**
111
 * op_generic_select_entry - Select the current entry - Implements ::postpone_function_t - @ingroup postpone_function_api
112
 */
113
static int op_generic_select_entry(struct PostponeData *pd, int op)
114
{
115
  int index = menu_get_index(pd->menu);
116
  struct MailboxView *mv = pd->mailbox_view;
117
  struct Mailbox *m = mv->mailbox;
118
  pd->email = m->emails[index];
119
  pd->done = true;
120
  return FR_SUCCESS;
121
}
122
123
/**
124
 * op_search - Search for a regular expression - Implements ::postpone_function_t - @ingroup postpone_function_api
125
 */
126
static int op_search(struct PostponeData *pd, int op)
127
{
128
  SearchFlags flags = SEARCH_NO_FLAGS;
129
  switch (op)
130
  {
131
    case OP_SEARCH:
132
      flags |= SEARCH_PROMPT;
133
      pd->search_state->reverse = false;
134
      break;
135
    case OP_SEARCH_REVERSE:
136
      flags |= SEARCH_PROMPT;
137
      pd->search_state->reverse = true;
138
      break;
139
    case OP_SEARCH_NEXT:
140
      break;
141
    case OP_SEARCH_OPPOSITE:
142
      flags |= SEARCH_OPPOSITE;
143
      break;
144
  }
145
146
  int index = menu_get_index(pd->menu);
147
  struct MailboxView *mv = pd->mailbox_view;
148
  index = mutt_search_command(mv, pd->menu, index, pd->search_state, flags);
149
  if (index != -1)
150
    menu_set_index(pd->menu, index);
151
152
  return FR_SUCCESS;
153
}
154
155
// -----------------------------------------------------------------------------
156
157
/**
158
 * PostponeFunctions - All the NeoMutt functions that the Postpone supports
159
 */
160
static const struct PostponeFunction PostponeFunctions[] = {
161
  // clang-format off
162
  { OP_DELETE,                 op_delete },
163
  { OP_EXIT,                   op_exit },
164
  { OP_GENERIC_SELECT_ENTRY,   op_generic_select_entry },
165
  { OP_SEARCH,                 op_search },
166
  { OP_SEARCH_NEXT,            op_search },
167
  { OP_SEARCH_OPPOSITE,        op_search },
168
  { OP_SEARCH_REVERSE,         op_search },
169
  { OP_UNDELETE,               op_delete },
170
  { 0, NULL },
171
  // clang-format on
172
};
173
174
/**
175
 * postpone_function_dispatcher - Perform a Postpone function - Implements ::function_dispatcher_t - @ingroup dispatcher_api
176
 */
177
int postpone_function_dispatcher(struct MuttWindow *win, int op)
178
0
{
179
  // The Dispatcher may be called on any Window in the Dialog
180
0
  struct MuttWindow *dlg = dialog_find(win);
181
0
  if (!dlg || !dlg->wdata)
182
0
    return FR_ERROR;
183
184
0
  struct Menu *menu = dlg->wdata;
185
0
  struct PostponeData *pd = menu->mdata;
186
187
0
  int rc = FR_UNKNOWN;
188
0
  for (size_t i = 0; PostponeFunctions[i].op != OP_NULL; i++)
189
0
  {
190
0
    const struct PostponeFunction *fn = &PostponeFunctions[i];
191
0
    if (fn->op == op)
192
0
    {
193
0
      rc = fn->function(pd, op);
194
0
      break;
195
0
    }
196
0
  }
197
198
0
  if (rc == FR_UNKNOWN) // Not our function
199
0
    return rc;
200
201
0
  const char *result = dispatcher_get_retval_name(rc);
202
0
  mutt_debug(LL_DEBUG1, "Handled %s (%d) -> %s\n", opcodes_get_name(op), op, NONULL(result));
203
204
0
  return rc;
205
0
}
206
207
/**
208
 * postponed_get_mailbox_view - Extract the Mailbox from the Postponed Dialog
209
 * @param dlg Postponed Dialog
210
 * @retval ptr Mailbox view
211
 */
212
struct MailboxView *postponed_get_mailbox_view(struct MuttWindow *dlg)
213
0
{
214
0
  if (!dlg)
215
0
    return NULL;
216
217
0
  struct Menu *menu = dlg->wdata;
218
0
  struct PostponeData *pd = menu->mdata;
219
0
  if (!pd)
220
0
    return NULL;
221
222
0
  return pd->mailbox_view;
223
0
}