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

nautilus-burn-drive-selection.c

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
 * 
 * nautilus-burn-drive-selection.c
 *
 * Copyright (C) 2002-2004 Bastien Nocera <hadess@hadess.net>
 * Copyright (C) 2005 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: Bastien Nocera <hadess@hadess.net>
 *          William Jon McCann <mccann@jhu.edu>
 *
 */

#include "config.h"

#include <string.h>

#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkcombobox.h>
#include <gtk/gtkliststore.h>
#include <gtk/gtkcelllayout.h>
#include <gtk/gtkcellrenderertext.h>

#include "nautilus-burn-drive-selection.h"

/* Signals */
enum {
      DEVICE_CHANGED,
      LAST_SIGNAL
};

/* Arguments */
enum {
      PROP_0,
      PROP_DEVICE,
      PROP_FILE_IMAGE,
      PROP_RECORDERS_ONLY,
};

#define NAUTILUS_BURN_DRIVE_SELECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_BURN_TYPE_DRIVE_SELECTION, NautilusBurnDriveSelectionPrivate))

struct NautilusBurnDriveSelectionPrivate {
      GList   *cdroms;
      gboolean have_file_image;
      gboolean show_recorders_only;
};

static void nautilus_burn_drive_selection_init         (NautilusBurnDriveSelection *selection);

static void nautilus_burn_drive_selection_set_property (GObject      *object,
                                          guint         property_id,
                                          const GValue *value,
                                          GParamSpec   *pspec);
static void nautilus_burn_drive_selection_get_property (GObject      *object,
                                          guint         property_id,
                                          GValue       *value,
                                          GParamSpec   *pspec);

static void nautilus_burn_drive_selection_finalize     (GObject      *object);

static GtkWidgetClass *parent_class = NULL;

static int nautilus_burn_drive_selection_table_signals [LAST_SIGNAL] = { 0 };

static NautilusBurnDrive *
get_drive (NautilusBurnDriveSelection *selection,
         int                         nr)
{
      GList *item;

      item = g_list_nth (selection->priv->cdroms, nr);
      if (item == NULL)
            return NULL;
      else
            return item->data;
}

G_DEFINE_TYPE(NautilusBurnDriveSelection, nautilus_burn_drive_selection, GTK_TYPE_COMBO_BOX);

static void
nautilus_burn_drive_selection_class_init (NautilusBurnDriveSelectionClass *klass)
{
      GObjectClass *object_class;
      GtkWidgetClass *widget_class;

      object_class = (GObjectClass *) klass;
      widget_class = (GtkWidgetClass *) klass;

      parent_class = g_type_class_peek_parent (klass);

      /* GObject */
      object_class->set_property = nautilus_burn_drive_selection_set_property;
      object_class->get_property = nautilus_burn_drive_selection_get_property;
      object_class->finalize = nautilus_burn_drive_selection_finalize;

      g_type_class_add_private (klass, sizeof (NautilusBurnDriveSelectionPrivate));

      /* Properties */
      g_object_class_install_property (object_class, PROP_DEVICE,
                               g_param_spec_string ("device", NULL, NULL,
                                                NULL, G_PARAM_READWRITE));
      g_object_class_install_property (object_class, PROP_FILE_IMAGE,
                               g_param_spec_boolean ("file-image", NULL, NULL,
                                                 FALSE, G_PARAM_READWRITE));
      g_object_class_install_property (object_class, PROP_RECORDERS_ONLY,
                               g_param_spec_boolean ("show-recorders-only", NULL, NULL,
                                                 FALSE, G_PARAM_READWRITE));

      /* Signals */
      nautilus_burn_drive_selection_table_signals [DEVICE_CHANGED] =
            g_signal_new ("device-changed",
                        G_TYPE_FROM_CLASS (object_class),
                        G_SIGNAL_RUN_LAST,
                        G_STRUCT_OFFSET (NautilusBurnDriveSelectionClass,
                                     device_changed),
                        NULL, NULL,
                        g_cclosure_marshal_VOID__STRING,
                        G_TYPE_NONE, 1, G_TYPE_STRING);
}

