Beispiel #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;
}
Beispiel #2
0
/* TextureXPanel::newTextureFromFile
 * Creates a new texture from an image file. The file will be
 * imported and added to the patch table if needed
 *******************************************************************/
void TextureXPanel::newTextureFromFile()
{
	// Get all entry types
	vector<EntryType*> etypes = EntryType::allTypes();

	// Go through types
	string ext_filter = "All files (*.*)|*.*|";
	for (unsigned a = 0; a < etypes.size(); a++)
	{
		// If the type is a valid image type, add its extension filter
		if (etypes[a]->extraProps().propertyExists("image"))
		{
			ext_filter += etypes[a]->getFileFilterString();
			ext_filter += "|";
		}
	}

	// Create open file dialog
	wxFileDialog dialog_open(this, "Choose file(s) to open", dir_last, wxEmptyString,
	                         ext_filter, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST, wxDefaultPosition);

	// Run the dialog & check that the user didn't cancel
	if (dialog_open.ShowModal() == wxID_OK)
	{
		// Get file selection
		wxArrayString files;
		dialog_open.GetPaths(files);

		// Save 'dir_last'
		dir_last = dialog_open.GetDirectory();

		// Go through file selection
		for (unsigned a = 0; a < files.size(); a++)
		{
			// Load the file into a temporary ArchiveEntry
			ArchiveEntry* entry = new ArchiveEntry();
			entry->importFile(files[a]);

			// Determine type
			EntryType::detectEntryType(entry);

			// If it's not a valid image type, ignore this file
			if (!entry->getType()->extraProps().propertyExists("image"))
			{
				wxLogMessage("%s is not a valid image file", files[a]);
				continue;
			}

			// Ask for name for texture
			wxFileName fn(files[a]);
			string name = fn.GetName().Upper().Truncate(8);
			name = wxGetTextFromUser(S_FMT("Enter a texture name for %s:", fn.GetFullName()), "New Texture", name);
			name = name.Truncate(8);

			// Add patch to archive
			entry->setName(name);
			entry->setExtensionByType();
			tx_entry->getParent()->addEntry(entry, "patches");

			// Add patch to patch table if needed
			if (texturex.getFormat() != TXF_TEXTURES)
				tx_editor->patchTable().addPatch(name);


			// Create new texture from patch
			CTexture* tex = newTextureFromPatch(name, name);

			// Add texture after the last selected item
			int selected = list_textures->getLastSelected();
			if (selected == -1) selected = texturex.nTextures() - 1; // Add to end of the list if nothing selected
			texturex.addTexture(tex, selected + 1);

			// Record undo level
			undo_manager->beginRecord("New Texture from File");
			undo_manager->recordUndoStep(new TextureCreateDeleteUS(this, tex, true));
			undo_manager->endRecord(true);

			// Update texture list
			list_textures->updateList();

			// Select the new texture
			list_textures->clearSelection();
			list_textures->selectItem(selected + 1);
			list_textures->EnsureVisible(selected + 1);

			// Update patch table counts
			tx_editor->patchTable().updatePatchUsage(tex);
		}
	}
}
Beispiel #3
0
/* PatchTablePanel::onBtnPatchFromFile
 * Called when the 'New Patch from File' button is clicked
 *******************************************************************/
void PatchTablePanel::onBtnPatchFromFile(wxCommandEvent& e)
{
	// Get all entry types
	vector<EntryType*> etypes = EntryType::allTypes();

	// Go through types
	string ext_filter = "All files (*.*)|*.*|";
	for (unsigned a = 0; a < etypes.size(); a++)
	{
		// If the type is a valid image type, add its extension filter
		if (etypes[a]->extraProps().propertyExists("image"))
		{
			ext_filter += etypes[a]->getFileFilterString();
			ext_filter += "|";
		}
	}

	// Create open file dialog
	wxFileDialog dialog_open(this, "Choose file(s) to open", dir_last, wxEmptyString,
	                         ext_filter, wxFD_OPEN|wxFD_MULTIPLE|wxFD_FILE_MUST_EXIST, wxDefaultPosition);

	// Run the dialog & check that the user didn't cancel
	if (dialog_open.ShowModal() == wxID_OK)
	{
		// Get file selection
		wxArrayString files;
		dialog_open.GetPaths(files);

		// Save 'dir_last'
		dir_last = dialog_open.GetDirectory();

		// Go through file selection
		for (unsigned a = 0; a < files.size(); a++)
		{
			// Load the file into a temporary ArchiveEntry
			ArchiveEntry* entry = new ArchiveEntry();
			entry->importFile(files[a]);

			// Determine type
			EntryType::detectEntryType(entry);

			// If it's not a valid image type, ignore this file
			if (!entry->getType()->extraProps().propertyExists("image"))
			{
				wxLogMessage("%s is not a valid image file", files[a]);
				continue;
			}

			// Ask for name for patch
			wxFileName fn(files[a]);
			string name = fn.GetName().Upper().Truncate(8);
			name = wxGetTextFromUser(S_FMT("Enter a patch name for %s:", fn.GetFullName()), "New Patch", name);
			name = name.Truncate(8);

			// Add patch to archive
			entry->setName(name);
			entry->setExtensionByType();
			parent->getArchive()->addEntry(entry, "patches");

			// Add patch to patch table
			patch_table->addPatch(name);
		}

		// Refresh patch list
		list_patches->updateList();
		parent->pnamesModified(true);
	}
}
Beispiel #4
0
/* EntryOperations::compileACS
 * Attempts to compile [entry] as an ACS script. If the entry is
 * named SCRIPTS, the compiled data is imported to the BEHAVIOR
 * entry previous to it, otherwise it is imported to a same-name
 * compiled library entry in the acs namespace
 *******************************************************************/
