Files
SingularityViewer/indra/newview/hgfloatertexteditor.cpp
Shyotl e756140e1d Innitial commit of experimental v2 texture system port work. Compiles and runs on windows, at least. Fixing bugs as they come.
Need to test:
localassetbrowser
preview related floaters
hgfloatertexteditor
maps
media textures! Currently very hacky
web browser
alpha masks on avatars
bumpmaps
Are all sky components appearing?
LLViewerDynamicTexture (texture baking, browser, animated textures, anim previews, etc)
Snapshot related features
Customize avatar
vfs floater
UI textures in general
Texture priority issues
2011-03-31 03:22:01 -05:00

399 lines
11 KiB
C++

/**
* @file hgfloatertexteditor.cpp
* @brief Asset Text Editor floater made by Hazim Gazov (based on hex editor floater by Day Oh)
* @author Hazim Gazov
*
* $LicenseInfo:firstyear=2010&license=WTFPLV2$
*
*/
// <edit>
#include "llviewerprecompiledheaders.h"
#include "hgfloatertexteditor.h"
#include "lluictrlfactory.h"
#include "llinventorybackup.h" // for downloading
#include "llviewercontrol.h" // gSavedSettings
#include "llviewerwindow.h" // alertXML
#include "llagent.h" // gAgent getID
#include "llviewermenufile.h"
#include "llviewerregion.h" // getCapability
#include "llassetuploadresponders.h" // LLUpdateAgentInventoryResponder
#include "llinventorymodel.h" // gInventory.updateItem
#include "llappviewer.h" // System Folders
#include "llfloaterperms.h" //get default perms
#include "lllocalinventory.h"
std::list<HGFloaterTextEditor*> HGFloaterTextEditor::sInstances;
S32 HGFloaterTextEditor::sUploadAmount = 10;
HGFloaterTextEditor::HGFloaterTextEditor(LLInventoryItem* item)
: LLFloater()
{
sInstances.push_back(this);
mItem = item;
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_asset_text_editor.xml");
}
// static
void HGFloaterTextEditor::show(LLUUID item_id)
{
LLInventoryItem* item = (LLInventoryItem*)gInventory.getItem(item_id);
if(item)
{
S32 left, top;
gFloaterView->getNewFloaterPosition(&left, &top);
LLRect rect = gSavedSettings.getRect("FloaterAssetTextEditorRect");
rect.translate(left - rect.mLeft, top - rect.mTop);
HGFloaterTextEditor* floaterp = new HGFloaterTextEditor(item);
floaterp->setRect(rect);
gFloaterView->adjustToFitScreen(floaterp, FALSE);
}
}
HGFloaterTextEditor::~HGFloaterTextEditor()
{
sInstances.remove(this);
}
void HGFloaterTextEditor::close(bool app_quitting)
{
LLFloater::close(app_quitting);
}
BOOL HGFloaterTextEditor::postBuild(void)
{
LLTextEditor* editor = getChild<LLTextEditor>("text_editor");
mEditor = editor;
childSetEnabled("upload_btn", false);
childSetLabelArg("upload_btn", "[UPLOAD]", std::string("Upload"));
childSetAction("upload_btn", onClickUpload, this);
childSetEnabled("save_btn", false);
childSetAction("save_btn", onClickSave, this);
if(mItem)
{
std::string title = "Text editor: " + mItem->getName();
const char* asset_type_name = LLAssetType::lookup(mItem->getType());
if(asset_type_name)
{
title.append(" (" + std::string(asset_type_name) + ")");
}
setTitle(title);
}
#if OPENSIM_RULES!=1
if(mItem->getCreatorUUID() == gAgentID)
{
#endif /* OPENSIM_RULES!=1 */
// Load the asset
editor->setVisible(FALSE);
childSetText("status_text", std::string("Loading..."));
LLInventoryBackup::download(mItem, this, imageCallback, assetCallback);
#if OPENSIM_RULES!=1
} else {
this->close(false);
}
#endif /* OPENSIM_RULES!=1 */
return TRUE;
}
// static
void HGFloaterTextEditor::imageCallback(BOOL success,
LLViewerFetchedTexture *src_vi,
LLImageRaw* src,
LLImageRaw* aux_src,
S32 discard_level,
BOOL final,
void* userdata)
{
if(final)
{
LLInventoryBackup::callbackdata* data = static_cast<LLInventoryBackup::callbackdata*>(userdata);
HGFloaterTextEditor* floater = (HGFloaterTextEditor*)(data->floater);
if(!floater) return;
if(std::find(sInstances.begin(), sInstances.end(), floater) == sInstances.end()) return; // no more crash
//LLInventoryItem* item = data->item;
if(!success)
{
floater->childSetText("status_text", std::string("Unable to download asset."));
return;
}
U8* src_data = src->getData();
S32 size = src->getDataSize();
std::string new_data;
for(S32 i = 0; i < size; i++)
new_data += (char)src_data[i];
delete[] src_data;
floater->mEditor->setValue(new_data);
floater->mEditor->setVisible(TRUE);
floater->childSetText("status_text", std::string("Note: Image data shown isn't the actual asset data, yet"));
floater->childSetEnabled("save_btn", false);
floater->childSetEnabled("upload_btn", true);
floater->childSetLabelArg("upload_btn", "[UPLOAD]", std::string("Upload (L$10)"));
}
else
{
src_vi->setBoostLevel(LLViewerTexture::BOOST_UI);
}
}
// static
void HGFloaterTextEditor::assetCallback(LLVFS *vfs,
const LLUUID& asset_uuid,
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status)
{
LLInventoryBackup::callbackdata* data = static_cast<LLInventoryBackup::callbackdata*>(user_data);
HGFloaterTextEditor* floater = (HGFloaterTextEditor*)(data->floater);
if(!floater) return;
if(std::find(sInstances.begin(), sInstances.end(), floater) == sInstances.end()) return; // no more crash
LLInventoryItem* item = data->item;
if(status != 0 && item->getType() != LLAssetType::AT_NOTECARD)
{
floater->childSetText("status_text", std::string("Unable to download asset."));
return;
}
// Todo: this doesn't work for static vfs shit
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
S32 size = file.getSize();
std::string new_data("");
if(size > 0)
{
char* buffer = new char[size + 1];
if (buffer == NULL)
{
llerrs << "Memory Allocation Failed" << llendl;
return;
}
file.read((U8*)buffer, size);
buffer[size - 1] = 0;
new_data = std::string(buffer);
delete[] buffer;
}
floater->mEditor->setText(LLStringExplicit(new_data));
floater->mEditor->setVisible(TRUE);
floater->childSetText("status_text", llformat("File Size: %d", size));
floater->childSetEnabled("upload_btn", true);
floater->childSetEnabled("save_btn", false);
if(item->getPermissions().allowModifyBy(gAgent.getID()))
{
switch(item->getType())
{
case LLAssetType::AT_TEXTURE:
case LLAssetType::AT_ANIMATION:
case LLAssetType::AT_SOUND:
floater->childSetLabelArg("upload_btn", "[UPLOAD]", std::string("Upload (L$10)"));
break;
case LLAssetType::AT_LANDMARK:
case LLAssetType::AT_CALLINGCARD:
floater->childSetEnabled("upload_btn", false);
floater->childSetEnabled("save_btn", false);
break;
default:
floater->childSetEnabled("save_btn", true);
break;
}
}
else
{
switch(item->getType())
{
case LLAssetType::AT_TEXTURE:
case LLAssetType::AT_ANIMATION:
case LLAssetType::AT_SOUND:
floater->childSetLabelArg("upload_btn", "[UPLOAD]", std::string("Upload (L$10)"));
break;
default:
break;
}
}
// Never enable save if it's a pretend item
if(gInventory.isObjectDescendentOf(item->getUUID(), gSystemFolderRoot))
{
floater->childSetEnabled("save_btn", false);
}
}
// static
void HGFloaterTextEditor::onClickUpload(void* user_data)
{
HGFloaterTextEditor* floater = (HGFloaterTextEditor*)user_data;
LLInventoryItem* item = floater->mItem;
LLTransactionID transaction_id;
transaction_id.generate();
LLUUID fake_asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID());
const char* value = floater->mEditor->getText().c_str();
int size = strlen(value);
U8* buffer = new U8[size];
for(int i = 0; i < size; i++)
buffer[i] = (U8)value[i];
delete[] value;
LLVFile file(gVFS, fake_asset_id, item->getType(), LLVFile::APPEND);
file.setMaxSize(size);
if (!file.write(buffer, size))
{
LLSD args;
args["ERROR_MESSAGE"] = "Couldn't write data to file";
LLNotifications::instance().add("ErrorMessage", args);
return;
}
LLAssetStorage::LLStoreAssetCallback callback = NULL;
void *fake_user_data = NULL;
if(item->getType() != LLAssetType::AT_GESTURE && item->getType() != LLAssetType::AT_LSL_TEXT
&& item->getType() != LLAssetType::AT_NOTECARD)
{
upload_new_resource(transaction_id,
item->getType(),
item->getName(),
item->getDescription(),
0,
item->getType(),
item->getInventoryType(),
LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
item->getName(),
callback,
sUploadAmount,
fake_user_data);
}
else // gestures and scripts, create an item first
{ // AND notecards
//if(item->getType() == LLAssetType::AT_NOTECARD) gDontOpenNextNotecard = true;
create_inventory_item( gAgent.getID(),
gAgent.getSessionID(),
item->getParentUUID(), //gInventory.findCategoryUUIDForType(item->getType()),
LLTransactionID::tnull,
item->getName(),
fake_asset_id.asString(),
item->getType(),
item->getInventoryType(),
(EWearableType)item->getFlags(),
PERM_ITEM_UNRESTRICTED,
new NewResourceItemCallback);
}
}
struct LLSaveInfo
{
LLSaveInfo(HGFloaterTextEditor* floater, LLTransactionID transaction_id)
: mFloater(floater), mTransactionID(transaction_id)
{
}
HGFloaterTextEditor* mFloater;
LLTransactionID mTransactionID;
};
// static
void HGFloaterTextEditor::onClickSave(void* user_data)
{
HGFloaterTextEditor* floater = (HGFloaterTextEditor*)user_data;
LLInventoryItem* item = floater->mItem;
LLTransactionID transaction_id;
transaction_id.generate();
LLUUID fake_asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID());
const char* value = floater->mEditor->getText().c_str();
int size = strlen(value);
U8* buffer = new U8[size];
for(int i = 0; i < size; i++)
buffer[i] = (U8)value[i];
LLVFile file(gVFS, fake_asset_id, item->getType(), LLVFile::APPEND);
file.setMaxSize(size);
if (!file.write(buffer, size))
{
LLSD args;
args["ERROR_MESSAGE"] = "Couldn't write data to file";
LLNotifications::instance().add("ErrorMessage", args);
return;
}
bool caps = false;
std::string url;
LLSD body;
body["item_id"] = item->getUUID();
switch(item->getType())
{
case LLAssetType::AT_GESTURE:
url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
caps = true;
break;
case LLAssetType::AT_LSL_TEXT:
url = gAgent.getRegion()->getCapability("UpdateScriptAgent");
body["target"] = "mono";
caps = true;
break;
case LLAssetType::AT_NOTECARD:
url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
caps = true;
break;
default: // wearables & notecards, Oct 12 2009
// ONLY WEARABLES, Oct 15 2009
floater->childSetText("status_text", std::string("Saving..."));
LLSaveInfo* info = new LLSaveInfo(floater, transaction_id);
gAssetStorage->storeAssetData(transaction_id, item->getType(), onSaveComplete, info);
caps = false;
break;
}
if(caps)
{
LLHTTPClient::post(url, body,
new LLUpdateAgentInventoryResponder(body, fake_asset_id, item->getType()));
}
}
void HGFloaterTextEditor::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
{
LLSaveInfo* info = (LLSaveInfo*)user_data;
HGFloaterTextEditor* floater = info->mFloater;
if(std::find(sInstances.begin(), sInstances.end(), floater) == sInstances.end()) return; // no more crash
LLInventoryItem* item = floater->mItem;
floater->childSetText("status_text", std::string(""));
if(item && (status == 0))
{
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->setDescription(item->getDescription());
new_item->setTransactionID(info->mTransactionID);
new_item->setAssetUUID(asset_uuid);
new_item->updateServer(FALSE);
gInventory.updateItem(new_item);
gInventory.notifyObservers();
}
else
{
LLSD args;
args["ERROR_MESSAGE"] = llformat("Upload failed with status %d, also %d", status, ext_status);
LLNotifications::instance().add("ErrorMessage", args);
}
}
// </edit>