Пример #1
0
/* Archive::importDir
 * Imports all files (including subdirectories) from [directory] into
 * the archive
 *******************************************************************/
bool Archive::importDir(string directory)
{
	// Get a list of all files in the directory
	wxArrayString files;
	wxDir::GetAllFiles(directory, &files);

	// Go through files
	for (unsigned a = 0; a < files.size(); a++)
	{
		string name = files[a];
		name.Replace(directory, "", false);	// Remove directory from entry name

		// Split filename into dir+name
		wxFileName fn(name);
		string ename = fn.GetFullName();
		string edir = fn.GetPath();

		// Remove beginning \ or / from dir
		if (edir.StartsWith("\\") || edir.StartsWith("/"))
			edir.Remove(0, 1);

		// Add the entry
		ArchiveTreeNode* dir = createDir(edir);
		ArchiveEntry* entry = addNewEntry(ename, dir->numEntries()+1, dir);

		// Load data
		entry->importFile(files[a]);

		// Set unmodified
		entry->setState(0);
		dir->getDirEntry()->setState(0);
	}

	return true;
}
Пример #2
0
// ----------------------------------------------------------------------------
// TextLanguage::loadLanguages
//
// Loads all text language definitions from slade.pk3
// ----------------------------------------------------------------------------
bool TextLanguage::loadLanguages()
{
	// Get slade resource archive
	Archive* res_archive = App::archiveManager().programResourceArchive();

	// Read language definitions from resource archive
	if (res_archive)
	{
		// Get 'config/languages' directly
		ArchiveTreeNode* dir = res_archive->getDir("config/languages");

		if (dir)
		{
			// Read all entries in this dir
			for (unsigned a = 0; a < dir->numEntries(); a++)
				readLanguageDefinition(dir->entryAt(a)->getMCData(), dir->entryAt(a)->getName());
		}
		else
			Log::warning(
				1,
				"Warning: 'config/languages' not found in slade.pk3, no builtin text language definitions loaded"
			);
	}

	return true;
}
Пример #3
0
/* ColourConfiguration::getConfigurationNames
 * Adds all available colour configuration names to [names]
 *******************************************************************/
void ColourConfiguration::getConfigurationNames(vector<string>& names)
{
	// TODO: search custom folder

	// Search resource pk3
	Archive* res = theArchiveManager->programResourceArchive();
	ArchiveTreeNode* dir = res->getDir("config/colours");
	for (unsigned a = 0; a < dir->numEntries(); a++)
		names.push_back(dir->getEntry(a)->getName(true));
}
Пример #4
0
// ----------------------------------------------------------------------------
// ArchiveEntryList::getItemText
//
// Called when the widget requests the text for [item] at [column]
// ----------------------------------------------------------------------------
string ArchiveEntryList::getItemText(long item, long column, long index) const
{
	// Get entry
	ArchiveEntry* entry = getEntry(index, false);

	// Check entry
	if (!entry)
		return "INVALID INDEX";

	// Determine what column we want
	int col = columnType(column);

	if (col == 0)
		return entry->getName();	// Name column
	else if (col == 1)
	{
		// Size column
		if (entry->getType() == EntryType::folderType())
		{
			// Entry is a folder, return the number of entries+subdirectories in it
			ArchiveTreeNode* dir = nullptr;

			// Get selected directory
			if (entry == entry_dir_back)
				dir = (ArchiveTreeNode*)current_dir->getParent();	// If it's the 'back directory', get the current dir's parent
			else
				dir = archive->getDir(entry->getName(), current_dir);

			// If it's null, return error
			if (!dir)
				return "INVALID DIRECTORY";

			// Return the number of items in the directory
			return S_FMT("%d entries", dir->numEntries() + dir->nChildren());
		}
		else
			return entry->getSizeString();	// Not a folder, just return the normal size string
	}
	else if (col == 2)
		return entry->getTypeString();	// Type column
	else if (col == 3)
	{
		// Index column
		if (entry->getType() == EntryType::folderType())
			return "";
		else
			return S_FMT("%d", entry->getParentDir()->entryIndex(entry));
	}
	else
		return "INVALID COLUMN";		// Invalid column
}
Пример #5
0
// ----------------------------------------------------------------------------
// ArchiveEntryList::entrySize
//
// Returns either the size of the entry at [index], or if it is a folder, the
// number of entries+subfolders within it
// ----------------------------------------------------------------------------
int ArchiveEntryList::entrySize(long index)
{
	ArchiveEntry* entry = getEntry(index, false);
	if (entry->getType() == EntryType::folderType())
	{
		ArchiveTreeNode* dir = archive->getDir(entry->getName(), current_dir);
		if (dir)
			return dir->numEntries() + dir->nChildren();
		else
			return 0;
	}
	else
		return entry->getSize();
}
Пример #6
0
/* ColourConfiguration::readConfiguration
 * Reads saved colour configuration [name]
 *******************************************************************/