bool EntryOperations::compileACS(ArchiveEntry* entry, bool hexen, ArchiveEntry* target, wxFrame* parent)
{
	// Check entry was given
	if (!entry)
		return false;

	// Check entry has a parent (this is useless otherwise)
	if (!target && !entry->getParent())
		return false;

	// Check entry is text
	if (!EntryDataFormat::getFormat("text")->isThisFormat(entry->getMCData()))
	{
		wxMessageBox("Error: Entry does not appear to be text", "Error", wxOK|wxCENTRE|wxICON_ERROR);
		return false;
	}

	// Check if the ACC path is set up
	string accpath = path_acc;
	if (accpath.IsEmpty() || !wxFileExists(accpath))
	{
		wxMessageBox("Error: ACC path not defined, please configure in SLADE preferences", "Error", wxOK|wxCENTRE|wxICON_ERROR);
		PreferencesDialog::openPreferences(parent, "ACS");
		return false;
	}

	// Setup some path strings
	string srcfile = appPath(entry->getName(true) + ".acs", DIR_TEMP);
	string ofile = appPath(entry->getName(true) + ".o", DIR_TEMP);
	wxArrayString include_paths = wxSplit(path_acc_libs, ';');

	// Setup command options
	string opt;
	if (hexen)
		opt += " -h";
	if (!include_paths.IsEmpty())
	{
		for (unsigned a = 0; a < include_paths.size(); a++)
			opt += S_FMT(" -i \"%s\"", include_paths[a]);
	}

	// Find/export any resource libraries
	Archive::search_options_t sopt;
	sopt.match_type = EntryType::getType("acs");
	sopt.search_subdirs = true;
	vector<ArchiveEntry*> entries = theArchiveManager->findAllResourceEntries(sopt);
	wxArrayString lib_paths;
	for (unsigned a = 0; a < entries.size(); a++)
	{
		// Ignore SCRIPTS
		if (S_CMPNOCASE(entries[a]->getName(true), "SCRIPTS"))
			continue;

		// Ignore entries from other archives
		if (entry->getParent() &&
			(entry->getParent()->getFilename(true) != entries[a]->getParent()->getFilename(true)))
			continue;

		string path = appPath(entries[a]->getName(true) + ".acs", DIR_TEMP);
		entries[a]->exportFile(path);
		lib_paths.Add(path);
		LOG_MESSAGE(2, "Exporting ACS library %s", entries[a]->getName());
	}

	// Export script to file
	entry->exportFile(srcfile);

	// Execute acc
	string command = path_acc + " " + opt + " \"" + srcfile + "\" \"" + ofile + "\"";
	wxArrayString output;
	wxArrayString errout;
	theApp->SetTopWindow(parent);
	wxExecute(command, output, errout, wxEXEC_SYNC);
	theApp->SetTopWindow(theMainWindow);

	// Log output
	theConsole->logMessage("ACS compiler output:");
	string output_log;
	if (!output.IsEmpty())
	{
		const char *title1 = "=== Log: ===\n";
		theConsole->logMessage(title1);
		output_log += title1;
		for (unsigned a = 0; a < output.size(); a++)
		{
			theConsole->logMessage(output[a]);
			output_log += output[a];
		}
	}

	if (!errout.IsEmpty())
	{
		const char *title2 = "\n=== Error log: ===\n";
		theConsole->logMessage(title2);
		output_log += title2;
		for (unsigned a = 0; a < errout.size(); a++)
		{
			theConsole->logMessage(errout[a]);
			output_log += errout[a];
		}
	}

	// Delete source file
	wxRemoveFile(srcfile);

	// Delete library files
	for (unsigned a = 0; a < lib_paths.size(); a++)
		wxRemoveFile(lib_paths[a]);

	// Check it compiled successfully
	if (wxFileExists(ofile))
	{
		// If no target entry was given, find one
		if (!target)
		{
			// Check if the script is a map script (BEHAVIOR)
			if (S_CMPNOCASE(entry->getName(), "SCRIPTS"))
			{
				// Get entry before SCRIPTS
				ArchiveEntry* prev = entry->prevEntry();

				// Create a new entry there if it isn't BEHAVIOR
				if (!prev || !(S_CMPNOCASE(prev->getName(), "BEHAVIOR")))
					prev = entry->getParent()->addNewEntry("BEHAVIOR", entry->getParent()->entryIndex(entry));

				// Import compiled script
				prev->importFile(ofile);
			}
			else
			{
				// Otherwise, treat it as a library

				// See if the compiled library already exists as an entry
				Archive::search_options_t opt;
				opt.match_namespace = "acs";
				opt.match_name = entry->getName(true);
				if (entry->getParent()->getDesc().names_extensions)
				{
					opt.match_name += ".o";
					opt.ignore_ext = false;
				}
				ArchiveEntry* lib = entry->getParent()->findLast(opt);

				// If it doesn't exist, create it
				if (!lib)
					lib = entry->getParent()->addEntry(new ArchiveEntry(entry->getName(true) + ".o"), "acs");

				// Import compiled script
				lib->importFile(ofile);
			}
		}
		else
			target->importFile(ofile);

		// Delete compiled script file
		wxRemoveFile(ofile);
	}
	else
	{
		string errors;
		if (wxFileExists(appPath("acs.err", DIR_TEMP)))
		{
			// Read acs.err to string
			wxFile file(appPath("acs.err", DIR_TEMP));
			char* buf = new char[file.Length()];
			file.Read(buf, file.Length());
			errors = wxString::From8BitData(buf, file.Length());
			delete[] buf;
		}
		else
			errors = output_log;

		ExtMessageDialog dlg(NULL, "Error Compiling");
		dlg.setMessage("The following errors were encountered while compiling, please fix them and recompile:");
		dlg.setExt(errors);
		dlg.ShowModal();

		return false;
	}

	return true;
}
Beispiel #5
0
/* DirArchive::updateChangedEntries
 * Updates entries/directories based on [changes] list
 *******************************************************************/
