Remove unused RendererTiles::tile_cols
[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 <glib-object.h>
25
26 #include <config.h>
27
28 #include "bar.h"
29 #include "compat.h"
30 #include "debug.h"
31 #include "filedata.h"
32 #include "intl.h"
33 #include "metadata.h"
34 #include "rcfile.h"
35 #include "typedefs.h"
36 #include "ui-misc.h"
37
38 /**
39  * @file
40  * Rating values as specified by: \n
41  * Adobe XMP Basic namespace \n
42  * -1 Rejected \n
43  * 0 Unrated \n
44  * 1 to 5 Rating value
45  */
46
47 struct PaneRatingData
48 {
49         PaneData pane;
50         GtkWidget *widget;
51         GtkWidget *radio_button_first;
52         FileData *fd;
53         GtkCheckButton *rating_buttons[7];
54 };
55
56 static void bar_pane_rating_update(PaneRatingData *prd)
57 {
58         guint64 rating;
59
60         rating = metadata_read_int(prd->fd, RATING_KEY, 0) + 1;
61
62         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prd->rating_buttons[rating]), TRUE);
63 }
64
65 static void bar_pane_rating_set_fd(GtkWidget *pane, FileData *fd)
66 {
67         PaneRatingData *prd;
68
69         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
70         if (!prd) return;
71
72         file_data_unref(prd->fd);
73         prd->fd = file_data_ref(fd);
74
75         bar_pane_rating_update(prd);
76 }
77
78 static void bar_pane_rating_write_config(GtkWidget *pane, GString *outstr, gint indent)
79 {
80         PaneRatingData *prd;
81
82         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
83         if (!prd) return;
84
85         WRITE_NL();
86         WRITE_STRING("<pane_rating ");
87         write_char_option(outstr, indent, "id", prd->pane.id);
88         write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(prd->pane.title)));
89         WRITE_BOOL(prd->pane, expanded);
90         WRITE_STRING("/>");
91 }
92
93 static void bar_pane_rating_notify_cb(FileData *fd, NotifyType type, gpointer data)
94 {
95         auto prd = static_cast<PaneRatingData *>(data);
96
97         if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_HISTMAP | NOTIFY_PIXBUF)) && fd == prd->fd)
98                 {
99                 DEBUG_1("Notify pane_rating: %s %04x", fd->path, type);
100                 bar_pane_rating_update(prd);
101                 }
102 }
103
104 static void bar_pane_rating_destroy(GtkWidget *, gpointer data)
105 {
106         auto prd = static_cast<PaneRatingData *>(data);
107
108         file_data_unregister_notify_func(bar_pane_rating_notify_cb, prd);
109         file_data_unref(prd->fd);
110         g_free(prd->pane.id);
111         g_free(prd);
112 }
113
114 static void bar_pane_rating_selected_cb(GtkCheckButton *checkbutton, gpointer data)
115 {
116         auto prd = static_cast<PaneRatingData *>(data);
117         gchar *rating;
118
119 #if HAVE_GTK4
120         const gchar *rating_label;
121
122         rating_label = gtk_check_button_get_label(checkbutton);
123
124         if (g_strcmp0(rating_label, "Rejected") == 0)
125                 {
126                 rating = g_strdup("-1");
127                 }
128         else if (g_strcmp0(rating_label, "Unrated") == 0)
129                 {
130                 rating = g_strdup("0");
131                 }
132         else
133                 {
134                 rating = g_strdup(rating_label);
135                 }
136
137         metadata_write_string(prd->fd, RATING_KEY, rating);
138
139         g_free(rating);
140 #else
141         gint i;
142
143         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton)))
144                 {
145                 i = 0;
146                 while (i < 7)
147                         {
148                         if (prd->rating_buttons[i] == checkbutton)
149                                 {
150                                 rating = g_strdup_printf("%d",   i - 1 );
151                                 metadata_write_string(prd->fd, RATING_KEY, rating);
152                                 g_free(rating);
153                                 break;
154                                 }
155
156                         i++;
157                         }
158                 }
159 #endif
160 }
161
162 static GtkWidget *bar_pane_rating_new(const gchar *id, const gchar *title, gboolean expanded)
163 {
164         PaneRatingData *prd;
165         GtkWidget *radio_rejected;
166         GtkWidget *radio_unrated;
167         GtkWidget *radio_rating;
168         GtkWidget *row_1;
169         GtkWidget *row_2;
170         gint i;
171         gchar *i_str;
172
173         prd = g_new0(PaneRatingData, 1);
174
175         prd->pane.pane_set_fd = bar_pane_rating_set_fd;
176         prd->pane.pane_write_config = bar_pane_rating_write_config;
177         prd->pane.title = bar_pane_expander_title(title);
178         prd->pane.id = g_strdup(id);
179         prd->pane.type = PANE_RATING;
180
181         prd->pane.expanded = expanded;
182
183         prd->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
184
185         g_object_set_data(G_OBJECT(prd->widget), "pane_data", prd);
186         g_signal_connect(G_OBJECT(prd->widget), "destroy", G_CALLBACK(bar_pane_rating_destroy), prd);
187
188         row_1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);
189         gq_gtk_box_pack_start(GTK_BOX(prd->widget), row_1, FALSE, FALSE, 0);
190
191 #if HAVE_GTK4
192         radio_rejected = gtk_check_button_new_with_label(_("Rejected"));
193 #else
194         radio_rejected = gtk_radio_button_new_with_label(nullptr, _("Rejected"));
195 #endif
196         gq_gtk_box_pack_start(GTK_BOX(row_1), radio_rejected, FALSE, FALSE, 0);
197         g_signal_connect(radio_rejected, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
198         prd->rating_buttons[0] = GTK_CHECK_BUTTON(radio_rejected);
199
200 #if HAVE_GTK4
201         radio_unrated = gtk_check_button_new_with_label(_("Unrated"));
202         gtk_check_button_set_group(GTK_CHECK_BUTTON(radio_unrated), GTK_CHECK_BUTTON(radio_rejected));
203 #else
204         radio_unrated = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio_rejected), _("Unrated"));
205 #endif
206         gq_gtk_box_pack_start(GTK_BOX(row_1), radio_unrated, FALSE, FALSE, 0);
207         g_signal_connect(radio_unrated, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
208         prd->rating_buttons[1] = GTK_CHECK_BUTTON(radio_unrated);
209
210         row_2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);
211         gq_gtk_box_pack_start(GTK_BOX(prd->widget), row_2, FALSE, FALSE, 0);
212
213         i = 2;
214         while (i <= 6)
215                 {
216                 i_str = g_strdup_printf("%d", i - 1);
217
218 #if HAVE_GTK4
219                 radio_rating = gtk_check_button_new_with_label(i_str);
220                 gtk_check_button_set_group(GTK_CHECK_BUTTON(radio_rating), GTK_CHECK_BUTTON(radio_rejected));
221 #else
222                 radio_rating = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio_rejected), i_str);
223 #endif
224                 g_signal_connect(radio_rating, "released", G_CALLBACK(bar_pane_rating_selected_cb), prd);
225
226                 gq_gtk_box_pack_start(GTK_BOX(row_2), radio_rating, FALSE, FALSE, 1);
227                 prd->rating_buttons[i ] = GTK_CHECK_BUTTON(radio_rating);
228
229                 g_free(i_str);
230                 i++;
231                 }
232
233         prd->radio_button_first = radio_rating;
234
235         gtk_widget_show(prd->widget);
236
237         file_data_register_notify_func(bar_pane_rating_notify_cb, prd, NOTIFY_PRIORITY_LOW);
238
239         return prd->widget;
240 }
241
242 GtkWidget *bar_pane_rating_new_from_config(const gchar **attribute_names, const gchar **attribute_values)
243 {
244         gchar *title = nullptr;
245         gchar *id = g_strdup("rating");
246         gboolean expanded = TRUE;
247         GtkWidget *ret;
248
249         while (*attribute_names)
250                 {
251                 const gchar *option = *attribute_names++;
252                 const gchar *value = *attribute_values++;
253
254                 if (READ_CHAR_FULL("id", id)) continue;
255                 if (READ_CHAR_FULL("title", title)) continue;
256                 if (READ_BOOL_FULL("expanded", expanded)) continue;
257
258                 log_printf("unknown attribute %s = %s\n", option, value);
259                 }
260
261         bar_pane_translate_title(PANE_RATING, id, &title);
262         ret = bar_pane_rating_new(id, title, expanded);
263
264         g_free(title);
265         g_free(id);
266         return ret;
267 }
268
269 void bar_pane_rating_update_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values)
270 {
271         PaneRatingData *prd;
272         gchar *title = nullptr;
273
274         prd = static_cast<PaneRatingData *>(g_object_get_data(G_OBJECT(pane), "pane_data"));
275         if (!prd) return;
276
277         while (*attribute_names)
278                 {
279                 const gchar *option = *attribute_names++;
280                 const gchar *value = *attribute_values++;
281
282                 if (READ_CHAR_FULL("title", title)) continue;
283                 if (READ_CHAR_FULL("id", prd->pane.id)) continue;
284                 if (READ_BOOL_FULL("expanded", prd->pane.expanded)) continue;
285
286                 log_printf("unknown attribute %s = %s\n", option, value);
287                 }
288
289         bar_update_expander(pane);
290         bar_pane_rating_update(prd);
291 }
292 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */