1 /*
2 * Copyright © 2003 Callum McKenzie <callum@physics.otago.ac.nz>
3 * Copyright © 2007 Christian Persch
4 *
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.
9 *
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.
14 *
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/>.
17 */
18
19 #include <config.h>
20
21 #include <glib/gi18n.h>
22
23 #include <gtk/gtk.h>
24
25 #include "util.h"
26
27 #include "ar-stock.h"
28
29 #include "conf.h"
30 #include "util.h"
31
32 #include "stats-dialog.h"
33
34 #define AISLERIOT_STATS_DIALOG_GET_PRIVATE(stats_dialog)(G_TYPE_INSTANCE_GET_PRIVATE ((stats_dialog), AISLERIOT_TYPE_STATS_DIALOG, AisleriotStatsDialogPrivate))
35
36 struct _AisleriotStatsDialogPrivate
37 {
38 GtkLabel *game_label;
39 GtkLabel *wins_label;
40 GtkLabel *total_label;
41 GtkLabel *percentage_label;
42 GtkLabel *best_label;
43 GtkLabel *worst_label;
44 };
45
46 G_DEFINE_TYPE (AisleriotStatsDialog, aisleriot_stats_dialog, GTK_TYPE_DIALOG);
47
48 /* helper functions */
49
50 static void
pack_in_frame(GtkWidget * box,GtkWidget * content,const char * text)51 pack_in_frame (GtkWidget *box,
52 GtkWidget *content,
53 const char *text)
54 {
55 GtkWidget *frame, *alignment, *label;
56 char *markup;
57
58 markup = g_markup_printf_escaped ("<b>%s</b>", text);
59 label = gtk_label_new (markup);
60 g_free (markup);
61 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
62 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
63
64 frame = gtk_vbox_new (FALSE, 6);
65 gtk_box_pack_start (GTK_BOX (frame), label, FALSE, FALSE, 0);
66
67 alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
68 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
69 0, 0, 12, 0);
70 gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0);
71
72 gtk_container_add (GTK_CONTAINER (alignment), content);
73
74 gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 0);
75 gtk_widget_show_all (frame);
76
77 ar_atk_util_add_atk_relation (label, frame, ATK_RELATION_LABEL_FOR);
78 ar_atk_util_add_atk_relation (frame, label, ATK_RELATION_LABELLED_BY);
79 }
80
81 static GtkLabel *
add_row(GtkTable * table,int row,const char * text)82 add_row (GtkTable *table,
83 int row,
84 const char *text)
85 {
86 GtkWidget *label, *data_label;
87
88 label = gtk_label_new (text);
89 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
90 gtk_table_attach (table, label,
91 0, 1, row, row + 1,
92 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
93
94 data_label = gtk_label_new (NULL);
95 gtk_misc_set_alignment (GTK_MISC (data_label), 0.0, 0.5);
96 gtk_label_set_selectable (GTK_LABEL (data_label), TRUE);
97 gtk_table_attach_defaults (table, data_label,
98 1, 2, row, row + 1);
99
100 ar_atk_util_add_atk_relation (label, data_label, ATK_RELATION_LABEL_FOR);
101 ar_atk_util_add_atk_relation (data_label, label, ATK_RELATION_LABELLED_BY);
102
103 return GTK_LABEL (data_label);
104 }
105
106 /* Class implementation */
107
108 static void
aisleriot_stats_dialog_init(AisleriotStatsDialog * stats_dialog)109 aisleriot_stats_dialog_init (AisleriotStatsDialog *stats_dialog)
110 {
111 AisleriotStatsDialogPrivate *priv;
112 GtkDialog *dialog = GTK_DIALOG (stats_dialog);
113 GtkWidget *vbox, *hbox, *content_area, *action_area;
114 GtkTable *table;
115
116 priv = stats_dialog->priv = AISLERIOT_STATS_DIALOG_GET_PRIVATE (stats_dialog);
117
118 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
119
120 content_area = gtk_dialog_get_content_area (dialog);
121
122 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
123 gtk_box_set_spacing (GTK_BOX (content_area), 2);
124
125 vbox = gtk_vbox_new (FALSE, 18);
126 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
127 gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0);
128 gtk_widget_show (vbox);
129
130 priv->game_label = GTK_LABEL (gtk_label_new (NULL));
131 gtk_label_set_use_markup (priv->game_label, TRUE);
132 gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->game_label),
133 FALSE, FALSE, 0);
134 gtk_widget_show (GTK_WIDGET (priv->game_label));
135
136 hbox = gtk_hbox_new (TRUE, 18);
137 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
138 gtk_widget_show (hbox);
139
140 table = GTK_TABLE (gtk_table_new (3, 2, FALSE));
141 gtk_table_set_row_spacings (table, 6);
142 gtk_table_set_col_spacings (table, 12);
143
144 /* Translators: this is the total number of won games */
145 priv->wins_label = add_row (table, 0, _("Wins:"));
146 /* Translators: this is the number of games played */
147 priv->total_label = add_row (table, 1, _("Total:"));
148 /* Translators: this is the percentage of games won out of all games played */
149 priv->percentage_label = add_row (table, 2, _("Percentage:"));
150 /* Translators: this is the section title of a section which contains the n
151 * number of games played, number of games won, and the ratio of these 2 numbers.
152 */
153 pack_in_frame (hbox, GTK_WIDGET (table), _("Wins"));
154
155 table = GTK_TABLE (gtk_table_new (2, 2, FALSE));
156 gtk_table_set_row_spacings (table, 6);
157 gtk_table_set_col_spacings (table, 12);
158
159 /* Translators: this is the best time of all wins */
160 priv->best_label = add_row (table, 0, _("Best:"));
161 /* Translators: this is the worst time of all wins */
162 priv->worst_label = add_row (table, 1, _("Worst:"));
163 /* Translators: this is the section title of a section containing the
164 * best and worst time taken to win a game.
165 */
166 pack_in_frame (hbox, GTK_WIDGET (table), _("Time"));
167
168 gtk_dialog_add_buttons (dialog,
169 AR_STOCK_RESET, GTK_RESPONSE_REJECT,
170 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
171 NULL);
172 gtk_dialog_set_alternative_button_order (dialog,
173 GTK_RESPONSE_CLOSE,
174 GTK_RESPONSE_REJECT,
175 -1);
176 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
177
178 gtk_window_set_title (GTK_WINDOW (dialog), "");
179 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
180
181 /* Fixup dialogue padding, #735242 */
182 action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
183 gtk_widget_set_margin_left (action_area, 5);
184 gtk_widget_set_margin_right (action_area, 5);
185 gtk_widget_set_margin_top (action_area, 5);
186 gtk_widget_set_margin_bottom (action_area, 5);
187 }
188
189 static void
aisleriot_stats_dialog_class_init(AisleriotStatsDialogClass * klass)190 aisleriot_stats_dialog_class_init (AisleriotStatsDialogClass *klass)
191 {
192 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
193
194 g_type_class_add_private (gobject_class, sizeof (AisleriotStatsDialogPrivate));
195 }
196
197 /* public API */
198
199 AisleriotStatsDialog *
aisleriot_stats_dialog_new(void)200 aisleriot_stats_dialog_new (void)
201 {
202 return g_object_new (AISLERIOT_TYPE_STATS_DIALOG,
203 "title", _("Statistics"),
204 NULL);
205 }
206
207 void
aisleriot_stats_dialog_update(AisleriotStatsDialog * dialog,AisleriotStatistic * current_stats)208 aisleriot_stats_dialog_update (AisleriotStatsDialog *dialog,
209 AisleriotStatistic *current_stats)
210 {
211 AisleriotStatsDialogPrivate *priv = dialog->priv;
212 char text[128];
213
214 /* Translators: Translate this to "%Id" if you want to use localised digits,
215 * and to "%d" otherwise. Do not translate it to anything else!
216 */
217 g_snprintf (text, sizeof (text), _("%d"), current_stats->wins);
218 gtk_label_set_text (priv->wins_label, text);
219
220 /* Translators: Translate this to "%Id" if you want to use localised digits,
221 * and to "%d" otherwise. Do not translate it to anything else!
222 */
223 g_snprintf (text, sizeof (text), _("%d"), current_stats->total);
224 gtk_label_set_text (priv->total_label, text);
225
226 if (current_stats->total != 0) {
227 /* Translators: Translate the "%d" in this string this to "%Id" if you
228 * want to use localised digits, and to "%d" otherwise.
229 * Do not translate the "%d" part to anything else!
230 * You may translate the "%%" part to use any other percent character(s)
231 * instead, or leave it as "%%". If you chose a character other than
232 * "%" (U+0025 PERCENT SIGN) you do NOT need to escape it with another "%"!
233 */
234 g_snprintf (text, sizeof (text), _("%d%%"),
235 (int) (100.0 * ((double) current_stats->wins) / ((double) current_stats->total) + 0.5));
236 gtk_label_set_text (priv->percentage_label, text);
237 } else
238 /* For translators: N/A means "Not Applicable", use whatever
239 * abbreviation you have for a value that has no meaning. */
240 gtk_label_set_text (priv->percentage_label, _("N/A"));
241
242 if (current_stats->best != 0) {
243 /* Translators: this represents minutes:seconds. */
244 g_snprintf (text, sizeof (text), _("%d:%02d"),
245 current_stats->best / 60,
246 current_stats->best % 60);
247 gtk_label_set_text (priv->best_label, text);
248 } else
249 gtk_label_set_text (priv->best_label, _("N/A"));
250
251 if (current_stats->worst != 0) {
252 g_snprintf (text, sizeof (text), _("%d:%02d"),
253 current_stats->worst / 60,
254 current_stats->worst % 60);
255 gtk_label_set_text (priv->worst_label, text);
256 } else
257 gtk_label_set_text (priv->worst_label, _("N/A"));
258 }
259
260 void
aisleriot_stats_dialog_set_name(AisleriotStatsDialog * dialog,const char * game_name)261 aisleriot_stats_dialog_set_name (AisleriotStatsDialog *dialog,
262 const char *game_name)
263 {
264 AisleriotStatsDialogPrivate *priv = dialog->priv;
265 char *markup;
266
267 markup = g_markup_printf_escaped ("<b>%s</b>", game_name);
268 gtk_label_set_markup (priv->game_label, markup);
269 g_free (markup);
270 }
271