static void
combo_device_changed (GtkComboBox *combo,
                  gpointer     user_data)
{
      NautilusBurnDriveSelection *selection = (NautilusBurnDriveSelection *) user_data;
      NautilusBurnDrive          *drive;
      int                         i;

      i = gtk_combo_box_get_active (GTK_COMBO_BOX (selection));
      /* No selection */
      if (i < 0) {
            g_signal_emit (G_OBJECT (selection),
                         nautilus_burn_drive_selection_table_signals [DEVICE_CHANGED],
                         0, NULL);
            return;
      }
      drive = get_drive (selection, i);
      if (drive == NULL)
            return;

      g_signal_emit (G_OBJECT (selection),
                   nautilus_burn_drive_selection_table_signals [DEVICE_CHANGED],
                   0, drive->device);

      g_object_notify (G_OBJECT (selection), "device");
}

static void
cdrom_combo_box (NautilusBurnDriveSelection *selection,
             gboolean                    show_recorders_only,
             gboolean                    show_file_image)
{
      GList             *l;
      NautilusBurnDrive *cdrom;

      selection->priv->cdroms = nautilus_burn_drive_get_list (show_recorders_only, show_file_image);

      for (l = selection->priv->cdroms; l != NULL; l = l->next) {
            cdrom = l->data;

            if (cdrom->display_name == NULL) {
                  g_warning ("cdrom->display_name != NULL failed");
            }

            gtk_combo_box_append_text (GTK_COMBO_BOX (selection),
                                 cdrom->display_name
                                 ? cdrom->display_name : _("Unnamed CDROM"));
      }
      gtk_combo_box_set_active (GTK_COMBO_BOX (selection), 0);

      if (selection->priv->cdroms == NULL) {
            gtk_widget_set_sensitive (GTK_WIDGET (selection), FALSE);
      }
}

static void
nautilus_burn_drive_selection_init (NautilusBurnDriveSelection *selection)
{
      GtkCellRenderer *cell;
      GtkListStore    *store;

      selection->priv = NAUTILUS_BURN_DRIVE_SELECTION_GET_PRIVATE (selection);

      store = gtk_list_store_new (1, G_TYPE_STRING);
      gtk_combo_box_set_model (GTK_COMBO_BOX (selection),
                         GTK_TREE_MODEL (store));

      cell = gtk_cell_renderer_text_new ();
      gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (selection), cell, TRUE);
      gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (selection), cell,
                              "text", 0,
                              NULL);

      cdrom_combo_box (selection, FALSE, FALSE);

      g_signal_connect (G_OBJECT (selection), "changed",
                    G_CALLBACK (combo_device_changed), selection);
      
}

static void
nautilus_burn_drive_selection_finalize (GObject *object)
{
      GList                      *l;
      NautilusBurnDriveSelection *selection = (NautilusBurnDriveSelection *) object;

      g_return_if_fail (selection != NULL);
      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection));

      l = selection->priv->cdroms;
      while (l != NULL) {
            NautilusBurnDrive *cdrom = l->data;

            l = g_list_remove (l, cdrom);
            nautilus_burn_drive_unref (cdrom);
      }

      if (G_OBJECT_CLASS (parent_class)->finalize != NULL) {
            (* G_OBJECT_CLASS (parent_class)->finalize) (object);
      }
}

/**
 * nautilus_burn_drive_selection_new:
 *
 * Create a new drive selector.
 *
 * Return value: Newly allocated #NautilusBurnDriveSelection widget
 **/
GtkWidget *
nautilus_burn_drive_selection_new (void)
{
      GtkWidget *widget;

      widget = GTK_WIDGET
            (g_object_new (NAUTILUS_BURN_TYPE_DRIVE_SELECTION, NULL));

        return widget;
}

