Beispiel #1
0
bool FeFilterEditMenu::save( FeConfigContext &ctx )
{
	if (( m_display ) && ( m_index >= 0 ))
	{
		FeFilter *f = m_display->get_filter( m_index );

		std::string name = ctx.opt_list[0].get_value();
		f->set_name( name );

		int sort_pos = ctx.opt_list.size() - 4;
		FeRomInfo::Index sort_by = (FeRomInfo::Index)ctx.opt_list[ sort_pos ].get_vindex();

		f->set_sort_by( sort_by );

		//
		// TODO - make reverse order configurable from the config menu
		//
		// right now we just arbitrarily sort players, playcount and playtime in "reverse" order so
		// higher values are first.
		//
		bool reverse_order( false );
		if (( sort_by == FeRomInfo::Players )
				|| ( sort_by == FeRomInfo::PlayedCount )
				|| ( sort_by == FeRomInfo::PlayedTime ))
			reverse_order = true;

		f->set_reverse_order( reverse_order );

		std::string limit_str = ctx.opt_list[ sort_pos + 1 ].get_value();
		int list_limit = as_int( limit_str );
		f->set_list_limit( list_limit );
	}

	return true;
}
Beispiel #2
0
bool FeFilterEditMenu::on_option_select(
		FeConfigContext &ctx, FeBaseConfigMenu *& submenu )
{
	if ( !m_display )
		return true;

	FeMenuOpt &o = ctx.curr_opt();
	FeFilter *f = m_display->get_filter( m_index );

	if (( o.opaque >= 100 ) || ( o.opaque == 1 ) || ( o.opaque == 2 ))
	{
		int r_index=0;

		if (( o.opaque == 1 ) || ( o.opaque == 2 ))
		{
			bool is_exception = ( o.opaque == 2 );

			std::vector<FeRule> &rules = f->get_rules();

			rules.push_back( FeRule() );
			rules.back().set_is_exception( is_exception );

			r_index = rules.size() - 1;
			ctx.save_req=true;
		}
		else
			r_index = o.opaque - 100;

		m_rule_menu.set_rule_index( f, r_index );
		submenu=&m_rule_menu;
	}
	else if ( o.opaque == 3 )
	{
		// "Delete this Filter"
		if ( ctx.confirm_dialog( "Delete filter '$1'?",
				f->get_name() ) == false )
			return false;

		m_display->delete_filter( m_index );
		m_display=NULL;
		m_index=-1;
		ctx.save_req=true;
	}

	return true;
}
Beispiel #3
0
bool FeRomList::fix_filters( FeDisplayInfo &display, FeRomInfo::Index target )
{
	bool retval = false;
	for ( int i=0; i<display.get_filter_count(); i++ )
	{
		FeFilter *f = display.get_filter( i );
		ASSERT( f );

		if ( f->test_for_target( target ) )
		{
			m_filtered_list[i].clear();
			retval = true;

			for ( FeRomInfoListType::iterator itr=m_list.begin(); itr!=m_list.end(); ++itr )
			{
				if ( f->apply_filter( *itr ) )
					m_filtered_list[i].push_back( &( *itr ) );
			}
		}
	}

	return retval;
}
Beispiel #4
0
void FeDisplayEditMenu::get_options( FeConfigContext &ctx )
{
	ctx.set_style( FeConfigContext::EditList, "Display Edit" );

	if ( m_display )
	{
		ctx.add_optl( Opt::EDIT, "Name",
				m_display->get_info( FeDisplayInfo::Name ), "_help_display_name" );

		ctx.add_optl( Opt::LIST, "Layout",
				m_display->get_info( FeDisplayInfo::Layout ), "_help_display_layout" );

		std::vector<std::string> layouts;
		ctx.fe_settings.get_layouts_list( layouts );
		ctx.back_opt().append_vlist( layouts );

		ctx.add_optl( Opt::LIST, "Collection/Rom List",
				m_display->get_info( FeDisplayInfo::Romlist ), "_help_display_romlist" );

		std::vector<std::string> romlists;
		ctx.fe_settings.get_romlists_list( romlists );
		ctx.back_opt().append_vlist( romlists );

		std::vector<std::string> bool_opts( 2 );
		ctx.fe_settings.get_resource( "Yes", bool_opts[0] );
		ctx.fe_settings.get_resource( "No", bool_opts[1] );

		ctx.add_optl( Opt::LIST, "Show in Cycle",
			m_display->show_in_cycle() ? bool_opts[0] : bool_opts[1],
			"_help_display_in_cycle" );

		ctx.back_opt().append_vlist( bool_opts );

		ctx.add_optl( Opt::LIST, "Show in Menu",
			m_display->show_in_menu() ? bool_opts[0] : bool_opts[1],
			"_help_display_in_menu" );
		ctx.back_opt().append_vlist( bool_opts );

		FeFilter *f = m_display->get_filter( -1 );

		std::string filter_desc;
		if ( f->get_rule_count() < 1 )
			ctx.fe_settings.get_resource( "Empty", filter_desc );
		else
			ctx.fe_settings.get_resource( "$1 Rule(s)",
					as_str(f->get_rule_count()), filter_desc );

		ctx.add_optl( Opt::SUBMENU, "Global Filter", filter_desc, "_help_display_global_filter" );
		ctx.back_opt().opaque = 9;

		std::vector<std::string> filters;
		m_display->get_filters_list( filters );
		int i=0;

		for ( std::vector<std::string>::iterator itr=filters.begin();
				itr != filters.end(); ++itr )
		{
			ctx.add_optl( Opt::SUBMENU, "Filter",
				(*itr), "_help_display_filter" );
			ctx.back_opt().opaque = 100 + i;
			i++;
		}

		ctx.add_optl( Opt::SUBMENU, "Add Filter", "", "_help_display_add_filter" );
		ctx.back_opt().opaque = 1;

		ctx.add_optl( Opt::SUBMENU, "Layout Options", "", "_help_display_layout_options" );
		ctx.back_opt().opaque = 2;

		ctx.add_optl( Opt::EXIT, "Delete this Display", "", "_help_display_delete" );
		ctx.back_opt().opaque = 3;
	}

	FeBaseConfigMenu::get_options( ctx );
}
Beispiel #5
0
void FeFilterEditMenu::get_options( FeConfigContext &ctx )
{
	ctx.set_style( FeConfigContext::EditList, "Filter Edit" );

	if ( m_display )
	{
		FeFilter *f = m_display->get_filter( m_index );

		if ( m_index < 0 )
		{
			std::string gf;
			ctx.fe_settings.get_resource( "Global Filter", gf );
			ctx.add_optl( Opt::INFO, "Filter Name", gf, "_help_filter_name" );
		}
		else
		{
			ctx.add_optl( Opt::EDIT, "Filter Name", f->get_name(),
				"_help_filter_name" );
		}

		int i=0;
		std::vector<FeRule> &rules = f->get_rules();

		for ( std::vector<FeRule>::const_iterator itr=rules.begin();
				itr != rules.end(); ++itr )
		{
			std::string rule_str;
			FeRomInfo::Index t = (*itr).get_target();

			if ( t != FeRomInfo::LAST_INDEX )
			{
				ctx.fe_settings.get_resource( FeRomInfo::indexStrings[t], rule_str );

				FeRule::FilterComp c = (*itr).get_comp();
				if ( c != FeRule::LAST_COMPARISON )
				{
					std::string comp_str;
					ctx.fe_settings.get_resource( FeRule::filterCompDisplayStrings[c], comp_str );

					rule_str += " ";
					rule_str += comp_str;
					rule_str += " ";
					rule_str += (*itr).get_what();
				}
			}

			if ( (*itr).is_exception() )
				ctx.add_optl( Opt::SUBMENU, "Exception", rule_str, "_help_filter_exception" );
			else
				ctx.add_optl( Opt::SUBMENU, "Rule", rule_str, "_help_filter_rule" );

			ctx.back_opt().opaque = 100 + i;
			i++;
		}

		ctx.add_optl(Opt::SUBMENU,"Add Rule","","_help_filter_add_rule");
		ctx.back_opt().opaque = 1;

		ctx.add_optl(Opt::SUBMENU,"Add Exception","","_help_filter_add_exception");
		ctx.back_opt().opaque = 2;

		if ( m_index >= 0 ) // don't add the following options for the global filter
		{
			std::string no_sort_str, sort_val;
			ctx.fe_settings.get_resource( "No Sort", no_sort_str );

			if ( f->get_sort_by() != FeRomInfo::LAST_INDEX )
				sort_val = FeRomInfo::indexStrings[f->get_sort_by()];
			else
				sort_val = no_sort_str;

			std::vector< std::string > targets;
			i=0;
			while ( FeRomInfo::indexStrings[i] != 0 )
			{
				targets.push_back( std::string() );
				ctx.fe_settings.get_resource( FeRomInfo::indexStrings[i], targets.back() );
				i++;
			}
			targets.push_back( no_sort_str );

			ctx.add_optl( Opt::LIST, "Sort By", sort_val, "_help_filter_sort_by" );
			ctx.back_opt().append_vlist( targets );

			ctx.add_optl( Opt::EDIT, "List Limit", as_str( f->get_list_limit() ),
				"_help_filter_list_limit" );

			ctx.add_optl(Opt::EXIT,"Delete this Filter","","_help_filter_delete");
			ctx.back_opt().opaque = 3;
		}
	}

	FeBaseConfigMenu::get_options( ctx );
}
Beispiel #6
0
bool FeSettings::build_romlist( const std::vector< FeImportTask > &task_list,
						const std::string &output_name,
						FeFilter &filter,
						bool full )
{
	FeRomInfoListType total_romlist;
	std::string best_name, list_name, path;

	for ( std::vector<FeImportTask>::const_iterator itr=task_list.begin();
			itr < task_list.end(); ++itr )
	{
		if ( (*itr).task_type == FeImportTask::BuildRomlist )
		{
			// Build romlist task
			std::cout << "*** Generating Collection/Rom List" << std::endl;

			FeEmulatorInfo *emu = m_rl.get_emulator( (*itr).emulator_name );
			if ( emu == NULL )
			{
				std::cout << "Error: Invalid -build-rom-list target: " <<  (*itr).emulator_name
					<< std::endl;
			}
			else
			{
				FeRomInfoListType romlist;

				best_name = emu->get_info( FeEmulatorInfo::Name );

				FeImporterContext ctx( *emu, romlist );
				build_basic_romlist( ctx );

				apply_xml_import( ctx );
				apply_import_extras( ctx );

				apply_emulator_name( best_name, romlist );
				total_romlist.splice( total_romlist.end(), romlist );
			}
		}
		else if ( (*itr).task_type == FeImportTask::ImportRomlist )
		{
			// import romlist from file task
			std::cout << "*** Importing Collection/Rom List" << std::endl;

			FeRomInfoListType romlist;
			std::string emu_name;

			if ( (*itr).emulator_name.empty() )
			{
				// deduce the emulator name from the filename provided
				size_t my_start = (*itr).file_name.find_last_of( "\\/" );
				if ( my_start == std::string::npos ) // if there is no / we start at the beginning
					my_start = 0;
				else
					my_start += 1;

				size_t my_end = (*itr).file_name.find_last_of( "." );
				if ( my_end != std::string::npos )
					emu_name = (*itr).file_name.substr( my_start, my_end - my_start  );
			}
			else
				emu_name = (*itr).emulator_name;

			best_name = emu_name;

			if ( tail_compare( (*itr).file_name, ".txt" ) )
			{
				// Attract-Mode format list
				//
				FeRomList temp_list( m_config_path );
				temp_list.load_from_file( (*itr).file_name, ";" );

				FeRomInfoListType &entries = temp_list.get_list();

				for ( FeRomInfoListType::iterator itr = entries.begin(); itr != entries.end(); ++itr )
					romlist.push_back( *itr );
			}
			else if ( tail_compare( (*itr).file_name, ".lst" ) )
			{
				// Mamewah/Wahcade! format list
				//
				import_mamewah( (*itr).file_name, emu_name, romlist );
			}
			else if ( tail_compare( (*itr).file_name, ".xml" ) )
			{
				// HyperSpin format list
				//
				FeHyperSpinXMLParser my_parser( romlist );
				if ( my_parser.parse( (*itr).file_name ) )
					apply_emulator_name( emu_name, romlist );
			}
			else
			{
				std::cerr << "Error: Unsupported --import-rom-list file: "
					<<  (*itr).file_name << std::endl;
			}

			std::cout << "[Import " << (*itr).file_name << "] - Imported " << romlist.size() << " entries."
				<< std::endl;

			FeEmulatorInfo *emu = m_rl.get_emulator( emu_name );
			if ( emu == NULL )
			{
				std::cout << "Warning: The emulator specified with --import-rom-list was not found: "
					<<  emu_name << std::endl;
			}
			else
			{
				FeImporterContext ctx( *emu, romlist );
				apply_import_extras( ctx );
			}

			total_romlist.splice( total_romlist.end(), romlist );
		}
		else // scrape artwork
		{
			FeEmulatorInfo *emu = m_rl.get_emulator( (*itr).emulator_name );
			if ( emu == NULL )
				return false;

			std::cout << "*** Scraping artwork for: " << (*itr).emulator_name << std::endl;

			FeRomInfoListType romlist;
			std::string fn = get_config_dir() + FE_ROMLIST_SUBDIR + (*itr).emulator_name + FE_ROMLIST_FILE_EXTENSION;

			FeImporterContext ctx( *emu, romlist );
			if ( file_exists( fn ) )
			{
				FeRomList loader( get_config_dir() );
				loader.load_from_file( fn, ";" );
				ctx.romlist.swap( loader.get_list() );
			}
			else
			{
				build_basic_romlist( ctx );
				apply_xml_import( ctx );
			}

			ctx.scrape_art = true;
			confirm_directory( get_config_dir(), FE_SCRAPER_SUBDIR );

			// do the mamedb scraper first (which only does anything for mame) followed
			// by the more general thegamesdb scraper.
			mamedb_scraper( ctx );
			thegamesdb_scraper( ctx );

			std::cout << "*** Scraping done." << std::endl;
		}
	}

	// return now if all we did was scrape artwork
	if ( total_romlist.empty() )
		return true;

	total_romlist.sort( FeRomListSorter() );

	// strip duplicate entries
	std::cout << " - Removing any duplicate entries..." << std::endl;
	total_romlist.unique();

	// Apply the specified filter
	if ( filter.get_rule_count() > 0 )
	{
		std::cout << " - Applying filter..." << std::endl;
		filter.init();

		FeRomInfoListType::iterator last_it=total_romlist.begin();
		for ( FeRomInfoListType::iterator it=total_romlist.begin(); it!=total_romlist.end(); )
		{
			if ( filter.apply_filter( *it ) )
			{
				if ( last_it != it )
					it = total_romlist.erase( last_it, it );
				else
					++it;

				last_it = it;
			}
			else
				++it;
		}

		if ( last_it != total_romlist.end() )
			total_romlist.erase( last_it, total_romlist.end() );
	}

	if ( task_list.size() > 1 )
		best_name = "multi";

	path = get_config_dir();
	confirm_directory( path, FE_ROMLIST_SUBDIR );

	path += FE_ROMLIST_SUBDIR;

	// if we weren't given a specific output name, then we come up with a name
	// that doesn't exist already
	//
	if ( output_name.empty() )
		get_available_filename( path, best_name, FE_ROMLIST_FILE_EXTENSION, list_name );
	else
		list_name = path + output_name + FE_ROMLIST_FILE_EXTENSION;

	write_romlist( list_name, total_romlist );

	return true;
}
Beispiel #7
0
bool FeRomList::load_romlist( const std::string &path,
			const std::string &romlist_name,
			const std::string &user_path,
			const std::string &stat_path,
			FeDisplayInfo &display )
{
	m_user_path = user_path;
	m_romlist_name = romlist_name;

	m_list.clear();
	m_filtered_list.clear();
	m_availability_checked = false;

	m_global_filter_ptr = NULL;
	m_global_filtered_out_count = 0;

	FeFilter *first_filter = display.get_global_filter();
	if ( first_filter )
	{
		first_filter->init();

		if ( !first_filter->test_for_target( FeRomInfo::FileIsAvailable )
			&& !first_filter->test_for_target( FeRomInfo::Favourite )
			&& !first_filter->test_for_target( FeRomInfo::Tags ) )
		{
			// If the global filter doesn't care about file availability,
			// favourites or tags then we can apply it right up front when we
			// load the romlist.  We signal this by setting m_global_filter_ptr
			m_global_filter_ptr = first_filter;
			first_filter = NULL;
		}
	}

	sf::Clock load_timer;

	bool retval = FeBaseConfigurable::load_from_file(
			path + m_romlist_name + FE_ROMLIST_FILE_EXTENSION, ";" );

	//
	// Create rom name to romlist entry lookup map
	//
	std::map < std::string, FeRomInfo * > rom_map;
	std::map < std::string, FeRomInfo * >::iterator rm_itr;
	for ( FeRomInfoListType::iterator itr = m_list.begin(); itr != m_list.end(); ++itr )
		rom_map[ (*itr).get_info( FeRomInfo::Romname ) ] = &(*itr);

	//
	// Load favourites
	//
	m_extra_favs.clear();
	m_fav_changed=false;

	std::string load_name( m_user_path + m_romlist_name + FE_FAVOURITE_FILE_EXTENSION );
	std::ifstream myfile( load_name.c_str() );

	if ( myfile.is_open() )
	{
		while ( myfile.good() )
		{
			size_t pos=0;
			std::string line, name;

			getline( myfile, line );
			token_helper( line, pos, name );

			if ( !name.empty() )
			{
				rm_itr = rom_map.find( name );
				if ( rm_itr != rom_map.end() )
					(*rm_itr).second->set_info( FeRomInfo::Favourite, "1" );
				else
					m_extra_favs.insert( name );
			}
		}

		myfile.close();
	}

	//
	// Load tags
	//
	m_tags.clear();
	m_extra_tags.clear();
	m_tags_changed=false;
	load_name = m_user_path + m_romlist_name + "/";

	if ( directory_exists( load_name ) )
	{
		std::vector<std::string> temp_tags;
		get_basename_from_extension( temp_tags, load_name, FE_FAVOURITE_FILE_EXTENSION );

		for ( std::vector<std::string>::iterator itr=temp_tags.begin(); itr!=temp_tags.end(); ++itr )
		{
			if ( (*itr).empty() )
				continue;

			std::ifstream myfile( std::string(load_name + (*itr) + FE_FAVOURITE_FILE_EXTENSION).c_str() );

			if ( !myfile.is_open() )
				continue;

			std::map<std::string, bool>::iterator itt = m_tags.begin();
			itt = m_tags.insert( itt, std::pair<std::string,bool>( (*itr), false ) );

			while ( myfile.good() )
			{
				size_t pos=0;
				std::string line, rname;

				getline( myfile, line );
				token_helper( line, pos, rname );

				if ( !rname.empty() )
				{
					rm_itr = rom_map.find( rname );
					if ( rm_itr != rom_map.end() )
						(*rm_itr).second->append_tag( (*itt).first.c_str() );
					else
						m_extra_tags.insert( std::pair<std::string,const char*>(rname, (*itt).first.c_str() ) );
				}
			}

			myfile.close();
		}
	}

	// Apply global filter if it hasn't been applied already
	if ( first_filter )
	{
		if ( first_filter->test_for_target( FeRomInfo::FileIsAvailable ) )
			get_file_availability();

		FeRomInfoListType::iterator last_it=m_list.begin();
		for ( FeRomInfoListType::iterator it=m_list.begin(); it!=m_list.end(); )
		{
			if ( first_filter->apply_filter( *it ) )
			{
				if ( last_it != it )
					it = m_list.erase( last_it, it );
				else
					++it;

				last_it = it;
			}
			else
			{
				//
				// This rom is being filtered out and we may need to keep track of a few things
				//
				// 1. Track if this is a favourite...
				//
				if ( !(*it).get_info( FeRomInfo::Favourite ).empty() )
					m_extra_favs.insert( (*it).get_info( FeRomInfo::Romname ) );

				//
				// 2. Track if this rom has tags we'll need to keep
				//
				if ( !(*it).get_info( FeRomInfo::Tags ).empty() )
				{
					const std::string &name = (*it).get_info( FeRomInfo::Romname );
					const std::string &tags = (*it).get_info( FeRomInfo::Tags );
					const char sep[] = { FE_TAGS_SEP, 0 };

					size_t pos=0;
					while ( pos < tags.size() )
					{
						std::string one_tag;
						token_helper( tags, pos, one_tag, sep );

						std::map<std::string, bool>::iterator itt = m_tags.find( one_tag );
						if ( itt != m_tags.end() )
							m_extra_tags.insert( std::pair<std::string,const char *>( name, (*itt).first.c_str() ) );
					}
				}

				m_global_filtered_out_count++;
				++it;
			}
		}

		if ( last_it != m_list.end() )
			m_list.erase( last_it, m_list.end() );
	}

	std::cout << " - Loaded master romlist '" << m_romlist_name
			<< "' in " << load_timer.getElapsedTime().asMilliseconds()
			<< " ms (" << m_list.size() << " entries kept, " << m_global_filtered_out_count
			<< " discarded)" << std::endl;

	load_timer.restart();

	//
	// Apply filters
	//
	int filters_count = display.get_filter_count();

	//
	// If the display doesn't have any filters configured, we create a single "filter" in the romlist object
	// with every romlist entry in it
	//
	if ( filters_count == 0 )
		filters_count = 1;

	m_filtered_list.reserve( filters_count );
	for ( int i=0; i<filters_count; i++ )
	{
		m_filtered_list.push_back( std::vector< FeRomInfo *>()  );

		FeFilter *f = display.get_filter( i );
		if ( f )
		{
			if ( f->get_size() > 0 ) // if this is non zero then we've loaded before and know how many to expect
				m_filtered_list[i].reserve( f->get_size() );

			if ( f->test_for_target( FeRomInfo::FileIsAvailable ) )
				get_file_availability();

			f->init();
			for ( FeRomInfoListType::iterator itr=m_list.begin(); itr!=m_list.end(); ++itr )
				if ( f->apply_filter( *itr ) )
					m_filtered_list[i].push_back( &( *itr ) );
		}
		else // no filter situation, so we just add the entire list...
		{
			m_filtered_list[i].reserve( m_list.size() );
			for ( FeRomInfoListType::iterator itr=m_list.begin(); itr!=m_list.end(); ++itr )
				m_filtered_list[i].push_back( &( *itr ) );
		}

		//
		// make sure stats are loaded for the roms we will be showing
		//
		if ( !stat_path.empty() )
		{
			for ( std::vector< FeRomInfo * >::iterator itf=m_filtered_list[i].begin();
						itf!=m_filtered_list[i].end();
						++itf )
				(*itf)->load_stats( stat_path ); // this will just return if stats are already loaded for the rom
		}

		if ( f )
		{
			// track the size of the filtered list in our filter info object
			f->set_size( m_filtered_list[i].size() );

			//
			// Sort and/or prune now if configured for this filter
			//
			FeRomInfo::Index sort_by=f->get_sort_by();
			bool rev = f->get_reverse_order();
			int list_limit = f->get_list_limit();

			if ( sort_by != FeRomInfo::LAST_INDEX )
			{
				std::stable_sort( m_filtered_list[i].begin(),
						m_filtered_list[i].end(),
						FeRomListSorter2( sort_by, rev ) );
			}
			else if ( rev != false )
				std::reverse( m_filtered_list[i].begin(), m_filtered_list[i].end() );

			if (( list_limit != 0 ) && ( (int)m_filtered_list[i].size() > abs( list_limit ) ))
			{
				if ( list_limit > 0 )
					m_filtered_list[i].erase( m_filtered_list[i].begin() + list_limit, m_filtered_list[i].end() );
				else
					m_filtered_list[i].erase( m_filtered_list[i].begin(), m_filtered_list[i].end() + list_limit );
			}
		}
	}

	std::cout << " - Constructed " << filters_count << " filters in "
			<< load_timer.getElapsedTime().asMilliseconds()
			<< " ms (" << filters_count * m_list.size() << " comparisons)" << std::endl;

	return retval;
}