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