static void
nautilus_burn_drive_selection_set_have_file_image (NautilusBurnDriveSelection *selection,
                                       gboolean                    have_file_image)
{
      NautilusBurnDrive *cdrom;

      g_return_if_fail (selection != NULL);
      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection));

      if (selection->priv->have_file_image == have_file_image) {
            return;
      }

      if (have_file_image == FALSE) {
            GList *item;
            int index;

            index = g_list_length (selection->priv->cdroms) - 1;
            gtk_combo_box_remove_text (GTK_COMBO_BOX (selection), index);

            item = g_list_last (selection->priv->cdroms);
            cdrom = (NautilusBurnDrive *)item->data;
            nautilus_burn_drive_unref (cdrom);
            selection->priv->cdroms = g_list_delete_link
                  (selection->priv->cdroms, item);
            gtk_widget_set_sensitive (GTK_WIDGET (selection), (selection->priv->cdroms != NULL));
      } else {
            gboolean activate = FALSE;

            cdrom = nautilus_burn_drive_get_file_image ();
            gtk_combo_box_append_text (GTK_COMBO_BOX (selection),
                                 cdrom->display_name);
            if (selection->priv->cdroms == NULL)
                  activate = TRUE;
            selection->priv->cdroms = g_list_append (selection->priv->cdroms, cdrom);
            gtk_widget_set_sensitive (GTK_WIDGET (selection), TRUE);
            if (activate != FALSE)
                  gtk_combo_box_set_active (GTK_COMBO_BOX (selection), 0);
      }

      selection->priv->have_file_image = have_file_image;
}

static gint
compare_drives (NautilusBurnDrive *drive1,
            NautilusBurnDrive *drive2)
{
      if (!drive1 || !drive2)
            return 1;

      if ((drive1->type & NAUTILUS_BURN_DRIVE_TYPE_FILE)
          && (drive2->type & NAUTILUS_BURN_DRIVE_TYPE_FILE))
            return 0;

      if (!drive1->device || !drive2->device)
            return 1;

      return strcmp (drive1->device, drive2->device);
}

static void
nautilus_burn_drive_selection_set_recorders_only (NautilusBurnDriveSelection *selection,
                                      gboolean                    recorders_only)
{
      g_return_if_fail (selection != NULL);
      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection));

      if (selection->priv->show_recorders_only == recorders_only)
            return;

      g_signal_handlers_block_by_func (G_OBJECT (selection),
                               combo_device_changed, selection);

      if (recorders_only == TRUE) {
            GList *l = g_list_last (selection->priv->cdroms);
            int i = g_list_length (selection->priv->cdroms);

            while (l) {
                  GList *prev = l->prev;
                  NautilusBurnDrive *drive = l->data;

                  i--;

                  if (!(drive->type & NAUTILUS_BURN_DRIVE_TYPE_CD_RECORDER
                        || drive->type & NAUTILUS_BURN_DRIVE_TYPE_CDRW_RECORDER
                        || drive->type & NAUTILUS_BURN_DRIVE_TYPE_DVD_RAM_RECORDER
                        || drive->type & NAUTILUS_BURN_DRIVE_TYPE_DVD_RW_RECORDER
                        || drive->type & NAUTILUS_BURN_DRIVE_TYPE_FILE)) {
                        gtk_combo_box_remove_text (GTK_COMBO_BOX (selection), i);
                        nautilus_burn_drive_unref (drive);
                        selection->priv->cdroms = g_list_delete_link (selection->priv->cdroms, l);
                  }

                  l = prev;
            }

            /* Removing entries from the combo box may have invalidated
             * the currently selected one
             */
            if (gtk_combo_box_get_active (GTK_COMBO_BOX (selection)) == -1)
                  gtk_combo_box_set_active (GTK_COMBO_BOX (selection), 0);

      } else {
            GList *drives = nautilus_burn_drive_get_list (recorders_only, selection->priv->have_file_image);
            GList *l;
            int    i = g_list_length (selection->priv->cdroms);

            gtk_widget_set_sensitive (GTK_WIDGET (selection), (drives != NULL));

            if (selection->priv->have_file_image)
                  i--;

            for (l = drives; l != NULL; l = l->next) {
                  NautilusBurnDrive *drive = l->data;

                  if (!g_list_find_custom (selection->priv->cdroms,
                                     drive,
                                     (GCompareFunc)compare_drives)) {
                        gtk_combo_box_insert_text (GTK_COMBO_BOX (selection),
                                             i,
                                             drive->display_name);
                        selection->priv->cdroms = g_list_insert (selection->priv->cdroms,
                                                       drive,
                                                       i);
                  } else {
                        nautilus_burn_drive_unref (drive);
                  }
            }
            g_list_free (drives);
      }

      g_signal_handlers_unblock_by_func (G_OBJECT (selection),
                                 combo_device_changed, selection);

      /* Force a signal out */
      combo_device_changed (NULL, (gpointer) selection);

      selection->priv->show_recorders_only = recorders_only;
}

