Added some debugging tools to the preview assets.
This commit is contained in:
@@ -44,6 +44,10 @@
|
||||
#include "lllineeditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluictrlfactory.h"
|
||||
// <edit>
|
||||
#include "llviewerwindow.h" // for alert
|
||||
#include "llappviewer.h" // gStaticVFS
|
||||
// </edit>
|
||||
|
||||
extern LLAgent gAgent;
|
||||
|
||||
@@ -54,6 +58,9 @@ LLPreviewAnim::LLPreviewAnim(const std::string& name, const LLRect& rect, const
|
||||
|
||||
childSetAction("Anim play btn",playAnim,this);
|
||||
childSetAction("Anim audition btn",auditionAnim,this);
|
||||
// <edit>
|
||||
childSetAction("Anim copy uuid btn", copyAnimID, this);
|
||||
// </edit>
|
||||
|
||||
const LLInventoryItem* item = getItem();
|
||||
|
||||
@@ -181,6 +188,242 @@ void LLPreviewAnim::auditionAnim( void *userdata )
|
||||
}
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// static
|
||||
/*
|
||||
void LLPreviewAnim::copyAnim(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForCopy(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, self, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
// Get it from the servers
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForCopy, self, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LLSaveInfo
|
||||
{
|
||||
LLSaveInfo(const LLUUID& item_id, const LLUUID& object_id, const std::string& desc,
|
||||
const LLTransactionID tid)
|
||||
: mItemUUID(item_id), mObjectUUID(object_id), mDesc(desc), mTransactionID(tid)
|
||||
{
|
||||
}
|
||||
|
||||
LLUUID mItemUUID;
|
||||
LLUUID mObjectUUID;
|
||||
std::string mDesc;
|
||||
LLTransactionID mTransactionID;
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
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...
|
||||
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
LLVFile ofile(gVFS, asset_id, LLAssetType::AT_ANIMATION, LLVFile::APPEND);
|
||||
|
||||
ofile.setMaxSize(size);
|
||||
ofile.write((U8*)buffer, size);
|
||||
|
||||
// Upload that asset to the database
|
||||
LLSaveInfo* info = new LLSaveInfo(self->mItemUUID, self->mObjectUUID, "animation", tid);
|
||||
gAssetStorage->storeAssetData(tid, LLAssetType::AT_ANIMATION, onSaveCopyComplete, info, FALSE);
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
std::string item_name = "New Animation";
|
||||
std::string item_desc = "";
|
||||
// Saving into user inventory
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
item_name = item->getName();
|
||||
item_desc = item->getDescription();
|
||||
}
|
||||
gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock);
|
||||
gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, info->mTransactionID);
|
||||
gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 2147483647);
|
||||
gMessageSystem->addS8Fast(_PREHASH_Type, LLAssetType::AT_ANIMATION);
|
||||
gMessageSystem->addS8Fast(_PREHASH_InvType, LLInventoryType::IT_ANIMATION);
|
||||
gMessageSystem->addU8Fast(_PREHASH_WearableType, 0);
|
||||
gMessageSystem->addStringFast(_PREHASH_Name, item_name);
|
||||
gMessageSystem->addStringFast(_PREHASH_Description, item_desc);
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Problem saving animation: " << status << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CannotUploadReason",args);
|
||||
}
|
||||
}
|
||||
*/
|
||||
void LLPreviewAnim::copyAnimID(void *userdata)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item->getAssetUUID().asString()));
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewAnim::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewAnim::saveAs()
|
||||
{
|
||||
const LLInventoryItem *item = getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
// Some animations aren't hosted on the servers
|
||||
// I guess they're in this static vfs thing
|
||||
bool static_vfile = false;
|
||||
LLVFile* anim_file = new LLVFile(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION);
|
||||
if (anim_file && anim_file->getSize())
|
||||
{
|
||||
//S32 anim_file_size = anim_file->getSize();
|
||||
//U8* anim_data = new U8[anim_file_size];
|
||||
//if(anim_file->read(anim_data, anim_file_size))
|
||||
//{
|
||||
// static_vfile = true;
|
||||
//}
|
||||
static_vfile = true; // for method 2
|
||||
LLPreviewAnim::gotAssetForSave(gStaticVFS, item->getAssetUUID(), LLAssetType::AT_ANIMATION, this, 0, 0);
|
||||
}
|
||||
delete anim_file;
|
||||
anim_file = NULL;
|
||||
|
||||
if(!static_vfile)
|
||||
{
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_ANIMATION, LLPreviewAnim::gotAssetForSave, this, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewAnim::gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewAnim* self = (LLPreviewAnim*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
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( LLFilePicker::FFSAVE_ANIMATN, LLDir::getScrubbedFileName(self->getItem()->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();
|
||||
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLUUID LLPreviewAnim::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
void LLPreviewAnim::onClose(bool app_quitting)
|
||||
{
|
||||
const LLInventoryItem *item = getItem();
|
||||
|
||||
@@ -46,10 +46,30 @@ public:
|
||||
|
||||
static void playAnim( void* userdata );
|
||||
static void auditionAnim( void* userdata );
|
||||
// <edit>
|
||||
/*
|
||||
static void copyAnim(void* userdata);
|
||||
static void gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
static void onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
*/
|
||||
static void gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
static void copyAnimID(void* userdata);
|
||||
// </edit>
|
||||
static void endAnimCallback( void *userdata );
|
||||
|
||||
protected:
|
||||
virtual void onClose(bool app_quitting);
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
virtual void saveAs();
|
||||
virtual LLUUID getItemID();
|
||||
// </edit>
|
||||
virtual const char *getTitleName() const { return "Animation"; }
|
||||
|
||||
LLAnimPauseRequest mPauseRequest;
|
||||
|
||||
@@ -70,7 +70,14 @@
|
||||
#include "llappviewer.h" // gVFS
|
||||
#include "llanimstatelabels.h"
|
||||
#include "llresmgr.h"
|
||||
|
||||
// <edit>
|
||||
#include "llviewercontrol.h"
|
||||
#include "llpreviewsound.h"
|
||||
#include "llpreviewanim.h"
|
||||
|
||||
#include "lllocalinventory.h"
|
||||
#include "llfilepicker.h"
|
||||
// </edit>
|
||||
|
||||
// *TODO: Translate?
|
||||
const std::string NONE_LABEL = "---";
|
||||
@@ -163,7 +170,10 @@ LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID&
|
||||
|
||||
// this will call refresh when we have everything.
|
||||
LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
|
||||
if(item && !item->isComplete())
|
||||
// <edit>
|
||||
//if(item && !item->isComplete())
|
||||
if(item && !item->isComplete() && !(gInventory.isObjectDescendentOf(item->getUUID(), gLocalInventoryRoot)))
|
||||
// </edit>
|
||||
{
|
||||
LLInventoryGestureAvailable* observer;
|
||||
observer = new LLInventoryGestureAvailable();
|
||||
@@ -219,19 +229,26 @@ BOOL LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
if (item
|
||||
&& gInventory.getItem(item->getUUID()))
|
||||
{
|
||||
LLPermissions perm = item->getPermissions();
|
||||
if (!((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED))
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
if (tooltip_msg.empty())
|
||||
{
|
||||
tooltip_msg.assign("Only animations and sounds\n"
|
||||
"with unrestricted permissions\n"
|
||||
"can be added to a gesture.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (drop)
|
||||
// <edit>
|
||||
/*
|
||||
// </edit>
|
||||
LLPermissions perm = item->getPermissions();
|
||||
if (!((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED))
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
if (tooltip_msg.empty())
|
||||
{
|
||||
tooltip_msg.assign("Only animations and sounds\n"
|
||||
"with unrestricted permissions\n"
|
||||
"can be added to a gesture.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (drop)
|
||||
// <edit>
|
||||
*/
|
||||
if(drop)
|
||||
// </edit>
|
||||
{
|
||||
LLScrollListItem* line = NULL;
|
||||
if (cargo_type == DAD_ANIMATION)
|
||||
@@ -364,6 +381,10 @@ LLPreviewGesture::LLPreviewGesture()
|
||||
mSoundCombo(NULL),
|
||||
mChatEditor(NULL),
|
||||
mSaveBtn(NULL),
|
||||
// <edit>
|
||||
mDuplicateBtn(NULL),
|
||||
mOpenBtn(NULL),
|
||||
// </edit>
|
||||
mPreviewBtn(NULL),
|
||||
mPreviewGesture(NULL),
|
||||
mDirty(FALSE)
|
||||
@@ -528,6 +549,18 @@ BOOL LLPreviewGesture::postBuild()
|
||||
btn->setCallbackUserData(this);
|
||||
mSaveBtn = btn;
|
||||
|
||||
// <edit>
|
||||
btn = getChild<LLButton>( "duplicate_btn");
|
||||
btn->setClickedCallback(onClickDuplicate);
|
||||
btn->setCallbackUserData(this);
|
||||
mDuplicateBtn = btn;
|
||||
|
||||
btn = getChild<LLButton>( "open_btn");
|
||||
btn->setClickedCallback(onClickOpen);
|
||||
btn->setCallbackUserData(this);
|
||||
mOpenBtn = btn;
|
||||
// </edit>
|
||||
|
||||
btn = getChild<LLButton>( "preview_btn");
|
||||
btn->setClickedCallback(onClickPreview);
|
||||
btn->setCallbackUserData(this);
|
||||
@@ -607,7 +640,10 @@ void LLPreviewGesture::addAnimations()
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION,
|
||||
PERM_ITEM_UNRESTRICTED,
|
||||
// <edit>
|
||||
// PERM_ITEM_UNRESTRICTED,
|
||||
PERM_NONE,
|
||||
// </edit>
|
||||
gAgent.getID(),
|
||||
gAgent.getGroupID());
|
||||
gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
|
||||
@@ -724,13 +760,22 @@ void LLPreviewGesture::refresh()
|
||||
mWaitTimeEditor->setEnabled(FALSE);
|
||||
mActiveCheck->setEnabled(FALSE);
|
||||
mSaveBtn->setEnabled(FALSE);
|
||||
// <edit>
|
||||
mDuplicateBtn->setEnabled(TRUE);
|
||||
mOpenBtn->setEnabled(TRUE);
|
||||
mStepList->setEnabled(TRUE);
|
||||
// </edit>
|
||||
|
||||
// Make sure preview button is enabled, so we can stop it
|
||||
mPreviewBtn->setEnabled(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID());
|
||||
// <edit>
|
||||
//BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID());
|
||||
BOOL modifiable = TRUE;
|
||||
mOpenBtn->setEnabled(TRUE);
|
||||
// </edit>
|
||||
|
||||
childSetEnabled("desc", modifiable);
|
||||
mTriggerEditor->setEnabled(TRUE);
|
||||
@@ -779,6 +824,9 @@ void LLPreviewGesture::refresh()
|
||||
mWaitAnimCheck->setVisible(FALSE);
|
||||
mWaitTimeCheck->setVisible(FALSE);
|
||||
mWaitTimeEditor->setVisible(FALSE);
|
||||
// <edit>
|
||||
mOpenBtn->setVisible(FALSE);
|
||||
// </edit>
|
||||
|
||||
std::string optionstext;
|
||||
|
||||
@@ -798,6 +846,9 @@ void LLPreviewGesture::refresh()
|
||||
mAnimationRadio->setVisible(TRUE);
|
||||
mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0);
|
||||
mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID);
|
||||
// <edit>
|
||||
mOpenBtn->setVisible(TRUE);
|
||||
// </edit>
|
||||
break;
|
||||
}
|
||||
case STEP_SOUND:
|
||||
@@ -806,6 +857,9 @@ void LLPreviewGesture::refresh()
|
||||
optionstext = getString("step_sound");
|
||||
mSoundCombo->setVisible(TRUE);
|
||||
mSoundCombo->setCurrentByID(sound_step->mSoundAssetID);
|
||||
// <edit>
|
||||
mOpenBtn->setVisible(TRUE);
|
||||
// </edit>
|
||||
break;
|
||||
}
|
||||
case STEP_CHAT:
|
||||
@@ -1117,7 +1171,10 @@ void LLPreviewGesture::saveIfNeeded()
|
||||
|
||||
BOOL ok = gesture->serialize(dp);
|
||||
|
||||
if (dp.getCurrentSize() > 1000)
|
||||
// <edit>
|
||||
//if (dp.getCurrentSize() > 1000)
|
||||
if(0)
|
||||
// </edit>
|
||||
{
|
||||
LLNotifications::instance().add("GestureSaveFailedTooManySteps");
|
||||
|
||||
@@ -1216,6 +1273,62 @@ void LLPreviewGesture::saveIfNeeded()
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
// <edit>
|
||||
void LLPreviewGesture::saveDuplicate()
|
||||
{
|
||||
LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
create_inventory_item( gAgent.getID(),
|
||||
gAgent.getSessionID(),
|
||||
item->getParentUUID(),
|
||||
LLTransactionID::tnull,
|
||||
item->getName(),
|
||||
item->getUUID().asString(),
|
||||
item->getType(),
|
||||
item->getInventoryType(),
|
||||
NOT_WEARABLE,
|
||||
PERM_ITEM_UNRESTRICTED,
|
||||
new LLPreviewGesture::GestureItemForDuplicateCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPreviewGesture::GestureItemForDuplicateCallback::fire(const LLUUID& new_item_id)
|
||||
{
|
||||
LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)gInventory.getItem(new_item_id);
|
||||
LLUUID old_item_id = LLUUID(new_item->getDescription());
|
||||
if(old_item_id.isNull()) return;
|
||||
LLViewerInventoryItem* old_item = (LLViewerInventoryItem*)gInventory.getItem(old_item_id);
|
||||
if(!old_item) return;
|
||||
new_item->setDescription(old_item->getDescription());
|
||||
new_item->updateServer(FALSE);
|
||||
gInventory.updateItem(new_item);
|
||||
gInventory.notifyObservers();
|
||||
LLPreviewGesture* preview = (LLPreviewGesture*)LLPreview::find(old_item_id);
|
||||
if(!preview) return;
|
||||
LLMultiGesture* gesture = preview->createGesture();
|
||||
S32 max_size = gesture->getMaxSerialSize();
|
||||
char* buffer = new char[max_size];
|
||||
LLDataPackerAsciiBuffer dp(buffer, max_size);
|
||||
BOOL ok = gesture->serialize(dp);
|
||||
if(!ok) return;
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND);
|
||||
S32 size = dp.getCurrentSize();
|
||||
file.setMaxSize(size);
|
||||
file.write((U8*)buffer, size);
|
||||
|
||||
std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
|
||||
if(agent_url.empty()) return;
|
||||
LLSD body;
|
||||
body["item_id"] = new_item_id;
|
||||
LLHTTPClient::post(agent_url, body,
|
||||
new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// TODO: This is very similar to LLPreviewNotecard::onSaveComplete.
|
||||
// Could merge code.
|
||||
@@ -1287,6 +1400,58 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data,
|
||||
info = NULL;
|
||||
}
|
||||
|
||||
// <edit>
|
||||
void LLPreviewGesture::onSaveDuplicateComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
|
||||
{
|
||||
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||
if (info && (status == 0))
|
||||
{
|
||||
std::string item_name = "New Gesture";
|
||||
std::string item_desc = "";
|
||||
// Saving into user inventory
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
item_name = item->getName();
|
||||
item_desc = item->getDescription();
|
||||
}
|
||||
gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock);
|
||||
gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, info->mTransactionID);
|
||||
gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 2147483647);
|
||||
gMessageSystem->addS8Fast(_PREHASH_Type, 21);
|
||||
gMessageSystem->addS8Fast(_PREHASH_InvType, 20);
|
||||
gMessageSystem->addU8Fast(_PREHASH_WearableType, 0);
|
||||
gMessageSystem->addStringFast(_PREHASH_Name, item_name);
|
||||
gMessageSystem->addStringFast(_PREHASH_Description, item_desc);
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
|
||||
// Find our window and close it if requested.
|
||||
/*
|
||||
LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(info->mItemUUID);
|
||||
if (previewp && previewp->mCloseAfterSave)
|
||||
{
|
||||
previewp->close();
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Problem saving gesture: " << status << llendl;
|
||||
LLSD args;
|
||||
args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
LLNotifications::instance().add("GestureSaveFailedReason", args);
|
||||
}
|
||||
delete info;
|
||||
info = NULL;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
LLMultiGesture* LLPreviewGesture::createGesture()
|
||||
{
|
||||
@@ -1740,6 +1905,36 @@ void LLPreviewGesture::onClickSave(void* data)
|
||||
self->saveIfNeeded();
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// static
|
||||
void LLPreviewGesture::onClickDuplicate(void* data)
|
||||
{
|
||||
LLPreviewGesture* self = (LLPreviewGesture*)data;
|
||||
self->saveDuplicate();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewGesture::onClickOpen(void* data)
|
||||
{
|
||||
LLPreviewGesture* self = (LLPreviewGesture*)data;
|
||||
|
||||
LLScrollListItem* step_item = self->mStepList->getFirstSelected();
|
||||
if (!step_item) return;
|
||||
|
||||
LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
|
||||
if (step->getType() == STEP_SOUND)
|
||||
{
|
||||
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
|
||||
LLLocalInventory::addItem(sound_step->mSoundName, (int)LLAssetType::AT_SOUND, sound_step->mSoundAssetID, true);
|
||||
}
|
||||
else if (step->getType() == STEP_ANIMATION)
|
||||
{
|
||||
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
|
||||
LLLocalInventory::addItem(anim_step->mAnimName, (int)LLAssetType::AT_ANIMATION, anim_step->mAnimAssetID, true);
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// static
|
||||
void LLPreviewGesture::onClickPreview(void* data)
|
||||
{
|
||||
@@ -1784,3 +1979,64 @@ void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data)
|
||||
|
||||
self->refresh();
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewGesture::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewGesture::saveAs()
|
||||
{
|
||||
std::string default_filename("untitled.gesture");
|
||||
const LLInventoryItem *item = getItem();
|
||||
if(item)
|
||||
{
|
||||
default_filename = LLDir::getScrubbedFileName(item->getName());
|
||||
}
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_GESTURE, default_filename ) )
|
||||
{
|
||||
// User canceled or we failed to acquire save file.
|
||||
return;
|
||||
}
|
||||
// remember the user-approved/edited file name.
|
||||
std::string filename = file_picker.getFirstFile();
|
||||
|
||||
// Copy the UI into a gesture
|
||||
LLMultiGesture* gesture = createGesture();
|
||||
|
||||
// Serialize the gesture
|
||||
S32 max_size = gesture->getMaxSerialSize();
|
||||
char* buffer = new char[max_size];
|
||||
LLDataPackerAsciiBuffer dp(buffer, max_size);
|
||||
|
||||
if(!gesture->serialize(dp))
|
||||
{
|
||||
// FIXME: Notify user
|
||||
delete [] buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
S32 size = dp.getCurrentSize();
|
||||
|
||||
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||
export_file.write(buffer, size);
|
||||
export_file.close();
|
||||
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
LLUUID LLPreviewGesture::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// </edit>
|
||||
@@ -99,10 +99,24 @@ protected:
|
||||
|
||||
void saveIfNeeded();
|
||||
|
||||
// <edit>
|
||||
void saveDuplicate();
|
||||
class GestureItemForDuplicateCallback : public LLInventoryCallback
|
||||
{
|
||||
void fire(const LLUUID& inv_item);
|
||||
};
|
||||
// </edit>
|
||||
|
||||
static void onSaveComplete(const LLUUID& asset_uuid,
|
||||
void* user_data,
|
||||
S32 status, LLExtStat ext_status);
|
||||
|
||||
// <edit>
|
||||
static void onSaveDuplicateComplete(const LLUUID& asset_uuid,
|
||||
void* user_data,
|
||||
S32 status, LLExtStat ext_status);
|
||||
// </edit>
|
||||
|
||||
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
|
||||
|
||||
// Write UI back into gesture
|
||||
@@ -135,12 +149,22 @@ protected:
|
||||
|
||||
static void onCommitActive(LLUICtrl* ctrl, void* data);
|
||||
static void onClickSave(void* data);
|
||||
// <edit>
|
||||
static void onClickDuplicate(void* data);
|
||||
static void onClickOpen(void* data);
|
||||
virtual LLUUID getItemID();
|
||||
// </edit>
|
||||
static void onClickPreview(void* data);
|
||||
|
||||
static void onDonePreview(LLMultiGesture* gesture, void* data);
|
||||
|
||||
virtual const char *getTitleName() const { return "Gesture"; }
|
||||
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
virtual void saveAs();
|
||||
// </edit>
|
||||
|
||||
protected:
|
||||
// LLPreview contains mDescEditor
|
||||
LLLineEditor* mTriggerEditor;
|
||||
@@ -168,6 +192,10 @@ protected:
|
||||
|
||||
LLCheckBoxCtrl* mActiveCheck;
|
||||
LLButton* mSaveBtn;
|
||||
// <edit>
|
||||
LLButton* mDuplicateBtn;
|
||||
LLButton* mOpenBtn;
|
||||
// </edit>
|
||||
LLButton* mPreviewBtn;
|
||||
|
||||
LLMultiGesture* mPreviewGesture;
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
#include "llappviewer.h" // app_abort_quit()
|
||||
#include "lllineeditor.h"
|
||||
#include "lluictrlfactory.h"
|
||||
// <edit>
|
||||
#include "llfilepicker.h"
|
||||
// </edit>
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
@@ -108,7 +111,10 @@ LLPreviewNotecard::LLPreviewNotecard(const std::string& name,
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_preview_notecard.xml");
|
||||
childSetAction("Save",onClickSave,this);
|
||||
|
||||
// <edit>
|
||||
childSetAction("Get Items", onClickGetItems, this);
|
||||
// </edit>
|
||||
|
||||
if( mAssetID.isNull() )
|
||||
{
|
||||
const LLInventoryItem* item = getItem();
|
||||
@@ -335,6 +341,9 @@ void LLPreviewNotecard::loadAsset()
|
||||
GP_OBJECT_MANIPULATE))
|
||||
{
|
||||
editor->setEnabled(FALSE);
|
||||
// <edit> You can always save in task inventory
|
||||
if(!mObjectUUID.isNull()) editor->setEnabled(TRUE);
|
||||
// </edit>
|
||||
childSetVisible("lock", TRUE);
|
||||
}
|
||||
}
|
||||
@@ -442,7 +451,51 @@ void LLPreviewNotecard::onClickSave(void* user_data)
|
||||
preview->saveIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// static
|
||||
void LLPreviewNotecard::onClickGetItems(void* user_data)
|
||||
{
|
||||
LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data;
|
||||
if(preview)
|
||||
{
|
||||
LLViewerTextEditor* editor = preview->getChild<LLViewerTextEditor>("Notecard Editor");
|
||||
if(editor)
|
||||
{
|
||||
std::vector<LLPointer<LLInventoryItem>> items = editor->getEmbeddedItems();
|
||||
if(items.size())
|
||||
{
|
||||
const BOOL use_caps = FALSE;
|
||||
|
||||
std::vector<LLPointer<LLInventoryItem>>::iterator iter = items.begin();
|
||||
std::vector<LLPointer<LLInventoryItem>>::iterator end = items.end();
|
||||
for( ; iter != end; ++iter)
|
||||
{
|
||||
LLInventoryItem* item = static_cast<LLInventoryItem*>(*iter);
|
||||
if(use_caps)
|
||||
{
|
||||
copy_inventory_from_notecard(preview->getObjectID(), preview->getNotecardItemID(), item, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only one item per message actually works
|
||||
gMessageSystem->newMessageFast(_PREHASH_CopyInventoryFromNotecard);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_NotecardData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_NotecardItemID, preview->getNotecardItemID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ObjectID, preview->getObjectID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getUUID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, gInventory.findCategoryUUIDForType(item->getType()));
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
struct LLSaveNotecardInfo
|
||||
{
|
||||
LLPreviewNotecard* mSelf;
|
||||
@@ -649,4 +702,69 @@ void LLPreviewNotecard::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewNotecard::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewNotecard::saveAs()
|
||||
{
|
||||
std::string default_filename("untitled.notecard");
|
||||
const LLInventoryItem *item = getItem();
|
||||
if(item)
|
||||
{
|
||||
// gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_NOTECARD, LLPreviewNotecard::gotAssetForSave, this, TRUE);
|
||||
default_filename = LLDir::getScrubbedFileName(item->getName());
|
||||
}
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_NOTECARD, default_filename ) )
|
||||
{
|
||||
// User canceled or we failed to acquire save file.
|
||||
return;
|
||||
}
|
||||
// remember the user-approved/edited file name.
|
||||
std::string filename = file_picker.getFirstFile();
|
||||
|
||||
LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor");
|
||||
|
||||
std::string buffer;
|
||||
if (!editor->exportBuffer(buffer))
|
||||
{
|
||||
// FIXME: Notify the user!
|
||||
return;
|
||||
}
|
||||
|
||||
S32 size = buffer.length() + 1;
|
||||
|
||||
std::ofstream export_file(filename.c_str(), std::ofstream::binary);
|
||||
export_file.write(buffer.c_str(), size);
|
||||
export_file.close();
|
||||
}
|
||||
|
||||
LLUUID LLPreviewNotecard::getNotecardItemID()
|
||||
{
|
||||
return mNotecardItemID;
|
||||
}
|
||||
|
||||
LLUUID LLPreviewNotecard::getObjectID()
|
||||
{
|
||||
return mObjectID;
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLUUID LLPreviewNotecard::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// EOF
|
||||
@@ -84,6 +84,11 @@ public:
|
||||
// asset system. :(
|
||||
void refreshFromInventory();
|
||||
|
||||
// <edit>
|
||||
LLUUID getNotecardItemID();
|
||||
LLUUID getObjectID();
|
||||
virtual LLUUID getItemID();
|
||||
// </edit>
|
||||
protected:
|
||||
|
||||
virtual void loadAsset();
|
||||
@@ -97,6 +102,8 @@ protected:
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
static void onClickSave(void* data);
|
||||
// <edit>
|
||||
static void onClickGetItems(void* data);
|
||||
|
||||
static void onSaveComplete(const LLUUID& asset_uuid,
|
||||
void* user_data,
|
||||
@@ -114,6 +121,11 @@ protected:
|
||||
|
||||
LLUUID mNotecardItemID;
|
||||
LLUUID mObjectID;
|
||||
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
virtual void saveAs();
|
||||
// </edit>
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1684,7 +1684,39 @@ void LLPreviewLSL::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
gSavedSettings.setRect("PreviewScriptRect", getRect());
|
||||
}
|
||||
}
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewLSL::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewLSL::saveAs()
|
||||
{
|
||||
std::string default_filename("untitled.lsl");
|
||||
const LLInventoryItem *item = getItem();
|
||||
if(item)
|
||||
{
|
||||
default_filename = LLDir::getScrubbedFileName(item->getName());
|
||||
}
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_LSL, default_filename ) )
|
||||
{
|
||||
// User canceled or we failed to acquire save file.
|
||||
return;
|
||||
}
|
||||
// remember the user-approved/edited file name.
|
||||
std::string filename = file_picker.getFirstFile();
|
||||
|
||||
std::string utf8text = mScriptEd->mEditor->getText();
|
||||
LLFILE* fp = LLFile::fopen(filename, "wb");
|
||||
fputs(utf8text.c_str(), fp);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
// </edit>
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// LLLiveLSLEditor
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -186,6 +186,10 @@ protected:
|
||||
void uploadAssetLegacy(const std::string& filename,
|
||||
const LLUUID& item_id,
|
||||
const LLTransactionID& tid);
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
virtual void saveAs();
|
||||
// </edit>
|
||||
|
||||
static void onSearchReplace(void* userdata);
|
||||
static void onLoad(void* userdata);
|
||||
|
||||
@@ -43,6 +43,15 @@
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewermessage.h" // send_guid_sound_trigger
|
||||
#include "lluictrlfactory.h"
|
||||
// <edit>
|
||||
#include "llvoavatar.h"
|
||||
#include "llchat.h"
|
||||
#include "llfloaterchat.h"
|
||||
#include "llviewerwindow.h" // for alert
|
||||
#include "llfilepicker.h"
|
||||
// for ambient play:
|
||||
#include "llviewerregion.h"
|
||||
// </edit>
|
||||
|
||||
extern LLAudioEngine* gAudiop;
|
||||
extern LLAgent gAgent;
|
||||
@@ -57,6 +66,10 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons
|
||||
|
||||
childSetAction("Sound play btn",&LLPreviewSound::playSound,this);
|
||||
childSetAction("Sound audition btn",&LLPreviewSound::auditionSound,this);
|
||||
// <edit>
|
||||
childSetAction("Sound copy uuid btn", &LLPreviewSound::copyUUID, this);
|
||||
childSetAction("Play ambient btn", &LLPreviewSound::playAmbient, this);
|
||||
// </edit>
|
||||
|
||||
LLButton* button = getChild<LLButton>("Sound play btn");
|
||||
button->setSoundFlags(LLView::SILENT);
|
||||
@@ -74,6 +87,13 @@ LLPreviewSound::LLPreviewSound(const std::string& name, const LLRect& rect, cons
|
||||
if(item && gAudiop)
|
||||
{
|
||||
gAudiop->preloadSound(item->getAssetUUID());
|
||||
// <edit>
|
||||
// that thing above doesn't actually start a sound transfer, so I will do it
|
||||
//LLAudioSource *asp = new LLAudioSource(gAgent.getID(), gAgent.getID(), F32(1.0f), LLAudioEngine::AUDIO_TYPE_UI);
|
||||
LLAudioSource *asp = gAgent.getAvatarObject()->getAudioSource(gAgent.getID());
|
||||
LLAudioData *datap = gAudiop->getAudioData(item->getAssetUUID());
|
||||
asp->addAudioData(datap, FALSE);
|
||||
// </edit>
|
||||
}
|
||||
|
||||
setTitle(title);
|
||||
@@ -110,3 +130,228 @@ void LLPreviewSound::auditionSound( void *userdata )
|
||||
gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
|
||||
}
|
||||
}
|
||||
|
||||
// <edit>
|
||||
void LLPreviewSound::playAmbient( void* userdata )
|
||||
{
|
||||
LLPreviewSound* self = (LLPreviewSound*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item && gAudiop)
|
||||
{
|
||||
int gain = 0.01f;
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
gMessageSystem->newMessageFast(_PREHASH_SoundTrigger);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_SoundData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SoundID, LLUUID(item->getAssetUUID()));
|
||||
gMessageSystem->addUUIDFast(_PREHASH_OwnerID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ObjectID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_ParentID, LLUUID::null);
|
||||
gMessageSystem->addU64Fast(_PREHASH_Handle, gAgent.getRegion()->getHandle());
|
||||
LLVector3d pos = -from_region_handle(gAgent.getRegion()->getHandle());
|
||||
gMessageSystem->addVector3Fast(_PREHASH_Position, (LLVector3)pos);
|
||||
gMessageSystem->addF32Fast(_PREHASH_Gain, gain);
|
||||
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
|
||||
gain = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
// <edit>
|
||||
/*
|
||||
struct LLSaveInfo
|
||||
{
|
||||
LLSaveInfo(const LLUUID& item_id, const LLUUID& object_id, const std::string& desc,
|
||||
const LLTransactionID tid)
|
||||
: mItemUUID(item_id), mObjectUUID(object_id), mDesc(desc), mTransactionID(tid)
|
||||
{
|
||||
}
|
||||
|
||||
LLUUID mItemUUID;
|
||||
LLUUID mObjectUUID;
|
||||
std::string mDesc;
|
||||
LLTransactionID mTransactionID;
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPreviewSound::makeCopy( void *userdata )
|
||||
{
|
||||
LLPreviewSound* self = (LLPreviewSound*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item && gAudiop)
|
||||
{
|
||||
// Find out if asset data is ready
|
||||
// I might be able to get rid of this
|
||||
if(!gAssetStorage->hasLocalAsset(item->getAssetUUID(), LLAssetType::AT_SOUND))
|
||||
{
|
||||
LLChat chat("Sound isn't downloaded yet, please try again in a moment.");
|
||||
LLFloaterChat::addChat(chat);
|
||||
return;
|
||||
}
|
||||
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_SOUND, LLPreviewSound::gotAssetForCopy, self, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewSound::gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewSound* self = (LLPreviewSound*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
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...
|
||||
|
||||
LLTransactionID tid;
|
||||
LLAssetID asset_id;
|
||||
tid.generate();
|
||||
asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
|
||||
|
||||
LLVFile ofile(gVFS, asset_id, LLAssetType::AT_SOUND, LLVFile::APPEND);
|
||||
|
||||
ofile.setMaxSize(size);
|
||||
ofile.write((U8*)buffer, size);
|
||||
|
||||
// Upload that asset to the database
|
||||
LLSaveInfo* info = new LLSaveInfo(self->mItemUUID, self->mObjectUUID, "sound", tid);
|
||||
gAssetStorage->storeAssetData(tid, LLAssetType::AT_SOUND, onSaveCopyComplete, info, FALSE);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewSound::onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLSaveInfo* info = (LLSaveInfo*)user_data;
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
std::string item_name = "New Sound";
|
||||
std::string item_desc = "";
|
||||
// Saving into user inventory
|
||||
LLViewerInventoryItem* item;
|
||||
item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
|
||||
if(item)
|
||||
{
|
||||
item_name = item->getName();
|
||||
item_desc = item->getDescription();
|
||||
}
|
||||
gMessageSystem->newMessageFast(_PREHASH_CreateInventoryItem);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_InventoryBlock);
|
||||
gMessageSystem->addU32Fast(_PREHASH_CallbackID, 0);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_FolderID, LLUUID::null);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_TransactionID, info->mTransactionID);
|
||||
gMessageSystem->addU32Fast(_PREHASH_NextOwnerMask, 2147483647);
|
||||
gMessageSystem->addS8Fast(_PREHASH_Type, 1);
|
||||
gMessageSystem->addS8Fast(_PREHASH_InvType, 1);
|
||||
gMessageSystem->addU8Fast(_PREHASH_WearableType, 0);
|
||||
gMessageSystem->addStringFast(_PREHASH_Name, item_name);
|
||||
gMessageSystem->addStringFast(_PREHASH_Description, item_desc);
|
||||
gMessageSystem->sendReliable(gAgent.getRegionHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Problem saving sound: " << status << llendl;
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
|
||||
gViewerWindow->alertXml("CannotUploadReason",args);
|
||||
}
|
||||
}
|
||||
*/
|
||||
// static
|
||||
void LLPreviewSound::copyUUID( void *userdata )
|
||||
{
|
||||
LLPreviewSound* self = (LLPreviewSound*) userdata;
|
||||
const LLInventoryItem *item = self->getItem();
|
||||
|
||||
if(item )
|
||||
{
|
||||
gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item->getAssetUUID().asString()));
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
// <edit>
|
||||
// virtual
|
||||
BOOL LLPreviewSound::canSaveAs() const
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLPreviewSound::saveAs()
|
||||
{
|
||||
const LLInventoryItem *item = getItem();
|
||||
|
||||
if(item)
|
||||
{
|
||||
gAssetStorage->getAssetData(item->getAssetUUID(), LLAssetType::AT_SOUND, LLPreviewSound::gotAssetForSave, this, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPreviewSound::gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLPreviewSound* self = (LLPreviewSound*) user_data;
|
||||
//const LLInventoryItem *item = self->getItem();
|
||||
|
||||
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( LLFilePicker::FFSAVE_OGG, LLDir::getScrubbedFileName(self->getItem()->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();
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLUUID LLPreviewSound::getItemID()
|
||||
{
|
||||
const LLViewerInventoryItem* item = getItem();
|
||||
if(item)
|
||||
{
|
||||
return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
// </edit>
|
||||
|
||||
@@ -44,9 +44,30 @@ public:
|
||||
|
||||
static void playSound( void* userdata );
|
||||
static void auditionSound( void* userdata );
|
||||
// <edit>
|
||||
/*
|
||||
static void makeCopy(void* userdata);
|
||||
static void gotAssetForCopy(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
static void onSaveCopyComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status);
|
||||
*/
|
||||
static void playAmbient(void* userdata);
|
||||
static void copyUUID(void* userdata);
|
||||
static void gotAssetForSave(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
// </edit>
|
||||
|
||||
protected:
|
||||
virtual const char *getTitleName() const { return "Sound"; }
|
||||
// <edit>
|
||||
virtual BOOL canSaveAs() const;
|
||||
virtual void saveAs();
|
||||
virtual LLUUID getItemID();
|
||||
// </edit>
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1079,23 +1079,29 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
{
|
||||
switch( cargo_type )
|
||||
{
|
||||
case DAD_CALLINGCARD:
|
||||
if(acceptsCallingCardNames())
|
||||
{
|
||||
if (drop)
|
||||
{
|
||||
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
|
||||
std::string name = item->getName();
|
||||
appendText(name, true, true);
|
||||
}
|
||||
*accept = ACCEPT_YES_COPY_SINGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
}
|
||||
break;
|
||||
|
||||
// <edit>
|
||||
// This does not even appear to be used maybe
|
||||
// Throwing it out so I can embed calling cards
|
||||
/*
|
||||
case DAD_CALLINGCARD:
|
||||
if(acceptsCallingCardNames())
|
||||
{
|
||||
if (drop)
|
||||
{
|
||||
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
|
||||
std::string name = item->getName();
|
||||
appendText(name, true, true);
|
||||
}
|
||||
*accept = ACCEPT_YES_COPY_SINGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*accept = ACCEPT_NO;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case DAD_CALLINGCARD:
|
||||
// </edit>
|
||||
case DAD_TEXTURE:
|
||||
case DAD_SOUND:
|
||||
case DAD_LANDMARK:
|
||||
@@ -1108,10 +1114,30 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
case DAD_GESTURE:
|
||||
{
|
||||
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
|
||||
// <edit>
|
||||
if((item->getPermissions().getMaskOwner() & PERM_ITEM_UNRESTRICTED) != PERM_ITEM_UNRESTRICTED)
|
||||
{
|
||||
if(gSavedSettings.getBOOL("ForceNotecardDragCargoPermissive"))
|
||||
{
|
||||
item = new LLInventoryItem((LLInventoryItem *)cargo_data);
|
||||
LLPermissions old = item->getPermissions();
|
||||
LLPermissions perm;
|
||||
perm.init(old.getCreator(), old.getOwner(), old.getLastOwner(), old.getGroup());
|
||||
perm.setMaskBase(PERM_ITEM_UNRESTRICTED);
|
||||
perm.setMaskEveryone(PERM_ITEM_UNRESTRICTED);
|
||||
perm.setMaskGroup(PERM_ITEM_UNRESTRICTED);
|
||||
perm.setMaskNext(PERM_ITEM_UNRESTRICTED);
|
||||
perm.setMaskOwner(PERM_ITEM_UNRESTRICTED);
|
||||
item->setPermissions(perm);
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
if( item && allowsEmbeddedItems() )
|
||||
{
|
||||
U32 mask_next = item->getPermissions().getMaskNextOwner();
|
||||
if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
|
||||
// <edit>
|
||||
//if((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
|
||||
if(((mask_next & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || gSavedSettings.getBOOL("ForceNotecardDragCargoAcceptance"))
|
||||
{
|
||||
if( drop )
|
||||
{
|
||||
@@ -1525,6 +1551,14 @@ bool LLViewerTextEditor::hasEmbeddedInventory()
|
||||
return ! mEmbeddedItemList->empty();
|
||||
}
|
||||
|
||||
// <edit>
|
||||
std::vector<LLPointer<LLInventoryItem> > LLViewerTextEditor::getEmbeddedItems()
|
||||
{
|
||||
std::vector<LLPointer<LLInventoryItem> > items;
|
||||
mEmbeddedItemList->getEmbeddedItemList(items);
|
||||
return items;
|
||||
}
|
||||
// </edit>
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL LLViewerTextEditor::importBuffer( const char* buffer, S32 length )
|
||||
|
||||
@@ -97,6 +97,9 @@ public:
|
||||
// should be changed to get a different asset id from the verifier
|
||||
// rather than checking if a re-load is necessary. Phoenix 2007-02-27
|
||||
bool hasEmbeddedInventory();
|
||||
// <edit>
|
||||
std::vector<LLPointer<LLInventoryItem> > getEmbeddedItems();
|
||||
// </edit>
|
||||
|
||||
private:
|
||||
// Embedded object operations
|
||||
|
||||
@@ -13,12 +13,24 @@
|
||||
mouse_opaque="true" name="desc txt" v_pad="0" width="80">
|
||||
Description:
|
||||
</text>
|
||||
<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
<!--<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Play in World" label_selected="Stop" left="27" mouse_opaque="true"
|
||||
name="Anim play btn" scale_image="true"
|
||||
tool_tip="Play this animation so that others can see it." width="96" />
|
||||
<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Play Locally" label_selected="Stop" left="177" mouse_opaque="true"
|
||||
name="Anim audition btn" scale_image="true"
|
||||
tool_tip="Play this animation so that only you can see it." width="96" />-->
|
||||
<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Play in World" label_selected="Stop" left="4" mouse_opaque="true"
|
||||
name="Anim play btn" scale_image="true"
|
||||
tool_tip="Play this animation so that others can see it." width="96" />
|
||||
<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Play Locally" label_selected="Stop" left_delta="98" mouse_opaque="true"
|
||||
name="Anim audition btn" scale_image="true"
|
||||
tool_tip="Play this animation so that only you can see it." width="96" />
|
||||
<button bottom="-66" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Copy UUID" label_selected="Copy UUID" left_delta="98" mouse_opaque="true"
|
||||
name="Anim copy uuid btn" scale_image="true"
|
||||
tool_tip="Copy asset UUID" width="96" />
|
||||
</floater>
|
||||
|
||||
@@ -97,12 +97,16 @@ unless you add wait steps.
|
||||
left_delta="0" name="wait_time_check" width="100" />
|
||||
<line_editor bottom_delta="0" follows="top|left" height="20" left_delta="105"
|
||||
max_length="15" name="wait_time_editor" width="50" />
|
||||
<check_box bottom="7" follows="top|left" height="20" label="Active" left="140"
|
||||
<button bottom_delta="-10" follows="top|left" height="20" left="233"
|
||||
label="Open" name="open_btn" width="64" />
|
||||
<check_box bottom="7" follows="top|left" height="20" label="Active" left="100"
|
||||
name="active_check"
|
||||
tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."
|
||||
width="100" />
|
||||
<button bottom="5" follows="top|left" height="20" label="Preview" left="215"
|
||||
<button bottom="5" follows="top|left" height="20" label="Preview" left_delta="80"
|
||||
name="preview_btn" width="80" />
|
||||
<button bottom="5" follows="top|left" height="20" label="Save" left_delta="90"
|
||||
name="save_btn" width="80" />
|
||||
<button bottom="5" follows="top|left" height="20" label="Make Copy" left_delta="90"
|
||||
name="duplicate_btn" width="80" />
|
||||
</floater>
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
<button bottom="-352" enabled="false" follows="left|bottom" font="SansSerif"
|
||||
halign="center" height="20" label="Save" label_selected="Save" left="9"
|
||||
mouse_opaque="false" name="Save" scale_image="true" width="100" />
|
||||
<button bottom="-352" enabled="true" follows="left|bottom" font="SansSerif"
|
||||
halign="center" height="20" label="Get Items" label_selected="Get Items" left_delta="110"
|
||||
mouse_opaque="false" name="Get Items" scale_image="true" width="100" />
|
||||
<!--<check_box follows="left|bottom" bottom_delta="0" left_delta="110" name="https_chk" label="Saves via HTTPS" />-->
|
||||
<icon bottom="-19" color="1 1 1 1" enabled="true" follows="top|right" height="16"
|
||||
image_name="icon_lock.tga" left="344" mouse_opaque="true" name="lock"
|
||||
width="16" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater bottom="-85" can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||
can_resize="false" enabled="true" height="85" left="176" min_height="0"
|
||||
<floater bottom="-110" can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||
can_resize="false" enabled="true" height="110" left="176" min_height="0"
|
||||
min_width="0" mouse_opaque="true" name="preview_sound" width="300">
|
||||
<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="-38"
|
||||
enabled="true" follows="left|top|right" font="SansSerif"
|
||||
@@ -23,4 +23,14 @@
|
||||
mouse_opaque="true" name="Sound play btn" scale_image="true"
|
||||
sound_flags="0" tool_tip="Play this sound so that others can hear it."
|
||||
width="120" />
|
||||
<button bottom_delta="-23" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Play Ambient" label_selected="Play Ambient" left_delta="0"
|
||||
mouse_opaque="true" name="Play ambient btn" scale_image="true"
|
||||
sound_flags="0" tool_tip="Play Ambient"
|
||||
width="120" />
|
||||
<button bottom_delta="0" enabled="true" font="SansSerif" halign="center" height="19"
|
||||
label="Copy UUID" label_selected="Copy UUID" left_delta="126"
|
||||
mouse_opaque="true" name="Sound copy uuid btn" scale_image="true"
|
||||
sound_flags="0" tool_tip="Copy asset UUID"
|
||||
width="120" />
|
||||
</floater>
|
||||
|
||||
Reference in New Issue
Block a user