Improve some sieve-related translations
[claws.git] / src / gtk / foldersort.c
blob80eec42e60e9f2322f18dd40be350c2a3399f284
1 /*
2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2004-2022 the Claws Mail Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "config.h"
21 #include "defs.h"
23 #include <glib.h>
24 #include <glib/gi18n.h>
25 #include <gdk/gdkkeysyms.h>
27 #include "foldersort.h"
28 #include "inc.h"
29 #include "utils.h"
30 #include "prefs_common.h"
32 enum {
33 FOLDERSORT_COL_NAME,
34 FOLDERSORT_COL_PTR,
35 N_FOLDERSORT_COLS
38 typedef struct _FolderSortDialog FolderSortDialog;
40 struct _FolderSortDialog
42 GtkWidget *window;
43 GtkWidget *moveup_btn;
44 GtkWidget *movedown_btn;
45 GtkWidget *folderlist;
46 gint rows;
49 static void destroy_dialog(FolderSortDialog *dialog)
51 inc_unlock();
52 gtk_widget_destroy(dialog->window);
54 g_free(dialog);
57 static void ok_clicked(GtkWidget *widget, FolderSortDialog *dialog)
59 Folder *folder;
60 GtkTreeModel *model;
61 GtkTreeIter iter;
62 int i;
64 model = gtk_tree_view_get_model(GTK_TREE_VIEW(dialog->folderlist));
66 for (i = 0; i < dialog->rows; i++) {
67 if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, i))
68 continue;
70 gtk_tree_model_get(model, &iter, FOLDERSORT_COL_PTR, &folder, -1);
72 folder_set_sort(folder, dialog->rows - i);
75 destroy_dialog(dialog);
78 static void cancel_clicked(GtkWidget *widget, FolderSortDialog *dialog)
80 destroy_dialog(dialog);
83 static void set_selected(FolderSortDialog *dialog)
85 GtkTreeSelection *sel;
86 GtkTreeModel *model;
87 GtkTreeIter iter;
88 GtkTreePath *path;
89 gint *indices;
90 gint selected;
92 /* Get row number of the selected row */
93 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->folderlist));
94 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
95 return;
96 path = gtk_tree_model_get_path(model, &iter);
97 indices = gtk_tree_path_get_indices(path);
98 selected = indices[0];
99 gtk_tree_path_free(path);
101 if (selected >= 0) {
102 gtk_widget_set_sensitive(dialog->moveup_btn, selected > 0);
103 gtk_widget_set_sensitive(dialog->movedown_btn, selected < (dialog->rows - 1));
104 } else {
105 gtk_widget_set_sensitive(dialog->moveup_btn, FALSE);
106 gtk_widget_set_sensitive(dialog->movedown_btn, FALSE);
110 static void moveup_clicked(GtkWidget *widget, FolderSortDialog *dialog)
112 GtkTreeSelection *sel;
113 GtkTreeModel *model;
114 GtkTreeIter iter, previter;
116 /* Get currently selected iter */
117 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->folderlist));
118 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
119 return;
121 /* Now get the iter above it, if any */
122 previter = iter;
123 if (!gtk_tree_model_iter_previous(model, &previter)) {
124 /* No previous iter, are we already on top? */
125 return;
128 gtk_list_store_move_before(GTK_LIST_STORE(model), &iter, &previter);
130 set_selected(dialog);
133 static void movedown_clicked(GtkWidget *widget, FolderSortDialog *dialog)
135 GtkTreeSelection *sel;
136 GtkTreeModel *model;
137 GtkTreeIter iter, nextiter;
139 /* Get currently selected iter */
140 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->folderlist));
141 if (!gtk_tree_selection_get_selected(sel, &model, &iter))
142 return;
144 /* Now get the iter above it, if any */
145 nextiter = iter;
146 if (!gtk_tree_model_iter_next(model, &nextiter)) {
147 /* No next iter, are we already on the bottom? */
148 return;
151 gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &nextiter);
153 set_selected(dialog);
156 static void folderlist_cursor_changed_cb(GtkTreeView *view, gpointer user_data)
158 FolderSortDialog *dialog = (FolderSortDialog *)user_data;
159 set_selected(dialog);
162 static void folderlist_row_inserted_cb(GtkTreeModel *model,
163 GtkTreePath *path, GtkTreeIter *iter,
164 gpointer user_data)
166 FolderSortDialog *dialog = (FolderSortDialog *)user_data;
167 GtkTreeSelection *sel;
169 /* The only time "row-inserted" signal should be fired is when
170 * a row is reordered using drag&drop. So we want to select
171 * the recently moved row, and call set_selected(), to update
172 * the up/down button sensitivity. */
173 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->folderlist));
174 gtk_tree_selection_select_iter(sel, iter);
176 set_selected(dialog);
179 static gint delete_event(GtkWidget *widget, GdkEventAny *event, FolderSortDialog *dialog)
181 destroy_dialog(dialog);
182 return TRUE;
185 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, FolderSortDialog *dialog)
187 if (event && event->keyval == GDK_KEY_Escape)
188 destroy_dialog(dialog);
189 return FALSE;
192 static void foldersort_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation)
194 cm_return_if_fail(allocation != NULL);
196 gtk_window_get_size(GTK_WINDOW(widget),
197 &prefs_common.foldersortwin_width, &prefs_common.foldersortwin_height);
200 void foldersort_open()
202 FolderSortDialog *dialog = g_new0(FolderSortDialog, 1);
203 GList *flist;
205 GtkWidget *window;
206 GtkWidget *vbox;
207 GtkWidget *vbox1;
208 GtkWidget *label1;
209 GtkWidget *hbox;
210 GtkWidget *hbox2;
211 GtkWidget *ok_btn;
212 GtkWidget *cancel_btn;
213 GtkWidget *confirm_area;
214 GtkWidget *moveup_btn;
215 GtkWidget *movedown_btn;
216 GtkWidget *btn_vbox;
217 GtkWidget *scrolledwindow1;
218 GtkWidget *folderlist;
219 GtkTreeViewColumn *col;
220 GtkListStore *store;
221 GtkCellRenderer *rdr;
222 GtkTreeSelection *selector;
223 GtkTreeIter iter;
224 static GdkGeometry geometry;
226 window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "foldersort");
227 g_object_set_data(G_OBJECT(window), "window", window);
228 gtk_container_set_border_width(GTK_CONTAINER(window), 8);
229 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
230 gtk_window_set_title(GTK_WINDOW(window), _("Set mailbox order"));
231 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
232 gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
233 g_signal_connect(G_OBJECT(window), "delete_event",
234 G_CALLBACK(delete_event), dialog);
235 g_signal_connect (G_OBJECT(window), "size_allocate",
236 G_CALLBACK (foldersort_size_allocate_cb), NULL);
237 g_signal_connect(G_OBJECT(window), "key_press_event",
238 G_CALLBACK(key_pressed), dialog);
240 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
241 gtk_widget_show(vbox);
242 gtk_container_add(GTK_CONTAINER(window), vbox);
244 gtkut_stock_button_set_create(&confirm_area, &cancel_btn, NULL, _("_Cancel"),
245 &ok_btn, NULL, _("_OK"),
246 NULL, NULL, NULL);
247 gtk_widget_show(confirm_area);
248 gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
249 gtk_widget_grab_focus(ok_btn);
251 g_signal_connect(G_OBJECT(ok_btn), "clicked",
252 G_CALLBACK(ok_clicked), dialog);
253 g_signal_connect(G_OBJECT(cancel_btn), "clicked",
254 G_CALLBACK(cancel_clicked), dialog);
256 vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
257 gtk_widget_show(vbox1);
258 gtk_box_pack_start(GTK_BOX(vbox), vbox1, TRUE, TRUE, 0);
259 gtk_container_set_border_width(GTK_CONTAINER(vbox1), 2);
261 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
262 gtk_widget_show(hbox);
263 gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
265 label1 = gtk_label_new(_
266 ("Move mailboxes up or down to change the sort order "
267 "in the Folder list."));
268 gtk_widget_show(label1);
269 gtk_widget_set_size_request(GTK_WIDGET(label1), 392, -1);
270 gtk_label_set_line_wrap(GTK_LABEL(label1), TRUE);
271 gtk_box_pack_start(GTK_BOX(hbox), label1, FALSE, FALSE, 0);
273 hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
274 gtk_widget_show(hbox2);
275 gtk_box_pack_start(GTK_BOX(vbox1), hbox2, TRUE, TRUE, 0);
277 scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL);
278 gtk_widget_show(scrolledwindow1);
279 gtk_widget_set_size_request(scrolledwindow1, -1, 150);
280 gtk_box_pack_start(GTK_BOX(hbox2), scrolledwindow1,
281 TRUE, TRUE, 0);
282 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolledwindow1),
283 GTK_POLICY_AUTOMATIC,
284 GTK_POLICY_AUTOMATIC);
286 /* Create the list store */
287 store = gtk_list_store_new(N_FOLDERSORT_COLS,
288 G_TYPE_STRING, G_TYPE_POINTER, -1);
290 /* Create the view widget */
291 folderlist = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
292 g_object_unref(store);
293 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(folderlist), TRUE);
294 gtk_tree_view_set_reorderable(GTK_TREE_VIEW(folderlist), TRUE);
295 selector = gtk_tree_view_get_selection(GTK_TREE_VIEW(folderlist));
296 gtk_tree_selection_set_mode(selector, GTK_SELECTION_BROWSE);
298 /* The only column for the view widget */
299 rdr = gtk_cell_renderer_text_new();
300 col = gtk_tree_view_column_new_with_attributes(_("Mailboxes"),
301 rdr, "markup", FOLDERSORT_COL_NAME, NULL);
302 gtk_tree_view_column_set_min_width(col, 80);
303 gtk_tree_view_append_column(GTK_TREE_VIEW(folderlist), col);
305 gtk_widget_show(folderlist);
306 gtk_container_add(GTK_CONTAINER(scrolledwindow1), folderlist);
308 btn_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8);
309 gtk_widget_show(btn_vbox);
310 gtk_box_pack_start(GTK_BOX(hbox2), btn_vbox, FALSE, FALSE, 0);
312 moveup_btn = gtkut_stock_button("go-up", _("_Up"));
313 gtk_widget_show(moveup_btn);
314 gtk_box_pack_start(GTK_BOX(btn_vbox), moveup_btn, FALSE, FALSE, 0);
315 CLAWS_SET_TIP(moveup_btn,
316 _("Move the selected mailbox up"));
318 movedown_btn = gtkut_stock_button("go-down", _("_Down"));
319 gtk_widget_show(movedown_btn);
320 gtk_box_pack_start(GTK_BOX(btn_vbox), movedown_btn, FALSE, FALSE, 0);
321 CLAWS_SET_TIP(movedown_btn,
322 _("Move the selected mailbox down"));
324 if (!geometry.min_height) {
325 geometry.min_width = 400;
326 geometry.min_height = 300;
329 gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
330 GDK_HINT_MIN_SIZE);
331 gtk_window_set_default_size(GTK_WINDOW(window),
332 prefs_common.foldersortwin_width,
333 prefs_common.foldersortwin_height);
335 dialog->window = window;
336 dialog->moveup_btn = moveup_btn;
337 dialog->movedown_btn = movedown_btn;
338 dialog->folderlist = folderlist;
340 gtk_widget_show(window);
341 gtk_widget_set_sensitive(moveup_btn, FALSE);
342 gtk_widget_set_sensitive(movedown_btn, FALSE);
344 /* Connect up the signals for the up/down buttons */
345 g_signal_connect(G_OBJECT(moveup_btn), "clicked",
346 G_CALLBACK(moveup_clicked), dialog);
347 g_signal_connect(G_OBJECT(movedown_btn), "clicked",
348 G_CALLBACK(movedown_clicked), dialog);
350 // g_signal_connect(G_OBJECT(folderlist), "select-row",
351 // G_CALLBACK(row_selected), dialog);
352 // g_signal_connect(G_OBJECT(folderlist), "unselect-row",
353 // G_CALLBACK(row_unselected), dialog);
354 // g_signal_connect(G_OBJECT(folderlist), "row-move",
355 // G_CALLBACK(row_moved), dialog);
357 /* Populate the list with mailboxes */
358 dialog->rows = 0;
359 for (flist = folder_get_list(); flist != NULL; flist = g_list_next(flist)) {
360 Folder *folder = flist->data;
362 gtk_list_store_append(store, &iter);
363 gtk_list_store_set(store, &iter,
364 FOLDERSORT_COL_NAME, folder->name,
365 FOLDERSORT_COL_PTR, folder,
366 -1);
367 dialog->rows++;
370 /* Connect up the signals for the folderlist */
371 g_signal_connect(G_OBJECT(folderlist), "cursor-changed",
372 G_CALLBACK(folderlist_cursor_changed_cb), dialog);
373 g_signal_connect(G_OBJECT(store), "row-inserted",
374 G_CALLBACK(folderlist_row_inserted_cb), dialog);
376 /* Select the first row and adjust the sensitivity of
377 * the up/down buttons */
378 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) {
379 gtk_tree_selection_select_iter(selector, &iter);
380 set_selected(dialog);
383 inc_lock();