static void
nautilus_burn_drive_selection_set_property (GObject      *object,
                                  guint         property_id,
                                  const GValue *value,
                                  GParamSpec   *pspec)
{
      NautilusBurnDriveSelection *selection;

      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (object));

      selection = NAUTILUS_BURN_DRIVE_SELECTION (object);

      switch (property_id) {
      case PROP_DEVICE:
            nautilus_burn_drive_selection_set_device (selection, g_value_get_string (value));
            break;
      case PROP_FILE_IMAGE:
            nautilus_burn_drive_selection_set_have_file_image (selection,
                                                   g_value_get_boolean (value));
            break;
      case PROP_RECORDERS_ONLY:
            nautilus_burn_drive_selection_set_recorders_only (selection,
                                                  g_value_get_boolean (value));
            break;
      default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      }
}

static void
nautilus_burn_drive_selection_get_property (GObject    *object,
                                  guint       property_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
{
      NautilusBurnDriveSelection *selection;

      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (object));

      selection = NAUTILUS_BURN_DRIVE_SELECTION (object);

      switch (property_id) {
      case PROP_DEVICE:
            g_value_set_string (value, nautilus_burn_drive_selection_get_device (selection));
            break;
      case PROP_FILE_IMAGE:
            g_value_set_boolean (value, selection->priv->have_file_image);
            break;
      case PROP_RECORDERS_ONLY:
            g_value_set_boolean (value, selection->priv->show_recorders_only);
            break;
      default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      }
}

/**
 * nautilus_burn_drive_selection_set_active:
 * @selection: #NautilusBurnDriveSelection
 * @drive: #NautilusBurnDrive
 *
 * Set the current selected drive to that which corresponds to the
 * specified drive.
 *
 * Since: 2.14
 *
 **/
void
nautilus_burn_drive_selection_set_active (NautilusBurnDriveSelection *selection,
                                NautilusBurnDrive          *drive)
{
      GList             *l;
      gboolean           found;
      int                i;

      g_return_if_fail (selection != NULL);
      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection));

      found = FALSE;
      i = -1;
      for (l = selection->priv->cdroms; l != NULL && found == FALSE; l = l->next) {
            NautilusBurnDrive *drive2;

            i++;

            drive2 = l->data;

            if (nautilus_burn_drive_equal (drive, drive2)) {
                  found = TRUE;
            }
      }

      if (found) {
            gtk_combo_box_set_active (GTK_COMBO_BOX (selection), i);
      } else {
            /* If the device doesn't exist, set it back to
             * the default */
            gtk_combo_box_set_active (GTK_COMBO_BOX (selection), 0);

            drive = get_drive (selection, 0);

            if (drive == NULL)
                  return;

            g_signal_emit (G_OBJECT (selection),
                         nautilus_burn_drive_selection_table_signals [DEVICE_CHANGED],
                         0, drive->device);
      }
      g_object_notify (G_OBJECT (selection), "device");
}

/**
 * nautilus_burn_drive_selection_get_active:
 * @selection: #NautilusBurnDriveSelection
 *
 * Get the currently selected drive
 *
 * Return value: currently selected #NautilusBurnDrive.  The drive must be
 * unreffed using nautilus_burn_drive_unref after use.
 *
 * Since: 2.14
 *
 **/
