Esempio n. 1
0
// ----------------------------------------------------------------------------
// ArchiveEntryList::labelEdited
//
// Called when a label has been edited
// ----------------------------------------------------------------------------
void ArchiveEntryList::labelEdited(int col, int index, string new_label)
{
	if (undo_manager)
		undo_manager->beginRecord("Rename Entry");

	// Rename the entry
	ArchiveEntry* entry = getEntry(index);
	if (entry->getParent())
		entry->getParent()->renameEntry(entry, new_label);
	else
		entry->rename(new_label);

	if (undo_manager)
		undo_manager->endRecord(true);
}
Esempio n. 2
0
/* PatchTableListView::getItemText
 * Returns the string for [item] at [column]
 *******************************************************************/
string PatchTableListView::getItemText(long item, long column, long index) const
{
	// Check patch table exists
	if (!patch_table)
		return "INVALID INDEX";

	// Check index is ok
	if (index < 0 || (unsigned)index > patch_table->nPatches())
		return "INVALID INDEX";

	// Get associated patch
	patch_t& patch = patch_table->patch(index);

	if (column == 0)						// Index column
		return S_FMT("%04d", index);
	else if (column == 1)					// Name column
		return patch.name;
	else if (column == 2)					// Usage count column
		return S_FMT("%lu", patch.used_in.size());
	else if (column == 3)  					// Archive column
	{
		// Get patch entry
		ArchiveEntry* entry = patch_table->patchEntry(index);

		// If patch entry can't be found return invalid
		if (entry)
			return entry->getParent()->getFilename(false);
		else
			return "(!) NOT FOUND";
	}
	else									// Invalid column
		return "INVALID COLUMN";
}
Esempio n. 3
0
/* TextureXPanel::paste
 * Pastes any textures on the clipboard after the last selected
 * texture
 *******************************************************************/
void TextureXPanel::paste()
{
	// Check there is anything on the clipboard
	if (theClipboard->nItems() == 0)
		return;

	// Get last selected index
	int selected = list_textures->getLastSelected();
	if (selected == -1) selected = texturex.nTextures() - 1; // Add to end of the list if nothing selected

	// Begin recording undo level
	undo_manager->beginRecord("Paste Texture(s)");

	// Go through clipboard items
	for (unsigned a = 0; a < theClipboard->nItems(); a++)
	{
		// Skip if not a texture clipboard item
		if (theClipboard->getItem(a)->getType() != CLIPBOARD_COMPOSITE_TEXTURE)
			continue;

		// Get texture item
		TextureClipboardItem* item = (TextureClipboardItem*)(theClipboard->getItem(a));

		// Add new texture after last selected item
		CTexture* ntex = new CTexture((texturex.getFormat() == TXF_TEXTURES));
		ntex->copyTexture(item->getTexture(), true);
		ntex->setState(2);
		texturex.addTexture(ntex, ++selected);

		// Record undo step
		undo_manager->recordUndoStep(new TextureCreateDeleteUS(this, ntex, true));

		// Deal with patches
		for (unsigned p = 0; p < ntex->nPatches(); p++)
		{
			CTPatch* patch = ntex->getPatch(p);

			// Update patch table if necessary
			if (texturex.getFormat() != TXF_TEXTURES)
				tx_editor->patchTable().addPatch(patch->getName());

			// Get the entry for this patch
			ArchiveEntry* entry = patch->getPatchEntry(tx_editor->getArchive());

			// If the entry wasn't found in any open archive, try copying it from the clipboard
			// (the user may have closed the archive the original patch was in)
			if (!entry)
			{
				entry = item->getPatchEntry(patch->getName());

				// Copy the copied patch entry over to this archive
				if (entry)
					tx_editor->getArchive()->addEntry(entry, "patches", true);
			}

			// If the entry exists in the base resource archive or this archive, do nothing
			else if (entry->getParent() == theArchiveManager->baseResourceArchive() ||
			         entry->getParent() == tx_editor->getArchive())
				continue;

			// Otherwise, copy the entry over to this archive
			else
				tx_editor->getArchive()->addEntry(entry, "patches", true);
		}
	}

	// End recording undo level
	undo_manager->endRecord(true);

	// Refresh
	list_textures->updateList();

	// Update variables
	modified = true;
}
Esempio n. 4
0
/* PatchTablePanel::updateDisplay
 * Called when a different patch or palette is selected
 * TODO: Separate palette changed and patch changed without breaking
 * default palette display; optimize label_textures display
 *******************************************************************/
