Added hex editor by day oh, ported it to snowglobe trunk
This commit is contained in:
@@ -127,5 +127,6 @@ const std::string
|
|||||||
LL_FLYOUT_BUTTON_ITEM_TAG("flyout_button_item"),
|
LL_FLYOUT_BUTTON_ITEM_TAG("flyout_button_item"),
|
||||||
LL_SIMPLE_TEXT_EDITOR_TAG("simple_text_editor"),
|
LL_SIMPLE_TEXT_EDITOR_TAG("simple_text_editor"),
|
||||||
LL_RADIO_ITEM_TAG("radio_item"),
|
LL_RADIO_ITEM_TAG("radio_item"),
|
||||||
LL_PROGRESS_BAR_TAG("progress_bar");
|
LL_PROGRESS_BAR_TAG("progress_bar"),
|
||||||
|
DO_HEX_EDITOR_TAG("hex_editor");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ include_directories(
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(viewer_SOURCE_FILES
|
set(viewer_SOURCE_FILES
|
||||||
|
dofloaterhex.cpp
|
||||||
|
dohexeditor.cpp
|
||||||
|
doinventorybackup.cpp
|
||||||
jcfloaterareasearch.cpp
|
jcfloaterareasearch.cpp
|
||||||
llagent.cpp
|
llagent.cpp
|
||||||
llagentaccess.cpp
|
llagentaccess.cpp
|
||||||
@@ -484,6 +487,9 @@ set(viewer_HEADER_FILES
|
|||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
ViewerInstall.cmake
|
ViewerInstall.cmake
|
||||||
|
|
||||||
|
dofloaterhex.h
|
||||||
|
dohexeditor.h
|
||||||
|
doinventorybackup.h
|
||||||
jcfloaterareasearch.h
|
jcfloaterareasearch.h
|
||||||
llagent.h
|
llagent.h
|
||||||
llagentaccess.h
|
llagentaccess.h
|
||||||
|
|||||||
@@ -12637,6 +12637,22 @@
|
|||||||
<integer>250</integer>
|
<integer>250</integer>
|
||||||
<integer>200</integer>
|
<integer>200</integer>
|
||||||
</array>
|
</array>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FloaterHexRect</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Rectangle for hex editor floater.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Rect</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<array>
|
||||||
|
<integer>343</integer>
|
||||||
|
<integer>687</integer>
|
||||||
|
<integer>901</integer>
|
||||||
|
<integer>473</integer>
|
||||||
|
</array>
|
||||||
|
</map>
|
||||||
</map>
|
</map>
|
||||||
</llsd>
|
</llsd>
|
||||||
|
|||||||
412
indra/newview/dofloaterhex.cpp
Normal file
412
indra/newview/dofloaterhex.cpp
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
/**
|
||||||
|
* @file dofloaterhex.h
|
||||||
|
* @brief Hex Editor Floater made by Day
|
||||||
|
* @author Day Oh
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=WTFPLV2$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "dofloaterhex.h"
|
||||||
|
#include "lluictrlfactory.h"
|
||||||
|
#include "doinventorybackup.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" // gLocalInventoryRoot
|
||||||
|
#include "llfloaterperms.h" //get default perms
|
||||||
|
|
||||||
|
std::list<DOFloaterHex*> DOFloaterHex::sInstances;
|
||||||
|
S32 DOFloaterHex::sUploadAmount = 10;
|
||||||
|
|
||||||
|
DOFloaterHex::DOFloaterHex(LLInventoryItem* item)
|
||||||
|
: LLFloater()
|
||||||
|
{
|
||||||
|
sInstances.push_back(this);
|
||||||
|
mItem = item;
|
||||||
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_hex.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterHex::show(LLUUID item_id)
|
||||||
|
{
|
||||||
|
LLInventoryItem* item = (LLInventoryItem*)gInventory.getItem(item_id);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
S32 left, top;
|
||||||
|
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||||
|
LLRect rect = gSavedSettings.getRect("FloaterHexRect");
|
||||||
|
rect.translate(left - rect.mLeft, top - rect.mTop);
|
||||||
|
DOFloaterHex* floaterp = new DOFloaterHex(item);
|
||||||
|
floaterp->setRect(rect);
|
||||||
|
gFloaterView->adjustToFitScreen(floaterp, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DOFloaterHex::~DOFloaterHex()
|
||||||
|
{
|
||||||
|
sInstances.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOFloaterHex::close(bool app_quitting)
|
||||||
|
{
|
||||||
|
LLFloater::close(app_quitting);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DOFloaterHex::postBuild(void)
|
||||||
|
{
|
||||||
|
DOHexEditor* editor = getChild<DOHexEditor>("hex");
|
||||||
|
mEditor = editor;
|
||||||
|
|
||||||
|
// Set number of columns
|
||||||
|
U8 columns = U8(gSavedSettings.getU32("HexEditorColumns"));
|
||||||
|
editor->setColumns(columns);
|
||||||
|
// Reflect clamped U8ness in settings
|
||||||
|
gSavedSettings.setU32("HexEditorColumns", U32(columns));
|
||||||
|
|
||||||
|
// Reshape a little based on columns
|
||||||
|
S32 min_width = S32(editor->getSuggestedWidth()) + 20;
|
||||||
|
setResizeLimits(min_width, getMinHeight());
|
||||||
|
if(getRect().getWidth() < min_width)
|
||||||
|
{
|
||||||
|
//LLRect rect = getRect();
|
||||||
|
//rect.setOriginAndSize(rect.mLeft, rect.mBottom, min_width, rect.getHeight());
|
||||||
|
//setRect(rect);
|
||||||
|
|
||||||
|
reshape(min_width, getRect().getHeight(), FALSE);
|
||||||
|
editor->reshape(editor->getRect().getWidth(), editor->getRect().getHeight(), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = "Hex 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(mItem->getCreatorUUID() == gAgentID)
|
||||||
|
{
|
||||||
|
// Load the asset
|
||||||
|
editor->setVisible(FALSE);
|
||||||
|
childSetText("status_text", std::string("Loading..."));
|
||||||
|
DOInventoryBackup::download(mItem, this, imageCallback, assetCallback);
|
||||||
|
} else {
|
||||||
|
this->close(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterHex::imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata)
|
||||||
|
{
|
||||||
|
if(final)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(userdata);
|
||||||
|
DOFloaterHex* floater = (DOFloaterHex*)(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::vector<U8> new_data;
|
||||||
|
for(S32 i = 0; i < size; i++)
|
||||||
|
new_data.push_back(src_data[i]);
|
||||||
|
|
||||||
|
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(LLViewerImageBoostLevel::BOOST_UI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterHex::assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(user_data);
|
||||||
|
DOFloaterHex* floater = (DOFloaterHex*)(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();
|
||||||
|
|
||||||
|
char* buffer = new char[size];
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
llerrs << "Memory Allocation Failed" << llendl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.read((U8*)buffer, size);
|
||||||
|
|
||||||
|
std::vector<U8> new_data;
|
||||||
|
for(S32 i = 0; i < size; i++)
|
||||||
|
new_data.push_back(buffer[i]);
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
floater->mEditor->setValue(new_data);
|
||||||
|
floater->mEditor->setVisible(TRUE);
|
||||||
|
floater->childSetText("status_text", std::string(""));
|
||||||
|
|
||||||
|
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(), gLocalInventoryRoot))
|
||||||
|
{
|
||||||
|
floater->childSetEnabled("save_btn", false);
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterHex::onClickUpload(void* user_data)
|
||||||
|
{
|
||||||
|
DOFloaterHex* floater = (DOFloaterHex*)user_data;
|
||||||
|
LLInventoryItem* item = floater->mItem;
|
||||||
|
|
||||||
|
LLTransactionID transaction_id;
|
||||||
|
transaction_id.generate();
|
||||||
|
LLUUID fake_asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID());
|
||||||
|
|
||||||
|
std::vector<U8> value = floater->mEditor->getValue();
|
||||||
|
int size = value.size();
|
||||||
|
U8* buffer = new U8[size];
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
buffer[i] = value[i];
|
||||||
|
value.clear();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
//U32 const std::string &display_name, LLAssetStorage::LLStoreAssetCallback callback, S32 expected_upload_cost, void *userdata)
|
||||||
|
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(DOFloaterHex* floater, LLTransactionID transaction_id)
|
||||||
|
: mFloater(floater), mTransactionID(transaction_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DOFloaterHex* mFloater;
|
||||||
|
LLTransactionID mTransactionID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterHex::onClickSave(void* user_data)
|
||||||
|
{
|
||||||
|
DOFloaterHex* floater = (DOFloaterHex*)user_data;
|
||||||
|
LLInventoryItem* item = floater->mItem;
|
||||||
|
|
||||||
|
LLTransactionID transaction_id;
|
||||||
|
transaction_id.generate();
|
||||||
|
LLUUID fake_asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID());
|
||||||
|
|
||||||
|
std::vector<U8> value = floater->mEditor->getValue();
|
||||||
|
int size = value.size();
|
||||||
|
U8* buffer = new U8[size];
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
buffer[i] = value[i];
|
||||||
|
value.clear();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
|
||||||
|
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 DOFloaterHex::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
|
||||||
|
{
|
||||||
|
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||||
|
DOFloaterHex* 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>
|
||||||
53
indra/newview/dofloaterhex.h
Normal file
53
indra/newview/dofloaterhex.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @file dofloaterhex.h
|
||||||
|
* @brief Hex Editor Floater made by Day
|
||||||
|
* @author Day Oh
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=WTFPLV2$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DO_DOFLOATERHEX_H
|
||||||
|
#define DO_DOFLOATERHEX_H
|
||||||
|
|
||||||
|
#include "llfloater.h"
|
||||||
|
#include "dohexeditor.h"
|
||||||
|
#include "llinventory.h"
|
||||||
|
#include "llviewerimage.h"
|
||||||
|
|
||||||
|
class DOFloaterHex
|
||||||
|
: public LLFloater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DOFloaterHex(LLInventoryItem* item);
|
||||||
|
static void show(LLUUID item_id);
|
||||||
|
BOOL postBuild(void);
|
||||||
|
void close(bool app_quitting);
|
||||||
|
static void imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata);
|
||||||
|
static void assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status);
|
||||||
|
static void onClickSave(void* user_data);
|
||||||
|
static void onClickUpload(void* user_data);
|
||||||
|
static void onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||||
|
LLInventoryItem* mItem;
|
||||||
|
DOHexEditor* mEditor;
|
||||||
|
static std::list<DOFloaterHex*> sInstances;
|
||||||
|
private:
|
||||||
|
virtual ~DOFloaterHex();
|
||||||
|
protected:
|
||||||
|
static S32 sUploadAmount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// </edit>
|
||||||
1238
indra/newview/dohexeditor.cpp
Normal file
1238
indra/newview/dohexeditor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
152
indra/newview/dohexeditor.h
Normal file
152
indra/newview/dohexeditor.h
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* @file dohexeditor.h
|
||||||
|
* @brief DOHexEditor Widget
|
||||||
|
* @author Day Oh
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=WTFPLV2$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
#ifndef DO_DOHEXEDITOR_H
|
||||||
|
#define DO_DOHEXEDITOR_H
|
||||||
|
|
||||||
|
#include "lluictrl.h"
|
||||||
|
#include "llscrollbar.h"
|
||||||
|
#include "llviewborder.h"
|
||||||
|
#include "llundo.h"
|
||||||
|
#include "lleditmenuhandler.h"
|
||||||
|
|
||||||
|
class DOHexEditor : public LLUICtrl, public LLEditMenuHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DOHexEditor(const std::string& name, const LLRect& rect);
|
||||||
|
~DOHexEditor();
|
||||||
|
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory);
|
||||||
|
void setValue(const LLSD& value);
|
||||||
|
LLSD getValue() const;
|
||||||
|
void setColumns(U8 columns);
|
||||||
|
U8 getColumns(U8 columns) { return mColumns; };
|
||||||
|
U32 getLineCount();
|
||||||
|
F32 getSuggestedWidth();
|
||||||
|
U32 getProperSelectionStart();
|
||||||
|
U32 getProperSelectionEnd();
|
||||||
|
void reshape(S32 width, S32 height, BOOL called_from_parent);
|
||||||
|
void setFocus(BOOL b);
|
||||||
|
|
||||||
|
BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||||
|
BOOL handleMouseDown(S32 x, S32 y, MASK mask);
|
||||||
|
BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||||
|
BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||||
|
|
||||||
|
BOOL handleKeyHere(KEY key, MASK mask);
|
||||||
|
BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
|
||||||
|
BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
|
||||||
|
BOOL handleUnicodeCharHere(llwchar uni_char);
|
||||||
|
|
||||||
|
void draw();
|
||||||
|
|
||||||
|
void moveCursor(U32 pos, BOOL second_nibble);
|
||||||
|
|
||||||
|
void insert(U32 pos, std::vector<U8> new_data, BOOL undoable);
|
||||||
|
void overwrite(U32 first_pos, U32 last_pos, std::vector<U8> new_data, BOOL undoable);
|
||||||
|
void del(U32 first_pos, U32 last_pos, BOOL undoable);
|
||||||
|
|
||||||
|
virtual void cut();
|
||||||
|
virtual BOOL canCut() const;
|
||||||
|
|
||||||
|
virtual void copy();
|
||||||
|
virtual BOOL canCopy() const;
|
||||||
|
|
||||||
|
virtual void paste();
|
||||||
|
virtual BOOL canPaste() const;
|
||||||
|
|
||||||
|
virtual void doDelete();
|
||||||
|
virtual BOOL canDoDelete() const;
|
||||||
|
|
||||||
|
virtual void selectAll();
|
||||||
|
virtual BOOL canSelectAll() const;
|
||||||
|
|
||||||
|
virtual void deselect();
|
||||||
|
virtual BOOL canDeselect() const;
|
||||||
|
|
||||||
|
virtual void undo();
|
||||||
|
virtual BOOL canUndo() const;
|
||||||
|
|
||||||
|
virtual void redo();
|
||||||
|
virtual BOOL canRedo() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<U8> mValue;
|
||||||
|
U8 mColumns;
|
||||||
|
|
||||||
|
U32 mCursorPos;
|
||||||
|
BOOL mSecondNibble;
|
||||||
|
BOOL mInData;
|
||||||
|
BOOL mSelecting;
|
||||||
|
BOOL mHasSelection;
|
||||||
|
U32 mSelectionStart;
|
||||||
|
U32 mSelectionEnd;
|
||||||
|
|
||||||
|
LLFontGL* mGLFont;
|
||||||
|
LLRect mTextRect;
|
||||||
|
LLScrollbar* mScrollbar;
|
||||||
|
LLViewBorder* mBorder;
|
||||||
|
|
||||||
|
LLUndoBuffer* mUndoBuffer;
|
||||||
|
|
||||||
|
void changedLength();
|
||||||
|
void getPosAndContext(S32 x, S32 y, BOOL force_context, U32& pos, BOOL& in_data, BOOL& second_nibble);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOUndoHex : public LLUndoBuffer::LLUndoAction
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
DOUndoHex() { }
|
||||||
|
DOHexEditor* mHexEditor;
|
||||||
|
U32 mFirstPos;
|
||||||
|
U32 mLastPos;
|
||||||
|
std::vector<U8> mOldData;
|
||||||
|
std::vector<U8> mNewData;
|
||||||
|
public:
|
||||||
|
static LLUndoAction* create() { return new DOUndoHex(); }
|
||||||
|
virtual void set(DOHexEditor* hex_editor,
|
||||||
|
void (*undo_action)(DOUndoHex*),
|
||||||
|
void (*redo_action)(DOUndoHex*),
|
||||||
|
U32 first_pos,
|
||||||
|
U32 last_pos,
|
||||||
|
std::vector<U8> old_data,
|
||||||
|
std::vector<U8> new_data);
|
||||||
|
void (*mUndoAction)(DOUndoHex*);
|
||||||
|
void (*mRedoAction)(DOUndoHex*);
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
|
||||||
|
static void undoInsert(DOUndoHex* action);
|
||||||
|
static void redoInsert(DOUndoHex* action);
|
||||||
|
static void undoOverwrite(DOUndoHex* action);
|
||||||
|
static void redoOverwrite(DOUndoHex* action);
|
||||||
|
static void undoDel(DOUndoHex* action);
|
||||||
|
static void redoDel(DOUndoHex* action);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOHexInsert : public DOUndoHex
|
||||||
|
{
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOHexOverwrite : public DOUndoHex
|
||||||
|
{
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOHexDel : public DOUndoHex
|
||||||
|
{
|
||||||
|
virtual void undo();
|
||||||
|
virtual void redo();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// </edit>
|
||||||
786
indra/newview/doinventorybackup.cpp
Normal file
786
indra/newview/doinventorybackup.cpp
Normal file
@@ -0,0 +1,786 @@
|
|||||||
|
/**
|
||||||
|
* @file doinventorybackup.cpp
|
||||||
|
* @brief DOInventoryBackup Floaters and Inventory Backup System
|
||||||
|
* @author Day Oh
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=WTFPLV2$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "doinventorybackup.h"
|
||||||
|
#include "llinventorymodel.h"
|
||||||
|
#include "llviewerinventory.h"
|
||||||
|
#include "llfilepicker.h"
|
||||||
|
#include "lldirpicker.h"
|
||||||
|
#include "llviewerimage.h"
|
||||||
|
#include "llviewerimagelist.h" // gImageList
|
||||||
|
#include "llagent.h" // gAgent
|
||||||
|
#include "llviewerwindow.h" // gViewerWindow
|
||||||
|
#include "llfloater.h"
|
||||||
|
#include "lluictrlfactory.h"
|
||||||
|
#include "llscrolllistctrl.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::list<DOFloaterInventoryBackup*> DOFloaterInventoryBackup::sInstances;
|
||||||
|
|
||||||
|
DOInventoryBackupOrder::DOInventoryBackupOrder()
|
||||||
|
{
|
||||||
|
// My personal defaults based on what is assumed to not work
|
||||||
|
mDownloadTextures = true;
|
||||||
|
mDownloadSounds = true;
|
||||||
|
mDownloadCallingCards = false;
|
||||||
|
mDownloadLandmarks = true;
|
||||||
|
mDownloadScripts = true;
|
||||||
|
mDownloadWearables = true;
|
||||||
|
mDownloadObjects = false;
|
||||||
|
mDownloadNotecards = true;
|
||||||
|
mDownloadAnimations = true;
|
||||||
|
mDownloadGestures = true;
|
||||||
|
//mDownloadOthers = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOFloaterInventoryBackupSettings::DOFloaterInventoryBackupSettings(DOInventoryBackupOrder* order)
|
||||||
|
: LLFloater(),
|
||||||
|
mOrder(order)
|
||||||
|
{
|
||||||
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_backup_settings.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
DOFloaterInventoryBackupSettings::~DOFloaterInventoryBackupSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DOFloaterInventoryBackupSettings::postBuild(void)
|
||||||
|
{
|
||||||
|
childSetValue("chk_textures", mOrder->mDownloadTextures);
|
||||||
|
childSetValue("chk_sounds", mOrder->mDownloadSounds);
|
||||||
|
childSetValue("chk_callingcards", mOrder->mDownloadCallingCards);
|
||||||
|
childSetValue("chk_landmarks", mOrder->mDownloadLandmarks);
|
||||||
|
childSetValue("chk_scripts", mOrder->mDownloadScripts);
|
||||||
|
childSetValue("chk_wearables", mOrder->mDownloadWearables);
|
||||||
|
childSetValue("chk_objects", mOrder->mDownloadObjects);
|
||||||
|
childSetValue("chk_notecards", mOrder->mDownloadNotecards);
|
||||||
|
childSetValue("chk_animations", mOrder->mDownloadAnimations);
|
||||||
|
childSetValue("chk_gestures", mOrder->mDownloadGestures);
|
||||||
|
//childSetValue("chk_others", mOrder->mDownloadOthers);
|
||||||
|
|
||||||
|
childSetAction("next_btn", DOFloaterInventoryBackupSettings::onClickNext, this);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterInventoryBackupSettings::onClickNext(void* userdata)
|
||||||
|
{
|
||||||
|
DOFloaterInventoryBackupSettings* floater = (DOFloaterInventoryBackupSettings*)userdata;
|
||||||
|
DOInventoryBackupOrder* order = floater->mOrder;
|
||||||
|
|
||||||
|
// Apply changes to filters
|
||||||
|
order->mDownloadAnimations = floater->childGetValue("chk_animations");
|
||||||
|
order->mDownloadCallingCards = floater->childGetValue("chk_callingcards");
|
||||||
|
order->mDownloadGestures = floater->childGetValue("chk_gestures");
|
||||||
|
order->mDownloadLandmarks = floater->childGetValue("chk_landmarks");
|
||||||
|
order->mDownloadNotecards = floater->childGetValue("chk_notecards");
|
||||||
|
order->mDownloadObjects = floater->childGetValue("chk_objects");
|
||||||
|
//order->mDownloadOthers = floater->childGetValue("chk_others");
|
||||||
|
order->mDownloadScripts = floater->childGetValue("chk_scripts");
|
||||||
|
order->mDownloadSounds = floater->childGetValue("chk_sounds");
|
||||||
|
order->mDownloadTextures = floater->childGetValue("chk_textures");
|
||||||
|
order->mDownloadWearables = floater->childGetValue("chk_wearables");
|
||||||
|
|
||||||
|
// Make filters
|
||||||
|
std::map<LLAssetType::EType, bool> type_remove;
|
||||||
|
type_remove[LLAssetType::AT_ANIMATION] = !order->mDownloadAnimations;
|
||||||
|
type_remove[LLAssetType::AT_BODYPART] = !order->mDownloadWearables;
|
||||||
|
type_remove[LLAssetType::AT_CALLINGCARD] = !order->mDownloadCallingCards;
|
||||||
|
type_remove[LLAssetType::AT_CLOTHING] = !order->mDownloadWearables;
|
||||||
|
type_remove[LLAssetType::AT_GESTURE] = !order->mDownloadGestures;
|
||||||
|
type_remove[LLAssetType::AT_IMAGE_JPEG] = !order->mDownloadTextures;
|
||||||
|
type_remove[LLAssetType::AT_IMAGE_TGA] = !order->mDownloadTextures;
|
||||||
|
type_remove[LLAssetType::AT_LANDMARK] = !order->mDownloadLandmarks;
|
||||||
|
type_remove[LLAssetType::AT_LSL_TEXT] = !order->mDownloadScripts;
|
||||||
|
type_remove[LLAssetType::AT_NOTECARD] = !order->mDownloadNotecards;
|
||||||
|
type_remove[LLAssetType::AT_OBJECT] = !order->mDownloadObjects;
|
||||||
|
type_remove[LLAssetType::AT_SCRIPT] = !order->mDownloadScripts;
|
||||||
|
type_remove[LLAssetType::AT_SOUND] = !order->mDownloadSounds;
|
||||||
|
type_remove[LLAssetType::AT_SOUND_WAV] = !order->mDownloadSounds;
|
||||||
|
type_remove[LLAssetType::AT_TEXTURE] = !order->mDownloadTextures;
|
||||||
|
type_remove[LLAssetType::AT_TEXTURE_TGA] = !order->mDownloadTextures;
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
std::vector<LLInventoryItem*>::iterator item_iter = order->mItems.begin();
|
||||||
|
for( ; item_iter != order->mItems.end(); )
|
||||||
|
{
|
||||||
|
if(type_remove[(*item_iter)->getType()])
|
||||||
|
order->mItems.erase(item_iter);
|
||||||
|
else
|
||||||
|
++item_iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(order->mItems.size() < 1)
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
args["ERROR_MESSAGE"] = "No items passed the filter \\o/";
|
||||||
|
LLNotifications::instance().add("ErrorMessage", args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get dir name
|
||||||
|
LLDirPicker& picker = LLDirPicker::instance();
|
||||||
|
std::string filename = "New Folder";
|
||||||
|
if (!picker.getDir(&filename))
|
||||||
|
{
|
||||||
|
floater->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
filename = picker.getDirName();
|
||||||
|
|
||||||
|
// Make local directory tree
|
||||||
|
LLFile::mkdir(filename);
|
||||||
|
std::vector<LLInventoryCategory*>::iterator _cat_iter = order->mCats.begin();
|
||||||
|
std::vector<LLInventoryCategory*>::iterator _cat_end = order->mCats.end();
|
||||||
|
for( ; _cat_iter != _cat_end; ++_cat_iter)
|
||||||
|
{
|
||||||
|
std::string path = filename + "\\" + DOInventoryBackup::getPath(*_cat_iter, order->mCats);
|
||||||
|
LLFile::mkdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go go backup floater
|
||||||
|
DOFloaterInventoryBackup* backup_floater = new DOFloaterInventoryBackup(filename, order->mCats, order->mItems);
|
||||||
|
backup_floater->center();
|
||||||
|
|
||||||
|
// Close myself
|
||||||
|
floater->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool DOInventoryBackup::itemIsFolder(LLInventoryItem* item)
|
||||||
|
{
|
||||||
|
return ((item->getInventoryType() == LLInventoryType::IT_CATEGORY)
|
||||||
|
|| (item->getInventoryType() == LLInventoryType::IT_ROOT_CATEGORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
LLFilePicker::ESaveFilter DOInventoryBackup::getSaveFilter(LLInventoryItem* item)
|
||||||
|
{
|
||||||
|
LLAssetType::EType type = item->getType();
|
||||||
|
EWearableType wear = (EWearableType)(item->getFlags() & 0xFF);
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case LLAssetType::AT_TEXTURE:
|
||||||
|
return LLFilePicker::FFSAVE_TGA;
|
||||||
|
case LLAssetType::AT_SOUND:
|
||||||
|
return LLFilePicker::FFSAVE_OGG;
|
||||||
|
case LLAssetType::AT_SCRIPT:
|
||||||
|
case LLAssetType::AT_LSL_TEXT:
|
||||||
|
return LLFilePicker::FFSAVE_LSL;
|
||||||
|
case LLAssetType::AT_ANIMATION:
|
||||||
|
return LLFilePicker::FFSAVE_ANIMATN;
|
||||||
|
case LLAssetType::AT_GESTURE:
|
||||||
|
return LLFilePicker::FFSAVE_GESTURE;
|
||||||
|
case LLAssetType::AT_NOTECARD:
|
||||||
|
return LLFilePicker::FFSAVE_NOTECARD;
|
||||||
|
case LLAssetType::AT_LANDMARK:
|
||||||
|
return LLFilePicker::FFSAVE_LANDMARK;
|
||||||
|
case LLAssetType::AT_BODYPART:
|
||||||
|
case LLAssetType::AT_CLOTHING:
|
||||||
|
switch(wear)
|
||||||
|
{
|
||||||
|
case WT_EYES:
|
||||||
|
return LLFilePicker::FFSAVE_EYES;
|
||||||
|
case WT_GLOVES:
|
||||||
|
return LLFilePicker::FFSAVE_GLOVES;
|
||||||
|
case WT_HAIR:
|
||||||
|
return LLFilePicker::FFSAVE_HAIR;
|
||||||
|
case WT_JACKET:
|
||||||
|
return LLFilePicker::FFSAVE_JACKET;
|
||||||
|
case WT_PANTS:
|
||||||
|
return LLFilePicker::FFSAVE_PANTS;
|
||||||
|
case WT_SHAPE:
|
||||||
|
return LLFilePicker::FFSAVE_SHAPE;
|
||||||
|
case WT_SHIRT:
|
||||||
|
return LLFilePicker::FFSAVE_SHIRT;
|
||||||
|
case WT_SHOES:
|
||||||
|
return LLFilePicker::FFSAVE_SHOES;
|
||||||
|
case WT_SKIN:
|
||||||
|
return LLFilePicker::FFSAVE_SKIN;
|
||||||
|
case WT_SKIRT:
|
||||||
|
return LLFilePicker::FFSAVE_SKIRT;
|
||||||
|
case WT_SOCKS:
|
||||||
|
return LLFilePicker::FFSAVE_SOCKS;
|
||||||
|
case WT_UNDERPANTS:
|
||||||
|
return LLFilePicker::FFSAVE_UNDERPANTS;
|
||||||
|
case WT_UNDERSHIRT:
|
||||||
|
return LLFilePicker::FFSAVE_UNDERSHIRT;
|
||||||
|
default:
|
||||||
|
return LLFilePicker::FFSAVE_ALL;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return LLFilePicker::FFSAVE_ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string DOInventoryBackup::getExtension(LLInventoryItem* item)
|
||||||
|
{
|
||||||
|
LLAssetType::EType type = item->getType();
|
||||||
|
EWearableType wear = (EWearableType)(item->getFlags() & 0xFF);
|
||||||
|
std::string scratch;
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case LLAssetType::AT_TEXTURE:
|
||||||
|
return ".tga";
|
||||||
|
case LLAssetType::AT_SOUND:
|
||||||
|
return ".ogg";
|
||||||
|
case LLAssetType::AT_SCRIPT:
|
||||||
|
case LLAssetType::AT_LSL_TEXT:
|
||||||
|
return ".lsl";
|
||||||
|
case LLAssetType::AT_ANIMATION:
|
||||||
|
return ".animatn";
|
||||||
|
case LLAssetType::AT_GESTURE:
|
||||||
|
return ".gesture";
|
||||||
|
case LLAssetType::AT_NOTECARD:
|
||||||
|
return ".notecard";
|
||||||
|
case LLAssetType::AT_LANDMARK:
|
||||||
|
return ".landmark";
|
||||||
|
case LLAssetType::AT_BODYPART:
|
||||||
|
case LLAssetType::AT_CLOTHING:
|
||||||
|
scratch = LLWearable::typeToTypeName(wear);
|
||||||
|
if(scratch == "invalid")
|
||||||
|
{
|
||||||
|
if(type == LLAssetType::AT_BODYPART)
|
||||||
|
scratch = "bodypart";
|
||||||
|
else
|
||||||
|
scratch = "clothing";
|
||||||
|
}
|
||||||
|
return "." + scratch;
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string DOInventoryBackup::getUniqueFilename(std::string filename, std::string extension)
|
||||||
|
{
|
||||||
|
if(LLFile::isfile( (filename + extension).c_str() ))
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
while(LLFile::isfile( (filename + llformat(" %d", i) + extension).c_str() ))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return filename + llformat(" %d", i) + extension;
|
||||||
|
}
|
||||||
|
return filename + extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string DOInventoryBackup::getUniqueDirname(std::string dirname)
|
||||||
|
{
|
||||||
|
if(LLFile::isdir(dirname.c_str()))
|
||||||
|
{
|
||||||
|
int i = 1;
|
||||||
|
while(LLFile::isdir( (dirname + llformat(" %d", i)).c_str() ))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return dirname + llformat(" %d", i);
|
||||||
|
}
|
||||||
|
return dirname;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOInventoryBackup::download(LLInventoryItem* item, LLFloater* floater, loaded_callback_func onImage, LLGetAssetCallback onAsset)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* userdata = new DOInventoryBackup::callbackdata();
|
||||||
|
userdata->floater = floater;
|
||||||
|
userdata->item = item;
|
||||||
|
LLViewerImage* imagep;
|
||||||
|
|
||||||
|
//don't be a jerk. (this check probably breaks stuff)
|
||||||
|
if(item->getCreatorUUID() == gAgentID)
|
||||||
|
{
|
||||||
|
switch(item->getType())
|
||||||
|
{
|
||||||
|
case LLAssetType::AT_TEXTURE:
|
||||||
|
imagep = gImageList.getImage(item->getAssetUUID(), MIPMAP_TRUE, TRUE);
|
||||||
|
imagep->setLoadedCallbackNoAux( onImage, 0, TRUE, FALSE, userdata );
|
||||||
|
break;
|
||||||
|
case LLAssetType::AT_NOTECARD:
|
||||||
|
case LLAssetType::AT_SCRIPT:
|
||||||
|
case LLAssetType::AT_LSL_TEXT: // normal script download
|
||||||
|
case LLAssetType::AT_LSL_BYTECODE:
|
||||||
|
gAssetStorage->getInvItemAsset(LLHost::invalid,
|
||||||
|
gAgent.getID(),
|
||||||
|
gAgent.getSessionID(),
|
||||||
|
item->getPermissions().getOwner(),
|
||||||
|
LLUUID::null,
|
||||||
|
item->getUUID(),
|
||||||
|
item->getAssetUUID(),
|
||||||
|
item->getType(),
|
||||||
|
onAsset,
|
||||||
|
userdata, // user_data
|
||||||
|
TRUE);
|
||||||
|
break;
|
||||||
|
case LLAssetType::AT_SOUND:
|
||||||
|
case LLAssetType::AT_CLOTHING:
|
||||||
|
case LLAssetType::AT_BODYPART:
|
||||||
|
case LLAssetType::AT_ANIMATION:
|
||||||
|
case LLAssetType::AT_GESTURE:
|
||||||
|
default:
|
||||||
|
gAssetStorage->getAssetData(item->getAssetUUID(), item->getType(), onAsset, userdata, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOInventoryBackup::imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata)
|
||||||
|
{
|
||||||
|
if(final)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(userdata);
|
||||||
|
LLInventoryItem* item = data->item;
|
||||||
|
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
args["ERROR_MESSAGE"] = "Download didn't work on " + item->getName() + ".";
|
||||||
|
LLNotifications::instance().add("ErrorMessage", args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||||
|
if( !file_picker.getSaveFile( getSaveFilter(item), LLDir::getScrubbedFileName(item->getName())) )
|
||||||
|
{
|
||||||
|
// User canceled or we failed to acquire save file.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// remember the user-approved/edited file name.
|
||||||
|
std::string filename = file_picker.getFirstFile();
|
||||||
|
|
||||||
|
LLPointer<LLImageTGA> image_tga = new LLImageTGA;
|
||||||
|
if( !image_tga->encode( src ) )
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
args["ERROR_MESSAGE"] = "Couldn't encode file.";
|
||||||
|
LLNotifications::instance().add("ErrorMessage", args);
|
||||||
|
}
|
||||||
|
else if( !image_tga->save( filename ) )
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
args["ERROR_MESSAGE"] = "Couldn't write file.";
|
||||||
|
LLNotifications::instance().add("ErrorMessage", args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_vi->setBoostLevel(LLViewerImageBoostLevel::BOOST_UI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOInventoryBackup::assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(user_data);
|
||||||
|
LLInventoryItem* item = data->item;
|
||||||
|
|
||||||
|
if(status != 0)
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
args["ERROR_MESSAGE"] = "Download didn't work on " + item->getName() + ".";
|
||||||
|
LLNotifications::instance().add("ErrorMessage", args);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: this doesn't work for static vfs shit
|
||||||
|
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||||
|
S32 size = file.getSize();
|
||||||
|
|
||||||
|
char* buffer = new char[size];
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
llerrs << "Memory Allocation Failed" << llendl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.read((U8*)buffer, size);
|
||||||
|
|
||||||
|
// Write it back out...
|
||||||
|
|
||||||
|
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||||
|
if( !file_picker.getSaveFile( getSaveFilter(item), LLDir::getScrubbedFileName(item->getName())) )
|
||||||
|
{
|
||||||
|
// User canceled or we failed to acquire save file.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// remember the user-approved/edited file name.
|
||||||
|
std::string filename = file_picker.getFirstFile();
|
||||||
|
|
||||||
|
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||||
|
export_file.write(buffer, size);
|
||||||
|
export_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOInventoryBackup::climb(LLInventoryCategory* cat,
|
||||||
|
std::vector<LLInventoryCategory*>& cats,
|
||||||
|
std::vector<LLInventoryItem*>& items)
|
||||||
|
{
|
||||||
|
LLInventoryModel* model = &gInventory;
|
||||||
|
|
||||||
|
// Add this category
|
||||||
|
cats.push_back(cat);
|
||||||
|
|
||||||
|
LLInventoryModel::cat_array_t *direct_cats;
|
||||||
|
LLInventoryModel::item_array_t *direct_items;
|
||||||
|
model->getDirectDescendentsOf(cat->getUUID(), direct_cats, direct_items);
|
||||||
|
|
||||||
|
// Add items
|
||||||
|
LLInventoryModel::item_array_t::iterator item_iter = direct_items->begin();
|
||||||
|
LLInventoryModel::item_array_t::iterator item_end = direct_items->end();
|
||||||
|
for( ; item_iter != item_end; ++item_iter)
|
||||||
|
{
|
||||||
|
items.push_back(*item_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do subcategories
|
||||||
|
LLInventoryModel::cat_array_t::iterator cat_iter = direct_cats->begin();
|
||||||
|
LLInventoryModel::cat_array_t::iterator cat_end = direct_cats->end();
|
||||||
|
for( ; cat_iter != cat_end; ++cat_iter)
|
||||||
|
{
|
||||||
|
climb(*cat_iter, cats, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string DOInventoryBackup::getPath(LLInventoryCategory* cat, std::vector<LLInventoryCategory*> cats)
|
||||||
|
{
|
||||||
|
LLInventoryModel* model = &gInventory;
|
||||||
|
std::string path = LLDir::getScrubbedFileName(cat->getName());
|
||||||
|
LLInventoryCategory* parent = model->getCategory(cat->getParentUUID());
|
||||||
|
while(parent && (std::find(cats.begin(), cats.end(), parent) != cats.end()))
|
||||||
|
{
|
||||||
|
path = LLDir::getScrubbedFileName(parent->getName()) + "\\" + path;
|
||||||
|
parent = model->getCategory(parent->getParentUUID());
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOInventoryBackup::save(LLFolderView* folder)
|
||||||
|
{
|
||||||
|
LLInventoryModel* model = &gInventory;
|
||||||
|
|
||||||
|
std::set<LLUUID> selected_items;
|
||||||
|
folder->getSelectionList(selected_items);
|
||||||
|
|
||||||
|
if(selected_items.size() < 1)
|
||||||
|
{
|
||||||
|
// No items selected? Omg
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(selected_items.size() == 1)
|
||||||
|
{
|
||||||
|
// One item. See if it's a folder
|
||||||
|
LLUUID id = *(selected_items.begin());
|
||||||
|
LLInventoryItem* item = model->getItem(id);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
if(!itemIsFolder(item))
|
||||||
|
{
|
||||||
|
// Single item, save it now
|
||||||
|
DOInventoryBackup::download((LLViewerInventoryItem*)item, NULL, imageCallback, assetCallback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got here? We need to save multiple items or at least make a folder
|
||||||
|
|
||||||
|
std::vector<LLInventoryCategory*> cats;
|
||||||
|
std::vector<LLInventoryItem*> items;
|
||||||
|
|
||||||
|
// Make complete lists of child categories and items
|
||||||
|
std::set<LLUUID>::iterator sel_iter = selected_items.begin();
|
||||||
|
std::set<LLUUID>::iterator sel_end = selected_items.end();
|
||||||
|
for( ; sel_iter != sel_end; ++sel_iter)
|
||||||
|
{
|
||||||
|
LLInventoryCategory* cat = model->getCategory(*sel_iter);
|
||||||
|
if(cat)
|
||||||
|
{
|
||||||
|
climb(cat, cats, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And what about items inside a folder that wasn't selected?
|
||||||
|
// I guess I will just add selected items, so long as they aren't already added
|
||||||
|
for(sel_iter = selected_items.begin(); sel_iter != sel_end; ++sel_iter)
|
||||||
|
{
|
||||||
|
LLInventoryItem* item = model->getItem(*sel_iter);
|
||||||
|
if(item)
|
||||||
|
{
|
||||||
|
if(std::find(items.begin(), items.end(), item) == items.end())
|
||||||
|
{
|
||||||
|
items.push_back(item);
|
||||||
|
LLInventoryCategory* parent = model->getCategory(item->getParentUUID());
|
||||||
|
if(std::find(cats.begin(), cats.end(), parent) == cats.end())
|
||||||
|
{
|
||||||
|
cats.push_back(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DOInventoryBackupOrder* order = new DOInventoryBackupOrder();
|
||||||
|
order->mCats = cats;
|
||||||
|
order->mItems = items;
|
||||||
|
DOFloaterInventoryBackupSettings* floater = new DOFloaterInventoryBackupSettings(order);
|
||||||
|
floater->center();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DOFloaterInventoryBackup::DOFloaterInventoryBackup(std::string path, std::vector<LLInventoryCategory*> cats, std::vector<LLInventoryItem*> items)
|
||||||
|
: LLFloater(),
|
||||||
|
mPath(path),
|
||||||
|
mCats(cats),
|
||||||
|
mItems(items),
|
||||||
|
mBusy(0)
|
||||||
|
{
|
||||||
|
mItemsTotal = mItems.size();
|
||||||
|
mItemsCompleted = 0;
|
||||||
|
|
||||||
|
DOFloaterInventoryBackup::sInstances.push_back(this);
|
||||||
|
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inventory_backup.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DOFloaterInventoryBackup::~DOFloaterInventoryBackup()
|
||||||
|
{
|
||||||
|
DOFloaterInventoryBackup::sInstances.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL DOFloaterInventoryBackup::postBuild(void)
|
||||||
|
{
|
||||||
|
// Make progress bar
|
||||||
|
|
||||||
|
/*
|
||||||
|
LLLineEditor* line = new LLLineEditor(
|
||||||
|
std::string("progress_line"),
|
||||||
|
LLRect(4, 80, 396, 60),
|
||||||
|
std::string("Progress"));
|
||||||
|
line->setEnabled(FALSE);
|
||||||
|
addChild(line);
|
||||||
|
|
||||||
|
LLViewBorder* border = new LLViewBorder(
|
||||||
|
"progress_border",
|
||||||
|
LLRect(4, 79, 395, 60));
|
||||||
|
addChild(border);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Add all items to the list
|
||||||
|
|
||||||
|
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("item_list");
|
||||||
|
|
||||||
|
std::vector<LLInventoryItem*>::iterator item_iter = mItems.begin();
|
||||||
|
std::vector<LLInventoryItem*>::iterator item_end = mItems.end();
|
||||||
|
for( ; item_iter != item_end; ++item_iter)
|
||||||
|
{
|
||||||
|
LLSD element;
|
||||||
|
element["id"] = (*item_iter)->getUUID();
|
||||||
|
|
||||||
|
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||||
|
type_column["column"] = "type";
|
||||||
|
type_column["type"] = "icon";
|
||||||
|
type_column["value"] = "move_down_in.tga"; // FIXME
|
||||||
|
|
||||||
|
LLSD& name_column = element["columns"][LIST_NAME];
|
||||||
|
name_column["column"] = "name";
|
||||||
|
name_column["value"] = (*item_iter)->getName();
|
||||||
|
|
||||||
|
LLSD& status_column = element["columns"][LIST_STATUS];
|
||||||
|
status_column["column"] = "status";
|
||||||
|
status_column["value"] = "Pending";
|
||||||
|
|
||||||
|
list->addElement(element, ADD_BOTTOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup and go!
|
||||||
|
mBusy = 1;
|
||||||
|
mItemIter = mItems.begin();
|
||||||
|
setStatus((*mItemIter)->getUUID(), "Downloading");
|
||||||
|
DOInventoryBackup::download(*mItemIter, this, DOFloaterInventoryBackup::imageCallback, DOFloaterInventoryBackup::assetCallback);
|
||||||
|
advance();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOFloaterInventoryBackup::advance()
|
||||||
|
{
|
||||||
|
while((mItemIter != mItems.end()) && (mBusy < 4))
|
||||||
|
{
|
||||||
|
mBusy++;
|
||||||
|
mItemIter++;
|
||||||
|
if(mItemIter >= mItems.end()) break;
|
||||||
|
setStatus((*mItemIter)->getUUID(), "Downloading");
|
||||||
|
DOInventoryBackup::download(*mItemIter, this, DOFloaterInventoryBackup::imageCallback, DOFloaterInventoryBackup::assetCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOFloaterInventoryBackup::setStatus(LLUUID itemid, std::string status)
|
||||||
|
{
|
||||||
|
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("item_list");
|
||||||
|
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||||
|
std::vector<LLScrollListItem*>::iterator iter = items.begin();
|
||||||
|
std::vector<LLScrollListItem*>::iterator end = items.end();
|
||||||
|
for( ; iter != end; ++iter)
|
||||||
|
{
|
||||||
|
if((*iter)->getUUID() == itemid)
|
||||||
|
{
|
||||||
|
(*iter)->getColumn(LIST_STATUS)->setValue(status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOFloaterInventoryBackup::finishItem(LLUUID itemid, std::string status)
|
||||||
|
{
|
||||||
|
// Update big happy progress bar
|
||||||
|
mItemsCompleted++;
|
||||||
|
LLView* progress_background = getChildView("progress_background", TRUE, TRUE);
|
||||||
|
LLRect rect = progress_background->getRect();
|
||||||
|
float item_count = (float)mItemsTotal;
|
||||||
|
float item_pos = (float)mItemsCompleted;
|
||||||
|
float rect_width = (float)rect.getWidth();
|
||||||
|
float incr = rect_width / item_count;
|
||||||
|
incr *= item_pos;
|
||||||
|
rect.mRight = rect.mLeft + (S32)incr;
|
||||||
|
LLView* progress_foreground = getChildView("progress_foreground", TRUE, TRUE);
|
||||||
|
progress_foreground->setRect(rect);
|
||||||
|
|
||||||
|
if(mItemsCompleted >= mItemsTotal)
|
||||||
|
{
|
||||||
|
childSetText("progress_background", llformat("Completed %d items.", mItemsTotal));
|
||||||
|
childSetVisible("progress_foreground", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update item status
|
||||||
|
setStatus(itemid, status);
|
||||||
|
|
||||||
|
// And advance
|
||||||
|
mBusy--;
|
||||||
|
advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterInventoryBackup::imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata)
|
||||||
|
{
|
||||||
|
if(final)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(userdata);
|
||||||
|
DOFloaterInventoryBackup* floater = (DOFloaterInventoryBackup*)(data->floater);
|
||||||
|
LLInventoryItem* item = data->item;
|
||||||
|
|
||||||
|
if(std::find(DOFloaterInventoryBackup::sInstances.begin(), DOFloaterInventoryBackup::sInstances.end(), floater) == DOFloaterInventoryBackup::sInstances.end())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
floater->finishItem(item->getUUID(), "Failed download");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string filename = floater->mPath + "\\" + DOInventoryBackup::getPath(gInventory.getCategory(item->getParentUUID()), floater->mCats) + "\\" + LLDir::getScrubbedFileName(item->getName());
|
||||||
|
filename = DOInventoryBackup::getUniqueFilename(filename, DOInventoryBackup::getExtension(item));
|
||||||
|
|
||||||
|
LLPointer<LLImageTGA> image_tga = new LLImageTGA;
|
||||||
|
if( !image_tga->encode( src ) )
|
||||||
|
{
|
||||||
|
floater->finishItem(item->getUUID(), "Failed tga encode");
|
||||||
|
}
|
||||||
|
else if( !image_tga->save( filename ) )
|
||||||
|
{
|
||||||
|
floater->finishItem(item->getUUID(), "Failed save");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
floater->finishItem(item->getUUID(), "Done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_vi->setBoostLevel(LLViewerImageBoostLevel::BOOST_UI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void DOFloaterInventoryBackup::assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status)
|
||||||
|
{
|
||||||
|
DOInventoryBackup::callbackdata* data = static_cast<DOInventoryBackup::callbackdata*>(user_data);
|
||||||
|
DOFloaterInventoryBackup* floater = (DOFloaterInventoryBackup*)(data->floater);
|
||||||
|
LLInventoryItem* item = data->item;
|
||||||
|
|
||||||
|
if(std::find(DOFloaterInventoryBackup::sInstances.begin(), DOFloaterInventoryBackup::sInstances.end(), floater) == DOFloaterInventoryBackup::sInstances.end())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(status != 0)
|
||||||
|
{
|
||||||
|
floater->finishItem(item->getUUID(), "Failed download");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: this doesn't work for static vfs shit
|
||||||
|
LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
|
||||||
|
S32 size = file.getSize();
|
||||||
|
|
||||||
|
char* buffer = new char[size];
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
//llerrs << "Memory Allocation Failed" << llendl;
|
||||||
|
floater->finishItem(item->getUUID(), "Failed memory allocation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.read((U8*)buffer, size);
|
||||||
|
|
||||||
|
// Write it back out...
|
||||||
|
std::string filename = floater->mPath + "\\" + DOInventoryBackup::getPath(gInventory.getCategory(item->getParentUUID()), floater->mCats) + "\\" + LLDir::getScrubbedFileName(item->getName());
|
||||||
|
filename = DOInventoryBackup::getUniqueFilename(filename, DOInventoryBackup::getExtension(item));
|
||||||
|
|
||||||
|
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||||
|
export_file.write(buffer, size);
|
||||||
|
export_file.close();
|
||||||
|
|
||||||
|
floater->finishItem(item->getUUID(), "Done");
|
||||||
|
}
|
||||||
|
// </edit>
|
||||||
137
indra/newview/doinventorybackup.h
Normal file
137
indra/newview/doinventorybackup.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**
|
||||||
|
* @file doinventorybackup.h
|
||||||
|
* @brief DOInventoryBackup Floaters and Inventory Backup System
|
||||||
|
* @author Day Oh
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2009&license=WTFPLV2$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
#ifndef DO_DOINVENTORYBACKUP_H
|
||||||
|
#define DO_DOINVENTORYBACKUP_H
|
||||||
|
|
||||||
|
#include "llviewerinventory.h"
|
||||||
|
#include "llfolderview.h"
|
||||||
|
#include "llfilepicker.h"
|
||||||
|
#include "llviewerimage.h"
|
||||||
|
#include "llfloater.h"
|
||||||
|
|
||||||
|
|
||||||
|
class DOInventoryBackupOrder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DOInventoryBackupOrder();
|
||||||
|
|
||||||
|
std::string mPath;
|
||||||
|
std::vector<LLInventoryCategory*> mCats;
|
||||||
|
std::vector<LLInventoryItem*> mItems;
|
||||||
|
|
||||||
|
bool mDownloadTextures;
|
||||||
|
bool mDownloadSounds;
|
||||||
|
bool mDownloadCallingCards;
|
||||||
|
bool mDownloadLandmarks;
|
||||||
|
bool mDownloadScripts;
|
||||||
|
bool mDownloadWearables;
|
||||||
|
bool mDownloadObjects;
|
||||||
|
bool mDownloadNotecards;
|
||||||
|
bool mDownloadAnimations;
|
||||||
|
bool mDownloadGestures;
|
||||||
|
//bool mDownloadOthers;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOFloaterInventoryBackupSettings
|
||||||
|
: public LLFloater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DOFloaterInventoryBackupSettings(DOInventoryBackupOrder* order);
|
||||||
|
BOOL postBuild(void);
|
||||||
|
static void onClickNext(void* userdata);
|
||||||
|
|
||||||
|
DOInventoryBackupOrder* mOrder;
|
||||||
|
virtual ~DOFloaterInventoryBackupSettings();
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOFloaterInventoryBackup
|
||||||
|
: public LLFloater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DOFloaterInventoryBackup(std::string path, std::vector<LLInventoryCategory*> cats, std::vector<LLInventoryItem*> items);
|
||||||
|
BOOL postBuild(void);
|
||||||
|
|
||||||
|
std::string mPath;
|
||||||
|
std::vector<LLInventoryCategory*> mCats;
|
||||||
|
std::vector<LLInventoryItem*> mItems;
|
||||||
|
std::vector<LLInventoryItem*>::iterator mItemIter;
|
||||||
|
int mBusy;
|
||||||
|
|
||||||
|
static std::list<DOFloaterInventoryBackup*> sInstances;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual ~DOFloaterInventoryBackup();
|
||||||
|
void setStatus(LLUUID itemid, std::string status);
|
||||||
|
void finishItem(LLUUID itemid, std::string status);
|
||||||
|
void advance();
|
||||||
|
static void imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata);
|
||||||
|
static void assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status);
|
||||||
|
|
||||||
|
int mItemsTotal;
|
||||||
|
int mItemsCompleted;
|
||||||
|
|
||||||
|
enum LIST_COLUMN_ORDER
|
||||||
|
{
|
||||||
|
LIST_TYPE,
|
||||||
|
LIST_NAME,
|
||||||
|
LIST_STATUS
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class DOInventoryBackup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static LLFilePicker::ESaveFilter getSaveFilter(LLInventoryItem* item);
|
||||||
|
static std::string getExtension(LLInventoryItem* item);
|
||||||
|
static std::string getUniqueFilename(std::string filename, std::string extension);
|
||||||
|
static std::string getUniqueDirname(std::string dirname);
|
||||||
|
static bool itemIsFolder(LLInventoryItem* item);
|
||||||
|
static void save(LLFolderView* folder);
|
||||||
|
static void download(LLInventoryItem* item, LLFloater* floater, loaded_callback_func onImage, LLGetAssetCallback onAsset);
|
||||||
|
static std::string getPath(LLInventoryCategory* cat, std::vector<LLInventoryCategory*> cats);
|
||||||
|
|
||||||
|
struct callbackdata
|
||||||
|
{
|
||||||
|
LLFloater* floater;
|
||||||
|
LLInventoryItem* item;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void imageCallback(BOOL success,
|
||||||
|
LLViewerImage *src_vi,
|
||||||
|
LLImageRaw* src,
|
||||||
|
LLImageRaw* aux_src,
|
||||||
|
S32 discard_level,
|
||||||
|
BOOL final,
|
||||||
|
void* userdata);
|
||||||
|
static void assetCallback(LLVFS *vfs,
|
||||||
|
const LLUUID& asset_uuid,
|
||||||
|
LLAssetType::EType type,
|
||||||
|
void* user_data, S32 status, LLExtStat ext_status);
|
||||||
|
static void climb(LLInventoryCategory* cat,
|
||||||
|
std::vector<LLInventoryCategory*>& cats,
|
||||||
|
std::vector<LLInventoryItem*>& items);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// </edit>
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
## - Avoids using any OpenAL audio driver.
|
## - Avoids using any OpenAL audio driver.
|
||||||
#export LL_BAD_OPENAL_DRIVER=x
|
#export LL_BAD_OPENAL_DRIVER=x
|
||||||
## - Avoids using any FMOD audio driver.
|
## - Avoids using any FMOD audio driver.
|
||||||
#export LL_BAD_FMOD_DRIVER=x
|
export LL_BAD_FMOD_DRIVER=x
|
||||||
|
|
||||||
## - Avoids using the FMOD ESD audio driver.
|
## - Avoids using the FMOD ESD audio driver.
|
||||||
#export LL_BAD_FMOD_ESD=x
|
#export LL_BAD_FMOD_ESD=x
|
||||||
## - Avoids using the FMOD OSS audio driver.
|
## - Avoids using the FMOD OSS audio driver.
|
||||||
#export LL_BAD_FMOD_OSS=x
|
#export LL_BAD_FMOD_OSS=x
|
||||||
## - Avoids using the FMOD ALSA audio driver.
|
## - Avoids using the FMOD ALSA audio driver.
|
||||||
export LL_BAD_FMOD_ALSA=x
|
#export LL_BAD_FMOD_ALSA=x
|
||||||
|
|
||||||
## - Avoids the optional OpenGL extensions which have proven most problematic
|
## - Avoids the optional OpenGL extensions which have proven most problematic
|
||||||
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
|
## on some hardware. Disabling this option may cause BETTER PERFORMANCE but
|
||||||
@@ -114,7 +114,7 @@ if [ -n "$LL_TCMALLOC" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export VIEWER_BINARY='inertia-do-not-run-directly'
|
export VIEWER_BINARY='snowglobe-do-not-run-directly'
|
||||||
export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}"'
|
export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-linux-i686:"${LD_LIBRARY_PATH}"'
|
||||||
export SL_CMD='$LL_WRAPPER bin/$VIEWER_BINARY'
|
export SL_CMD='$LL_WRAPPER bin/$VIEWER_BINARY'
|
||||||
export SL_OPT="`cat gridargs.dat` $@"
|
export SL_OPT="`cat gridargs.dat` $@"
|
||||||
|
|||||||
@@ -51,8 +51,11 @@
|
|||||||
LLFilePicker LLFilePicker::sInstance;
|
LLFilePicker LLFilePicker::sInstance;
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
#define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0"
|
// <edit/>
|
||||||
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
|
#define SOUND_FILTER L"Sounds (*.wav; *.ogg)\0*.wav;*.ogg\0"
|
||||||
|
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png; *.jp2; *.j2k; *.j2c)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png;*.jp2;*.j2k;*.j2c\0"
|
||||||
|
#define INVGZ_FILTER L"Inv cache (*.inv; *.inv.gz)\0*.inv;*.inv.gz\0"
|
||||||
|
// <edit/>
|
||||||
#define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0"
|
#define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0"
|
||||||
#ifdef _CORY_TESTING
|
#ifdef _CORY_TESTING
|
||||||
#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0"
|
#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0"
|
||||||
@@ -192,6 +195,16 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
|
|||||||
mOFN.lpstrFilter = RAW_FILTER \
|
mOFN.lpstrFilter = RAW_FILTER \
|
||||||
L"\0";
|
L"\0";
|
||||||
break;
|
break;
|
||||||
|
// <edit>
|
||||||
|
case FFLOAD_INVGZ:
|
||||||
|
mOFN.lpstrFilter = INVGZ_FILTER \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFLOAD_AO:
|
||||||
|
mOFN.lpstrFilter = AO_FILTER \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
// </edit>
|
||||||
default:
|
default:
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
break;
|
||||||
@@ -451,6 +464,218 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
|
|||||||
L"Compressed Images (*.j2c)\0*.j2c\0" \
|
L"Compressed Images (*.j2c)\0*.j2c\0" \
|
||||||
L"\0";
|
L"\0";
|
||||||
break;
|
break;
|
||||||
|
// <edit>
|
||||||
|
case FFSAVE_ANIMATN:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.animatn", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"animatn";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"SL Animations (*.animatn)\0*.animatn\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_OGG:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.ogg", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"ogg";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Ogg (*.ogg)\0*.ogg\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_NOTECARD:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.notecard", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"notecard";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Notecards (*.notecard)\0*.notecard\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_GESTURE:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.gesture", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"gesture";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Gestures (*.gesture)\0*.gesture\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_LSL:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"lsl";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"LSL (*.lsl)\0*.lsl\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SHAPE:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.shape", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"shape";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Shapes (*.shape)\0*.shape\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SKIN:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.skin", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"skin";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Skins (*.skin)\0*.skin\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_HAIR:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.hair", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"hair";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Hair (*.hair)\0*.hair\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_EYES:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.eyes", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"eyes";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Eyes (*.eyes)\0*.eyes\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SHIRT:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.shirt", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"shirt";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Shirts (*.shirt)\0*.shirt\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_PANTS:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.pants", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"pants";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Pants (*.pants)\0*.pants\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SHOES:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.shoes", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"shoes";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Shoes (*.shoes)\0*.shoes\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SOCKS:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.socks", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"socks";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Socks (*.socks)\0*.socks\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_JACKET:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.jacket", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"jacket";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Jackets (*.jacket)\0*.jacket\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_GLOVES:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.gloves", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"gloves";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Gloves (*.gloves)\0*.gloves\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_UNDERSHIRT:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.undershirt", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"undershirt";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Undershirts (*.undershirt)\0*.undershirt\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_UNDERPANTS:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.underpants", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"underpants";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Underpants (*.underpants)\0*.underpants\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_SKIRT:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.skirt", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"skirt";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Skirts (*.skirt)\0*.skirt\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_LANDMARK:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.landmark", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"landmark";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Landmarks (*.landmark)\0*.landmark\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_AO:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.ao", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L"ao";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"Animation overrides (*.ao)\0*.ao\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
case FFSAVE_INVGZ:
|
||||||
|
if(filename.empty())
|
||||||
|
{
|
||||||
|
wcsncpy( mFilesW,L"untitled.inv", FILENAME_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
mOFN.lpstrDefExt = L".inv";
|
||||||
|
mOFN.lpstrFilter =
|
||||||
|
L"InvCache (*.inv)\0*.inv\0" \
|
||||||
|
L"\0";
|
||||||
|
break;
|
||||||
|
// </edit>
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ public:
|
|||||||
FFLOAD_XML = 6,
|
FFLOAD_XML = 6,
|
||||||
FFLOAD_SLOBJECT = 7,
|
FFLOAD_SLOBJECT = 7,
|
||||||
FFLOAD_RAW = 8,
|
FFLOAD_RAW = 8,
|
||||||
|
// <edit>
|
||||||
|
FFLOAD_INVGZ = 9,
|
||||||
|
FFLOAD_AO = 10,
|
||||||
|
// </edit>
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ESaveFilter
|
enum ESaveFilter
|
||||||
@@ -110,6 +114,30 @@ public:
|
|||||||
FFSAVE_J2C = 12,
|
FFSAVE_J2C = 12,
|
||||||
FFSAVE_PNG = 13,
|
FFSAVE_PNG = 13,
|
||||||
FFSAVE_JPEG = 14,
|
FFSAVE_JPEG = 14,
|
||||||
|
// <edit>
|
||||||
|
FFSAVE_ANIMATN = 15,
|
||||||
|
FFSAVE_OGG = 16,
|
||||||
|
FFSAVE_NOTECARD = 17,
|
||||||
|
FFSAVE_GESTURE = 18,
|
||||||
|
FFSAVE_LSL = 19,
|
||||||
|
// good grief
|
||||||
|
FFSAVE_SHAPE = 20,
|
||||||
|
FFSAVE_SKIN = 21,
|
||||||
|
FFSAVE_HAIR = 22,
|
||||||
|
FFSAVE_EYES = 23,
|
||||||
|
FFSAVE_SHIRT = 24,
|
||||||
|
FFSAVE_PANTS = 25,
|
||||||
|
FFSAVE_SHOES = 26,
|
||||||
|
FFSAVE_SOCKS = 27,
|
||||||
|
FFSAVE_JACKET = 28,
|
||||||
|
FFSAVE_GLOVES = 29,
|
||||||
|
FFSAVE_UNDERSHIRT = 30,
|
||||||
|
FFSAVE_UNDERPANTS = 31,
|
||||||
|
FFSAVE_SKIRT = 32,
|
||||||
|
FFSAVE_INVGZ = 33,
|
||||||
|
FFSAVE_LANDMARK = 34,
|
||||||
|
FFSAVE_AO = 35,
|
||||||
|
// </edit>
|
||||||
};
|
};
|
||||||
|
|
||||||
// open the dialog. This is a modal operation
|
// open the dialog. This is a modal operation
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
#include "lluictrlfactory.h"
|
#include "lluictrlfactory.h"
|
||||||
#include "llselectmgr.h"
|
#include "llselectmgr.h"
|
||||||
#include "llfloateropenobject.h"
|
#include "llfloateropenobject.h"
|
||||||
|
#include "dofloaterhex.h"
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
// bug in busy count inc/dec right now, logic is complex... do we really need it?
|
// bug in busy count inc/dec right now, logic is complex... do we really need it?
|
||||||
@@ -443,6 +444,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, std::vector<std::str
|
|||||||
disabled_items.push_back(std::string("Copy Asset UUID"));
|
disabled_items.push_back(std::string("Copy Asset UUID"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items.push_back(std::string("Open With..."));
|
||||||
|
|
||||||
items.push_back(std::string("Copy Separator"));
|
items.push_back(std::string("Copy Separator"));
|
||||||
|
|
||||||
@@ -764,6 +767,13 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model,
|
|||||||
{
|
{
|
||||||
restoreItem();
|
restoreItem();
|
||||||
}
|
}
|
||||||
|
else if("open hex" == action)
|
||||||
|
{
|
||||||
|
LLInventoryItem* item = model->getItem(mUUID);
|
||||||
|
if(!item) return;
|
||||||
|
if(item->getCreatorUUID() != gAgentID) return;
|
||||||
|
DOFloaterHex::show(mUUID);
|
||||||
|
}
|
||||||
else if ("copy_uuid" == action)
|
else if ("copy_uuid" == action)
|
||||||
{
|
{
|
||||||
// Single item only
|
// Single item only
|
||||||
|
|||||||
@@ -1320,6 +1320,31 @@ void LLViewerImage::setLoadedCallback( loaded_callback_func loaded_callback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this method is stupid, remove it if at all possible -Day
|
||||||
|
void LLViewerImage::setLoadedCallbackNoAux( loaded_callback_func loaded_callback,
|
||||||
|
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Don't do ANYTHING here, just add it to the global callback list
|
||||||
|
//
|
||||||
|
if (mLoadedCallbackList.empty())
|
||||||
|
{
|
||||||
|
// Put in list to call this->doLoadedCallbacks() periodically
|
||||||
|
gImageList.mCallbackList.insert(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata);
|
||||||
|
mLoadedCallbackList.push_back(entryp);
|
||||||
|
mNeedsAux = needs_aux;
|
||||||
|
|
||||||
|
if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
|
||||||
|
{
|
||||||
|
// We need aux data, but we've already loaded the image, and it didn't have any
|
||||||
|
llwarns << "No aux data available for callback for image:" << getID() << llendl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// </edit>
|
||||||
|
|
||||||
bool LLViewerImage::doLoadedCallbacks()
|
bool LLViewerImage::doLoadedCallbacks()
|
||||||
{
|
{
|
||||||
if (mNeedsCreateTexture)
|
if (mNeedsCreateTexture)
|
||||||
|
|||||||
@@ -246,6 +246,12 @@ public:
|
|||||||
void setLoadedCallback(loaded_callback_func cb,
|
void setLoadedCallback(loaded_callback_func cb,
|
||||||
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
|
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
|
||||||
void* userdata);
|
void* userdata);
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
void setLoadedCallbackNoAux(loaded_callback_func cb,
|
||||||
|
S32 discard_level, BOOL keep_imageraw, BOOL needs_aux,
|
||||||
|
void* userdata);
|
||||||
|
// </edit>
|
||||||
|
|
||||||
// ONLY call from LLViewerImageList
|
// ONLY call from LLViewerImageList
|
||||||
BOOL createTexture(S32 usename = 0);
|
BOOL createTexture(S32 usename = 0);
|
||||||
@@ -445,4 +451,6 @@ public:
|
|||||||
static S32 sLLViewerImageCount ;
|
static S32 sLLViewerImageCount ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1092,3 +1092,43 @@ void init_menu_file()
|
|||||||
(new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
|
(new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
|
||||||
(new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
|
(new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <edit>
|
||||||
|
void NewResourceItemCallback::fire(const LLUUID& new_item_id)
|
||||||
|
{
|
||||||
|
LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)gInventory.getItem(new_item_id);
|
||||||
|
if(!new_item) return;
|
||||||
|
LLUUID vfile_id = LLUUID(new_item->getDescription());
|
||||||
|
if(vfile_id.isNull()) return;
|
||||||
|
new_item->setDescription("(No Description)");
|
||||||
|
new_item->updateServer(FALSE);
|
||||||
|
gInventory.updateItem(new_item);
|
||||||
|
gInventory.notifyObservers();
|
||||||
|
|
||||||
|
std::string agent_url;
|
||||||
|
LLSD body;
|
||||||
|
body["item_id"] = new_item_id;
|
||||||
|
|
||||||
|
if(new_item->getType() == LLAssetType::AT_GESTURE)
|
||||||
|
{
|
||||||
|
agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
|
||||||
|
}
|
||||||
|
else if(new_item->getType() == LLAssetType::AT_LSL_TEXT)
|
||||||
|
{
|
||||||
|
agent_url = gAgent.getRegion()->getCapability("UpdateScriptAgent");
|
||||||
|
body["target"] = "lsl2";
|
||||||
|
}
|
||||||
|
else if(new_item->getType() == LLAssetType::AT_NOTECARD)
|
||||||
|
{
|
||||||
|
agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(agent_url.empty()) return;
|
||||||
|
LLHTTPClient::post(agent_url, body,
|
||||||
|
new LLUpdateAgentInventoryResponder(body, vfile_id, new_item->getType()));
|
||||||
|
}
|
||||||
|
// </edit>
|
||||||
|
|||||||
@@ -35,6 +35,14 @@
|
|||||||
|
|
||||||
#include "llassettype.h"
|
#include "llassettype.h"
|
||||||
#include "llinventorytype.h"
|
#include "llinventorytype.h"
|
||||||
|
// <edit>
|
||||||
|
#include "llviewerinventory.h"
|
||||||
|
|
||||||
|
class NewResourceItemCallback : public LLInventoryCallback
|
||||||
|
{
|
||||||
|
void fire(const LLUUID& inv_item);
|
||||||
|
};
|
||||||
|
// </edit>
|
||||||
|
|
||||||
class LLTransactionID;
|
class LLTransactionID;
|
||||||
|
|
||||||
|
|||||||
9
indra/newview/skins/default/xui/en-us/floater_hex.xml
Normal file
9
indra/newview/skins/default/xui/en-us/floater_hex.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
|
<floater can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||||
|
can_resize="true" height="200" width="560" min_width="560" min_height="128"
|
||||||
|
name="floater_hex" title="Hex Editor" rect_control="FloaterHexRect">
|
||||||
|
<text name="status_text" follows="left|top" left="10" top="-25" height="20">Loading...</text>
|
||||||
|
<button name="upload_btn" follows="right|top" top="-25" right="-120" width="100" bottom="155" label="[UPLOAD]" enabled="false"/>
|
||||||
|
<button name="save_btn" follows="right|top" top="-25" right="-10" width="100" bottom="155" label="Save" enabled="false"/>
|
||||||
|
<hex_editor name="hex" follows="left|top|right|bottom" left="10" top="-50" right="-10" bottom="10" visible="false"/>
|
||||||
|
</floater>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
|
<floater can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||||
|
can_resize="true" height="500" width="400" min_width="310" min_height="200"
|
||||||
|
name="floater_inventory_backup" title="Inventory Backup">
|
||||||
|
<scroll_list bottom="60" can_resize="true" column_padding="0" draw_heading="true"
|
||||||
|
follows="left|top|bottom|right" left="10" multi_select="true"
|
||||||
|
name="item_list" right="-10" search_column="1" top="-25">
|
||||||
|
<column name="type" width="20" />
|
||||||
|
<column dynamicwidth="true" label="Name" name="name" />
|
||||||
|
<column dynamicwidth="true" name="status" label="Status" />
|
||||||
|
</scroll_list>
|
||||||
|
|
||||||
|
<line_editor name="progress_background" bottom="10" top="50" height="20" left="10" right="-10"
|
||||||
|
can_resize="true" follows="left|bottom|right" enabled="false" />
|
||||||
|
<line_editor name="progress_foreground" bottom="10" top="50" height="20" left="10" width="0"
|
||||||
|
can_resize="true" follows="left|bottom|right" enabled="false"
|
||||||
|
bg_readonly_color="0.5 0.5 0.5" />
|
||||||
|
</floater>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
|
<floater can_close="true" can_drag_on_left="false" can_minimize="false" can_resize="false"
|
||||||
|
width="200" height="300" name="inventory_backup_settings" title="Download Options">
|
||||||
|
<check_box bottom_delta="-50" follows="left|top" left="10" name="chk_textures" label="Textures" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_sounds" label="Sounds" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_callingcards" label="Calling Cards" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_landmarks" label="Landmarks" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_scripts" label="Scripts" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_wearables" label="Wearables" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_objects" label="Objects" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_notecards" label="Notecards" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_animations" label="Animations" />
|
||||||
|
<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_gestures" label="Gestures" />
|
||||||
|
<!--<check_box bottom_delta="-20" follows="left|top" left="10" name="chk_others" label="Others" />-->
|
||||||
|
<button bottom="10" follows="bottom|left" height="20" label="Next >>"
|
||||||
|
left="110" width="80" name="next_btn" />
|
||||||
|
</floater>
|
||||||
@@ -129,6 +129,14 @@
|
|||||||
mouse_opaque="true" name="Restore Item" width="128">
|
mouse_opaque="true" name="Restore Item" width="128">
|
||||||
<on_click filter="" function="Inventory.DoToSelected" userdata="restore" />
|
<on_click filter="" function="Inventory.DoToSelected" userdata="restore" />
|
||||||
</menu_item_call>
|
</menu_item_call>
|
||||||
|
<menu bottom_delta="0" color="MenuDefaultBgColor" drop_shadow="true" height="175" left="0"
|
||||||
|
mouse_opaque="false" name="Open With..." opaque="true" tear_off="false"
|
||||||
|
width="125">
|
||||||
|
<menu_item_call bottom_delta="-18" height="18" label="Hex Editor" left="0" mouse_opaque="true"
|
||||||
|
name="Hex Open" width="128">
|
||||||
|
<on_click filter="" function="Inventory.DoToSelected" userdata="open hex" />
|
||||||
|
</menu_item_call>
|
||||||
|
</menu>
|
||||||
<menu_item_call bottom_delta="-18" height="18" label="Open" left="0" mouse_opaque="true"
|
<menu_item_call bottom_delta="-18" height="18" label="Open" left="0" mouse_opaque="true"
|
||||||
name="Open" width="128">
|
name="Open" width="128">
|
||||||
<on_click filter="" function="Inventory.DoToSelected" userdata="open" />
|
<on_click filter="" function="Inventory.DoToSelected" userdata="open" />
|
||||||
|
|||||||
Reference in New Issue
Block a user