NautilusBurnDrive *
nautilus_burn_drive_selection_get_active (NautilusBurnDriveSelection *selection)
{
      NautilusBurnDrive *drive;
      int                i;

      g_return_val_if_fail (selection != NULL, NULL);
      g_return_val_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection), NULL);

      i = gtk_combo_box_get_active (GTK_COMBO_BOX (selection));
      drive = get_drive (selection, i);

      if (drive)
            nautilus_burn_drive_ref (drive);

      return drive;
}


/* Deprecated functions */

/**
 * nautilus_burn_drive_selection_get_default_device:
 * @selection: #NautilusBurnDriveSelection
 *
 * Get the block device name that corresponds to the default drive.
 *
 * Deprecated:
 *
 **/
const char *
nautilus_burn_drive_selection_get_default_device (NautilusBurnDriveSelection *selection)
{
      GList             *l;
      NautilusBurnDrive *drive;

      g_return_val_if_fail (selection != NULL, "/dev/cdrom");
      g_return_val_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection), "/dev/cdrom");

      l = selection->priv->cdroms;
      if (selection->priv->cdroms == NULL)
            return "/dev/cdrom";

      drive = l->data;

      return drive->device;
}

/**
 * nautilus_burn_drive_selection_set_device:
 * @selection: #NautilusBurnDriveSelection
 * @device: block device name
 *
 * Set the current selected drive to that which corresponds to the
 * specified block device name.
 *
 * Deprecated: Use nautilus_burn_drive_selection_set_active() instead
 *
 **/
void
nautilus_burn_drive_selection_set_device (NautilusBurnDriveSelection *selection,
                                const char                 *device)
{
      GList             *l;
      NautilusBurnDrive *drive;
      gboolean           found;
      int                i;

      found = FALSE;
      i = -1;

      g_return_if_fail (selection != NULL);
      g_return_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection));

      for (l = selection->priv->cdroms; l != NULL && found == FALSE; l = l->next) {
            i++;

            drive = l->data;

            if (strcmp (drive->device, device) == 0)
                  found = TRUE;
      }

      if (found) {
            gtk_combo_box_set_active (GTK_COMBO_BOX (selection), i);
      } else {
            /* If the device doesn't exist, set it back to
             * the default */
            gtk_combo_box_set_active (GTK_COMBO_BOX (selection), 0);

            drive = get_drive (selection, 0);

            if (drive == NULL)
                  return;

            g_signal_emit (G_OBJECT (selection),
                         nautilus_burn_drive_selection_table_signals [DEVICE_CHANGED],
                         0, drive->device);
      }
      g_object_notify (G_OBJECT (selection), "device");
}

/**
 * nautilus_burn_drive_selection_get_device:
 * @selection: #NautilusBurnDriveSelection
 *
 * Get the block device name that corresponds to the currently
 * selected drive
 *
 * Return value: String block device name that corresponds to the
 * currently selected drive
 *
 * Deprecated: Use nautilus_burn_drive_selection_get_active() instead
 *
 **/
const char *
nautilus_burn_drive_selection_get_device (NautilusBurnDriveSelection *selection)
{
      NautilusBurnDrive *drive;
      int                i;

      g_return_val_if_fail (selection != NULL, NULL);
      g_return_val_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection), NULL);

      i = gtk_combo_box_get_active (GTK_COMBO_BOX (selection));
      drive = get_drive (selection, i);

      return drive ? drive->device : NULL;
}

/**
 * nautilus_burn_drive_selection_get_drive:
 * @selection: #NautilusBurnDriveSelection
 *
 * Get the currently selected drive
 *
 * Return value: currently selected #NautilusBurnDrive
 *
 * Deprecated: Use nautilus_burn_drive_selection_get_active() instead
 *
 **/
const NautilusBurnDrive *
nautilus_burn_drive_selection_get_drive (NautilusBurnDriveSelection *selection)
{
      NautilusBurnDrive *drive;
      int                i;

      g_return_val_if_fail (selection != NULL, NULL);
      g_return_val_if_fail (NAUTILUS_BURN_IS_DRIVE_SELECTION (selection), NULL);

      i = gtk_combo_box_get_active (GTK_COMBO_BOX (selection));
      drive = get_drive (selection, i);

      return drive;
}

Generated by  Doxygen 1.6.0   Back to index