void PatchTablePanel::updateDisplay()
{
	// Get selected patch
	patch_t& patch = patch_table->patch(list_patches->getLastSelected());

	// Load the image
	ArchiveEntry* entry = patch_table->patchEntry(list_patches->getLastSelected());
	if (Misc::loadImageFromEntry(patch_canvas->getImage(), entry))
	{
		theMainWindow->getPaletteChooser()->setGlobalFromArchive(entry->getParent());
		patch_canvas->setPalette(theMainWindow->getPaletteChooser()->getSelectedPalette());
		label_dimensions->SetLabel(S_FMT("Size: %d x %d", patch_canvas->getImage()->getWidth(), patch_canvas->getImage()->getHeight()));
	}
	else
	{
		patch_canvas->getImage()->clear();
		label_dimensions->SetLabel("Size: ? x ?");
	}
	patch_canvas->Refresh();

	// List which textures use this patch
	if (patch.used_in.size() > 0)
	{
		string alltextures = "";
		int count = 0;
		string previous = "";
		for (size_t a = 0; a < patch.used_in.size(); ++a)
		{
			string current = patch.used_in[a];

			// Is the use repeated for the same texture?
			if (!current.CmpNoCase(previous))
			{
				count++;
				// Else it's a new texture
			}
			else
			{
				// First add the count to the previous texture if needed
				if (count)
				{
					alltextures += S_FMT(" (%i)", count + 1);
					count = 0;
				}

				// Add a separator if appropriate
				if (a > 0)
					alltextures += ';';

				// Then print the new texture's name
				alltextures += S_FMT(" %s", patch.used_in[a].mb_str());

				// And set it for comparison with the next one
				previous = current;
			}
		}
		// If count is still non-zero, it's because the patch was repeated in the last texture
		if (count)
			alltextures += S_FMT(" (%i)", count + 1);

		// Finally display the listing
		label_textures->SetLabel(S_FMT("In Textures:%s", alltextures.mb_str()));
	}
	else
		label_textures->SetLabel("In Textures: -");

	// Wrap the text label
	label_textures->Wrap(label_textures->GetSize().GetWidth());

	// Update layout
	Layout();
}
Esempio n. 5
0
// -----------------------------------------------------------------------------
// Removes any patches and associated entries from [archive] that are not used
// in any texture definitions
// -----------------------------------------------------------------------------
bool ArchiveOperations::removeUnusedPatches(Archive* archive)
{
	if (!archive)
		return false;

	// Find PNAMES entry
	Archive::SearchOptions opt;
	opt.match_type       = EntryType::fromId("pnames");
	ArchiveEntry* pnames = archive->findLast(opt);

	// Find TEXTUREx entries
	opt.match_type                   = EntryType::fromId("texturex");
	vector<ArchiveEntry*> tx_entries = archive->findAll(opt);

	// Can't do anything without PNAMES/TEXTUREx
	if (!pnames || tx_entries.size() == 0)
		return false;

	// Open patch table
	PatchTable ptable;
	ptable.loadPNAMES(pnames, archive);

	// Open texturex entries to update patch usage
	vector<TextureXList*> tx_lists;
	for (unsigned a = 0; a < tx_entries.size(); a++)
	{
		TextureXList* texturex = new TextureXList();
		texturex->readTEXTUREXData(tx_entries[a], ptable);
		for (unsigned t = 0; t < texturex->nTextures(); t++)
			ptable.updatePatchUsage(texturex->getTexture(t));
		tx_lists.push_back(texturex);
	}

	// Go through patch table
	unsigned              removed = 0;
	vector<ArchiveEntry*> to_remove;
	for (unsigned a = 0; a < ptable.nPatches(); a++)
	{
		auto& p = ptable.patch(a);

		// Check if used in any texture
		if (p.used_in.size() == 0)
		{
			// Unused

			// If its entry is in the archive, flag it to be removed
			ArchiveEntry* entry = theResourceManager->getPatchEntry(p.name, "patches", archive);
			if (entry && entry->getParent() == archive)
				to_remove.push_back(entry);

			// Update texturex list patch indices
			for (unsigned t = 0; t < tx_lists.size(); t++)
				tx_lists[t]->removePatch(p.name);

			// Remove the patch from the patch table
			LOG_MESSAGE(1, "Removed patch %s", p.name);
			removed++;
			ptable.removePatch(a--);
		}
	}

	// Remove unused patch entries
	for (unsigned a = 0; a < to_remove.size(); a++)
	{
		LOG_MESSAGE(1, "Removed entry %s", to_remove[a]->getName());
		archive->removeEntry(to_remove[a]);
	}

	// Write PNAMES changes
	ptable.writePNAMES(pnames);

	// Write TEXTUREx changes
	for (unsigned a = 0; a < tx_lists.size(); a++)
		tx_lists[a]->writeTEXTUREXData(tx_entries[a], ptable);

	// Cleanup
	for (unsigned a = 0; a < tx_lists.size(); a++)
		delete tx_lists[a];

	// Notify user
	wxMessageBox(
		S_FMT("Removed %d patches and %lu entries. See console log for details.", removed, to_remove.size()),
		"Removed Unused Patches",
		wxOK | wxICON_INFORMATION);

	return true;
}
Esempio n. 6
0
/* ArchiveManager::closeArchive
 * Closes the archive at index, and removes it from the list if the
 * index is valid. Returns false on invalid index, true otherwise
 *******************************************************************/
