Fix missing translation
[geeqie.git] / src / bar-rating.cc
1 /*
2  * Copyright (C) 2004 John Ellis
3  * Copyright (C) 2008 - 2022 The Geeqie Team
4  *
5  * Author: Colin Clark
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include "bar-rating.h"
23
24 #include <config.h>
25
26 #include "bar.h"
27 #include "compat.h"
28 #include "debug.h"
29 #include "filedata.h"
30 #include "intl.h"
31 #include "metadata.h"
32 #include "rcfile.h"
33 #include "ui-misc.h"
34
35 /**
36  * @file
37  * Rating values as specified by: \n
38  * Adobe XMP Basic namespace \n
39  * -1 Rejected \n
40  * 0 Unrated \n
41  * 1 to 5 Rating value
42  */
43
44 struct PaneRatingData
45 {
46         PaneData pane;
47         GtkWidget *widget;
48         GtkWidget *radio_button_first;
49         FileData *fd;
50         GtkCheckButton *rating_buttons[7];
51 };
52
53 static void bar_pane_rating_update(PaneRatingData *prd)
54 {
55         guint64 rating;
56
57         rating = metadata_read_int(prd->fd, RATING_KEY, 0) + 1;
58
59         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prd->rating_buttons[rating]), TRUE);
60 }
61
62 static void bar_pane_rating_set_fd(GtkWidget *pane, FileData *fd)
63 {
64         PaneRatingData *prd;
65
66         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
67         if (!prd) return;
68
69         file_data_unref(prd->fd);
70         prd->fd = file_data_ref(fd);
71
72         bar_pane_rating_update(prd);
73 }
74
75 static void bar_pane_rating_write_config(GtkWidget *pane, GString *outstr, gint indent)
76 {
77         PaneRatingData *prd;
78
79         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
80         if (!prd) return;
81
82         WRITE_NL();
83         WRITE_STRING("<pane_rating ");
84         write_char_option(outstr, indent, "id", prd->pane.id);
85         write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(prd->pane.title)));
86         WRITE_BOOL(prd->pane, expanded);
87         WRITE_STRING("/>");
88 }
89
90 static void bar_pane_rating_notify_cb(FileData *fd, NotifyType type, gpointer data)
91 {
92         auto prd = static_cast<PaneRatingData *>(data);
93
94         if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_HISTMAP | NOTIFY_PIXBUF)) && fd == prd->fd)
95                 {
96                 DEBUG_1("Notify pane_rating: %s %04x", fd->path, type);
97                 bar_pane_rating_update(prd);
98                 }
99 }
100
101 static void bar_pane_rating_destroy(GtkWidget *, gpointer data)
102 {
103         auto prd = static_cast<PaneRatingData *>(data);
104
105         file_data_unregister_notify_func(bar_pane_rating_notify_cb, prd);
106         file_data_unref(prd->fd);
107         g_free(prd->pane.id);
108         g_free(prd);
109 }
110
111 static void bar_pane_rating_selected_cb(GtkCheckButton *checkbutton, gpointer data)
112 {
113         auto prd = static_cast<PaneRatingData *>(data);
114         gchar *rating;
115
116 #ifdef HAVE_GTK4
117         const gchar *rating_label;
118
119         rating_label = gtk_check_button_get_label(checkbutton);
120
121         if (g_strcmp0(rating_label, "Rejected") == 0)
122                 {
123                 rating = g_strdup("-1");
124                 }
125         else if (g_strcmp0(rating_label, "Unrated") == 0)
126                 {
127                 rating = g_strdup("0");
128                 }
129         else
130                 {
131                 rating = g_strdup(rating_label);
132                 }
133
134         metadata_write_string(prd->fd, RATING_KEY, rating);
135
136         g_free(rating);
137 #else
138         gint i;
139
140         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton)))
141                 {
142                 i = 0;
143                 while (i < 7)
144                         {
145                         if (prd->rating_buttons[i] == checkbutton)
146                                 {
147                                 rating = g_strdup_printf("%d",   i - 1 );
148                                 metadata_write_string(prd->fd, RATING_KEY, rating);
149                                 g_free(rating);
150                                 break;
151                                 }
152
153                         i++;
154                         }
155                 }
156 #endif
157 }
158
159 static GtkWidget *bar_pane_rating_new(const gchar *id, const gchar *title, gboolean expanded)
160 {
161         PaneRatingData *prd;
162         GtkWidget *radio_rejected;
163         GtkWidget *radio_unrated;
164         GtkWidget *radio_rating;
165         GtkWidget *row_1;
166         GtkWidget *row_2;
167         gint i;
168         gchar *i_str;
169
170         prd = g_new0(PaneRatingData, 1);
171
172         prd->pane.pane_set_fd = bar_pane_rating_set_fd;
173         prd->pane.pane_write_config = bar_pane_rating_write_config;
174         prd->pane.title = bar_pane_expander_title(title);
175         prd->pane.id = g_strdup(id);
176         prd->pane.type = PANE_RATING;
177
178         prd->pane.expanded = expanded;
179
180         prd->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
181
182         g_object_set_data(G_OBJECT(prd->widget), "pane_data", prd);
183         g_signal_connect(G_OBJECT(prd->widget), "destroy", G_CALLBACK(bar_pane_rating_destroy), prd);
184
185         row_1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);
186         gq_gtk_box_pack_start(GTK_BOX(prd->widget), row_1, FALSE, FALSE, 0);
187
188 #ifdef HAVE_GTK4
189         radio_rejected = gtk_check_button_new_with_label(_("Rejected"));
190 #else
191         radio_rejected = gtk_radio_button_new_with_label(nullptr, _("Rejected"));
192 #endif
193         gq_gtk_box_pack_start(GTK_BOX(row_1), radio_rejected, FALSE, FALSE, 0);
194         g_signal_connect(radio_rejected, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
195         prd->rating_buttons[0] = GTK_CHECK_BUTTON(radio_rejected);
196
197 #ifdef HAVE_GTK4
198         radio_unrated = gtk_check_button_new_with_label(_("Unrated"));
199         gtk_check_button_set_group(GTK_CHECK_BUTTON(radio_unrated), GTK_CHECK_BUTTON(radio_rejected));
200 #else
201         radio_unrated = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio_rejected), _("Unrated"));
202 #endif
203         gq_gtk_box_pack_start(GTK_BOX(row_1), radio_unrated, FALSE, FALSE, 0);
204         g_signal_connect(radio_unrated, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
205         prd->rating_buttons[1] = GTK_CHECK_BUTTON(radio_unrated);
206
207         row_2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);
208         gq_gtk_box_pack_start(GTK_BOX(prd->widget), row_2, FALSE, FALSE, 0);
209
210         i = 2;
211         while (i <= 6)
212                 {
213                 i_str = g_strdup_printf("%d", i - 1);
214
215 #ifdef HAVE_GTK4
216                 radio_rating = gtk_check_button_new_with_label(i_str);
217                 gtk_check_button_set_group(GTK_CHECK_BUTTON(radio_rating), GTK_CHECK_BUTTON(radio_rejected));
218 #else
219                 radio_rating = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio_rejected), i_str);
220 #endif
221                 g_signal_connect(radio_rating, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
222
223                 gq_gtk_box_pack_start(GTK_BOX(row_2), radio_rating, FALSE, FALSE, 1);
224                 prd->rating_buttons[i ] = GTK_CHECK_BUTTON(radio_rating);
225
226                 g_free(i_str);
227                 i++;
228                 }
229
230         prd->radio_button_first = radio_rating;
231
232         gtk_widget_show(prd->widget);
233
234         file_data_register_notify_func(bar_pane_rating_notify_cb, prd, NOTIFY_PRIORITY_LOW);
235
236         return prd->widget;
237 }
238
239 GtkWidget *bar_pane_rating_new_from_config(const gchar **attribute_names, const gchar **attribute_values)
240 {
241         gchar *title = nullptr;
242         gchar *id = g_strdup("rating");
243         gboolean expanded = TRUE;
244         GtkWidget *ret;
245
246         while (*attribute_names)
247                 {
248                 const gchar *option = *attribute_names++;
249                 const gchar *value = *attribute_values++;
250
251                 if (READ_CHAR_FULL("id", id)) continue;
252                 if (READ_CHAR_FULL("title", title)) continue;
253                 if (READ_BOOL_FULL("expanded", expanded)) continue;
254
255                 log_printf("unknown attribute %s = %s\n", option, value);
256                 }
257
258         bar_pane_translate_title(PANE_RATING, id, &title);
259         ret = bar_pane_rating_new(id, title, expanded);
260
261         g_free(title);
262         g_free(id);
263         return ret;
264 }
265
266 void bar_pane_rating_update_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values)
267 {
268         PaneRatingData *prd;
269         gchar *title = nullptr;
270
271         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
272         if (!prd) return;
273
274         while (*attribute_names)
275                 {
276                 const gchar *option = *attribute_names++;
277                 const gchar *value = *attribute_values++;
278
279                 if (READ_CHAR_FULL("title", title)) continue;
280                 if (READ_CHAR_FULL("id", prd->pane.id)) continue;
281                 if (READ_BOOL_FULL("expanded", prd->pane.expanded)) continue;
282
283                 log_printf("unknown attribute %s = %s\n", option, value);
284                 }
285
286         bar_update_expander(pane);
287         bar_pane_rating_update(prd);
288 }
289 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */