static gboolean rb_ipod_db_load (RbIpodDb *ipod_db, GMount *mount) { GFile *mount_root; char *mount_path; const Itdb_IpodInfo *info; RbIpodDbPrivate *priv = IPOD_DB_GET_PRIVATE (ipod_db); mount_root = g_mount_get_root (mount); if (mount_root == NULL) { return FALSE; } mount_path = g_file_get_path (mount_root); g_object_unref (mount_root); priv->itdb = itdb_parse (mount_path, NULL); g_free (mount_path); if (priv->itdb == NULL) { return FALSE; } info = itdb_device_get_ipod_info (priv->itdb->device); if (info->ipod_generation == ITDB_IPOD_GENERATION_UNKNOWN || info->ipod_generation == ITDB_IPOD_GENERATION_SHUFFLE_1 || info->ipod_generation == ITDB_IPOD_GENERATION_SHUFFLE_2 || info->ipod_generation == ITDB_IPOD_GENERATION_SHUFFLE_3) { priv->needs_shuffle_db = TRUE; } else { priv->needs_shuffle_db = FALSE; } return TRUE; }
QString IpodDeviceHelper::collectionName( Itdb_iTunesDB *itdb ) { const Itdb_IpodInfo *info = (itdb && itdb->device) ? itdb_device_get_ipod_info( itdb->device ) : 0; QString modelName = info ? QString::fromUtf8( itdb_info_get_ipod_model_name_string( info->ipod_model ) ) : i18nc( "iPod model that is not (yet) recognized", "Unrecognized model" ); return i18nc( "Name of the iPod collection; %1 is iPod name, %2 is iPod model; example: My iPod: Nano (Blue)", "%1: %2", IpodDeviceHelper::ipodName( itdb ), modelName ); }
/** * Return ipod info if iPod model is recognized, returns null if itdb is null or if iPod * is invalid or unknown. */ static const Itdb_IpodInfo *getIpodInfo( const Itdb_iTunesDB *itdb ) { if( !itdb || !itdb->device ) return 0; const Itdb_IpodInfo *info = itdb_device_get_ipod_info( itdb->device ); if( !info ) return 0; if( info->ipod_model == ITDB_IPOD_MODEL_INVALID || info->ipod_model == ITDB_IPOD_MODEL_UNKNOWN ) { return 0; } return info; }
static void fill_model_combo (GtkWidget *combo, const char *mount_path) { GHashTable *models; Itdb_Device *device; GtkTreeStore *store; const Itdb_IpodInfo *ipod_info; GtkCellRenderer *renderer; struct FillModelContext ctx; device = itdb_device_new (); itdb_device_set_mountpoint (device, mount_path); itdb_device_read_sysinfo (device); ipod_info = itdb_device_get_ipod_info (device); itdb_device_free (device); store = gtk_tree_store_new (1, G_TYPE_POINTER); gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store)); ctx.combo = combo; ctx.store = store; ctx.ipod_info = ipod_info; models = build_model_table (mount_path); g_hash_table_foreach (models, fill_one_generation, &ctx); g_hash_table_destroy (models); g_object_unref (store); gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); renderer = gtk_cell_renderer_text_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_cell, NULL, NULL); }
/** * repository_ipod_init_set_model: * * Ask for the iPod model, pre-select @old_model, set the selected * model in the preferences. * * @itdb: the itdb to set * @old_model: the model number string to initially propose. */ void repository_ipod_init_set_model(iTunesDB *itdb, const gchar *old_model) { GtkBuilder *builder; GtkWidget *window; gint response; gchar *model, *mountpoint; gchar buf[PATH_MAX]; GtkComboBox *cb; const IpodInfo *info; GtkTreeIter iter; g_return_if_fail (itdb); /* Create window */ builder = init_repository_builder(); window = GET_WIDGET (builder, "set_ipod_model_dialog"); g_return_if_fail (window); /* Set up label */ mountpoint = get_itdb_prefs_string(itdb, KEY_MOUNTPOINT); gchar *displaymp = g_uri_unescape_string(mountpoint, NULL); g_return_if_fail (mountpoint); g_snprintf(buf, PATH_MAX, _("<b>Please select your iPod model at </b><i>%s</i>"), displaymp); gtk_label_set_markup(GTK_LABEL (GET_WIDGET (builder, SIMD_LABEL)), buf); g_free(mountpoint); g_free(displaymp); /* Setup model number combo */ cb = GTK_COMBO_BOX (GET_WIDGET (builder, SIMD_MODEL_COMBO)); repository_init_model_number_combo(cb); /* If available set current model number, otherwise indicate that none is available */ info = itdb_device_get_ipod_info(itdb->device); if (info && (info->ipod_generation != ITDB_IPOD_GENERATION_UNKNOWN)) { g_snprintf(buf, PATH_MAX, "x%s", info->model_number); } else { model = get_itdb_prefs_string(itdb, KEY_IPOD_MODEL); if (model && (strlen(g_strstrip (model)) != 0)) { g_snprintf(buf, PATH_MAX, "%s", model); g_free(model); } else { g_snprintf(buf, PATH_MAX, "%s", gettext (SELECT_OR_ENTER_YOUR_MODEL)); } } /* Try and set buf as the active selection in the combo box */ _model_combo_set_active_iter(cb, buf); response = gtk_dialog_run(GTK_DIALOG (window)); switch (response) { case GTK_RESPONSE_OK: g_return_if_fail(gtk_combo_box_get_active_iter(cb, &iter)); gtk_tree_model_get(gtk_combo_box_get_model(cb), &iter, COL_STRING, &model, -1); if (!model) { gtkpod_warning(_("Could not determine the model you selected -- this could be a bug or incompatibilty in the GTK+ or glade library.\n\n")); } else if (strcmp(model, gettext(SELECT_OR_ENTER_YOUR_MODEL)) == 0) { /* User didn't choose a model */ g_free(model); model = NULL; } if (model) { /* Set model in the prefs system */ set_itdb_prefs_string(itdb, KEY_IPOD_MODEL, model); /* Set the model on the iPod */ itdb_device_set_sysinfo(itdb->device, "ModelNumStr", model); g_free(model); } break; default: /* canceled -- do nothing */ break; } gtk_widget_destroy(window); }
/** * repository_ipod_init: * * Ask for the iPod model and mountpoint and then create the directory * structure on the iPod. * * @itdb: itdb from where to extract the mountpoint. After * initialisation the model number is set. */ gboolean repository_ipod_init(iTunesDB *itdb) { IpodInit *ii; gint response; gboolean result = FALSE; gchar *mountpoint, *new_mount, *name, *model; GError *error = NULL; gchar buf[PATH_MAX]; GtkComboBox *cb; const IpodInfo *info; GtkTreeIter iter; g_return_val_if_fail (itdb, FALSE); /* Create window */ ii = g_new0 (IpodInit, 1); ii->itdb = itdb; ii->builder = init_repository_builder(); ii->window = gtkpod_builder_xml_get_widget(ii->builder, "ipod_init_dialog"); g_return_val_if_fail (ii->window, FALSE); /* Set mountpoint */ mountpoint = get_itdb_prefs_string(itdb, KEY_MOUNTPOINT); if (mountpoint) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(GET_WIDGET (ii->builder, IID_MOUNTPOINT_CHOOSER)), mountpoint); } /* Setup model number combo */ cb = GTK_COMBO_BOX (GET_WIDGET (ii->builder, IID_MODEL_COMBO)); repository_init_model_number_combo(cb); /* If available set current model number, otherwise indicate that none is available */ info = itdb_device_get_ipod_info(itdb->device); if (info && (info->ipod_generation != ITDB_IPOD_GENERATION_UNKNOWN)) { g_snprintf(buf, PATH_MAX, "x%s", info->model_number); } else { model = get_itdb_prefs_string(itdb, KEY_IPOD_MODEL); if (model && (strlen(g_strstrip (model)) != 0)) { g_snprintf(buf, PATH_MAX, "%s", model); g_free(model); } else { g_snprintf(buf, PATH_MAX, "%s", gettext (SELECT_OR_ENTER_YOUR_MODEL)); } } /* Try and set buf as the active selection in the combo box */ _model_combo_set_active_iter(cb, buf); gtk_window_set_transient_for(GTK_WINDOW (ii->window), GTK_WINDOW (gtkpod_app)); response = gtk_dialog_run(GTK_DIALOG (ii->window)); switch (response) { case GTK_RESPONSE_OK: new_mount = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(GET_WIDGET (ii->builder, IID_MOUNTPOINT_CHOOSER)))); if (!new_mount || (strlen(new_mount) == 0)) { gtkpod_statusbar_message("No mount point has been selected"); return FALSE; } if (!gtk_combo_box_get_has_entry(cb)) { gtkpod_statusbar_message("No model has been selected"); return FALSE; } /* remove trailing '/' in case it's present. */ if (mountpoint && (strlen(mountpoint) > 0)) { if (G_IS_DIR_SEPARATOR(mountpoint[strlen(mountpoint) - 1])) { mountpoint[strlen(mountpoint) - 1] = 0; } } if (new_mount && (strlen(new_mount) > 0)) { if (G_IS_DIR_SEPARATOR(new_mount[strlen(new_mount) - 1])) { new_mount[strlen(new_mount) - 1] = 0; } } if (!(mountpoint && new_mount && (strcmp(mountpoint, new_mount) == 0))) { /* mountpoint has changed */ g_free(mountpoint); mountpoint = new_mount; new_mount = NULL; set_itdb_prefs_string(itdb, KEY_MOUNTPOINT, mountpoint); call_script("gtkpod.load", mountpoint, NULL); itdb_set_mountpoint(itdb, mountpoint); } else { g_free(new_mount); new_mount = NULL; } g_return_val_if_fail(gtk_combo_box_get_active_iter(cb, &iter), FALSE); gtk_tree_model_get(gtk_combo_box_get_model(cb), &iter, COL_STRING, &model, -1); g_return_val_if_fail(model, FALSE); if ((strcmp(model, gettext(SELECT_OR_ENTER_YOUR_MODEL)) == 0) || (strlen(model) == 0)) { /* User didn't choose a model */ g_free(model); model = NULL; } /* Set model in the prefs system */ set_itdb_prefs_string(itdb, KEY_IPOD_MODEL, model); name = get_itdb_prefs_string(itdb, "name"); result = itdb_init_ipod(mountpoint, model, name, &error); /* Set the model in the sysinfo of the itdb */ itdb_device_set_sysinfo(itdb->device, "ModelNumStr", model); if (!result) { if (error) { gtkpod_warning(_("Error initialising iPod: %s\n"), error->message); g_error_free(error); error = NULL; } else { gtkpod_warning(_("Error initialising iPod, unknown error\n")); } } else { /* Should write the extended info file */ result = gp_create_extended_info(itdb); } g_free(name); g_free(model); break; default: /* canceled -- do nothing */ break; } gtk_widget_destroy(ii->window); g_free(mountpoint); g_free(ii); return result; }
void IpodDeviceHelper::fillInConfigureDialog( KDialog *configureDialog, Ui::IpodConfiguration *configureDialogUi, const QString &mountPoint, Itdb_iTunesDB *itdb, const Transcoding::Configuration &transcodeConfig, const QString &errorMessage ) { static const QString unknown = i18nc( "Unknown iPod model, generation...", "Unknown" ); static const QString supported = i18nc( "In a dialog: Video: Supported", "Supported" ); static const QString notSupported = i18nc( "In a dialog: Video: Not supported", "Not supported" ); static const QString present = i18nc( "In a dialog: Some file: Present", "Present" ); static const QString notFound = i18nc( "In a dialog: Some file: Not found", "<b>Not found</b>" ); static const QString notNeeded = i18nc( "In a dialog: Some file: Not needed", "Not needed" ); // following call accepts null itdb configureDialogUi->nameLineEdit->setText( IpodDeviceHelper::ipodName( itdb ) ); QString notes; QString warningText; QString safeToWriteMessage; bool isSafeToWrite = safeToWriteWithMessage( mountPoint, itdb, safeToWriteMessage ); bool sysInfoExtendedExists = fileFound( mountPoint, "SysInfoExtended" ); bool sysInfoExists = fileFound( mountPoint, "SysInfo" ); if( itdb ) { configureDialogUi->nameLineEdit->setEnabled( isSafeToWrite ); configureDialogUi->transcodeComboBox->setEnabled( isSafeToWrite ); configureDialogUi->transcodeComboBox->fillInChoices( transcodeConfig ); configureDialogUi->modelComboLabel->setEnabled( false ); configureDialogUi->modelComboBox->setEnabled( false ); configureDialogUi->initializeLabel->setEnabled( false ); configureDialogUi->initializeButton->setEnabled( false ); if( !errorMessage.isEmpty() ) // to inform user about successful initialization. warningText = QString( "<b>%1</b>" ).arg( errorMessage ); const Itdb_Device *device = itdb->device; const Itdb_IpodInfo *info = device ? itdb_device_get_ipod_info( device ) : 0; configureDialogUi->infoGroupBox->setEnabled( true ); configureDialogUi->modelPlaceholer->setText( info ? QString::fromUtf8( itdb_info_get_ipod_model_name_string( info->ipod_model ) ) : unknown ); configureDialogUi->generationPlaceholder->setText( info ? QString::fromUtf8( itdb_info_get_ipod_generation_string( info->ipod_generation ) ) : unknown ); configureDialogUi->videoPlaceholder->setText( device ? ( itdb_device_supports_video( device ) ? supported : notSupported ) : unknown ); configureDialogUi->albumArtworkPlaceholder->setText( device ? ( itdb_device_supports_artwork( device ) ? supported : notSupported ) : unknown ); if( isSafeToWrite ) notes += safeToWriteMessage; // may be empty, doesn't hurt else { Q_ASSERT( !safeToWriteMessage.isEmpty() ); const QString link( "http://gtkpod.git.sourceforge.net/git/gitweb.cgi?p=gtkpod/libgpod;a=blob_plain;f=README.overview" ); notes += i18nc( "%1 is informational sentence giving reason", "<b>%1</b><br><br>" "As a safety measure, Amarok will <i>refuse to perform any writes</i> to " "iPod. (modifying iTunes database could make it look empty from the device " "point of view)<br>" "See <a href='%2'>README.overview</a> file from libgpod source repository " "for more information.", safeToWriteMessage, link ); } } else { configureDialogUi->nameLineEdit->setEnabled( true ); // for initialization configureDialogUi->modelComboLabel->setEnabled( true ); configureDialogUi->modelComboBox->setEnabled( true ); if( configureDialogUi->modelComboBox->count() == 0 ) fillInModelComboBox( configureDialogUi->modelComboBox, sysInfoExists || sysInfoExtendedExists ); configureDialogUi->initializeLabel->setEnabled( true ); configureDialogUi->initializeButton->setEnabled( true ); configureDialogUi->initializeButton->setIcon( KIcon( "task-attention" ) ); if( !errorMessage.isEmpty() ) warningText = i18n( "<b>%1</b><br><br>" "Above problem prevents Amarok from using your iPod. You can try to " "re-create critical iPod folders and files (including iTunes database) " "using the <b>%2</b> button below.<br><br> " "Initializing iPod <b>destroys iPod track and photo database</b>, however " "it should not delete any tracks. The tracks will become orphaned.", errorMessage, configureDialogUi->initializeButton->text().remove( QChar('&') ) ); configureDialogUi->infoGroupBox->setEnabled( false ); configureDialogUi->modelPlaceholer->setText( unknown ); configureDialogUi->generationPlaceholder->setText( unknown ); configureDialogUi->videoPlaceholder->setText( unknown ); configureDialogUi->albumArtworkPlaceholder->setText( unknown ); } if( !warningText.isEmpty() ) { configureDialogUi->initializeLabel->setText( warningText ); configureDialogUi->initializeLabel->adjustSize(); } QString sysInfoExtendedString = sysInfoExtendedExists ? present : notFound; QString sysInfoString = sysInfoExists ? present : ( sysInfoExtendedExists ? notNeeded : notFound ); configureDialogUi->sysInfoPlaceholder->setText( sysInfoString ); configureDialogUi->sysInfoExtendedPlaceholder->setText( sysInfoExtendedString ); configureDialogUi->notesPlaceholder->setText( notes ); configureDialogUi->notesPlaceholder->adjustSize(); configureDialog->enableButtonOk( isSafeToWrite ); }
/* called by itdb_photodb_add_photo() and itdb_photodb_add_photo_from_data() */ static Itdb_Artwork *itdb_photodb_add_photo_internal (Itdb_PhotoDB *db, const gchar *filename, const guchar *image_data, gsize image_data_len, gpointer pixbuf, gint position, gint rotation, GError **error) { #ifdef HAVE_GDKPIXBUF gboolean result; Itdb_Artwork *artwork; Itdb_PhotoAlbum *album; const Itdb_ArtworkFormat *format; g_return_val_if_fail (db, NULL); g_return_val_if_fail (db->device, NULL); g_return_val_if_fail (filename || image_data, NULL); g_return_val_if_fail (!(image_data && (image_data_len == 0)), NULL); g_return_val_if_fail (!(pixbuf && (!GDK_IS_PIXBUF (pixbuf))), NULL); if (!ipod_supports_photos (db->device)) { const Itdb_IpodInfo *ipodinfo = itdb_device_get_ipod_info (db->device); const gchar *model, *generation; if (!ipodinfo) { g_set_error (error, 0, -1, _("You need to specify the iPod model used before photos can be added.")); return NULL; /* For information: The model is set by calling the rather unintuitive function itdb_device_set_sysinfo as follows: itdb_device_set_sysinfo (db->device, "ModelNumStr", model); For example, "MA450" would stand for an 80 GB 6th generation iPod Video. See itdb_device.c for a list of supported models. This information will be written to the iPod when the PhotoDB is saved (itdb_device_write_sysinfo() is called). */ } model = itdb_info_get_ipod_model_name_string (ipodinfo->ipod_model); generation = itdb_info_get_ipod_generation_string (ipodinfo->ipod_generation); g_return_val_if_fail (model && generation, NULL); g_set_error (error, 0, -1, _("Your iPod does not seem to support photos. Maybe you need to specify the correct iPod model number? It is currently set to 'x%s' (%s/%s)."), ipodinfo->model_number, generation, model); return NULL; } /* check if filename is valid */ if (filename) { struct stat statbuf; if (g_stat (filename, &statbuf) != 0) { g_set_error (error, 0, -1, _("Could not access file '%s'. Photo not added."), filename); return NULL; } } artwork = itdb_artwork_new (); /* Add a thumbnail for every supported format */ format = itdb_device_get_artwork_formats (db->device); g_return_val_if_fail (format, NULL); for(result = TRUE; format->type != -1 && result == TRUE; format++) { if((format->type == ITDB_THUMB_COVER_SMALL) || (format->type == ITDB_THUMB_COVER_LARGE)) continue; if (filename) { result = itdb_artwork_add_thumbnail (artwork, format->type, filename, rotation, error); } if (image_data) { result = itdb_artwork_add_thumbnail_from_data (artwork, format->type, image_data, image_data_len, rotation, error); } if (pixbuf) { result = itdb_artwork_add_thumbnail_from_pixbuf (artwork, format->type, pixbuf, rotation, error); } } if (result != TRUE) { itdb_artwork_free (artwork); g_set_error (error, 0, -1, _("Unexpected error in itdb_photodb_add_photo_internal() while adding photo, please report.")); return NULL; } /* Add artwork to the list of photos */ /* (it would be sufficient to append to the end) */ db->photos = g_list_insert (db->photos, artwork, position); /* Add artwork to the first album */ album = itdb_photodb_photoalbum_by_name (db, NULL); if (!album) { album = itdb_photodb_photoalbum_create (db, _("Photo Library"), -1); album->album_type = 1; /* Photo Library */ } itdb_photodb_photoalbum_add_photo (db, album, artwork, position); return artwork; #else g_set_error (error, 0, -1, _("Library compiled without gdk-pixbuf support. Picture support is disabled.")); return NULL; #endif }