void DirArchive::updateChangedEntries(vector<dir_entry_change_t>& changes)
{
	bool was_modified = isModified();

	for (unsigned a = 0; a < changes.size(); a++)
	{
		ignored_file_changes.erase(changes[a].file_path);

		// Modified Entries
		if (changes[a].action == dir_entry_change_t::UPDATED)
		{
			ArchiveEntry* entry = entryAtPath(changes[a].entry_path);
			entry->importFile(changes[a].file_path);
			EntryType::detectEntryType(entry);
			file_modification_times[entry] = wxFileModificationTime(changes[a].file_path);
		}

		// Deleted Entries
		else if (changes[a].action == dir_entry_change_t::DELETED_FILE)
			removeEntry(entryAtPath(changes[a].entry_path));

		// Deleted Directories
		else if (changes[a].action == dir_entry_change_t::DELETED_DIR)
			removeDir(changes[a].entry_path);

		// New Directory
		else if (changes[a].action == dir_entry_change_t::ADDED_DIR)
		{
			string name = changes[a].file_path;
			name.Remove(0, filename.Length());
			if (name.StartsWith(separator))
				name.Remove(0, 1);
			name.Replace("\\", "/");

			ArchiveTreeNode* ndir = createDir(name);
			ndir->getDirEntry()->setState(0);
			ndir->getDirEntry()->exProp("filePath") = changes[a].file_path;
		}

		// New Entry
		else if (changes[a].action == dir_entry_change_t::ADDED_FILE)
		{
			string name = changes[a].file_path;
			name.Remove(0, filename.Length());
			if (name.StartsWith(separator))
				name.Remove(0, 1);
			name.Replace("\\", "/");

			// Create entry
			wxFileName fn(name);
			ArchiveEntry* new_entry = new ArchiveEntry(fn.GetFullName());

			// Setup entry info
			new_entry->setLoaded(false);
			new_entry->exProp("filePath") = changes[a].file_path;

			// Add entry and directory to directory tree
			ArchiveTreeNode* ndir = createDir(fn.GetPath(true, wxPATH_UNIX));
			ndir->addEntry(new_entry);

			// Read entry data
			new_entry->importFile(changes[a].file_path);
			new_entry->setLoaded(true);

			time_t modtime = wxFileModificationTime(changes[a].file_path);
			file_modification_times[new_entry] = modtime;

			// Detect entry type
			EntryType::detectEntryType(new_entry);

			// Unload data if needed
			if (!archive_load_data)
				new_entry->unloadData();

			// Set entry not modified
			new_entry->setState(0);
		}
	}

	// Preserve old modified state
	setModified(was_modified);
}