3 * Copyright (C) 2006-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
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.
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.
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/>.
23 #include "new-label-dialog.h"
25 #include <glib/gi18n.h>
29 #include "builder-util.h"
31 #include "media-select.h"
32 #include "mini-label-preview.h"
33 #include "mini-preview.h"
38 #define LABEL_PREVIEW_WIDTH 96
39 #define LABEL_PREVIEW_HEIGHT 96
41 #define MINI_PREVIEW_MIN_WIDTH 300
42 #define MINI_PREVIEW_MIN_HEIGHT 360
45 /*===========================================*/
46 /* Private data types */
47 /*===========================================*/
49 struct _glNewLabelDialogPrivate {
53 GtkWidget *template_page_vbox;
54 GtkWidget *combo_hbox;
57 GtkWidget *rotate_page_vbox;
58 GtkWidget *normal_radio;
59 GtkWidget *rotated_radio;
60 GtkWidget *normal_preview_hbox;
61 GtkWidget *rotated_preview_hbox;
62 GtkWidget *normal_preview;
63 GtkWidget *rotated_preview;
65 GtkWidget *confirm_page_vbox;
66 GtkWidget *preview_vbox;
68 GtkWidget *desc_label;
69 GtkWidget *page_size_label;
70 GtkWidget *label_size_label;
71 GtkWidget *layout_label;
72 GtkWidget *vendor_label;
73 GtkWidget *part_label;
74 GtkWidget *similar_label;
77 /* Page numbers for traversing GtkAssistant */
79 TEMPLATE_PAGE_NUM = 0,
90 /*===========================================*/
92 /*===========================================*/
94 static gint signals[LAST_SIGNAL] = { 0 };
97 /*===========================================*/
98 /* Local function prototypes */
99 /*===========================================*/
101 static void gl_new_label_dialog_finalize (GObject *object);
103 static void cancel_cb (glNewLabelDialog *this);
104 static void apply_cb (glNewLabelDialog *this);
105 static void close_cb (glNewLabelDialog *this);
107 static gint forward_page_function (gint current_page,
108 glNewLabelDialog *this);
110 static void combo_changed_cb (glNewLabelDialog *this);
111 static void rotate_toggled_cb (glNewLabelDialog *this);
113 static void set_info (glNewLabelDialog *this,
117 /*****************************************************************************/
118 /* Boilerplate object stuff. */
119 /*****************************************************************************/
120 G_DEFINE_TYPE (glNewLabelDialog, gl_new_label_dialog, GTK_TYPE_ASSISTANT)
123 /*****************************************************************************/
124 /* Class Init Function. */
125 /*****************************************************************************/
127 gl_new_label_dialog_class_init (glNewLabelDialogClass *class)
129 GObjectClass *object_class = G_OBJECT_CLASS (class);
131 gl_debug (DEBUG_FILE, "");
133 gl_new_label_dialog_parent_class = g_type_class_peek_parent (class);
135 object_class->finalize = gl_new_label_dialog_finalize;
138 g_signal_new ("complete",
139 G_OBJECT_CLASS_TYPE(object_class),
141 G_STRUCT_OFFSET (glNewLabelDialogClass, complete),
143 gl_marshal_VOID__VOID,
149 /*****************************************************************************/
150 /* Object Instance Init Function. */
151 /*****************************************************************************/
153 gl_new_label_dialog_init (glNewLabelDialog *this)
155 gchar *logo_filename;
158 gchar *builder_filename;
159 static gchar *object_ids[] = { "template_page_vbox",
163 GError *error = NULL;
165 gl_debug (DEBUG_FILE, "START");
167 g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
169 this->priv = g_new0 (glNewLabelDialogPrivate, 1);
171 builder = gtk_builder_new ();
172 builder_filename = g_build_filename (GLABELS_DATA_DIR, "ui", "new-label-dialog.ui", NULL);
173 gtk_builder_add_objects_from_file (builder, builder_filename, object_ids, &error);
174 g_free (builder_filename);
176 g_critical ("%s\n\ngLabels may not be installed correctly!", error->message);
177 g_error_free (error);
181 gl_builder_util_get_widgets (builder,
182 "template_page_vbox", &this->priv->template_page_vbox,
183 "combo_hbox", &this->priv->combo_hbox,
184 "rotate_page_vbox", &this->priv->rotate_page_vbox,
185 "normal_radio", &this->priv->normal_radio,
186 "rotated_radio", &this->priv->rotated_radio,
187 "normal_preview_hbox", &this->priv->normal_preview_hbox,
188 "rotated_preview_hbox", &this->priv->rotated_preview_hbox,
189 "confirm_page_vbox", &this->priv->confirm_page_vbox,
190 "preview_vbox", &this->priv->preview_vbox,
191 "desc_label", &this->priv->desc_label,
192 "page_size_label", &this->priv->page_size_label,
193 "label_size_label", &this->priv->label_size_label,
194 "layout_label", &this->priv->layout_label,
195 "vendor_label", &this->priv->vendor_label,
196 "part_label", &this->priv->part_label,
197 "similar_label", &this->priv->similar_label,
200 this->priv->builder = builder;
202 gtk_assistant_append_page (GTK_ASSISTANT (this), this->priv->template_page_vbox);
203 gtk_assistant_set_page_title (GTK_ASSISTANT (this), this->priv->template_page_vbox, _("Select Product"));
204 gtk_assistant_set_page_type (GTK_ASSISTANT (this), this->priv->template_page_vbox, GTK_ASSISTANT_PAGE_INTRO);
205 logo_filename = g_build_filename (GLABELS_DATA_DIR, "pixmaps", "new-select.png", NULL);
206 logo = gdk_pixbuf_new_from_file (logo_filename, NULL);
207 gtk_assistant_set_page_header_image (GTK_ASSISTANT (this), this->priv->template_page_vbox, logo);
208 g_free (logo_filename);
209 g_object_unref (logo);
211 this->priv->combo = gl_media_select_new ();
212 gtk_container_add (GTK_CONTAINER (this->priv->combo_hbox), this->priv->combo);
214 gtk_assistant_append_page (GTK_ASSISTANT (this), this->priv->rotate_page_vbox);
215 gtk_assistant_set_page_title (GTK_ASSISTANT (this), this->priv->rotate_page_vbox, _("Choose Orientation"));
216 gtk_assistant_set_page_complete (GTK_ASSISTANT (this), this->priv->rotate_page_vbox, TRUE);
217 logo_filename = g_build_filename (GLABELS_DATA_DIR, "pixmaps", "new-rotate.png", NULL);
218 logo = gdk_pixbuf_new_from_file (logo_filename, NULL);
219 gtk_assistant_set_page_header_image (GTK_ASSISTANT (this), this->priv->rotate_page_vbox, logo);
220 g_free (logo_filename);
221 g_object_unref (logo);
223 this->priv->normal_preview = gl_mini_label_preview_new (LABEL_PREVIEW_WIDTH, LABEL_PREVIEW_HEIGHT);
224 gtk_container_add (GTK_CONTAINER (this->priv->normal_preview_hbox), this->priv->normal_preview);
225 this->priv->rotated_preview = gl_mini_label_preview_new (LABEL_PREVIEW_WIDTH, LABEL_PREVIEW_HEIGHT);
226 gtk_container_add (GTK_CONTAINER (this->priv->rotated_preview_hbox), this->priv->rotated_preview);
228 gtk_assistant_append_page (GTK_ASSISTANT (this), this->priv->confirm_page_vbox);
229 gtk_assistant_set_page_title (GTK_ASSISTANT (this), this->priv->confirm_page_vbox, _("Review"));
230 gtk_assistant_set_page_type (GTK_ASSISTANT (this), this->priv->confirm_page_vbox, GTK_ASSISTANT_PAGE_CONFIRM);
231 gtk_assistant_set_page_complete (GTK_ASSISTANT (this), this->priv->confirm_page_vbox, TRUE);
232 logo_filename = g_build_filename (GLABELS_DATA_DIR, "pixmaps", "new-confirm.png", NULL);
233 logo = gdk_pixbuf_new_from_file (logo_filename, NULL);
234 gtk_assistant_set_page_header_image (GTK_ASSISTANT (this), this->priv->confirm_page_vbox, logo);
235 g_free (logo_filename);
236 g_object_unref (logo);
238 this->priv->preview = gl_mini_preview_new (MINI_PREVIEW_MIN_HEIGHT, MINI_PREVIEW_MIN_WIDTH);
239 gl_mini_preview_set_draw_arrow (GL_MINI_PREVIEW (this->priv->preview), TRUE);
240 gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), FALSE);
241 gtk_container_add (GTK_CONTAINER (this->priv->preview_vbox), this->priv->preview);
243 gtk_assistant_set_forward_page_func (GTK_ASSISTANT (this), (GtkAssistantPageFunc)forward_page_function, this, NULL);
245 g_signal_connect_swapped (G_OBJECT(this), "cancel", G_CALLBACK(cancel_cb), this);
246 g_signal_connect_swapped (G_OBJECT(this), "apply", G_CALLBACK(apply_cb), this);
247 g_signal_connect_swapped (G_OBJECT(this), "close", G_CALLBACK(close_cb), this);
249 g_signal_connect_swapped (G_OBJECT (this->priv->combo), "changed", G_CALLBACK (combo_changed_cb), this);
250 g_signal_connect_swapped (G_OBJECT (this->priv->normal_radio), "toggled", G_CALLBACK (rotate_toggled_cb), this);
251 g_signal_connect_swapped (G_OBJECT (this->priv->rotated_radio), "toggled", G_CALLBACK (rotate_toggled_cb), this);
253 combo_changed_cb (this);
255 gl_debug (DEBUG_FILE, "END");
259 /*****************************************************************************/
260 /* Finalize Function. */
261 /*****************************************************************************/
263 gl_new_label_dialog_finalize (GObject *object)
265 glNewLabelDialog* this = GL_NEW_LABEL_DIALOG (object);;
267 gl_debug (DEBUG_FILE, "START");
269 g_return_if_fail (object != NULL);
270 g_return_if_fail (GL_IS_NEW_LABEL_DIALOG (this));
271 g_return_if_fail (this->priv != NULL);
273 g_object_unref (G_OBJECT (this->priv->builder));
276 G_OBJECT_CLASS (gl_new_label_dialog_parent_class)->finalize (object);
278 gl_debug (DEBUG_FILE, "END");
283 /*****************************************************************************/
284 /* NEW object properties dialog. */
285 /*****************************************************************************/
287 gl_new_label_dialog_new (GtkWindow *win)
291 gl_debug (DEBUG_FILE, "");
293 this = GTK_WIDGET (g_object_new (GL_TYPE_NEW_LABEL_DIALOG, NULL));
295 gtk_window_set_transient_for (GTK_WINDOW (this), win);
301 /*--------------------------------------------------------------------------*/
302 /* PRIVATE. Handle non-linear forward traversal. */
303 /*--------------------------------------------------------------------------*/
305 forward_page_function (gint current_page,
306 glNewLabelDialog *this)
309 lglTemplate *template;
310 const lglTemplateFrame *frame;
313 switch (current_page)
315 case TEMPLATE_PAGE_NUM:
316 name = gl_media_select_get_name (GL_MEDIA_SELECT (this->priv->combo));
319 template = lgl_db_lookup_template_from_name (name);
320 frame = (lglTemplateFrame *)template->frames->data;
321 lgl_template_frame_get_size (frame, &w, &h);
325 /* Skip rotate page for square and circular labels. */
326 return CONFIRM_PAGE_NUM;
329 return ROTATE_PAGE_NUM;
331 case ROTATE_PAGE_NUM:
332 return CONFIRM_PAGE_NUM;
334 case CONFIRM_PAGE_NUM:
343 /*--------------------------------------------------------------------------*/
344 /* PRIVATE. cancel callback. */
345 /*--------------------------------------------------------------------------*/
347 cancel_cb (glNewLabelDialog *this)
350 gtk_widget_destroy (GTK_WIDGET(this));
355 /*--------------------------------------------------------------------------*/
356 /* PRIVATE. apply callback */
357 /*--------------------------------------------------------------------------*/
359 apply_cb (glNewLabelDialog *this)
362 g_signal_emit (G_OBJECT (this), signals[COMPLETE], 0);
367 /*--------------------------------------------------------------------------*/
368 /* PRIVATE. close callback */
369 /*--------------------------------------------------------------------------*/
371 close_cb (glNewLabelDialog *this)
374 gtk_widget_destroy (GTK_WIDGET(this));
379 /*---------------------------------------------------------------------------*/
380 /* PRIVATE. Template changed callback. */
381 /*---------------------------------------------------------------------------*/
383 combo_changed_cb (glNewLabelDialog *this)
387 gl_debug (DEBUG_FILE, "START");
389 name = gl_media_select_get_name (GL_MEDIA_SELECT (this->priv->combo));
391 gl_mini_label_preview_set_by_name (GL_MINI_LABEL_PREVIEW (this->priv->normal_preview), name, FALSE);
392 gl_mini_label_preview_set_by_name (GL_MINI_LABEL_PREVIEW (this->priv->rotated_preview), name, TRUE);
393 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->normal_radio), TRUE);
395 gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
396 set_info (this, name);
398 gtk_assistant_set_page_complete (GTK_ASSISTANT (this), this->priv->template_page_vbox, (name != NULL));
402 gl_debug (DEBUG_FILE, "END");
406 /*---------------------------------------------------------------------------*/
407 /* PRIVATE. Rotate toggled callback. */
408 /*---------------------------------------------------------------------------*/
410 rotate_toggled_cb (glNewLabelDialog *this)
414 gl_debug (DEBUG_FILE, "START");
416 state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (this->priv->rotated_radio));
417 gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
419 gl_debug (DEBUG_FILE, "END");
423 /*---------------------------------------------------------------------------*/
424 /* PRIVATE. Set information labels. */
425 /*---------------------------------------------------------------------------*/
427 set_info (glNewLabelDialog *this,
430 lglTemplate *template;
431 lglTemplateFrame *frame;
434 gchar *page_size_string;
435 gchar *label_size_string;
436 gchar *layout_string;
438 GString *list_string;
440 template = lgl_db_lookup_template_from_name (name);
441 frame = template->frames->data;
442 vendor = lgl_db_lookup_vendor_from_name (template->brand);
444 units = gl_prefs_model_get_units (gl_prefs);
446 page_size_string = lgl_db_lookup_paper_name_from_id (template->paper_id);
447 label_size_string = lgl_template_frame_get_size_description (frame, units);
448 layout_string = lgl_template_frame_get_layout_description (frame);
450 gtk_label_set_text (GTK_LABEL (this->priv->desc_label), template->description);
451 gtk_label_set_text (GTK_LABEL (this->priv->page_size_label), page_size_string);
452 gtk_label_set_text (GTK_LABEL (this->priv->label_size_label), label_size_string);
453 gtk_label_set_text (GTK_LABEL (this->priv->layout_label), layout_string);
455 if ( vendor && vendor->url )
460 escaped_url = g_markup_escape_text (vendor->url, -1);
461 markup = g_strdup_printf ("<a href='%s'>%s</a>", escaped_url, vendor->name);
462 gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), markup);
463 gtk_widget_set_tooltip_text (this->priv->vendor_label, escaped_url);
464 g_free (escaped_url);
469 /* FIXME: Using set_markup instead of set_text to clear out previous link. */
470 gtk_label_set_markup (GTK_LABEL (this->priv->vendor_label), template->brand);
471 gtk_widget_set_has_tooltip (this->priv->vendor_label, FALSE);
474 if ( template->product_url )
479 escaped_url = g_markup_escape_text (template->product_url, -1);
480 markup = g_strdup_printf ("<a href='%s'>%s</a>", escaped_url, template->part);
481 gtk_label_set_markup (GTK_LABEL (this->priv->part_label), markup);
482 gtk_widget_set_tooltip_text (this->priv->part_label, escaped_url);
483 g_free (escaped_url);
488 /* FIXME: Using set_markup instead of set_text to clear out previous link. */
489 gtk_label_set_markup (GTK_LABEL (this->priv->part_label), template->part);
490 gtk_widget_set_has_tooltip (this->priv->part_label, FALSE);
493 list = lgl_db_get_similar_template_name_list (name);
494 list_string = g_string_new ("");
495 for ( p = list; p; p = p->next )
497 g_string_append (list_string, (char *)p->data);
500 g_string_append (list_string, "\n");
503 gtk_label_set_text (GTK_LABEL (this->priv->similar_label), list_string->str);
505 lgl_db_free_template_name_list (list);
506 g_string_free (list_string, TRUE);
508 g_free (page_size_string);
509 g_free (label_size_string);
510 g_free (layout_string);
514 /*****************************************************************************/
515 /* Get template name. */
516 /*****************************************************************************/
518 gl_new_label_dialog_get_template_name (glNewLabelDialog *this)
522 name = gl_media_select_get_name (GL_MEDIA_SELECT (this->priv->combo));
528 /*****************************************************************************/
529 /* Set template name. */
530 /*****************************************************************************/
532 gl_new_label_dialog_set_template_name (glNewLabelDialog *this,
535 gl_mini_preview_set_by_name (GL_MINI_PREVIEW (this->priv->preview), name);
536 gl_media_select_set_name (GL_MEDIA_SELECT (this->priv->combo), name);
537 set_info (this, name);
541 /*****************************************************************************/
542 /* Get current filter parameters. */
543 /*****************************************************************************/
545 gl_new_label_dialog_get_filter_parameters (glNewLabelDialog *this,
546 gchar **page_size_id,
552 /*****************************************************************************/
553 /* Set current filter parameters. */
554 /*****************************************************************************/
556 gl_new_label_dialog_set_filter_parameters (glNewLabelDialog *this,
557 const gchar *page_size_id,
558 const gchar *category_id)
563 /*****************************************************************************/
564 /* Get rotate state. */
565 /*****************************************************************************/
567 gl_new_label_dialog_get_rotate_state (glNewLabelDialog *this)
569 return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (this->priv->rotated_radio));
573 /*****************************************************************************/
574 /* Set rotate state. */
575 /*****************************************************************************/
577 gl_new_label_dialog_set_rotate_state (glNewLabelDialog *this,
580 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->rotated_radio), state);
581 gl_mini_preview_set_rotate (GL_MINI_PREVIEW (this->priv->preview), state);
587 * Local Variables: -- emacs
589 * c-basic-offset: 8 -- emacs
590 * tab-width: 8 -- emacs
591 * indent-tabs-mode: nil -- emacs