bool ColourConfiguration::readConfiguration(string name)
{
	// TODO: search custom folder

	// Search resource pk3
	Archive* res = theArchiveManager->programResourceArchive();
	ArchiveTreeNode* dir = res->getDir("config/colours");
	for (unsigned a = 0; a < dir->numEntries(); a++)
	{
		if (S_CMPNOCASE(dir->getEntry(a)->getName(true), name))
			return readConfiguration(dir->getEntry(a)->getMCData());
	}

	return false;
}
Пример #7
0
/* ArchiveManager::addArchive
 * Adds an archive to the archive list
 *******************************************************************/
bool ArchiveManager::addArchive(Archive* archive)
{
	// Only add if archive is a valid pointer
	if (archive)
	{
		// Add to the list
		archive_t n_archive;
		n_archive.archive = archive;
		n_archive.resource = true;
		open_archives.push_back(n_archive);

		// Listen to the archive
		listenTo(archive);

		// Announce the addition
		announce("archive_added");

		// Add to resource manager
		theResourceManager->addArchive(archive);

		// ZDoom also loads any WADs found in the root of a PK3 or directory
		if ((archive->getType() == ARCHIVE_ZIP || archive->getType() == ARCHIVE_FOLDER) && auto_open_wads_root)
		{
			ArchiveTreeNode* root = archive->getRoot();
			ArchiveEntry* entry;
			EntryType* type;
			for (unsigned a = 0; a < root->numEntries(); a++)
			{
				entry = root->getEntry(a);

				if (entry->getType() == EntryType::unknownType())
					EntryType::detectEntryType(entry);

				type = entry->getType();

				if (type->getId() == "wad")
					// First true: yes, manage this
					// Second true: open silently, don't open a tab for it
					openArchive(entry, true, true);
			}
		}

		return true;
	}
	else
		return false;
}
Пример #8
0
/* ZipArchive::detectMaps
 * Detects all the maps in the archive and returns a vector of
 * information about them.
 *******************************************************************/
vector<Archive::mapdesc_t> ZipArchive::detectMaps()
{
	vector<mapdesc_t> ret;

	// Get the maps directory
	ArchiveTreeNode* mapdir = getDir("maps");
	if (!mapdir)
		return ret;

	// Go through entries in map dir
	for (unsigned a = 0; a < mapdir->numEntries(); a++)
	{
		ArchiveEntry* entry = mapdir->getEntry(a);

		// Maps can only be wad archives
		if (entry->getType()->getFormat() != "archive_wad")
			continue;

		// Detect map format (probably kinda slow but whatever, no better way to do it really)
		int format = MAP_UNKNOWN;
		Archive* tempwad = new WadArchive();
		tempwad->open(entry);
		vector<mapdesc_t> emaps = tempwad->detectMaps();
		if (emaps.size() > 0)
			format = emaps[0].format;
		delete tempwad;

		// Add map description
		mapdesc_t md;
		md.head = entry;
		md.end = entry;
		md.archive = true;
		md.name = entry->getName(true).Upper();
		md.format = format;
		ret.push_back(md);
	}

	return ret;
}
Пример #9
0
/* MapBackupPanel::updateMapPreview
 * Updates the map preview with the currently selected backup
 *******************************************************************/
void MapBackupPanel::updateMapPreview()
{
	// Clear current preview
	canvas_map->clearMap();

	// Check for selection
	if (list_backups->selectedItems().IsEmpty())
		return;
	int selection = (list_backups->GetItemCount()-1) - list_backups->selectedItems()[0];

	// Load map data to temporary wad
	if (archive_mapdata)
		delete archive_mapdata;
	archive_mapdata = new WadArchive();
	ArchiveTreeNode* dir = (ArchiveTreeNode*)dir_current->getChild(selection);
	for (unsigned a = 0; a < dir->numEntries(); a++)
		archive_mapdata->addEntry(dir->getEntry(a), "", true);

	// Open map preview
	vector<Archive::mapdesc_t> maps = archive_mapdata->detectMaps();
	if (!maps.empty())
		canvas_map->openMap(maps[0]);
}
Пример #10
0
/* StyleSet::loadResourceStyles
 * Loads all text styles from the slade resource archive (slade.pk3)
 *******************************************************************/
