Logo Search packages:      
Sourcecode: nautilus-cd-burner version File versions  Download package

ncb-progress-dialog.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 *
 * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Authors: William Jon McCann <mccann@jhu.edu>
 *
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>

#include <glade/glade.h>

#include "ncb-progress-dialog.h"
#include "nautilus-file-operations-progress-icons.h"

static void     ncb_progress_dialog_class_init (NcbProgressDialogClass *klass);
static void     ncb_progress_dialog_init       (NcbProgressDialog      *fade);
static void     ncb_progress_dialog_finalize   (GObject                *object);

#define NCB_PROGRESS_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NCB_TYPE_PROGRESS_DIALOG, NcbProgressDialogPrivate))

#define BURN_URI "burn:///"
#define MAX_ISO_NAME_LEN  32

struct NcbProgressDialogPrivate
{
        GladeXML                *xml;
        /* For the image spinning */
        GList                   *image_list;

        GtkWidget               *cancel_button;
        GtkWidget               *close_button;
        GtkWidget               *make_another_button;

        gboolean                 confirm_cancel;
        gboolean                 make_another_button_visible;

        guint                    spin_id;
};

G_DEFINE_TYPE (NcbProgressDialog, ncb_progress_dialog, GTK_TYPE_DIALOG)

static int                      progress_jar_position = 0;
static GdkPixbuf               *empty_jar_pixbuf;
static GdkPixbuf               *full_jar_pixbuf;

static void
ncb_progress_dialog_set_property (GObject            *object,
                                   guint               prop_id,
                                   const GValue       *value,
                                   GParamSpec         *pspec)
{
        switch (prop_id) {
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
        }
}

static void
ncb_progress_dialog_get_property (GObject            *object,
                                   guint               prop_id,
                                   GValue             *value,
                                   GParamSpec         *pspec)
{
        switch (prop_id) {
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
        }
}

static void
ncb_progress_dialog_update_icon (NcbProgressDialog *dialog,
                                 double             fraction)
{
        GdkPixbuf *pixbuf;
        int        position;

        position = gdk_pixbuf_get_height (empty_jar_pixbuf) * (1 - fraction);

        if (position == progress_jar_position) {
                return;
        }

        progress_jar_position = position;

        pixbuf = gdk_pixbuf_copy (empty_jar_pixbuf);
        gdk_pixbuf_copy_area (full_jar_pixbuf,
                              0, position,
                              gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf) - position,
                              pixbuf,
                              0, position);

        gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf);
        g_object_unref (pixbuf);
}

void
ncb_progress_dialog_set_fraction (NcbProgressDialog *dialog,
                                  double             fraction)
{
        GtkWidget *progress_bar;

        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        progress_bar = glade_xml_get_widget (dialog->priv->xml, "cd_progress");

        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress_bar), fraction);
        ncb_progress_dialog_update_icon (dialog, fraction);
}

/* Adapted from totem_time_to_string_text */
static char *
time_to_string_text (long time)
{
        char *secs, *mins, *hours, *string;
        int sec, min, hour;

        sec = time % 60;
        time = time - sec;
        min = (time % (60 * 60)) / 60;
        time = time - (min * 60);
        hour = time / (60 * 60);

        hours = g_strdup_printf (ngettext ("%d hour", "%d hours", hour), hour);

        mins = g_strdup_printf (ngettext ("%d minute",
                                          "%d minutes", min), min);

        secs = g_strdup_printf (ngettext ("%d second",
                                          "%d seconds", sec), sec);

        if (hour > 0) {
                /* hour:minutes:seconds */
                string = g_strdup_printf (_("%s %s %s"), hours, mins, secs);
        } else if (min > 0) {
                /* minutes:seconds */
                string = g_strdup_printf (_("%s %s"), mins, secs);
        } else if (sec > 0) {
                /* seconds */
                string = g_strdup_printf (_("%s"), secs);
        } else {
                /* 0 seconds */
                string = g_strdup (_("0 seconds"));
        }

        g_free (hours);
        g_free (mins);
        g_free (secs);

        return string;
}

void
ncb_progress_dialog_set_time_remaining (NcbProgressDialog *dialog,
                                        long               secs)
{
        GtkWidget *progress_bar;
        char      *text;

        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        progress_bar = glade_xml_get_widget (dialog->priv->xml, "cd_progress");

        if (secs >= 0) {
                char *remaining;
                remaining = time_to_string_text (secs);
                text = g_strdup_printf (_("About %s left"), remaining);
                g_free (remaining);
        } else {
                text = g_strdup (" ");
        }

        gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), text);

        g_free (text);
}