bool ArchiveManager::closeArchive(int index)
{
	// Check for invalid index
	if (index < 0 || index >= (int) open_archives.size())
		return false;

	// Announce archive closing
	MemChunk mc;
	int32_t temp = index;
	mc.write(&temp, 4);
	announce("archive_closing", mc);

	// Delete any bookmarked entries contained in the archive
	deleteBookmarksInArchive(open_archives[index].archive);

	// Remove from resource manager
	theResourceManager->removeArchive(open_archives[index].archive);

	// Delete any embedded configuration
	//theGameConfiguration->removeEmbeddedConfig(open_archives[index].archive->getFilename());

	// Close any open child archives
	// Clear out the open_children vector first, lest the children try to
	// remove themselves from it
	vector<Archive*> open_children = open_archives[index].open_children;
	open_archives[index].open_children.clear();
	for (size_t a = 0; a < open_children.size(); a++)
	{
		int ci = archiveIndex(open_children[a]);
		if (ci >= 0)
			closeArchive(ci);
	}

	// Remove ourselves from our parent's open-child list
	ArchiveEntry* parent = open_archives[index].archive->getParent();
	if (parent)
	{
		Archive* gp = parent->getParent();
		if (gp)
		{
			int pi = archiveIndex(gp);
			if (pi >= 0)
			{
				vector<Archive*>& children = open_archives[pi].open_children;
				for (vector<Archive*>::iterator it = children.begin();
					it < children.end();
					it++)
				{
					if (*it == open_archives[index].archive)
					{
						children.erase(it, it + 1);
						break;
					}
				}
			}
		}
	}

	// Close the archive
	open_archives[index].archive->close();

	// Delete the archive object
	delete open_archives[index].archive;

	// Remove the archive at index from the list
	open_archives.erase(open_archives.begin() + index);

	// Announce closed
	announce("archive_closed", mc);

	return true;
}