static bool content_file_init_extract( struct string_list *content, content_information_ctx_t *content_ctx, const struct retro_subsystem_info *special, union string_list_elem_attr *attr, char **error_string ) { unsigned i; for (i = 0; i < content->size; i++) { char temp_content[PATH_MAX_LENGTH]; char new_path[PATH_MAX_LENGTH]; bool block_extract = content->elems[i].attr.i & 1; const char *path = content->elems[i].data; const char *valid_ext = special ? special->roms[i].valid_extensions : content_ctx->valid_extensions; bool contains_compressed = path_contains_compressed_file(path); /* Block extract check. */ if (block_extract) continue; /* just use the first file in the archive */ if (!contains_compressed && !path_is_compressed_file(path)) continue; temp_content[0] = new_path[0] = '\0'; strlcpy(temp_content, path, sizeof(temp_content)); if (!valid_ext || !file_archive_extract_file( temp_content, sizeof(temp_content), valid_ext, !string_is_empty(content_ctx->directory_cache) ? content_ctx->directory_cache : NULL, new_path, sizeof(new_path))) { char str[1024]; snprintf(str, sizeof(str), "%s: %s.\n", msg_hash_to_str( MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE), temp_content); return false; } string_list_set(content, i, new_path); if (!string_list_append(content_ctx->temporary_content, new_path, *attr)) return false; } return true; }
static int action_start_playlist_association(unsigned type, const char *label) { int found; char new_playlist_cores[PATH_MAX_LENGTH] = {0}; struct string_list *stnames = NULL; struct string_list *stcores = NULL; core_info_list_t *list = NULL; settings_t *settings = config_get_ptr(); const char *path = path_basename(label); core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); if (!list) return -1; stnames = string_split(settings->playlist_names, ";"); stcores = string_split(settings->playlist_cores, ";"); found = string_list_find_elem(stnames, path); if (found) string_list_set(stcores, found-1, "DETECT"); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->playlist_cores, new_playlist_cores, sizeof(settings->playlist_cores)); return 0; }
static int action_start_playlist_association(unsigned type, const char *label) { int found; char new_playlist_cores[PATH_MAX_LENGTH]; struct string_list *stnames = NULL; struct string_list *stcores = NULL; core_info_list_t *list = NULL; settings_t *settings = config_get_ptr(); const char *path = path_basename(label); core_info_get_list(&list); if (!list) return -1; new_playlist_cores[0] = '\0'; stnames = string_split(settings->arrays.playlist_names, ";"); stcores = string_split(settings->arrays.playlist_cores, ";"); found = string_list_find_elem(stnames, path); if (found) string_list_set(stcores, found-1, file_path_str(FILE_PATH_DETECT)); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->arrays.playlist_cores, new_playlist_cores, sizeof(settings->arrays.playlist_cores)); string_list_free(stcores); string_list_free(stnames); return 0; }
static int playlist_association_right(unsigned type, const char *label, bool wraparound) { char core_path[PATH_MAX_LENGTH]; char new_playlist_cores[PATH_MAX_LENGTH]; size_t i, next, found, current = 0; core_info_t *info = NULL; struct string_list *stnames = NULL; struct string_list *stcores = NULL; core_info_list_t *list = NULL; settings_t *settings = config_get_ptr(); const char *path = path_basename(label); core_info_get_list(&list); if (!list) return menu_cbs_exit(); core_path[0] = new_playlist_cores[0] = '\0'; stnames = string_split(settings->arrays.playlist_names, ";"); stcores = string_split(settings->arrays.playlist_cores, ";"); if (!menu_content_playlist_find_associated_core(path, core_path, sizeof(core_path))) strlcpy(core_path, file_path_str(FILE_PATH_DETECT), sizeof(core_path)); for (i = 0; i < list->count; i++) { core_info_t *info = core_info_get(list, i); if (string_is_equal(info->path, core_path)) current = i; } next = current + 1; if (next >= list->count) { if (wraparound) next = 0; else next = list->count-1; } info = core_info_get(list, next); found = string_list_find_elem(stnames, path); if (found && info) string_list_set(stcores, (unsigned)(found-1), info->path); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->arrays.playlist_cores, new_playlist_cores, sizeof(settings->arrays.playlist_cores)); string_list_free(stnames); string_list_free(stcores); return 0; }
static bool init_content_file_extract( struct string_list *temporary_content, struct string_list *content, rarch_system_info_t *system, const struct retro_subsystem_info *special, union string_list_elem_attr *attr ) { unsigned i; settings_t *settings = config_get_ptr(); for (i = 0; i < content->size; i++) { const char *ext = NULL; const char *valid_ext = system->info.valid_extensions; /* Block extract check. */ if (content->elems[i].attr.i & 1) continue; ext = path_get_extension(content->elems[i].data); if (special) valid_ext = special->roms[i].valid_extensions; if (!ext) continue; if (string_is_equal_noncase(ext, "zip")) { char new_path[PATH_MAX_LENGTH]; char temp_content[PATH_MAX_LENGTH]; strlcpy(temp_content, content->elems[i].data, sizeof(temp_content)); if (!file_archive_extract_first_content_file(temp_content, sizeof(temp_content), valid_ext, *settings->cache_directory ? settings->cache_directory : NULL, new_path, sizeof(new_path))) { RARCH_ERR("Failed to extract content from zipped file: %s.\n", temp_content); return false; } string_list_set(content, i, new_path); if (!string_list_append(temporary_content, new_path, *attr)) return false; } } return true; }
static int playlist_association_left(unsigned type, const char *label, bool wraparound) { unsigned i; int next, found, current = 0; core_info_t *info = NULL; struct string_list *stnames = NULL; struct string_list *stcores = NULL; char core_path[PATH_MAX_LENGTH] = {0}; char new_playlist_cores[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); const char *path = path_basename(label); core_info_list_t *list = NULL; core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); if (!list) return menu_cbs_exit(); stnames = string_split(settings->playlist_names, ";"); stcores = string_split(settings->playlist_cores, ";"); if (!menu_playlist_find_associated_core(path, core_path, sizeof(core_path))) strlcpy(core_path, "DETECT", sizeof(core_path)); for (i = 0; i < list->count; i++) { core_info_t *info = core_info_get(list, i); if (string_is_equal(info->path, core_path)) current = i; } next = current - 1; if (next < 0) { if (wraparound) next = list->count; else next = 0; } info = core_info_get(list, next); found = string_list_find_elem(stnames, path); if (found) string_list_set(stcores, found-1, info->path); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->playlist_cores, new_playlist_cores, sizeof(settings->playlist_cores)); return 0; }
bool init_content_file(void) { unsigned i; g_extern.temporary_content = string_list_new(); if (!g_extern.temporary_content) return false; const struct retro_subsystem_info *special = NULL; if (*g_extern.subsystem) { special = libretro_find_subsystem_info(g_extern.system.special, g_extern.system.num_special, g_extern.subsystem); if (!special) { RARCH_ERR( "Failed to find subsystem \"%s\" in libretro implementation.\n", g_extern.subsystem); return false; } if (special->num_roms && !g_extern.subsystem_fullpaths) { RARCH_ERR("libretro core requires special content, but none were provided.\n"); return false; } else if (special->num_roms && special->num_roms != g_extern.subsystem_fullpaths->size) { RARCH_ERR("libretro core requires %u content files for subsystem \"%s\", but %u content files were provided.\n", special->num_roms, special->desc, (unsigned)g_extern.subsystem_fullpaths->size); return false; } else if (!special->num_roms && g_extern.subsystem_fullpaths && g_extern.subsystem_fullpaths->size) { RARCH_ERR("libretro core takes no content for subsystem \"%s\", but %u content files were provided.\n", special->desc, (unsigned)g_extern.subsystem_fullpaths->size); return false; } } union string_list_elem_attr attr; attr.i = 0; struct string_list *content = (struct string_list*)string_list_new(); if (!content) return false; if (*g_extern.subsystem) { for (i = 0; i < g_extern.subsystem_fullpaths->size; i++) { attr.i = special->roms[i].block_extract; attr.i |= special->roms[i].need_fullpath << 1; attr.i |= special->roms[i].required << 2; string_list_append(content, g_extern.subsystem_fullpaths->elems[i].data, attr); } } else { attr.i = g_extern.system.info.block_extract; attr.i |= g_extern.system.info.need_fullpath << 1; attr.i |= (!g_extern.system.no_content) << 2; string_list_append(content, g_extern.libretro_no_content ? "" : g_extern.fullpath, attr); } #ifdef HAVE_ZLIB /* Try to extract all content we're going to load if appropriate. */ for (i = 0; i < content->size; i++) { /* Block extract check. */ if (content->elems[i].attr.i & 1) continue; const char *ext = path_get_extension(content->elems[i].data); const char *valid_ext = special ? special->roms[i].valid_extensions : g_extern.system.info.valid_extensions; if (ext && !strcasecmp(ext, "zip")) { char temporary_content[PATH_MAX]; strlcpy(temporary_content, content->elems[i].data, sizeof(temporary_content)); if (!zlib_extract_first_content_file(temporary_content, sizeof(temporary_content), valid_ext, *g_settings.extraction_directory ? g_settings.extraction_directory : NULL)) { RARCH_ERR("Failed to extract content from zipped file: %s.\n", temporary_content); string_list_free(content); return false; } string_list_set(content, i, temporary_content); string_list_append(g_extern.temporary_content, temporary_content, attr); } } #endif /* Set attr to need_fullpath as appropriate. */ bool ret = load_content(special, content); string_list_free(content); return ret; }
/** * init_content_file: * * Initializes and loads a content file for the currently * selected libretro core. * * global->content_is_init will be set to the return value * on exit. * * Returns : true if successful, otherwise false. **/ bool init_content_file(void) { unsigned i; union string_list_elem_attr attr; bool ret = false; struct string_list *content = NULL; const struct retro_subsystem_info *special = NULL; settings_t *settings = config_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); global_t *global = global_get_ptr(); global->temporary_content = string_list_new(); if (!global->temporary_content) goto error; if (*global->subsystem) { special = libretro_find_subsystem_info(system->special, system->num_special, global->subsystem); if (!special) { RARCH_ERR( "Failed to find subsystem \"%s\" in libretro implementation.\n", global->subsystem); goto error; } if (special->num_roms && !global->subsystem_fullpaths) { RARCH_ERR("libretro core requires special content, but none were provided.\n"); goto error; } else if (special->num_roms && special->num_roms != global->subsystem_fullpaths->size) { RARCH_ERR("libretro core requires %u content files for subsystem \"%s\", but %u content files were provided.\n", special->num_roms, special->desc, (unsigned)global->subsystem_fullpaths->size); goto error; } else if (!special->num_roms && global->subsystem_fullpaths && global->subsystem_fullpaths->size) { RARCH_ERR("libretro core takes no content for subsystem \"%s\", but %u content files were provided.\n", special->desc, (unsigned)global->subsystem_fullpaths->size); goto error; } } content = string_list_new(); attr.i = 0; if (!content) goto error; if (*global->subsystem) { for (i = 0; i < global->subsystem_fullpaths->size; i++) { attr.i = special->roms[i].block_extract; attr.i |= special->roms[i].need_fullpath << 1; attr.i |= special->roms[i].required << 2; string_list_append(content, global->subsystem_fullpaths->elems[i].data, attr); } } else { attr.i = system->info.block_extract; attr.i |= system->info.need_fullpath << 1; attr.i |= (!system->no_content) << 2; string_list_append(content, (global->inited.core.no_content && settings->core.set_supports_no_game_enable) ? "" : global->path.fullpath, attr); } #ifdef HAVE_ZLIB /* Try to extract all content we're going to load if appropriate. */ for (i = 0; i < content->size; i++) { const char *ext = NULL; const char *valid_ext = NULL; /* Block extract check. */ if (content->elems[i].attr.i & 1) continue; ext = path_get_extension(content->elems[i].data); valid_ext = special ? special->roms[i].valid_extensions : system->info.valid_extensions; if (ext && !strcasecmp(ext, "zip")) { char temporary_content[PATH_MAX_LENGTH] = {0}; strlcpy(temporary_content, content->elems[i].data, sizeof(temporary_content)); if (!zlib_extract_first_content_file(temporary_content, sizeof(temporary_content), valid_ext, *settings->extraction_directory ? settings->extraction_directory : NULL)) { RARCH_ERR("Failed to extract content from zipped file: %s.\n", temporary_content); goto error; } string_list_set(content, i, temporary_content); string_list_append(global->temporary_content, temporary_content, attr); } } #endif /* Set attr to need_fullpath as appropriate. */ ret = load_content(special, content); error: global->inited.content = (ret) ? true : false; if (content) string_list_free(content); return ret; }
void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) { settings_t *settings = config_get_ptr(); QScopedPointer<QMenu> menu; QScopedPointer<QMenu> associateMenu; QScopedPointer<QMenu> hiddenPlaylistsMenu; QScopedPointer<QAction> hideAction; QScopedPointer<QAction> newPlaylistAction; QScopedPointer<QAction> deletePlaylistAction; QPointer<QAction> selectedAction; QPoint cursorPos = QCursor::pos(); QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos)); QDir playlistDir(settings->paths.directory_playlist); QString playlistDirAbsPath = playlistDir.absolutePath(); QString currentPlaylistDirPath; QString currentPlaylistPath; QString currentPlaylistFileName; QFile currentPlaylistFile; QByteArray currentPlaylistFileNameArray; QFileInfo currentPlaylistFileInfo; QMap<QString, const core_info_t*> coreList; core_info_list_t *core_info_list = NULL; union string_list_elem_attr attr = {0}; struct string_list *stnames = NULL; struct string_list *stcores = NULL; unsigned i = 0; int j = 0; size_t found = 0; const char *currentPlaylistFileNameData = NULL; char new_playlist_names[PATH_MAX_LENGTH]; char new_playlist_cores[PATH_MAX_LENGTH]; bool specialPlaylist = false; bool foundHiddenPlaylist = false; new_playlist_names[0] = new_playlist_cores[0] = '\0'; stnames = string_split(settings->arrays.playlist_names, ";"); stcores = string_split(settings->arrays.playlist_cores, ";"); if (selectedItem) { currentPlaylistPath = selectedItem->data(Qt::UserRole).toString(); currentPlaylistFile.setFileName(currentPlaylistPath); currentPlaylistFileInfo = QFileInfo(currentPlaylistPath); currentPlaylistFileName = currentPlaylistFileInfo.fileName(); currentPlaylistDirPath = currentPlaylistFileInfo.absoluteDir().absolutePath(); currentPlaylistFileNameArray.append(currentPlaylistFileName); currentPlaylistFileNameData = currentPlaylistFileNameArray.constData(); } menu.reset(new QMenu(this)); menu->setObjectName("menu"); hiddenPlaylistsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS), this)); newPlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST)) + "...", this)); hiddenPlaylistsMenu->setObjectName("hiddenPlaylistsMenu"); menu->addAction(newPlaylistAction.data()); if (currentPlaylistFile.exists()) { deletePlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST)) + "...", this)); menu->addAction(deletePlaylistAction.data()); } if (selectedItem) { hideAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDE), this)); menu->addAction(hideAction.data()); } for (j = 0; j < m_listWidget->count(); j++) { QListWidgetItem *item = m_listWidget->item(j); bool hidden = m_listWidget->isItemHidden(item); if (hidden) { QAction *action = hiddenPlaylistsMenu->addAction(item->text()); action->setProperty("row", j); action->setProperty("core_path", item->data(Qt::UserRole).toString()); foundHiddenPlaylist = true; } } if (!foundHiddenPlaylist) { QAction *action = hiddenPlaylistsMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE)); action->setProperty("row", -1); } menu->addMenu(hiddenPlaylistsMenu.data()); if (currentPlaylistDirPath != playlistDirAbsPath) { /* special playlists like history etc. can't have an association */ specialPlaylist = true; } if (!specialPlaylist) { associateMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE), this)); associateMenu->setObjectName("associateMenu"); core_info_get_list(&core_info_list); for (i = 0; i < core_info_list->count && core_info_list->count > 0; i++) { const core_info_t *core = &core_info_list->list[i]; coreList[core->core_name] = core; } { QMapIterator<QString, const core_info_t*> coreListIterator(coreList); QVector<QHash<QString, QString> > cores; while (coreListIterator.hasNext()) { QString key; const core_info_t *core = NULL; QString name; QHash<QString, QString> hash; coreListIterator.next(); key = coreListIterator.key(); core = coreList.value(key); if (string_is_empty(core->core_name)) name = core->display_name; else name = core->core_name; if (name.isEmpty()) continue; hash["name"] = name; hash["core_path"] = core->path; cores.append(hash); } std::sort(cores.begin(), cores.end(), comp_hash_name_key_lower); for (j = 0; j < cores.count(); j++) { const QHash<QString, QString> &hash = cores.at(j); QAction *action = associateMenu->addAction(hash.value("name")); action->setProperty("core_path", hash.value("core_path")); } } menu->addMenu(associateMenu.data()); } selectedAction = menu->exec(cursorPos); if (!selectedAction) goto end; if (!specialPlaylist && selectedAction->parent() == associateMenu.data()) { found = string_list_find_elem(stnames, currentPlaylistFileNameData); if (found) string_list_set(stcores, static_cast<unsigned>(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); else { string_list_append(stnames, currentPlaylistFileNameData, attr); string_list_append(stcores, "DETECT", attr); found = string_list_find_elem(stnames, currentPlaylistFileNameData); if (found) string_list_set(stcores, static_cast<unsigned>(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); } string_list_join_concat(new_playlist_names, sizeof(new_playlist_names), stnames, ";"); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->arrays.playlist_names, new_playlist_names, sizeof(settings->arrays.playlist_names)); strlcpy(settings->arrays.playlist_cores, new_playlist_cores, sizeof(settings->arrays.playlist_cores)); } else if (selectedItem && selectedAction == deletePlaylistAction.data()) { if (currentPlaylistFile.exists()) { if (showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST)).arg(selectedItem->text()), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) { if (currentPlaylistFile.remove()) reloadPlaylists(); else showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); } } } else if (selectedAction == newPlaylistAction.data()) { QString name = QInputDialog::getText(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME)); QString newPlaylistPath = playlistDirAbsPath + "/" + name + file_path_str(FILE_PATH_LPL_EXTENSION); QFile file(newPlaylistPath); if (file.open(QIODevice::WriteOnly)) file.close(); reloadPlaylists(); } else if (selectedItem && selectedAction == hideAction.data()) { int row = m_listWidget->row(selectedItem); if (row >= 0) { QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); if (!hiddenPlaylists.contains(currentPlaylistFileName)) { hiddenPlaylists.append(currentPlaylistFileName); m_settings->setValue("hidden_playlists", hiddenPlaylists); } m_listWidget->setRowHidden(row, true); } } else if (selectedAction->parent() == hiddenPlaylistsMenu.data()) { QVariant rowVariant = selectedAction->property("row"); if (rowVariant.isValid()) { QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); int row = rowVariant.toInt(); if (row >= 0) { QString playlistPath = selectedAction->property("core_path").toString(); QFileInfo playlistFileInfo(playlistPath); QString playlistFileName = playlistFileInfo.fileName(); if (hiddenPlaylists.contains(playlistFileName)) { hiddenPlaylists.removeOne(playlistFileName); m_settings->setValue("hidden_playlists", hiddenPlaylists); } m_listWidget->setRowHidden(row, false); } } } setCoreActions(); end: if (stnames) string_list_free(stnames); if (stcores) string_list_free(stcores); }
static bool init_content_file_extract( struct string_list *temporary_content, struct string_list *content, const struct retro_subsystem_info *special, union string_list_elem_attr *attr ) { unsigned i; settings_t *settings = config_get_ptr(); rarch_system_info_t *system = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); for (i = 0; i < content->size; i++) { char temp_content[PATH_MAX_LENGTH]; char new_path[PATH_MAX_LENGTH]; bool contains_compressed = NULL; bool block_extract = content->elems[i].attr.i & 1; const char *valid_ext = system->info.valid_extensions; /* Block extract check. */ if (block_extract) continue; contains_compressed = path_contains_compressed_file(content->elems[i].data); if (special) valid_ext = special->roms[i].valid_extensions; if (!contains_compressed) { /* just use the first file in the archive */ if (!path_is_compressed_file(content->elems[i].data)) continue; } temp_content[0] = new_path[0] = '\0'; strlcpy(temp_content, content->elems[i].data, sizeof(temp_content)); if (!valid_ext || !file_archive_extract_file(temp_content, sizeof(temp_content), valid_ext, *settings->directory.cache ? settings->directory.cache : NULL, new_path, sizeof(new_path))) { RARCH_ERR("%s: %s.\n", msg_hash_to_str( MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE), temp_content); runloop_msg_queue_push( msg_hash_to_str(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE) , 2, 180, true); return false; } string_list_set(content, i, new_path); if (!string_list_append(temporary_content, new_path, *attr)) return false; } return true; }