void
ncb_progress_dialog_set_description (NcbProgressDialog *dialog,
                                     const char        *text)
{
        GtkWidget *label;

        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        label = glade_xml_get_widget (dialog->priv->xml, "progress_description_label");
        gtk_label_set_text (GTK_LABEL (label), text);
}

void
ncb_progress_dialog_set_heading (NcbProgressDialog *dialog,
                                 const char        *text)
{
        GtkWidget *heading;
        char      *markup;

        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        heading = glade_xml_get_widget (dialog->priv->xml, "info_title_label");

        markup = g_strdup_printf ("<big><b>%s</b></big>", text);
        gtk_label_set_markup (GTK_LABEL (heading), markup);
        g_free (markup);
}

void
ncb_progress_dialog_set_operation_string (NcbProgressDialog *dialog,
                                          const char        *text)
{
        GtkWidget *progress_label;
        char      *string;

        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        progress_label = glade_xml_get_widget (dialog->priv->xml, "cd_progress_label");
        string = g_strdup_printf ("<i>%s</i>", text);
        gtk_label_set_markup (GTK_LABEL (progress_label), string);
        g_free (string);
}

static gboolean
ncb_progress_dialog_set_image (NcbProgressDialog *dialog)
{
        GtkWidget *image;
        GdkPixbuf *pixbuf;

        if (dialog->priv->image_list == NULL) {
                return FALSE;
        }

        image = glade_xml_get_widget (dialog->priv->xml, "cd_image");
        pixbuf = dialog->priv->image_list->data;

        if (pixbuf == NULL || image == NULL) {
                return FALSE;
        }

        gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);

        if (dialog->priv->image_list->next != NULL) {
                dialog->priv->image_list = dialog->priv->image_list->next;
        } else {
                dialog->priv->image_list = g_list_first (dialog->priv->image_list);
        }

        return TRUE;
}

void
ncb_progress_dialog_set_active (NcbProgressDialog *dialog,
                                gboolean           active)
{
        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        if (active) {
                if (dialog->priv->spin_id == 0) {
                        dialog->priv->spin_id = g_timeout_add (100, (GSourceFunc) ncb_progress_dialog_set_image, dialog);
                }
        } else {
                if (dialog->priv->spin_id != 0) {
                        g_source_remove (dialog->priv->spin_id);
                        dialog->priv->spin_id = 0;
                }
        }
}

static void
ncb_progress_dialog_image_setup (NcbProgressDialog *dialog)
{
        GdkPixbuf *pixbuf;
        char      *filename;
        int        i;

        if (dialog->priv->image_list != NULL) {
                return;
        }

        i = 1;

        /* Setup the pixbuf list */
        filename = g_strdup_printf (DATADIR "/cdspin%d.png", i);
        while (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
                pixbuf = gdk_pixbuf_new_from_file (filename, NULL);

                if (pixbuf != NULL) {
                        dialog->priv->image_list = g_list_prepend (dialog->priv->image_list, (gpointer) pixbuf);
                }

                i++;
                g_free (filename);
                filename = g_strdup_printf (DATADIR "/cdspin%d.png", i);
        }

        g_free (filename);
        if (dialog->priv->image_list != NULL) {
                dialog->priv->image_list = g_list_reverse (dialog->priv->image_list);
        }

        /* Set the first image */
        ncb_progress_dialog_set_image (dialog);
}

static void
ncb_progress_dialog_image_cleanup (NcbProgressDialog *dialog)
{
        GdkPixbuf *pixbuf;

        dialog->priv->image_list = g_list_first (dialog->priv->image_list);

        while (dialog->priv->image_list != NULL) {
                pixbuf = (GdkPixbuf *) dialog->priv->image_list->data;
                if (pixbuf != NULL) {
                        gdk_pixbuf_unref (pixbuf);
                }
                dialog->priv->image_list = g_list_remove (dialog->priv->image_list, dialog->priv->image_list->data);
        }
}