bool StyleSet::loadResourceStyles()
{
	// Get 'config/text_styles' directory in slade.pk3
	ArchiveTreeNode* dir = theArchiveManager->programResourceArchive()->getDir("config/text_styles");

	// Check it exists
	if (!dir)
	{
		wxLogMessage("Warning: No 'config/text_styles' directory exists in slade.pk3");
		return false;
	}

	// Read default style set first
	ArchiveEntry* default_style = dir->getEntry("default.sss");
	if (default_style)
	{
		// Read entry data into tokenizer
		Tokenizer tz;
		tz.openMem(&default_style->getMCData(), default_style->getName());

		// Parse it
		ParseTreeNode root;
		root.allowDup(true);
		root.parse(tz);

		// Read any styleset definitions
		vector<STreeNode*> nodes = root.getChildren("styleset");
		for (unsigned b = 0; b  < nodes.size(); b++)
		{
			StyleSet* newset = new StyleSet();
			if (newset->parseSet((ParseTreeNode*)nodes[b]))
				style_sets.push_back(newset);
			else
				delete newset;
		}
	}

	// Go through all entries within it
	for (unsigned a = 0; a < dir->numEntries(); a++)
	{
		ArchiveEntry* entry = dir->getEntry(a);

		// Skip default
		if (entry->getName(true) == "default")
			continue;

		// Read entry data into tokenizer
		Tokenizer tz;
		tz.openMem(&entry->getMCData(), entry->getName());

		// Parse it
		ParseTreeNode root;
		root.allowDup(true);
		root.parse(tz);

		// Read any styleset definitions
		vector<STreeNode*> nodes = root.getChildren("styleset");
		for (unsigned b = 0; b  < nodes.size(); b++)
		{
			StyleSet* newset = new StyleSet();
			if (newset->parseSet((ParseTreeNode*)nodes[b]))
				style_sets.push_back(newset);
			else
				delete newset;
		}
	}

	return true;
}
Пример #11
0
/* Archive::findAll
 * Returns a list of entries matching the search criteria in
 * [options]
 *******************************************************************/
vector<ArchiveEntry*> Archive::findAll(search_options_t& options)
{
	// Init search variables
	ArchiveTreeNode* dir = options.dir;
	if (!dir) dir = dir_root;
	vector<ArchiveEntry*> ret;
	options.match_name.MakeLower();		// Force case-insensitive

	// Begin search

	// Search entries
	for (unsigned a = 0; a < dir->numEntries(); a++)
	{
		ArchiveEntry* entry = dir->getEntry(a);

		// Check type
		if (options.match_type)
		{
			if (entry->getType() == EntryType::unknownType())
			{
				if (!options.match_type->isThisType(entry))
					continue;
			}
			else if (options.match_type != entry->getType())
				continue;
		}

		// Check name
		if (!options.match_name.IsEmpty())
		{
			// Cut extension if ignoring
			wxFileName fn(entry->getName());
			if (options.ignore_ext)
			{
				if (!fn.GetName().MakeLower().Matches(options.match_name))
					continue;
			}
			else if (!fn.GetFullName().MakeLower().Matches(options.match_name))
				continue;
		}

		// Check namespace
		if (!options.match_namespace.IsEmpty())
		{
			if (!(S_CMPNOCASE(detectNamespace(entry), options.match_namespace)))
				continue;
		}

		// Entry passed all checks so far, so we found a match
		ret.push_back(entry);
	}

	// Search subdirectories (if needed)
	if (options.search_subdirs)
	{
		for (unsigned a = 0; a < dir->nChildren(); a++)
		{
			search_options_t opt = options;
			opt.dir = (ArchiveTreeNode*)dir->getChild(a);

			// Add any matches to the list
			vector<ArchiveEntry*> vec = findAll(opt);
			ret.insert(ret.end(), vec.begin(), vec.end());
		}
	}

	// Return matches
	return ret;
}
Пример #12
0
/* Archive::findLast
 * Returns the last entry matching the search criteria in [options],
 * or NULL if no matching entry was found
 *******************************************************************/
ArchiveEntry* Archive::findLast(search_options_t& options)
{
	// Init search variables
	ArchiveTreeNode* dir = options.dir;
	if (!dir) dir = dir_root;
	options.match_name.MakeLower();		// Force case-insensitive

	// Begin search

	// Search subdirectories (if needed) (bottom-up)
	if (options.search_subdirs)
	{
		for (int a = dir->nChildren() - 1; a >= 0; a--)
		{
			search_options_t opt = options;
			opt.dir = (ArchiveTreeNode*)dir->getChild(a);
			ArchiveEntry* match = findLast(opt);

			// If a match was found in this subdir, return it
			if (match)
				return match;
		}
	}

	// Search entries (bottom-up)
	for (int a = dir->numEntries() - 1; a >= 0; a--)
	{
		ArchiveEntry* entry = dir->getEntry(a);

		// Check type
		if (options.match_type)
		{
			if (entry->getType() == EntryType::unknownType())
			{
				if (!options.match_type->isThisType(entry))
					continue;
			}
			else if (options.match_type != entry->getType())
				continue;
		}

		// Check name
		if (!options.match_name.IsEmpty())
		{
			// Cut extension if ignoring
			wxFileName fn(entry->getName());
			if (options.ignore_ext)
			{
				if (!options.match_name.Matches(fn.GetName().MakeLower()))
					continue;
			}
			else if (!options.match_name.Matches(fn.GetFullName().MakeLower()))
				continue;
		}

		// Check namespace
		if (!options.match_namespace.IsEmpty())
		{
			if (!(S_CMPNOCASE(detectNamespace(entry), options.match_namespace)))
				continue;
		}

		// Entry passed all checks so far, so we found a match
		return entry;
	}

	// No matches found
	return NULL;
}