]> git.sur5r.net Git - glabels/blob - src/new-label-dialog.c
Escape URLs in markup.
[glabels] / src / new-label-dialog.c
1 /*
2  *  new-label-dialog.c
3  *  Copyright (C) 2006-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 "new-label-dialog.h"
24
25 #include <glib/gi18n.h>
26 #include <gtk/gtk.h>
27
28 #include "hig.h"
29 #include "builder-util.h"
30 #include "prefs.h"
31 #include "template-history.h"
32 #include "mini-preview.h"
33 #include "media-combo.h"
34 #include "rotate-label-button.h"
35
36 #include "debug.h"
37
38
39 #define MINI_PREVIEW_MIN_HEIGHT 300
40 #define MINI_PREVIEW_MIN_WIDTH  256
41
42
43 /*===========================================*/
44 /* Private data types                        */
45 /*===========================================*/
46
47 struct _glNewLabelDialogPrivate {
48
49         GtkBuilder *builder;
50
51         GtkWidget  *preview_vbox;
52         GtkWidget  *combo_hbox;
53         GtkWidget  *rotate_hbox;
54
55         GtkWidget  *desc_label;
56         GtkWidget  *page_size_label;
57         GtkWidget  *label_size_label;
58         GtkWidget  *layout_label;
59         GtkWidget  *vendor_label;
60         GtkWidget  *part_label;
61         GtkWidget  *similar_label;
62
63         GtkWidget  *preview;
64         GtkWidget  *combo;
65         GtkWidget  *rotate_button;
66 };
67
68
69 /*===========================================*/
70 /* Private globals                           */
71 /*===========================================*/
72
73
74 /*===========================================*/
75 /* Local function prototypes                 */
76 /*===========================================*/
77
78 static void       gl_new_label_dialog_finalize        (GObject           *object);
79
80 static void       combo_changed_cb                    (glNewLabelDialog  *this);
81 static void       rotate_toggled_cb                   (glNewLabelDialog  *this);
82
83 static gchar     *get_default_name                    (void);
84
85 static void       set_info                            (glNewLabelDialog  *this,
86                                                        const gchar       *name);
87
88
89 /*****************************************************************************/
90 /* Boilerplate object stuff.                                                 */
91 /*****************************************************************************/
92 G_DEFINE_TYPE (glNewLabelDialog, gl_new_label_dialog, GTK_TYPE_DIALOG);
93
94
95 /*****************************************************************************/
96 /* Class Init Function.                                                      */
97 /*****************************************************************************/
98 static void
99 gl_new_label_dialog_class_init (glNewLabelDialogClass *class)
100 {
101         GObjectClass *object_class = G_OBJECT_CLASS (class);
102
103         gl_debug (DEBUG_FILE, "");
104         
105         gl_new_label_dialog_parent_class = g_type_class_peek_parent (class);
106
107         object_class->finalize = gl_new_label_dialog_finalize;
108 }
109
110
111 /*****************************************************************************/
112 /* Object Instance Init Function.                                            */
113 /*****************************************************************************/
114 static void
115 gl_new_label_dialog_init (glNewLabelDialog *this)
116 {
117         GtkWidget    *vbox;
118         GtkBuilder   *builder;
119         gchar        *builder_filename;
120         static gchar *object_ids[] = { "new_label_dialog_hbox", NULL };
121         GError       *error = NULL;
122         GtkWidget    *new_label_dialog_hbox;
123         gchar        *name;
124
125         gl_debug (DEBUG_FILE, "START");
126
127         g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
128
129         this->priv = g_new0 (glNewLabelDialogPrivate, 1);
130
131         gtk_container_set_border_width (GTK_CONTAINER (this), GL_HIG_PAD1);
132
133         gtk_dialog_set_has_separator (GTK_DIALOG (this), FALSE);
134         gtk_dialog_add_buttons (GTK_DIALOG (this),
135                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
136                                 GTK_STOCK_OK, GTK_RESPONSE_OK,
137                                 NULL);
138         gtk_dialog_set_default_response (GTK_DIALOG (this), GTK_RESPONSE_OK);
139         gtk_window_set_destroy_with_parent (GTK_WINDOW (this), TRUE);
140         gtk_window_set_modal (GTK_WINDOW (this), TRUE);
141
142         vbox = gtk_dialog_get_content_area (GTK_DIALOG (this));
143
144
145         builder = gtk_builder_new ();
146         builder_filename = g_build_filename (GLABELS_DATA_DIR, "builder", "new-label-dialog.builder", NULL);
147         gtk_builder_add_objects_from_file (builder, builder_filename, object_ids, &error);
148         g_free (builder_filename);
149         if (error) {
150                 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
151                 g_error_free (error);
152                 return;
153         }
154
155         gl_builder_util_get_widgets (builder,
156                                      "new_label_dialog_hbox",  &new_label_dialog_hbox,
157                                      "preview_vbox",           &this->priv->preview_vbox,
158                                      "combo_hbox",             &this->priv->combo_hbox,
159                                      "rotate_hbox",            &this->priv->rotate_hbox,
160                                      "desc_label",             &this->priv->desc_label,
161                                      "page_size_label",        &this->priv->page_size_label,
162                                      "label_size_label",       &this->priv->label_size_label,
163                                      "layout_label",           &this->priv->layout_label,
164                                      "vendor_label",           &this->priv->vendor_label,
165                                      "part_label",             &this->priv->part_label,
166                                      "similar_label",          &this->priv->similar_label,
167                                      NULL);
168
169         gtk_container_add (GTK_CONTAINER (vbox), new_label_dialog_hbox);
170         this->priv->builder = builder;
171
172         this->priv->preview = gl_mini_preview_new (MINI_PREVIEW_MIN_HEIGHT, MINI_PREVIEW_MIN_WIDTH);
173         gl_mini_preview_set_draw_arrow (GL_MINI_PREVIEW (this->priv->preview), TRUE);
174         gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), FALSE);
175         gtk_container_add (GTK_CONTAINER (this->priv->preview_vbox), this->priv->preview);
176
177         this->priv->combo = gl_media_combo_new ();
178         gtk_container_add (GTK_CONTAINER (this->priv->combo_hbox), this->priv->combo);
179
180         this->priv->rotate_button = gl_rotate_label_button_new ();
181         gtk_container_add (GTK_CONTAINER (this->priv->rotate_hbox), this->priv->rotate_button);
182
183         g_signal_connect_swapped (G_OBJECT (this->priv->combo), "changed",
184                           G_CALLBACK (combo_changed_cb), this);
185         g_signal_connect_swapped (G_OBJECT (this->priv->rotate_button), "changed",
186                           G_CALLBACK (rotate_toggled_cb), this);
187
188         name = get_default_name ();
189         gl_media_combo_set_name (GL_MEDIA_COMBO (this->priv->combo), name);
190         gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), name);
191         g_free (name);
192         combo_changed_cb (this);
193
194         gl_debug (DEBUG_FILE, "END");
195 }
196
197
198 /*****************************************************************************/
199 /* Finalize Function.                                                        */
200 /*****************************************************************************/
201 static void 
202 gl_new_label_dialog_finalize (GObject *object)
203 {
204         glNewLabelDialog* this = GL_NEW_LABEL_DIALOG (object);;
205         
206         gl_debug (DEBUG_FILE, "START");
207
208         g_return_if_fail (object != NULL);
209         g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
210         g_return_if_fail (this->priv != NULL);
211
212         g_object_unref (G_OBJECT (this->priv->builder));
213         g_free (this->priv);
214
215         G_OBJECT_CLASS (gl_new_label_dialog_parent_class)->finalize (object);
216
217         gl_debug (DEBUG_FILE, "END");
218
219 }
220
221
222 /*****************************************************************************/
223 /* NEW object properties dialog.                                             */
224 /*****************************************************************************/
225 GtkWidget *
226 gl_new_label_dialog_new (GtkWindow    *win)
227 {
228         GtkWidget *this;
229
230         gl_debug (DEBUG_FILE, "");
231
232         this = GTK_WIDGET (g_object_new (GL_TYPE_NEW_LABEL_DIALOG, NULL));
233
234         gtk_window_set_transient_for (GTK_WINDOW (this), win);
235
236         return this;
237 }
238
239
240 /*---------------------------------------------------------------------------*/
241 /* PRIVATE.  Template changed callback.                                      */
242 /*---------------------------------------------------------------------------*/
243 static void
244 combo_changed_cb (glNewLabelDialog  *this)
245 {
246         gchar             *name;
247
248         gl_debug (DEBUG_FILE, "START");
249
250         name = gl_media_combo_get_name (GL_MEDIA_COMBO (this->priv->combo));
251
252         gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
253         gl_rotate_label_button_set_template_name (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), name);
254         set_info (this, name);
255
256         g_free (name);
257
258         gl_debug (DEBUG_FILE, "END");
259 }
260
261
262 /*---------------------------------------------------------------------------*/
263 /* PRIVATE.  Rotate toggled callback.                                        */
264 /*---------------------------------------------------------------------------*/
265 static void
266 rotate_toggled_cb (glNewLabelDialog  *this)
267 {
268         gboolean state;
269
270         gl_debug (DEBUG_FILE, "START");
271
272         state = gl_rotate_label_button_get_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button));
273         gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
274
275         gl_debug (DEBUG_FILE, "END");
276 }
277
278
279 /*---------------------------------------------------------------------------*/
280 /* PRIVATE.  Get default template name.                                      */
281 /*---------------------------------------------------------------------------*/
282 static gchar *
283 get_default_name (void)
284 {
285         gchar *name = NULL;
286         GList *list;
287
288         list = gl_template_history_model_get_name_list (gl_template_history);
289
290         if ( list )
291         {
292                 name = g_strdup (list->data);
293                 gl_template_history_model_free_name_list (list);
294         }
295         else
296         {
297                 gchar *page_size;
298
299                 page_size = gl_prefs_model_get_default_page_size (gl_prefs);
300                 list = lgl_db_get_template_name_list_all (NULL, page_size, NULL);
301                 g_free (page_size);
302
303                 if ( list )
304                 {
305                         name = g_strdup (list->data);
306                         lgl_db_free_template_name_list (list);
307                 }
308         }
309
310         return name;
311 }
312
313
314 /*---------------------------------------------------------------------------*/
315 /* PRIVATE.  Set information labels.                                         */
316 /*---------------------------------------------------------------------------*/
317 static void
318 set_info (glNewLabelDialog  *this,
319           const gchar       *name)
320 {
321         lglTemplate          *template;
322         lglTemplateFrame     *frame;
323         lglVendor            *vendor;
324         lglUnits              units;
325         gchar                *page_size_string;
326         gchar                *label_size_string;
327         gchar                *layout_string;
328         GList                *list, *p;
329         GString              *list_string;
330
331         template = lgl_db_lookup_template_from_name (name);
332         frame    = template->frames->data;
333         vendor   = lgl_db_lookup_vendor_from_name (template->brand);
334
335         units    = gl_prefs_model_get_units (gl_prefs);
336
337         page_size_string  = lgl_db_lookup_paper_name_from_id (template->paper_id);
338         label_size_string = lgl_template_frame_get_size_description (frame, units);
339         layout_string     = lgl_template_frame_get_layout_description (frame);
340
341         gtk_label_set_text (GTK_LABEL (this->priv->desc_label),       template->description);
342         gtk_label_set_text (GTK_LABEL (this->priv->page_size_label),  page_size_string);
343         gtk_label_set_text (GTK_LABEL (this->priv->label_size_label), label_size_string);
344         gtk_label_set_text (GTK_LABEL (this->priv->layout_label),     layout_string);
345
346         if ( vendor && vendor->url )
347         {
348                 gchar *escaped_url;
349                 gchar *markup;
350
351                 escaped_url = g_markup_escape_text (vendor->url, -1);
352                 markup = g_strdup_printf ("<a href='%s'>%s</a>", escaped_url, vendor->name);
353                 gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), markup);
354                 g_free (escaped_url);
355                 g_free (markup);
356         }
357         else
358         {
359                 /* FIXME: Using set_markup instead of set_text to clear out previous link. */
360                 gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), template->brand);
361         }
362
363         if ( template->product_url )
364         {
365                 gchar *escaped_url;
366                 gchar *markup;
367
368                 escaped_url = g_markup_escape_text (template->product_url, -1);
369                 markup = g_strdup_printf ("<a href='%s'>%s</a>", escaped_url, template->part);
370                 gtk_label_set_markup (GTK_LABEL (this->priv->part_label), markup);
371                 g_free (escaped_url);
372                 g_free (markup);
373         }
374         else
375         {
376                 /* FIXME: Using set_markup instead of set_text to clear out previous link. */
377                 gtk_label_set_markup (GTK_LABEL (this->priv->part_label), template->part);
378         }
379
380         list = lgl_db_get_similar_template_name_list (name);
381         list_string = g_string_new ("");
382         for ( p = list; p; p = p->next )
383         {
384                 g_string_append (list_string, (char *)p->data);
385                 if ( p->next )
386                 {
387                         g_string_append (list_string, "\n");
388                 }
389         }
390         gtk_label_set_text (GTK_LABEL (this->priv->similar_label), list_string->str);
391
392         lgl_db_free_template_name_list (list);
393         g_string_free (list_string, TRUE);
394
395         g_free (page_size_string);
396         g_free (label_size_string);
397         g_free (layout_string);
398 }
399
400
401 /*****************************************************************************/
402 /* Get template name.                                                        */
403 /*****************************************************************************/
404 gchar *
405 gl_new_label_dialog_get_template_name (glNewLabelDialog *this)
406 {
407         gchar *name;
408
409         name = gl_media_combo_get_name (GL_MEDIA_COMBO (this->priv->combo));
410
411         return name;
412 }
413
414
415 /*****************************************************************************/
416 /* Set template name.                                                        */
417 /*****************************************************************************/
418 void
419 gl_new_label_dialog_set_template_name (glNewLabelDialog *this,
420                                        gchar            *name)
421 {
422         gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
423         gl_media_combo_set_name (GL_MEDIA_COMBO (this->priv->combo), name);
424         set_info (this, name);
425 }
426
427
428 /*****************************************************************************/
429 /* Get current filter parameters.                                            */
430 /*****************************************************************************/
431 void
432 gl_new_label_dialog_get_filter_parameters (glNewLabelDialog  *this,
433                                            gchar            **page_size_id,
434                                            gchar            **category_id)
435 {
436 }
437
438
439 /*****************************************************************************/
440 /* Set current filter parameters.                                            */
441 /*****************************************************************************/
442 void
443 gl_new_label_dialog_set_filter_parameters (glNewLabelDialog *this,
444                                            const gchar      *page_size_id,
445                                            const gchar      *category_id)
446 {
447 }
448
449
450 /*****************************************************************************/
451 /* Get rotate state.                                                         */
452 /*****************************************************************************/
453 gboolean
454 gl_new_label_dialog_get_rotate_state (glNewLabelDialog *this)
455 {
456         return gl_rotate_label_button_get_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button));
457 }
458
459
460 /*****************************************************************************/
461 /* Set rotate state.                                                         */
462 /*****************************************************************************/
463 void
464 gl_new_label_dialog_set_rotate_state (glNewLabelDialog *this,
465                                       gboolean          state)
466 {
467         gl_rotate_label_button_set_state (GL_ROTATE_LABEL_BUTTON (this->priv->rotate_button), state);
468         gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
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  */