static void
dialog_sync_buttons (NcbProgressDialog *dialog,
                     gboolean           finished)
{
        if (finished) {
                gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL, FALSE);
                gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE, TRUE);
                gtk_widget_show (dialog->priv->close_button);
                gtk_widget_hide (dialog->priv->cancel_button);

                if (dialog->priv->make_another_button_visible) {
                        gtk_widget_show (dialog->priv->make_another_button);
                } else {
                        gtk_widget_hide (dialog->priv->make_another_button);
                }

                gtk_dialog_set_default_response (GTK_DIALOG (dialog),
                                                 GTK_RESPONSE_CLOSE);

        } else {
                gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL, TRUE);
                gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE, FALSE);
                gtk_widget_hide (dialog->priv->close_button);
                gtk_widget_show (dialog->priv->cancel_button);

                gtk_widget_hide (dialog->priv->make_another_button);
        }
}

void
ncb_progress_dialog_set_make_another_button_visible (NcbProgressDialog *dialog,
                                                     gboolean           visible)
{
        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        dialog->priv->make_another_button_visible = visible;

        dialog_sync_buttons (dialog, FALSE);
}

void
ncb_progress_dialog_clear (NcbProgressDialog *dialog)
{
        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        dialog_sync_buttons (dialog, FALSE);

        ncb_progress_dialog_set_fraction (dialog, 0.0);
        ncb_progress_dialog_set_time_remaining (dialog, -1);
        ncb_progress_dialog_set_operation_string (dialog, "");
}

void
ncb_progress_dialog_done (NcbProgressDialog *dialog)
{
        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (dialog));

        ncb_progress_dialog_set_fraction (dialog, 1.0);

        dialog_sync_buttons (dialog, TRUE);

        ncb_progress_dialog_set_operation_string (dialog, "");
}

static void
ncb_progress_dialog_class_init (NcbProgressDialogClass *klass)
{
        GObjectClass   *object_class = G_OBJECT_CLASS (klass);

        object_class->finalize     = ncb_progress_dialog_finalize;
        object_class->get_property = ncb_progress_dialog_get_property;
        object_class->set_property = ncb_progress_dialog_set_property;

        g_type_class_add_private (klass, sizeof (NcbProgressDialogPrivate));

        /* Load the jar pixbufs */
        empty_jar_pixbuf = gdk_pixbuf_new_from_inline (-1, progress_jar_empty_icon, FALSE, NULL);
        full_jar_pixbuf = gdk_pixbuf_new_from_inline (-1, progress_jar_full_icon, FALSE, NULL);
}

static void
ncb_progress_dialog_init (NcbProgressDialog *dialog)
{
        GtkWidget *vbox;

        dialog->priv = NCB_PROGRESS_DIALOG_GET_PRIVATE (dialog);

        dialog->priv->xml = glade_xml_new (DATADIR "/nautilus-cd-burner.glade", "progress_dialog_vbox", NULL);

        gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);

        vbox = glade_xml_get_widget (dialog->priv->xml, "progress_dialog_vbox");
        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
vbox,
                            TRUE, TRUE, 0);
        gtk_widget_show_all (vbox);

        dialog->priv->make_another_button_visible = TRUE;
        dialog->priv->make_another_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Make Another Copy"), GTK_RESPONSE_ACCEPT);
        dialog->priv->cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
        dialog->priv->close_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);

        dialog_sync_buttons (dialog, FALSE);

        /* Set window icon */
        gtk_window_set_icon (GTK_WINDOW (dialog), empty_jar_pixbuf);

        /* Set progress jar position */
        progress_jar_position = gdk_pixbuf_get_height (empty_jar_pixbuf);

        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
                                         GTK_RESPONSE_CLOSE);

        ncb_progress_dialog_image_setup (dialog);
}

static void
ncb_progress_dialog_finalize (GObject *object)
{
        NcbProgressDialog *dialog;

        g_return_if_fail (object != NULL);
        g_return_if_fail (NCB_IS_PROGRESS_DIALOG (object));

        dialog = NCB_PROGRESS_DIALOG (object);

        g_return_if_fail (dialog->priv != NULL);

        if (dialog->priv->spin_id != 0) {
                g_source_remove (dialog->priv->spin_id);
                dialog->priv->spin_id = 0;
        }

        ncb_progress_dialog_image_cleanup (dialog);

        G_OBJECT_CLASS (ncb_progress_dialog_parent_class)->finalize (object);
}

GtkWidget *
ncb_progress_dialog_new (void)
{
        GObject *object;

        object = g_object_new (NCB_TYPE_PROGRESS_DIALOG, NULL);

        return GTK_WIDGET (object);
}

Generated by  Doxygen 1.6.0   Back to index