]> git.sur5r.net Git - glabels/blob - src/label-properties-dialog.c
Add properties dialog
[glabels] / src / label-properties-dialog.c
1 /*
2  *  label-properties-dialog.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels 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 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels 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
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "label-properties-dialog.h"
24
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27
28 #include "builder-util.h"
29 #include "prefs.h"
30 #include "mini-preview.h"
31 #include "window.h"
32 #include "debug.h"
33
34
35 #define MINI_PREVIEW_MIN_WIDTH  270
36 #define MINI_PREVIEW_MIN_HEIGHT 360
37
38
39 /*========================================================*/
40 /* Private types.                                         */
41 /*========================================================*/
42
43 typedef struct
44 {
45         glLabel        *label;
46         GtkBox         *box;
47         GtkWidget      *preview;
48         GtkLabel       *vendor;
49         GtkLabel       *partnum;
50         GtkLabel       *description;
51         GtkLabel       *dimensions;
52         GtkLabel       *medium;
53         GtkLabel       *layout;
54         GtkLabel       *margins;
55         GtkLabel       *similar_label;
56         GtkLabel       *similar;
57         GtkLabel       *orientation_label;
58         GtkBox         *orientation_box;
59         GtkRadioButton *normal_orientation;
60         GtkRadioButton *rotated_orientation;
61
62 } glLabelPropertiesDialogPrivate;
63
64
65 struct _glLabelPropertiesDialog
66 {
67         GtkDialog                       parent;
68
69         glLabelPropertiesDialogPrivate *priv;
70 };
71
72
73
74 /*========================================================*/
75 /* Private function prototypes                            */
76 /*========================================================*/
77
78 static void gl_label_properties_dialog_finalize    (GObject *object);
79
80 static void gl_label_properties_dialog_rotation_cb (glLabelPropertiesDialog *dialog);
81
82 static void gl_label_properties_dialog_response_cb (glLabelPropertiesDialog *dialog,
83                                                     gint                     response);
84
85 static void gl_label_properties_dialog_construct   (glLabelPropertiesDialog *dialog,
86                                                     glLabel                 *label);
87
88
89 /*========================================================*/
90 /* Private globals.                                       */
91 /*========================================================*/
92
93
94 /*****************************************************************************/
95 /* Boilerplate object stuff.                                                 */
96 /*****************************************************************************/
97
98 G_DEFINE_TYPE_WITH_PRIVATE (glLabelPropertiesDialog, gl_label_properties_dialog, GTK_TYPE_DIALOG)
99
100
101
102 static void
103 gl_label_properties_dialog_class_init (glLabelPropertiesDialogClass *class)
104 {
105         GObjectClass *object_class = G_OBJECT_CLASS (class);
106
107         gl_debug (DEBUG_UI, "");
108
109         object_class->finalize = gl_label_properties_dialog_finalize;
110 }
111
112
113 static void
114 gl_label_properties_dialog_rotation_cb (glLabelPropertiesDialog *dialog)
115 {
116         gboolean  rotate_flag;
117         glWindow *window;
118         glView   *view;
119
120         gl_debug (DEBUG_UI, "START");
121
122         rotate_flag = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->rotated_orientation));
123         gl_mini_preview_set_rotate (GL_MINI_PREVIEW (dialog->priv->preview), rotate_flag);
124         gl_label_set_rotate_flag (dialog->priv->label, rotate_flag, TRUE);
125
126         window = GL_WINDOW (gtk_window_get_transient_for (GTK_WINDOW (dialog)));
127         view = GL_VIEW (window->view);
128         if (view->zoom_to_fit_flag)
129                 gl_view_zoom_to_fit (view);
130
131         gl_debug (DEBUG_UI, "END");
132 }
133
134
135 static void
136 gl_label_properties_dialog_response_cb (glLabelPropertiesDialog *dialog,
137                                         gint                     response)
138 {
139         gl_debug (DEBUG_UI, "START");
140
141         switch (response)
142         {
143         case GL_RESPONSE_SELECT_OTHER:
144         case GTK_RESPONSE_CLOSE:
145         case GTK_RESPONSE_DELETE_EVENT:
146                 gtk_widget_hide (GTK_WIDGET (dialog));
147                 break;
148         default:
149                 g_print ("response = %d", response);
150                 g_assert_not_reached ();
151         }
152
153         gl_debug (DEBUG_UI, "END");
154 }
155
156
157 static void
158 gl_label_properties_dialog_init (glLabelPropertiesDialog *dialog)
159 {
160         gchar             *builder_filename;
161         GtkBuilder        *builder;
162         static gchar      *object_ids[] = {"label_properties_box", NULL};
163         GError            *error = NULL;
164         GtkWidget         *vbox;
165
166         gl_debug (DEBUG_UI, "START");
167
168         dialog->priv = gl_label_properties_dialog_get_instance_private (dialog);
169
170         vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
171
172         /*Translators: Button label to choose different template*/
173         gtk_dialog_add_button (GTK_DIALOG (dialog), _("Choose _other…"), GL_RESPONSE_SELECT_OTHER);
174         gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Close"), GTK_RESPONSE_CLOSE);
175         gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
176
177         builder = gtk_builder_new ();
178         builder_filename = g_build_filename (GLABELS_DATA_DIR, "ui", "label-properties-dialog.ui", NULL);
179         gtk_builder_add_objects_from_file (builder, builder_filename, object_ids, &error);
180         g_free (builder_filename);
181         if (error) {
182                 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
183                 g_error_free (error);
184                 return;
185         }
186
187         gl_builder_util_get_widgets (builder,
188                                      "label_properties_box", &dialog->priv->box,
189                                      "vendor_value", &dialog->priv->vendor,
190                                      "partnum_value", &dialog->priv->partnum,
191                                      "description_value", &dialog->priv->description,
192                                      "dimensions_value", &dialog->priv->dimensions,
193                                      "medium_value", &dialog->priv->medium,
194                                      "layout_value", &dialog->priv->layout,
195                                      "margins_value", &dialog->priv->margins,
196                                      "similar_label", &dialog->priv->similar_label,
197                                      "similar_value", &dialog->priv->similar,
198                                      "orientation_label", &dialog->priv->orientation_label,
199                                      "orientation_box", &dialog->priv->orientation_box,
200                                      "orientation_normal_radio", &dialog->priv->normal_orientation,
201                                      "orientation_rotated_radio", &dialog->priv->rotated_orientation,
202                                      NULL);
203
204         gtk_container_add (GTK_CONTAINER (vbox), GTK_WIDGET (dialog->priv->box));
205
206         dialog->priv->preview = gl_mini_preview_new (MINI_PREVIEW_MIN_HEIGHT, MINI_PREVIEW_MIN_WIDTH);
207         gtk_box_pack_start (dialog->priv->box, GTK_WIDGET (dialog->priv->preview), FALSE, FALSE, 0);
208         gtk_widget_show_all (dialog->priv->preview);
209
210         g_object_unref (G_OBJECT (builder));
211
212         gl_debug (DEBUG_UI, "END");
213 }
214
215
216 static void
217 gl_label_properties_dialog_finalize (GObject *object)
218 {
219         glLabelPropertiesDialog* dialog = GL_LABEL_PROPERTIES_DIALOG (object);
220
221         gl_debug (DEBUG_UI, "START");
222
223         g_return_if_fail (object != NULL);
224         g_return_if_fail (GL_IS_LABEL_PROPERTIES_DIALOG (dialog));
225         g_return_if_fail (dialog->priv != NULL);
226
227
228         G_OBJECT_CLASS (gl_label_properties_dialog_parent_class)->finalize (object);
229
230         gl_debug (DEBUG_UI, "END");
231 }
232
233
234 /* FIXME: Move this function to library */
235 static void
236 lgl_template_get_margins (const lglTemplate *template,
237                           gdouble           *hmargin,
238                           gdouble           *vmargin)
239 {
240         GList                   *p, *q;
241         const lglTemplateFrame  *frame;
242         const lglTemplateLayout *layout;
243
244         /* Set margins to maximum */
245         *hmargin = template->page_width;
246         *vmargin = template->page_height;
247
248         /* and search lowest margin in layouts */
249         for (p = template->frames; p; p = p->next)
250         {
251                 frame = (lglTemplateFrame *)p->data;
252                 for (q = frame->all.layouts; q; q = q->next)
253                 {
254                         layout = (lglTemplateLayout *)q->data;
255                         if (layout->x0 < *hmargin)
256                                 *hmargin = layout->x0;
257                         if (layout->y0 < *vmargin)
258                                 *vmargin = layout->y0;
259                 }
260         }
261 }
262
263 /* FIXME: Move this function to library */
264 gchar *
265 lgl_template_get_margins_string (const lglTemplate *template)
266 {
267         lglUnits  units;
268         gdouble   units_per_point;
269         gdouble   hmargin, vmargin;
270         gchar    *hmargin_str, *vmargin_str;
271         gchar    *margins_str;
272
273         units = gl_prefs_model_get_units (gl_prefs);
274         units_per_point = lgl_units_get_units_per_point (units);
275
276         lgl_template_get_margins (template, &hmargin, &vmargin);
277
278         if (units == LGL_UNITS_INCH)
279         {
280                 hmargin_str = lgl_str_format_fraction (hmargin*units_per_point);
281                 vmargin_str = lgl_str_format_fraction (vmargin*units_per_point);
282         }
283         else
284         {
285                 hmargin_str = g_strdup_printf ("%.5g", hmargin*units_per_point);
286                 vmargin_str = g_strdup_printf ("%.5g", vmargin*units_per_point);
287         }
288
289         /*Translators: first param is numeric value of horizontal margine, second*/
290         /*is numeric value of vertical margine and third is unit. Example:       */
291         /*"10 / 12.5 mm (horizontal / vertical)"*/
292         margins_str = g_strdup_printf (_("%s / %s %s (horizontal / vertical)"),
293                                        hmargin_str, vmargin_str, lgl_units_get_name (units));
294
295         g_free (hmargin_str);
296         g_free (vmargin_str);
297
298         return margins_str;
299 }
300
301 /*--------------------------------------------------------------------------*/
302 /* PRIVATE.  Create properties widgets.                                          */
303 /*--------------------------------------------------------------------------*/
304 static void
305 gl_label_properties_dialog_construct (glLabelPropertiesDialog *dialog,
306                                       glLabel                 *label)
307 {
308         const lglTemplate *template;
309         gchar             *template_name;
310         lglUnits           units;
311         gdouble            units_per_point;
312         lglVendor         *vendor;
313         gchar             *text;
314         gchar             *link;
315         gchar             *escaped_url;
316         GList             *list, *p;
317         GString           *list_text;
318         gboolean           rotate_flag;
319         gdouble            w, h;
320
321         gl_debug (DEBUG_UI, "START");
322
323         dialog->priv->label = label;
324
325         template = gl_label_get_template (label);
326         template_name = lgl_template_get_name (template);
327         units = gl_prefs_model_get_units (gl_prefs);
328         units_per_point = lgl_units_get_units_per_point (units);
329
330         /* Vendor */
331         vendor = lgl_db_lookup_vendor_from_name (template->brand);
332         if (vendor && vendor->url)
333         {
334                 escaped_url = g_markup_escape_text (vendor->url, -1);
335                 link = g_strconcat ("<a href=\"", escaped_url , "\">", template->brand, "</a>", NULL);
336                 gtk_label_set_markup (dialog->priv->vendor, link);
337                 g_free (escaped_url);
338                 g_free (link);
339         }
340         else
341         {
342                 gtk_label_set_label (dialog->priv->vendor, template->brand);
343         }
344
345         /* Part number */
346         if (template->product_url)
347         {
348                 escaped_url = g_markup_escape_text (template->product_url, -1);
349                 link = g_strconcat ("<a href=\"", escaped_url, "\">", template->part, "</a>", NULL);
350                 gtk_label_set_markup (dialog->priv->partnum, link);
351                 g_free (escaped_url);
352                 g_free (link);
353         }
354         else
355         {
356                 gtk_label_set_label (dialog->priv->partnum, template->part);
357         }
358
359         /* Description */
360         gtk_label_set_label (dialog->priv->description, template->description);
361
362         /* Dimensions */
363         text = gl_label_get_dimensions_string (label);
364         gtk_label_set_label (dialog->priv->dimensions, text);
365         g_free (text);
366
367         /* Medium */
368         text = lgl_db_lookup_paper_name_from_id (template->paper_id);
369         gtk_label_set_label (dialog->priv->medium, text);
370         g_free (text);
371
372         /* Layout */
373         text = lgl_template_frame_get_layout_description (template->frames->data);
374         gtk_label_set_label (dialog->priv->layout, text);
375         g_free (text);
376
377         /* Margins */
378         text = lgl_template_get_margins_string (template);
379         gtk_label_set_label (dialog->priv->margins, text);
380         g_free (text);
381
382         /* Similar products */
383         list = lgl_db_get_similar_template_name_list (template_name);
384         if (list)
385         {
386                 list_text = g_string_new ("");
387                 for (p = list; p; p = p->next)
388                 {
389                         g_string_append (list_text, (char *)p->data);
390                         if (p->next)
391                                 g_string_append_c (list_text, '\n');
392                 }
393                 gtk_label_set_text (dialog->priv->similar, list_text->str);
394                 g_string_free (list_text, TRUE);
395         }
396         else
397         {
398                 gtk_widget_hide (GTK_WIDGET (dialog->priv->similar_label));
399                 gtk_widget_hide (GTK_WIDGET (dialog->priv->similar));
400         }
401
402         /* Orientation */
403         gl_label_get_size (label, &w, &h);
404         if (w == h)
405         {
406                 gtk_widget_hide (GTK_WIDGET (dialog->priv->orientation_label));
407                 gtk_widget_hide (GTK_WIDGET (dialog->priv->orientation_box));
408                 gl_mini_preview_set_draw_arrow (GL_MINI_PREVIEW (dialog->priv->preview), FALSE);
409         }
410         else
411         {
412                 rotate_flag = gl_label_get_rotate_flag (label);
413                 if (rotate_flag)
414                         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->rotated_orientation), TRUE);
415                 else
416                         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->normal_orientation), TRUE);
417                 gl_mini_preview_set_draw_arrow (GL_MINI_PREVIEW (dialog->priv->preview), TRUE);
418                 gl_mini_preview_set_rotate (GL_MINI_PREVIEW (dialog->priv->preview), rotate_flag);
419         }
420
421         /* Preview */
422         gl_mini_preview_set_template (GL_MINI_PREVIEW (dialog->priv->preview), template);
423
424         g_free (template_name);
425         g_free (vendor);
426
427         g_signal_connect_swapped (G_OBJECT (dialog->priv->normal_orientation),
428                                   "toggled",
429                                   G_CALLBACK (gl_label_properties_dialog_rotation_cb),
430                                   dialog);
431         g_signal_connect_swapped (G_OBJECT (dialog->priv->rotated_orientation),
432                                   "toggled",
433                                   G_CALLBACK (gl_label_properties_dialog_rotation_cb),
434                                   dialog);
435         g_signal_connect (G_OBJECT (dialog),
436                           "response",
437                           G_CALLBACK (gl_label_properties_dialog_response_cb),
438                           NULL);
439
440         gl_debug (DEBUG_UI, "END");
441 }
442
443
444 /*****************************************************************************/
445 /* NEW document properties dialog.                                                   */
446 /*****************************************************************************/
447 GtkWidget*
448 gl_label_properties_dialog_new (glLabel *label,
449                                 GtkWindow *parent)
450 {
451         glLabelPropertiesDialog *dialog;
452
453         g_assert (GL_IS_LABEL (label));
454
455         gl_debug (DEBUG_UI, "START");
456
457         dialog = GL_LABEL_PROPERTIES_DIALOG (g_object_new (GL_TYPE_LABEL_PROPERTIES_DIALOG, NULL));
458
459         if (parent)
460                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
461
462         gl_label_properties_dialog_construct (GL_LABEL_PROPERTIES_DIALOG (dialog),
463                                               label);
464
465         gl_debug (DEBUG_UI, "END");
466
467         return GTK_WIDGET (dialog);
468 }
469
470
471
472
473 /*
474  * Local Variables:       -- emacs
475  * mode: C                -- emacs
476  * c-basic-offset: 8      -- emacs
477  * tab-width: 8           -- emacs
478  * indent-tabs-mode: nil  -- emacs
479  * End:                   -- emacs
480  */