From 2b31dad40026d8078ea30d0da0656a4078d0f5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Fri, 9 Feb 2024 22:26:02 +0100 Subject: miscellaneous: BOOL (int) to real bool --- indra/newview/llpreviewgesture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 544ff8b5dc..2e40455a46 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1196,7 +1196,7 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, new_item->setDescription(info->mDesc); new_item->setTransactionID(info->mTransactionID); new_item->setAssetUUID(asset_uuid); - new_item->updateServer(FALSE); + new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); } -- cgit v1.2.3 From a5261a5fa8fad810ecb5c260d92c3e771822bf58 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 23:46:23 +0100 Subject: Convert BOOL to bool in llui --- indra/newview/llpreviewgesture.cpp | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 2e40455a46..867b3ab362 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -137,12 +137,12 @@ void LLPreviewGesture::draw() } // virtual -BOOL LLPreviewGesture::handleKeyHere(KEY key, MASK mask) +bool LLPreviewGesture::handleKeyHere(KEY key, MASK mask) { if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) { saveIfNeeded(); - return TRUE; + return true; } return LLPreview::handleKeyHere(key, mask); @@ -150,13 +150,13 @@ BOOL LLPreviewGesture::handleKeyHere(KEY key, MASK mask) // virtual -BOOL LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, +bool LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) { - BOOL handled = TRUE; + bool handled = true; switch(cargo_type) { case DAD_ANIMATION: @@ -225,12 +225,12 @@ BOOL LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, // virtual -BOOL LLPreviewGesture::canClose() +bool LLPreviewGesture::canClose() { if(!mDirty || mForceClose) { - return TRUE; + return true; } else { @@ -241,7 +241,7 @@ BOOL LLPreviewGesture::canClose() LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLPreviewGesture::handleSaveChangesDialog, this, _1, _2) ); } - return FALSE; + return false; } } @@ -336,7 +336,7 @@ LLPreviewGesture::~LLPreviewGesture() } -BOOL LLPreviewGesture::postBuild() +bool LLPreviewGesture::postBuild() { setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2)); @@ -353,20 +353,20 @@ BOOL LLPreviewGesture::postBuild() edit = getChild("trigger_editor"); edit->setKeystrokeCallback(onKeystrokeCommit, this); edit->setCommitCallback(onCommitSetDirty, this); - edit->setCommitOnFocusLost(TRUE); - edit->setIgnoreTab(TRUE); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); mTriggerEditor = edit; text = getChild("replace_text"); - text->setEnabled(FALSE); + text->setEnabled(false); mReplaceText = text; edit = getChild("replace_editor"); - edit->setEnabled(FALSE); + edit->setEnabled(false); edit->setKeystrokeCallback(onKeystrokeCommit, this); edit->setCommitCallback(onCommitSetDirty, this); - edit->setCommitOnFocusLost(TRUE); - edit->setIgnoreTab(TRUE); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); mReplaceEditor = edit; combo = getChild( "modifier_combo"); @@ -384,22 +384,22 @@ BOOL LLPreviewGesture::postBuild() btn = getChild( "add_btn"); btn->setClickedCallback(onClickAdd, this); - btn->setEnabled(FALSE); + btn->setEnabled(false); mAddBtn = btn; btn = getChild( "up_btn"); btn->setClickedCallback(onClickUp, this); - btn->setEnabled(FALSE); + btn->setEnabled(false); mUpBtn = btn; btn = getChild( "down_btn"); btn->setClickedCallback(onClickDown, this); - btn->setEnabled(FALSE); + btn->setEnabled(false); mDownBtn = btn; btn = getChild( "delete_btn"); btn->setClickedCallback(onClickDelete, this); - btn->setEnabled(FALSE); + btn->setEnabled(false); mDeleteBtn = btn; list = getChild("step_list"); @@ -410,47 +410,47 @@ BOOL LLPreviewGesture::postBuild() mOptionsText = getChild("options_text"); combo = getChild( "animation_list"); - combo->setVisible(FALSE); + combo->setVisible(false); combo->setCommitCallback(onCommitAnimation, this); mAnimationCombo = combo; LLRadioGroup* group; group = getChild("animation_trigger_type"); - group->setVisible(FALSE); + group->setVisible(false); group->setCommitCallback(onCommitAnimationTrigger, this); mAnimationRadio = group; combo = getChild( "sound_list"); - combo->setVisible(FALSE); + combo->setVisible(false); combo->setCommitCallback(onCommitSound, this); mSoundCombo = combo; edit = getChild("chat_editor"); - edit->setVisible(FALSE); + edit->setVisible(false); edit->setCommitCallback(onCommitChat, this); //edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitOnFocusLost(TRUE); - edit->setIgnoreTab(TRUE); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); mChatEditor = edit; check = getChild( "wait_anim_check"); - check->setVisible(FALSE); + check->setVisible(false); check->setCommitCallback(onCommitWait, this); mWaitAnimCheck = check; check = getChild( "wait_time_check"); - check->setVisible(FALSE); + check->setVisible(false); check->setCommitCallback(onCommitWait, this); mWaitTimeCheck = check; edit = getChild("wait_time_editor"); - edit->setEnabled(FALSE); - edit->setVisible(FALSE); + edit->setEnabled(false); + edit->setVisible(false); edit->setPrevalidate(LLTextValidate::validateFloat); // edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitOnFocusLost(TRUE); + edit->setCommitOnFocusLost(true); edit->setCommitCallback(onCommitWaitTime, this); - edit->setIgnoreTab(TRUE); + edit->setIgnoreTab(true); mWaitTimeEditor = edit; // Buttons at the bottom -- cgit v1.2.3 From 60d3dd98a44230c21803c1606552ee098ed9fa7c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 21 Feb 2024 21:05:14 +0100 Subject: Convert remaining BOOL to bool --- indra/newview/llpreviewgesture.cpp | 144 ++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 72 deletions(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 867b3ab362..1f66db92d5 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -199,7 +199,7 @@ bool LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, sound->mSoundName = item->getName(); } updateLabel(line); - mDirty = TRUE; + mDirty = true; refresh(); } *accept = ACCEPT_YES_COPY_MULTI; @@ -236,7 +236,7 @@ bool LLPreviewGesture::canClose() { if(!mSaveDialogShown) { - mSaveDialogShown = TRUE; + mSaveDialogShown = true; // Bring up view-modal dialog: Save changes? Yes, No, Cancel LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLPreviewGesture::handleSaveChangesDialog, this, _1, _2) ); @@ -268,19 +268,19 @@ void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility ) bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const LLSD& response) { - mSaveDialogShown = FALSE; + mSaveDialogShown = false; S32 option = LLNotificationsUtil::getSelectedOption(notification, response); switch(option) { case 0: // "Yes" LLGestureMgr::instance().stopGesture(mPreviewGesture); - mCloseAfterSave = TRUE; + mCloseAfterSave = true; onClickSave(this); break; case 1: // "No" LLGestureMgr::instance().stopGesture(mPreviewGesture); - mDirty = FALSE; // Force the dirty flag because user has clicked NO on confirm save dialog... + mDirty = false; // Force the dirty flag because user has clicked NO on confirm save dialog... closeFloater(); break; @@ -313,7 +313,7 @@ LLPreviewGesture::LLPreviewGesture(const LLSD& key) mSaveBtn(NULL), mPreviewBtn(NULL), mPreviewGesture(NULL), - mDirty(FALSE) + mDirty(false) { NONE_LABEL = LLTrans::getString("---"); SHIFT_LABEL = LLTrans::getString("KBShift"); @@ -620,39 +620,39 @@ void LLPreviewGesture::refresh() if (mPreviewGesture || !is_complete) { - getChildView("desc")->setEnabled(FALSE); - //mDescEditor->setEnabled(FALSE); - mTriggerEditor->setEnabled(FALSE); - mReplaceText->setEnabled(FALSE); - mReplaceEditor->setEnabled(FALSE); - mModifierCombo->setEnabled(FALSE); - mKeyCombo->setEnabled(FALSE); - mLibraryList->setEnabled(FALSE); - mAddBtn->setEnabled(FALSE); - mUpBtn->setEnabled(FALSE); - mDownBtn->setEnabled(FALSE); - mDeleteBtn->setEnabled(FALSE); - mStepList->setEnabled(FALSE); - mOptionsText->setEnabled(FALSE); - mAnimationCombo->setEnabled(FALSE); - mAnimationRadio->setEnabled(FALSE); - mSoundCombo->setEnabled(FALSE); - mChatEditor->setEnabled(FALSE); - mWaitAnimCheck->setEnabled(FALSE); - mWaitTimeCheck->setEnabled(FALSE); - mWaitTimeEditor->setEnabled(FALSE); - mActiveCheck->setEnabled(FALSE); - mSaveBtn->setEnabled(FALSE); + getChildView("desc")->setEnabled(false); + //mDescEditor->setEnabled(false); + mTriggerEditor->setEnabled(false); + mReplaceText->setEnabled(false); + mReplaceEditor->setEnabled(false); + mModifierCombo->setEnabled(false); + mKeyCombo->setEnabled(false); + mLibraryList->setEnabled(false); + mAddBtn->setEnabled(false); + mUpBtn->setEnabled(false); + mDownBtn->setEnabled(false); + mDeleteBtn->setEnabled(false); + mStepList->setEnabled(false); + mOptionsText->setEnabled(false); + mAnimationCombo->setEnabled(false); + mAnimationRadio->setEnabled(false); + mSoundCombo->setEnabled(false); + mChatEditor->setEnabled(false); + mWaitAnimCheck->setEnabled(false); + mWaitTimeCheck->setEnabled(false); + mWaitTimeEditor->setEnabled(false); + mActiveCheck->setEnabled(false); + mSaveBtn->setEnabled(false); // Make sure preview button is enabled, so we can stop it - mPreviewBtn->setEnabled(TRUE); + mPreviewBtn->setEnabled(true); return; } - BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); + bool modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); getChildView("desc")->setEnabled(modifiable); - mTriggerEditor->setEnabled(TRUE); + mTriggerEditor->setEnabled(true); mLibraryList->setEnabled(modifiable); mStepList->setEnabled(modifiable); mOptionsText->setEnabled(modifiable); @@ -663,27 +663,27 @@ void LLPreviewGesture::refresh() mWaitAnimCheck->setEnabled(modifiable); mWaitTimeCheck->setEnabled(modifiable); mWaitTimeEditor->setEnabled(modifiable); - mActiveCheck->setEnabled(TRUE); + mActiveCheck->setEnabled(true); const std::string& trigger = mTriggerEditor->getText(); - BOOL have_trigger = !trigger.empty(); + bool have_trigger = !trigger.empty(); const std::string& replace = mReplaceEditor->getText(); - BOOL have_replace = !replace.empty(); + bool have_replace = !replace.empty(); LLScrollListItem* library_item = mLibraryList->getFirstSelected(); - BOOL have_library = (library_item != NULL); + bool have_library = (library_item != NULL); LLScrollListItem* step_item = mStepList->getFirstSelected(); S32 step_index = mStepList->getFirstSelectedIndex(); S32 step_count = mStepList->getItemCount(); - BOOL have_step = (step_item != NULL); + bool have_step = (step_item != NULL); mReplaceText->setEnabled(have_trigger || have_replace); mReplaceEditor->setEnabled(have_trigger || have_replace); - mModifierCombo->setEnabled(TRUE); - mKeyCombo->setEnabled(TRUE); + mModifierCombo->setEnabled(true); + mKeyCombo->setEnabled(true); mAddBtn->setEnabled(modifiable && have_library); mUpBtn->setEnabled(modifiable && have_step && step_index > 0); @@ -691,13 +691,13 @@ void LLPreviewGesture::refresh() mDeleteBtn->setEnabled(modifiable && have_step); // Assume all not visible - mAnimationCombo->setVisible(FALSE); - mAnimationRadio->setVisible(FALSE); - mSoundCombo->setVisible(FALSE); - mChatEditor->setVisible(FALSE); - mWaitAnimCheck->setVisible(FALSE); - mWaitTimeCheck->setVisible(FALSE); - mWaitTimeEditor->setVisible(FALSE); + mAnimationCombo->setVisible(false); + mAnimationRadio->setVisible(false); + mSoundCombo->setVisible(false); + mChatEditor->setVisible(false); + mWaitAnimCheck->setVisible(false); + mWaitTimeCheck->setVisible(false); + mWaitTimeEditor->setVisible(false); std::string optionstext; @@ -713,8 +713,8 @@ void LLPreviewGesture::refresh() { LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; optionstext = getString("step_anim"); - mAnimationCombo->setVisible(TRUE); - mAnimationRadio->setVisible(TRUE); + mAnimationCombo->setVisible(true); + mAnimationRadio->setVisible(true); mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0); mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID); break; @@ -723,7 +723,7 @@ void LLPreviewGesture::refresh() { LLGestureStepSound* sound_step = (LLGestureStepSound*)step; optionstext = getString("step_sound"); - mSoundCombo->setVisible(TRUE); + mSoundCombo->setVisible(true); mSoundCombo->setCurrentByID(sound_step->mSoundAssetID); break; } @@ -731,7 +731,7 @@ void LLPreviewGesture::refresh() { LLGestureStepChat* chat_step = (LLGestureStepChat*)step; optionstext = getString("step_chat"); - mChatEditor->setVisible(TRUE); + mChatEditor->setVisible(true); mChatEditor->setText(chat_step->mChatText); break; } @@ -739,11 +739,11 @@ void LLPreviewGesture::refresh() { LLGestureStepWait* wait_step = (LLGestureStepWait*)step; optionstext = getString("step_wait"); - mWaitAnimCheck->setVisible(TRUE); + mWaitAnimCheck->setVisible(true); mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); - mWaitTimeCheck->setVisible(TRUE); + mWaitTimeCheck->setVisible(true); mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME); - mWaitTimeEditor->setVisible(TRUE); + mWaitTimeEditor->setVisible(true); std::string buffer = llformat("%.1f", (double)wait_step->mWaitSeconds); mWaitTimeEditor->setText(buffer); break; @@ -755,7 +755,7 @@ void LLPreviewGesture::refresh() mOptionsText->setText(optionstext); - BOOL active = LLGestureMgr::instance().isGestureActive(mItemUUID); + bool active = LLGestureMgr::instance().isGestureActive(mItemUUID); mActiveCheck->set(active); // Can only preview if there are steps @@ -791,7 +791,7 @@ void LLPreviewGesture::initDefaultGesture() mStepList->selectFirstItem(); // this is *new* content, so we are dirty - mDirty = TRUE; + mDirty = true; } @@ -824,7 +824,7 @@ void LLPreviewGesture::loadAsset() // window if the download gets stalled. LLUUID* item_idp = new LLUUID(mItemUUID); - const BOOL high_priority = TRUE; + const bool high_priority = true; gAssetStorage->getAssetData(asset_id, LLAssetType::AT_GESTURE, onLoadComplete, @@ -856,7 +856,7 @@ void LLPreviewGesture::onLoadComplete(const LLUUID& asset_uuid, LLMultiGesture* gesture = new LLMultiGesture(); LLDataPackerAsciiBuffer dp(&buffer[0], size+1); - BOOL ok = gesture->deserialize(dp); + bool ok = gesture->deserialize(dp); if (ok) { @@ -865,7 +865,7 @@ void LLPreviewGesture::onLoadComplete(const LLUUID& asset_uuid, self->mStepList->selectFirstItem(); - self->mDirty = FALSE; + self->mDirty = false; self->refresh(); self->refreshFromItem(); // to update description and title } @@ -1143,7 +1143,7 @@ void LLPreviewGesture::saveIfNeeded() LLLineEditor* descEditor = getChild("desc"); LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); - gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE); + gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, false); } } @@ -1342,7 +1342,7 @@ void LLPreviewGesture::onCommitKeyorModifier() mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), mModifierCombo->getSimple() != CTRL_LABEL); mModifierCombo->setEnabledByValue(CTRL_LABEL, mKeyCombo->getSimple() != LLKeyboard::stringFromKey(KEY_F10)); - mDirty = TRUE; + mDirty = true; refresh(); } @@ -1361,7 +1361,7 @@ void LLPreviewGesture::updateLabel(LLScrollListItem* item) void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data) { LLPreviewGesture* self = (LLPreviewGesture*)data; - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } @@ -1420,7 +1420,7 @@ void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } @@ -1451,7 +1451,7 @@ void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } @@ -1477,7 +1477,7 @@ void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } @@ -1501,7 +1501,7 @@ void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, void* data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } @@ -1537,7 +1537,7 @@ void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data) // Update the UI label in the list updateLabel(step_item); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } @@ -1552,7 +1552,7 @@ void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, void* data) LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); if (step->getType() != STEP_WAIT) return; - self->mWaitTimeCheck->set(TRUE); + self->mWaitTimeCheck->set(true); onCommitWait(ctrl, data); } @@ -1585,7 +1585,7 @@ void LLPreviewGesture::onClickAdd(void* data) } self->addStep( (EStepType)library_item_index ); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } @@ -1626,7 +1626,7 @@ LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type ) mLibraryList->deselectAllItems(); mStepList->deselectAllItems(); - step_item->setSelected(TRUE); + step_item->setSelected(true); return step_item; } @@ -1686,7 +1686,7 @@ void LLPreviewGesture::onClickUp(void* data) if (selected_index > 0) { self->mStepList->swapWithPrevious(selected_index); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } @@ -1703,7 +1703,7 @@ void LLPreviewGesture::onClickDown(void* data) if (selected_index < count-1) { self->mStepList->swapWithNext(selected_index); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } @@ -1723,7 +1723,7 @@ void LLPreviewGesture::onClickDelete(void* data) self->mStepList->deleteSingleItem(selected_index); - self->mDirty = TRUE; + self->mDirty = true; self->refresh(); } } -- cgit v1.2.3 From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/newview/llpreviewgesture.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 1f66db92d5..05faf17bdc 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -616,10 +616,9 @@ void LLPreviewGesture::refresh() LLPreview::refresh(); // If previewing or item is incomplete, all controls are disabled LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); - bool is_complete = (item && item->isFinished()) ? true : false; + bool is_complete = item && item->isFinished(); if (mPreviewGesture || !is_complete) { - getChildView("desc")->setEnabled(false); //mDescEditor->setEnabled(false); mTriggerEditor->setEnabled(false); -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/newview/llpreviewgesture.cpp | 3632 ++++++++++++++++++------------------ 1 file changed, 1816 insertions(+), 1816 deletions(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 010dc48391..56f23a0458 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1,1816 +1,1816 @@ -/** - * @file llpreviewgesture.cpp - * @brief Editing UI for inventory-based gestures. - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "llpreviewgesture.h" - -#include "llagent.h" -#include "llanimstatelabels.h" -#include "llanimationstates.h" -#include "llappviewer.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "lldatapacker.h" -#include "lldelayedgestureerror.h" -#include "llfloaterreg.h" -#include "llgesturemgr.h" -#include "llinventorydefines.h" -#include "llinventoryfunctions.h" -#include "llinventorymodel.h" -#include "llinventorymodelbackgroundfetch.h" -#include "llkeyboard.h" -#include "llmultigesture.h" -#include "llnotificationsutil.h" -#include "llradiogroup.h" -#include "llresmgr.h" -#include "lltrans.h" -#include "llfilesystem.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" -#include "llviewerstats.h" -#include "llviewerassetupload.h" - -std::string NONE_LABEL; -std::string SHIFT_LABEL; -std::string CTRL_LABEL; - -void dialog_refresh_all(); - -// used for getting - -class LLInventoryGestureAvailable : public LLInventoryCompletionObserver -{ -public: - LLInventoryGestureAvailable() {} - -protected: - virtual void done(); -}; - -void LLInventoryGestureAvailable::done() -{ - for(uuid_vec_t::iterator it = mComplete.begin(); it != mComplete.end(); ++it) - { - LLPreviewGesture* preview = LLFloaterReg::findTypedInstance("preview_gesture", *it); - if(preview) - { - preview->refresh(); - } - } - gInventory.removeObserver(this); - delete this; -} - -// Used for sorting -struct SortItemPtrsByName -{ - bool operator()(const LLInventoryItem* i1, const LLInventoryItem* i2) - { - return (LLStringUtil::compareDict(i1->getName(), i2->getName()) < 0); - } -}; - -// static -LLPreviewGesture* LLPreviewGesture::show(const LLUUID& item_id, const LLUUID& object_id) -{ - LLPreviewGesture* preview = LLFloaterReg::showTypedInstance("preview_gesture", LLSD(item_id), TAKE_FOCUS_YES); - if (!preview) - { - return NULL; - } - - preview->setObjectID(object_id); - - // Start speculative download of sounds and animations - const LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); - LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); - - const LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); - LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); - - // this will call refresh when we have everything. - LLViewerInventoryItem* item = (LLViewerInventoryItem*)preview->getItem(); - if (item && !item->isFinished()) - { - LLInventoryGestureAvailable* observer; - observer = new LLInventoryGestureAvailable(); - observer->watchItem(item_id); - gInventory.addObserver(observer); - item->fetchFromServer(); - } - else - { - // not sure this is necessary. - preview->refresh(); - } - - return preview; -} - -void LLPreviewGesture::draw() -{ - // Skip LLPreview::draw() to avoid description update - LLFloater::draw(); -} - -// virtual -bool LLPreviewGesture::handleKeyHere(KEY key, MASK mask) -{ - if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) - { - saveIfNeeded(); - return true; - } - - return LLPreview::handleKeyHere(key, mask); -} - - -// virtual -bool LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) -{ - bool handled = true; - switch(cargo_type) - { - case DAD_ANIMATION: - case DAD_SOUND: - { - // TODO: Don't allow this if you can't transfer the sound/animation - - // make a script step - LLInventoryItem* item = (LLInventoryItem*)cargo_data; - 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) - { - LLScrollListItem* line = NULL; - if (cargo_type == DAD_ANIMATION) - { - line = addStep( STEP_ANIMATION ); - LLGestureStepAnimation* anim = (LLGestureStepAnimation*)line->getUserdata(); - anim->mAnimAssetID = item->getAssetUUID(); - anim->mAnimName = item->getName(); - } - else if (cargo_type == DAD_SOUND) - { - line = addStep( STEP_SOUND ); - LLGestureStepSound* sound = (LLGestureStepSound*)line->getUserdata(); - sound->mSoundAssetID = item->getAssetUUID(); - sound->mSoundName = item->getName(); - } - updateLabel(line); - mDirty = true; - refresh(); - } - *accept = ACCEPT_YES_COPY_MULTI; - } - else - { - // Not in user's inventory means it was in object inventory - *accept = ACCEPT_NO; - } - break; - } - default: - *accept = ACCEPT_NO; - if (tooltip_msg.empty()) - { - tooltip_msg.assign("Only animations and sounds\n" - "can be added to a gesture."); - } - break; - } - return handled; -} - - -// virtual -bool LLPreviewGesture::canClose() -{ - - if(!mDirty || mForceClose) - { - return true; - } - else - { - if(!mSaveDialogShown) - { - mSaveDialogShown = true; - // Bring up view-modal dialog: Save changes? Yes, No, Cancel - LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), - boost::bind(&LLPreviewGesture::handleSaveChangesDialog, this, _1, _2) ); - } - return false; - } -} - -// virtual -void LLPreviewGesture::onClose(bool app_quitting) -{ - LLGestureMgr::instance().stopGesture(mPreviewGesture); -} - -// virtual -void LLPreviewGesture::onUpdateSucceeded() -{ - refresh(); -} - -void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility ) -{ - if (new_visibility.asBoolean()) - { - refresh(); - } -} - - -bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const LLSD& response) -{ - mSaveDialogShown = false; - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) - { - case 0: // "Yes" - LLGestureMgr::instance().stopGesture(mPreviewGesture); - mCloseAfterSave = true; - onClickSave(this); - break; - - case 1: // "No" - LLGestureMgr::instance().stopGesture(mPreviewGesture); - mDirty = false; // Force the dirty flag because user has clicked NO on confirm save dialog... - closeFloater(); - break; - - case 2: // "Cancel" - default: - // If we were quitting, we didn't really mean it. - LLAppViewer::instance()->abortQuit(); - break; - } - return false; -} - - -LLPreviewGesture::LLPreviewGesture(const LLSD& key) -: LLPreview(key), - mTriggerEditor(NULL), - mModifierCombo(NULL), - mKeyCombo(NULL), - mLibraryList(NULL), - mAddBtn(NULL), - mUpBtn(NULL), - mDownBtn(NULL), - mDeleteBtn(NULL), - mStepList(NULL), - mOptionsText(NULL), - mAnimationRadio(NULL), - mAnimationCombo(NULL), - mSoundCombo(NULL), - mChatEditor(NULL), - mSaveBtn(NULL), - mPreviewBtn(NULL), - mPreviewGesture(NULL), - mDirty(false) -{ - NONE_LABEL = LLTrans::getString("---"); - SHIFT_LABEL = LLTrans::getString("KBShift"); - CTRL_LABEL = LLTrans::getString("KBCtrl"); -} - - -LLPreviewGesture::~LLPreviewGesture() -{ - // Userdata for all steps is a LLGestureStep we need to clean up - std::vector data_list = mStepList->getAllData(); - std::vector::iterator data_itor; - for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) - { - LLScrollListItem* item = *data_itor; - LLGestureStep* step = (LLGestureStep*)item->getUserdata(); - delete step; - step = NULL; - } -} - - -bool LLPreviewGesture::postBuild() -{ - setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2)); - - LLLineEditor* edit; - LLComboBox* combo; - LLButton* btn; - LLScrollListCtrl* list; - LLTextBox* text; - LLCheckBoxCtrl* check; - - edit = getChild("desc"); - edit->setKeystrokeCallback(onKeystrokeCommit, this); - - edit = getChild("trigger_editor"); - edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitCallback(onCommitSetDirty, this); - edit->setCommitOnFocusLost(true); - edit->setIgnoreTab(true); - mTriggerEditor = edit; - - text = getChild("replace_text"); - text->setEnabled(false); - mReplaceText = text; - - edit = getChild("replace_editor"); - edit->setEnabled(false); - edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitCallback(onCommitSetDirty, this); - edit->setCommitOnFocusLost(true); - edit->setIgnoreTab(true); - mReplaceEditor = edit; - - combo = getChild( "modifier_combo"); - combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this)); - mModifierCombo = combo; - - combo = getChild( "key_combo"); - combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this)); - mKeyCombo = combo; - - list = getChild("library_list"); - list->setCommitCallback(onCommitLibrary, this); - list->setDoubleClickCallback(onClickAdd, this); - mLibraryList = list; - - btn = getChild( "add_btn"); - btn->setClickedCallback(onClickAdd, this); - btn->setEnabled(false); - mAddBtn = btn; - - btn = getChild( "up_btn"); - btn->setClickedCallback(onClickUp, this); - btn->setEnabled(false); - mUpBtn = btn; - - btn = getChild( "down_btn"); - btn->setClickedCallback(onClickDown, this); - btn->setEnabled(false); - mDownBtn = btn; - - btn = getChild( "delete_btn"); - btn->setClickedCallback(onClickDelete, this); - btn->setEnabled(false); - mDeleteBtn = btn; - - list = getChild("step_list"); - list->setCommitCallback(onCommitStep, this); - mStepList = list; - - // Options - mOptionsText = getChild("options_text"); - - combo = getChild( "animation_list"); - combo->setVisible(false); - combo->setCommitCallback(onCommitAnimation, this); - mAnimationCombo = combo; - - LLRadioGroup* group; - group = getChild("animation_trigger_type"); - group->setVisible(false); - group->setCommitCallback(onCommitAnimationTrigger, this); - mAnimationRadio = group; - - combo = getChild( "sound_list"); - combo->setVisible(false); - combo->setCommitCallback(onCommitSound, this); - mSoundCombo = combo; - - edit = getChild("chat_editor"); - edit->setVisible(false); - edit->setCommitCallback(onCommitChat, this); - //edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitOnFocusLost(true); - edit->setIgnoreTab(true); - mChatEditor = edit; - - check = getChild( "wait_key_release_check"); - check->setVisible(false); - check->setCommitCallback(onCommitWait, this); - mWaitKeyReleaseCheck = check; - - check = getChild( "wait_anim_check"); - check->setVisible(false); - check->setCommitCallback(onCommitWait, this); - mWaitAnimCheck = check; - - check = getChild( "wait_time_check"); - check->setVisible(false); - check->setCommitCallback(onCommitWait, this); - mWaitTimeCheck = check; - - edit = getChild("wait_time_editor"); - edit->setEnabled(false); - edit->setVisible(false); - edit->setPrevalidate(LLTextValidate::validateFloat); -// edit->setKeystrokeCallback(onKeystrokeCommit, this); - edit->setCommitOnFocusLost(true); - edit->setCommitCallback(onCommitWaitTime, this); - edit->setIgnoreTab(true); - mWaitTimeEditor = edit; - - // Buttons at the bottom - check = getChild( "active_check"); - check->setCommitCallback(onCommitActive, this); - mActiveCheck = check; - - btn = getChild( "save_btn"); - btn->setClickedCallback(onClickSave, this); - mSaveBtn = btn; - - btn = getChild( "preview_btn"); - btn->setClickedCallback(onClickPreview, this); - mPreviewBtn = btn; - - - // Populate the comboboxes - addModifiers(); - addKeys(); - addAnimations(); - addSounds(); - - const LLInventoryItem* item = getItem(); - - if (item) - { - getChild("desc")->setValue(item->getDescription()); - getChild("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); - } - - return LLPreview::postBuild(); -} - - -void LLPreviewGesture::addModifiers() -{ - LLComboBox* combo = mModifierCombo; - - combo->add( NONE_LABEL, ADD_BOTTOM ); - combo->add( SHIFT_LABEL, ADD_BOTTOM ); - combo->add( CTRL_LABEL, ADD_BOTTOM ); - combo->setCurrentByIndex(0); -} - -void LLPreviewGesture::addKeys() -{ - LLComboBox* combo = mKeyCombo; - - combo->add( NONE_LABEL ); - for (KEY key = KEY_F2; key <= KEY_F12; key++) - { - combo->add( LLKeyboard::stringFromKey(key), ADD_BOTTOM ); - } - combo->setCurrentByIndex(0); -} - - -// TODO: Sort the legacy and non-legacy together? -void LLPreviewGesture::addAnimations() -{ - LLComboBox* combo = mAnimationCombo; - - combo->removeall(); - - std::string none_text = getString("none_text"); - - combo->add(none_text, LLUUID::null); - - // Add all the default (legacy) animations - S32 i; - for (i = 0; i < gUserAnimStatesCount; ++i) - { - // Use the user-readable name - std::string label = LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ); - const LLUUID& id = gUserAnimStates[i].mID; - combo->add(label, id); - } - - // Get all inventory items that are animations - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION, - PERM_ITEM_UNRESTRICTED, - gAgent.getID(), - gAgent.getGroupID()); - gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_copyable_animation); - - // Copy into something we can sort - std::vector animations; - - S32 count = items.size(); - for(i = 0; i < count; ++i) - { - animations.push_back( items.at(i) ); - } - - // Do the sort - std::sort(animations.begin(), animations.end(), SortItemPtrsByName()); - - // And load up the combobox - std::vector::iterator it; - for (it = animations.begin(); it != animations.end(); ++it) - { - LLInventoryItem* item = *it; - - combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM); - } -} - - -void LLPreviewGesture::addSounds() -{ - LLComboBox* combo = mSoundCombo; - combo->removeall(); - - std::string none_text = getString("none_text"); - - combo->add(none_text, LLUUID::null); - - // Get all inventory items that are sounds - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLIsTypeWithPermissions is_copyable_sound(LLAssetType::AT_SOUND, - PERM_ITEM_UNRESTRICTED, - gAgent.getID(), - gAgent.getGroupID()); - gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_copyable_sound); - - // Copy sounds into something we can sort - std::vector sounds; - - S32 i; - S32 count = items.size(); - for(i = 0; i < count; ++i) - { - sounds.push_back( items.at(i) ); - } - - // Do the sort - std::sort(sounds.begin(), sounds.end(), SortItemPtrsByName()); - - // And load up the combobox - std::vector::iterator it; - for (it = sounds.begin(); it != sounds.end(); ++it) - { - LLInventoryItem* item = *it; - - combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM); - } -} - - -void LLPreviewGesture::refresh() -{ - LLPreview::refresh(); - // If previewing or item is incomplete, all controls are disabled - LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); - bool is_complete = item && item->isFinished(); - if (mPreviewGesture || !is_complete) - { - - getChildView("desc")->setEnabled(false); - //mDescEditor->setEnabled(false); - mTriggerEditor->setEnabled(false); - mReplaceText->setEnabled(false); - mReplaceEditor->setEnabled(false); - mModifierCombo->setEnabled(false); - mKeyCombo->setEnabled(false); - mLibraryList->setEnabled(false); - mAddBtn->setEnabled(false); - mUpBtn->setEnabled(false); - mDownBtn->setEnabled(false); - mDeleteBtn->setEnabled(false); - mStepList->setEnabled(false); - mOptionsText->setEnabled(false); - mAnimationCombo->setEnabled(false); - mAnimationRadio->setEnabled(false); - mSoundCombo->setEnabled(false); - mChatEditor->setEnabled(false); - mWaitKeyReleaseCheck->setEnabled(false); - mWaitAnimCheck->setEnabled(false); - mWaitTimeCheck->setEnabled(false); - mWaitTimeEditor->setEnabled(false); - mActiveCheck->setEnabled(false); - mSaveBtn->setEnabled(false); - - // Make sure preview button is enabled, so we can stop it - mPreviewBtn->setEnabled(true); - return; - } - - bool modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); - - getChildView("desc")->setEnabled(modifiable); - mTriggerEditor->setEnabled(true); - mLibraryList->setEnabled(modifiable); - mStepList->setEnabled(modifiable); - mOptionsText->setEnabled(modifiable); - mAnimationCombo->setEnabled(modifiable); - mAnimationRadio->setEnabled(modifiable); - mSoundCombo->setEnabled(modifiable); - mChatEditor->setEnabled(modifiable); - mWaitKeyReleaseCheck->setEnabled(modifiable); - mWaitAnimCheck->setEnabled(modifiable); - mWaitTimeCheck->setEnabled(modifiable); - mWaitTimeEditor->setEnabled(modifiable); - mActiveCheck->setEnabled(true); - - const std::string& trigger = mTriggerEditor->getText(); - bool have_trigger = !trigger.empty(); - - const std::string& replace = mReplaceEditor->getText(); - bool have_replace = !replace.empty(); - - LLScrollListItem* library_item = mLibraryList->getFirstSelected(); - bool have_library = (library_item != NULL); - - LLScrollListItem* step_item = mStepList->getFirstSelected(); - S32 step_index = mStepList->getFirstSelectedIndex(); - S32 step_count = mStepList->getItemCount(); - bool have_step = (step_item != NULL); - - mReplaceText->setEnabled(have_trigger || have_replace); - mReplaceEditor->setEnabled(have_trigger || have_replace); - - mModifierCombo->setEnabled(true); - mKeyCombo->setEnabled(true); - - mAddBtn->setEnabled(modifiable && have_library); - mUpBtn->setEnabled(modifiable && have_step && step_index > 0); - mDownBtn->setEnabled(modifiable && have_step && step_index < step_count-1); - mDeleteBtn->setEnabled(modifiable && have_step); - - // Assume all not visible - mAnimationCombo->setVisible(false); - mAnimationRadio->setVisible(false); - mSoundCombo->setVisible(false); - mChatEditor->setVisible(false); - mWaitKeyReleaseCheck->setVisible(false); - mWaitAnimCheck->setVisible(false); - mWaitTimeCheck->setVisible(false); - mWaitTimeEditor->setVisible(false); - - std::string optionstext; - - if (have_step) - { - // figure out the type, show proper options, update text - LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - EStepType type = step->getType(); - - switch(type) - { - case STEP_ANIMATION: - { - LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - optionstext = getString("step_anim"); - mAnimationCombo->setVisible(true); - mAnimationRadio->setVisible(true); - mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0); - mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID); - break; - } - case STEP_SOUND: - { - LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - optionstext = getString("step_sound"); - mSoundCombo->setVisible(true); - mSoundCombo->setCurrentByID(sound_step->mSoundAssetID); - break; - } - case STEP_CHAT: - { - LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - optionstext = getString("step_chat"); - mChatEditor->setVisible(true); - mChatEditor->setText(chat_step->mChatText); - break; - } - case STEP_WAIT: - { - LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - optionstext = getString("step_wait"); - mWaitKeyReleaseCheck->setVisible(true); - mWaitKeyReleaseCheck->set(wait_step->mFlags & WAIT_FLAG_KEY_RELEASE); - mWaitAnimCheck->setVisible(true); - mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); - mWaitTimeCheck->setVisible(true); - mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME); - mWaitTimeEditor->setVisible(true); - std::string buffer = llformat("%.1f", (double)wait_step->mWaitSeconds); - mWaitTimeEditor->setText(buffer); - break; - } - default: - break; - } - } - - mOptionsText->setText(optionstext); - - bool active = LLGestureMgr::instance().isGestureActive(mItemUUID); - mActiveCheck->set(active); - - // Can only preview if there are steps - mPreviewBtn->setEnabled(step_count > 0); - - // And can only save if changes have been made - mSaveBtn->setEnabled(mDirty); - addAnimations(); - addSounds(); -} - - -void LLPreviewGesture::initDefaultGesture() -{ - LLScrollListItem* item; - item = addStep( STEP_ANIMATION ); - LLGestureStepAnimation* anim = (LLGestureStepAnimation*)item->getUserdata(); - anim->mAnimAssetID = ANIM_AGENT_HELLO; - anim->mAnimName = LLTrans::getString("Wave"); - updateLabel(item); - - item = addStep( STEP_WAIT ); - LLGestureStepWait* wait = (LLGestureStepWait*)item->getUserdata(); - wait->mFlags = WAIT_FLAG_ALL_ANIM; - updateLabel(item); - - item = addStep( STEP_CHAT ); - LLGestureStepChat* chat_step = (LLGestureStepChat*)item->getUserdata(); - chat_step->mChatText = LLTrans::getString("HelloAvatar"); - updateLabel(item); - - // Start with item list selected - mStepList->selectFirstItem(); - - // this is *new* content, so we are dirty - mDirty = true; -} - - -void LLPreviewGesture::loadAsset() -{ - const LLInventoryItem* item = getItem(); - if (!item) - { - // Don't set asset status here; we may not have set the item id yet - // (e.g. when this gets called initially) - //mAssetStatus = PREVIEW_ASSET_ERROR; - return; - } - - LLUUID asset_id = item->getAssetUUID(); - if (asset_id.isNull()) - { - // Freshly created gesture, don't need to load asset. - // Blank gesture will be fine. - initDefaultGesture(); - refresh(); - mAssetStatus = PREVIEW_ASSET_LOADED; - return; - } - - // TODO: Based on item->getPermissions().allow* - // could enable/disable UI. - - // Copy the UUID, because the user might close the preview - // window if the download gets stalled. - LLUUID* item_idp = new LLUUID(mItemUUID); - - const bool high_priority = true; - gAssetStorage->getAssetData(asset_id, - LLAssetType::AT_GESTURE, - onLoadComplete, - (void**)item_idp, - high_priority); - mAssetStatus = PREVIEW_ASSET_LOADING; -} - - -// static -void LLPreviewGesture::onLoadComplete(const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) -{ - LLUUID* item_idp = (LLUUID*)user_data; - - LLPreviewGesture* self = LLFloaterReg::findTypedInstance("preview_gesture", *item_idp); - if (self) - { - if (0 == status) - { - LLFileSystem file(asset_uuid, type, LLFileSystem::READ); - S32 size = file.getSize(); - - std::vector buffer(size+1); - file.read((U8*)&buffer[0], size); - buffer[size] = '\0'; - - LLMultiGesture* gesture = new LLMultiGesture(); - - LLDataPackerAsciiBuffer dp(&buffer[0], size+1); - bool ok = gesture->deserialize(dp); - - if (ok) - { - // Everything has been successful. Load up the UI. - self->loadUIFromGesture(gesture); - - self->mStepList->selectFirstItem(); - - self->mDirty = false; - self->refresh(); - self->refreshFromItem(); // to update description and title - } - else - { - LL_WARNS() << "Unable to load gesture" << LL_ENDL; - } - - delete gesture; - gesture = NULL; - - self->mAssetStatus = PREVIEW_ASSET_LOADED; - } - else - { - if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || - LL_ERR_FILE_EMPTY == status) - { - LLDelayedGestureError::gestureMissing( *item_idp ); - } - else - { - LLDelayedGestureError::gestureFailedToLoad( *item_idp ); - } - - LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; - self->mAssetStatus = PREVIEW_ASSET_ERROR; - } - } - delete item_idp; - item_idp = NULL; -} - - -void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture) -{ - /*LLInventoryItem* item = getItem(); - - - - if (item) - { - LLLineEditor* descEditor = getChild("desc"); - descEditor->setText(item->getDescription()); - }*/ - - mTriggerEditor->setText(gesture->mTrigger); - - mReplaceEditor->setText(gesture->mReplaceText); - - switch (gesture->mMask) - { - default: - case MASK_NONE: - mModifierCombo->setSimple( NONE_LABEL ); - break; - case MASK_SHIFT: - mModifierCombo->setSimple( SHIFT_LABEL ); - break; - case MASK_CONTROL: - mModifierCombo->setSimple( CTRL_LABEL ); - break; - } - - mModifierCombo->setEnabledByValue(CTRL_LABEL, gesture->mKey != KEY_F10); - - mKeyCombo->setCurrentByIndex(0); - if (gesture->mKey != KEY_NONE) - { - mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey)); - } - - mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), gesture->mMask != MASK_CONTROL); - - // Make UI steps for each gesture step - S32 i; - S32 count = gesture->mSteps.size(); - for (i = 0; i < count; ++i) - { - LLGestureStep* step = gesture->mSteps[i]; - - LLGestureStep* new_step = NULL; - - switch(step->getType()) - { - case STEP_ANIMATION: - { - LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - LLGestureStepAnimation* new_anim_step = - new LLGestureStepAnimation(*anim_step); - new_step = new_anim_step; - break; - } - case STEP_SOUND: - { - LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - LLGestureStepSound* new_sound_step = - new LLGestureStepSound(*sound_step); - new_step = new_sound_step; - break; - } - case STEP_CHAT: - { - LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - LLGestureStepChat* new_chat_step = - new LLGestureStepChat(*chat_step); - new_step = new_chat_step; - break; - } - case STEP_WAIT: - { - LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - LLGestureStepWait* new_wait_step = - new LLGestureStepWait(*wait_step); - new_step = new_wait_step; - break; - } - default: - { - break; - } - } - - if (!new_step) continue; - - // Create an enabled item with this step - LLSD row; - row["columns"][0]["value"] = getLabel( new_step->getLabel()); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - LLScrollListItem* item = mStepList->addElement(row); - item->setUserdata(new_step); - } -} - -// Helpful structure so we can look up the inventory item -// after the save finishes. -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; -}; - - -void LLPreviewGesture::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId) -{ - // If this gesture is active, then we need to update the in-memory - // active map with the new pointer. - if (LLGestureMgr::instance().isGestureActive(itemId)) - { - // Active gesture edited from menu. - LLGestureMgr::instance().replaceGesture(itemId, newAssetId); - gInventory.notifyObservers(); - } - - //gesture will have a new asset_id - LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance("preview_gesture", LLSD(itemId)); - if (previewp) - { - previewp->onUpdateSucceeded(); - } -} - - -void LLPreviewGesture::saveIfNeeded() -{ - if (!gAssetStorage) - { - LL_WARNS() << "Can't save gesture, no asset storage system." << LL_ENDL; - return; - } - - if (!mDirty) - { - return; - } - - // Copy the UI into a gesture - LLMultiGesture* gesture = createGesture(); - - // Serialize the gesture - S32 maxSize = gesture->getMaxSerialSize(); - char* buffer = new char[maxSize]; - - LLDataPackerAsciiBuffer dp(buffer, maxSize); - - bool ok = gesture->serialize(dp); - - if (dp.getCurrentSize() > 1000) - { - LLNotificationsUtil::add("GestureSaveFailedTooManySteps"); - - delete gesture; - gesture = NULL; - return; - } - else if (!ok) - { - LLNotificationsUtil::add("GestureSaveFailedTryAgain"); - delete gesture; - gesture = NULL; - return; - } - - LLAssetID assetId; - LLPreview::onCommit(); - bool delayedUpload(false); - - LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem(); - if (item) - { - const LLViewerRegion* region = gAgent.getRegion(); - if (!region) - { - LL_WARNS() << "Not connected to a region, cannot save gesture." << LL_ENDL; - return; - } - std::string agent_url = region->getCapability("UpdateGestureAgentInventory"); - std::string task_url = region->getCapability("UpdateGestureTaskInventory"); - - if (!agent_url.empty() && !task_url.empty()) - { - std::string url; - LLResourceUploadInfo::ptr_t uploadInfo; - - if (mObjectUUID.isNull() && !agent_url.empty()) - { - //need to disable the preview floater so item - //isn't re-saved before new asset arrives - //fake out refresh. - item->setComplete(false); - refresh(); - item->setComplete(true); - - uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_GESTURE, buffer, - [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD) - { - LLPreviewGesture::finishInventoryUpload(itemId, newAssetId); - }, - nullptr); - url = agent_url; - } - else if (!mObjectUUID.isNull() && !task_url.empty()) - { - uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr, nullptr); - url = task_url; - } - - if (!url.empty() && uploadInfo) - { - delayedUpload = true; - - LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); - } - - } - else if (gAssetStorage) - { - // Every save gets a new UUID. Yup. - LLTransactionID tid; - tid.generate(); - assetId = tid.makeAssetID(gAgent.getSecureSessionID()); - - LLFileSystem file(assetId, LLAssetType::AT_GESTURE, LLFileSystem::APPEND); - - S32 size = dp.getCurrentSize(); - file.write((U8*)buffer, size); - - LLLineEditor* descEditor = getChild("desc"); - LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); - gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, false); - } - - } - - // If this gesture is active, then we need to update the in-memory - // active map with the new pointer. - if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID)) - { - // gesture manager now owns the pointer - LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, assetId); - - // replaceGesture may deactivate other gestures so let the - // inventory know. - gInventory.notifyObservers(); - } - else - { - // we're done with this gesture - delete gesture; - gesture = NULL; - } - - mDirty = false; - // refresh will be called when callback - // if triggered when delayedUpload - if(!delayedUpload) - { - refresh(); - } - -} - - -// TODO: This is very similar to LLPreviewNotecard::onSaveComplete. -// Could merge code. -// static -void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) -{ - LLSaveInfo* info = (LLSaveInfo*)user_data; - if (info && (status == 0)) - { - if(info->mObjectUUID.isNull()) - { - // Saving into user inventory - LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID); - if(item) - { - LLPointer new_item = new LLViewerInventoryItem(item); - new_item->setDescription(info->mDesc); - new_item->setTransactionID(info->mTransactionID); - new_item->setAssetUUID(asset_uuid); - new_item->updateServer(false); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - LL_WARNS() << "Inventory item for gesture " << info->mItemUUID - << " is no longer in agent inventory." << LL_ENDL; - } - } - else - { - // Saving into in-world object inventory - LLViewerObject* object = gObjectList.findObject(info->mObjectUUID); - LLViewerInventoryItem* item = NULL; - if(object) - { - item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID); - } - if(object && item) - { - item->setDescription(info->mDesc); - item->setAssetUUID(asset_uuid); - item->setTransactionID(info->mTransactionID); - object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false); - dialog_refresh_all(); - } - else - { - LLNotificationsUtil::add("GestureSaveFailedObjectNotFound"); - } - } - - // Find our window and close it if requested. - LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance("preview_gesture", info->mItemUUID); - if (previewp && previewp->mCloseAfterSave) - { - previewp->closeFloater(); - } - } - else - { - LL_WARNS() << "Problem saving gesture: " << status << LL_ENDL; - LLSD args; - args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); - LLNotificationsUtil::add("GestureSaveFailedReason", args); - } - delete info; - info = NULL; -} - - -LLMultiGesture* LLPreviewGesture::createGesture() -{ - LLMultiGesture* gesture = new LLMultiGesture(); - - gesture->mTrigger = mTriggerEditor->getText(); - gesture->mReplaceText = mReplaceEditor->getText(); - - const std::string& modifier = mModifierCombo->getSimple(); - if (modifier == CTRL_LABEL) - { - gesture->mMask = MASK_CONTROL; - } - else if (modifier == SHIFT_LABEL) - { - gesture->mMask = MASK_SHIFT; - } - else - { - gesture->mMask = MASK_NONE; - } - - if (mKeyCombo->getCurrentIndex() == 0) - { - gesture->mKey = KEY_NONE; - } - else - { - const std::string& key_string = mKeyCombo->getSimple(); - LLKeyboard::keyFromString(key_string, &(gesture->mKey)); - } - - std::vector data_list = mStepList->getAllData(); - std::vector::iterator data_itor; - for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) - { - LLScrollListItem* item = *data_itor; - LLGestureStep* step = (LLGestureStep*)item->getUserdata(); - - switch(step->getType()) - { - case STEP_ANIMATION: - { - // Copy UI-generated step into actual gesture step - LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - LLGestureStepAnimation* new_anim_step = - new LLGestureStepAnimation(*anim_step); - gesture->mSteps.push_back(new_anim_step); - break; - } - case STEP_SOUND: - { - // Copy UI-generated step into actual gesture step - LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - LLGestureStepSound* new_sound_step = - new LLGestureStepSound(*sound_step); - gesture->mSteps.push_back(new_sound_step); - break; - } - case STEP_CHAT: - { - // Copy UI-generated step into actual gesture step - LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - LLGestureStepChat* new_chat_step = - new LLGestureStepChat(*chat_step); - gesture->mSteps.push_back(new_chat_step); - break; - } - case STEP_WAIT: - { - // Copy UI-generated step into actual gesture step - LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - LLGestureStepWait* new_wait_step = - new LLGestureStepWait(*wait_step); - gesture->mSteps.push_back(new_wait_step); - break; - } - default: - { - break; - } - } - } - - return gesture; -} - - -void LLPreviewGesture::onCommitKeyorModifier() -{ - // SL-14139: ctrl-F10 is currently used to access top menu, - // so don't allow to bound gestures to this combination. - - mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), mModifierCombo->getSimple() != CTRL_LABEL); - mModifierCombo->setEnabledByValue(CTRL_LABEL, mKeyCombo->getSimple() != LLKeyboard::stringFromKey(KEY_F10)); - mDirty = true; - refresh(); -} - -// static -void LLPreviewGesture::updateLabel(LLScrollListItem* item) -{ - LLGestureStep* step = (LLGestureStep*)item->getUserdata(); - - LLScrollListCell* cell = item->getColumn(0); - LLScrollListText* text_cell = (LLScrollListText*)cell; - std::string label = getLabel( step->getLabel()); - text_cell->setText(label); -} - -// static -void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->mDirty = true; - self->refresh(); -} - -// static -void LLPreviewGesture::onCommitLibrary(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); - if (library_item) - { - self->mStepList->deselectAllItems(); - self->refresh(); - } -} - - -// static -void LLPreviewGesture::onCommitStep(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); - if (!step_item) return; - - self->mLibraryList->deselectAllItems(); - self->refresh(); -} - - -// static -void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); - if (step_item) - { - LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - if (step->getType() == STEP_ANIMATION) - { - // Assign the animation name - LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationCombo->getCurrentIndex() == 0) - { - anim_step->mAnimName.clear(); - anim_step->mAnimAssetID.setNull(); - } - else - { - anim_step->mAnimName = self->mAnimationCombo->getSimple(); - anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID(); - } - //anim_step->mFlags = 0x0; - - // Update the UI label in the list - updateLabel(step_item); - - self->mDirty = true; - self->refresh(); - } - } -} - -// static -void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); - if (step_item) - { - LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - if (step->getType() == STEP_ANIMATION) - { - LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationRadio->getSelectedIndex() == 0) - { - // start - anim_step->mFlags &= ~ANIM_FLAG_STOP; - } - else - { - // stop - anim_step->mFlags |= ANIM_FLAG_STOP; - } - // Update the UI label in the list - updateLabel(step_item); - - self->mDirty = true; - self->refresh(); - } - } -} - -// static -void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* step_item = self->mStepList->getFirstSelected(); - if (step_item) - { - LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); - if (step->getType() == STEP_SOUND) - { - // Assign the sound name - LLGestureStepSound* sound_step = (LLGestureStepSound*)step; - sound_step->mSoundName = self->mSoundCombo->getSimple(); - sound_step->mSoundAssetID = self->mSoundCombo->getCurrentID(); - sound_step->mFlags = 0x0; - - // Update the UI label in the list - updateLabel(step_item); - - self->mDirty = true; - self->refresh(); - } - } -} - -// static -void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, 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_CHAT) return; - - LLGestureStepChat* chat_step = (LLGestureStepChat*)step; - chat_step->mChatText = self->mChatEditor->getText(); - chat_step->mFlags = 0x0; - - // Update the UI label in the list - updateLabel(step_item); - - self->mDirty = true; - self->refresh(); -} - -// static -void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, 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_WAIT) return; - - LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - U32 flags = 0x0; - if (self->mWaitKeyReleaseCheck->get()) flags |= WAIT_FLAG_KEY_RELEASE; - if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; - if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; - wait_step->mFlags = flags; - - { - LLLocale locale(LLLocale::USER_LOCALE); - - F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str()); - if (wait_seconds < 0.f) wait_seconds = 0.f; - if (wait_seconds > 3600.f) wait_seconds = 3600.f; - wait_step->mWaitSeconds = wait_seconds; - } - - // Enable the input area if necessary - self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get()); - - // Update the UI label in the list - updateLabel(step_item); - - self->mDirty = true; - self->refresh(); -} - -// static -void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, 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_WAIT) return; - - self->mWaitTimeCheck->set(true); - onCommitWait(ctrl, data); -} - - -// static -void LLPreviewGesture::onKeystrokeCommit(LLLineEditor* caller, - void* data) -{ - // Just commit every keystroke - onCommitSetDirty(caller, data); -} - -// static -void LLPreviewGesture::onClickAdd(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); - if (!library_item) return; - - S32 library_item_index = self->mLibraryList->getFirstSelectedIndex(); - - const LLScrollListCell* library_cell = library_item->getColumn(0); - const std::string& library_text = library_cell->getValue().asString(); - - if( library_item_index >= STEP_EOF ) - { - LL_ERRS() << "Unknown step type: " << library_text << LL_ENDL; - return; - } - - self->addStep( (EStepType)library_item_index ); - self->mDirty = true; - self->refresh(); -} - -LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type ) -{ - // Order of enum EStepType MUST match the library_list element in floater_preview_gesture.xml - - LLGestureStep* step = NULL; - switch( step_type) - { - case STEP_ANIMATION: - step = new LLGestureStepAnimation(); - - break; - case STEP_SOUND: - step = new LLGestureStepSound(); - break; - case STEP_CHAT: - step = new LLGestureStepChat(); - break; - case STEP_WAIT: - step = new LLGestureStepWait(); - break; - default: - LL_ERRS() << "Unknown step type: " << (S32)step_type << LL_ENDL; - return NULL; - } - - - // Create an enabled item with this step - LLSD row; - row["columns"][0]["value"] = getLabel(step->getLabel()); - row["columns"][0]["font"] = "SANSSERIF_SMALL"; - LLScrollListItem* step_item = mStepList->addElement(row); - step_item->setUserdata(step); - - // And move selection to the list on the right - mLibraryList->deselectAllItems(); - mStepList->deselectAllItems(); - - step_item->setSelected(true); - - return step_item; -} - -// static -std::string LLPreviewGesture::getLabel(std::vector labels) -{ - std::vector v_labels = labels ; - std::string result(""); - - if( v_labels.size() != 2) - { - return result; - } - - if(v_labels[0]=="Chat") - { - result=LLTrans::getString("Chat Message"); - } - else if(v_labels[0]=="Sound") - { - result=LLTrans::getString("Sound"); - } - else if(v_labels[0]=="Wait") - { - result=LLTrans::getString("Wait"); - } - else if(v_labels[0]=="AnimFlagStop") - { - result=LLTrans::getString("AnimFlagStop"); - } - else if(v_labels[0]=="AnimFlagStart") - { - result=LLTrans::getString("AnimFlagStart"); - } - - // lets localize action value - std::string action = v_labels[1]; - if ("None" == action) - { - action = LLTrans::getString("GestureActionNone"); - } - else if ("until animations are done" == action) - { - action = LLFloaterReg::getInstance("preview_gesture")->getChild("wait_anim_check")->getLabel(); - } - result.append(action); - return result; - -} -// static -void LLPreviewGesture::onClickUp(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - S32 selected_index = self->mStepList->getFirstSelectedIndex(); - if (selected_index > 0) - { - self->mStepList->swapWithPrevious(selected_index); - self->mDirty = true; - self->refresh(); - } -} - -// static -void LLPreviewGesture::onClickDown(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - S32 selected_index = self->mStepList->getFirstSelectedIndex(); - if (selected_index < 0) return; - - S32 count = self->mStepList->getItemCount(); - if (selected_index < count-1) - { - self->mStepList->swapWithNext(selected_index); - self->mDirty = true; - self->refresh(); - } -} - -// static -void LLPreviewGesture::onClickDelete(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - LLScrollListItem* item = self->mStepList->getFirstSelected(); - S32 selected_index = self->mStepList->getFirstSelectedIndex(); - if (item && selected_index >= 0) - { - LLGestureStep* step = (LLGestureStep*)item->getUserdata(); - delete step; - step = NULL; - - self->mStepList->deleteSingleItem(selected_index); - - self->mDirty = true; - self->refresh(); - } -} - -// static -void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - if (!LLGestureMgr::instance().isGestureActive(self->mItemUUID)) - { - LLGestureMgr::instance().activateGesture(self->mItemUUID); - } - else - { - LLGestureMgr::instance().deactivateGesture(self->mItemUUID); - } - - // Make sure the (active) label in the inventory gets updated. - LLViewerInventoryItem* item = gInventory.getItem(self->mItemUUID); - if (item) - { - gInventory.updateItem(item); - gInventory.notifyObservers(); - } - - self->refresh(); -} - -// static -void LLPreviewGesture::onClickSave(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - self->saveIfNeeded(); -} - -// static -void LLPreviewGesture::onClickPreview(void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - if (!self->mPreviewGesture) - { - // make temporary gesture - self->mPreviewGesture = self->createGesture(); - - // add a callback - self->mPreviewGesture->mDoneCallback = onDonePreview; - self->mPreviewGesture->mCallbackData = self; - - // set the button title - self->mPreviewBtn->setLabel(self->getString("stop_txt")); - - // play it, and delete when done - LLGestureMgr::instance().playGesture(self->mPreviewGesture); - - self->refresh(); - } - else - { - // Will call onDonePreview() below - LLGestureMgr::instance().stopGesture(self->mPreviewGesture); - - self->refresh(); - } -} - - -// static -void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data) -{ - LLPreviewGesture* self = (LLPreviewGesture*)data; - - self->mPreviewBtn->setLabel(self->getString("preview_txt")); - - delete self->mPreviewGesture; - self->mPreviewGesture = NULL; - - self->refresh(); -} +/** + * @file llpreviewgesture.cpp + * @brief Editing UI for inventory-based gestures. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llpreviewgesture.h" + +#include "llagent.h" +#include "llanimstatelabels.h" +#include "llanimationstates.h" +#include "llappviewer.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "lldatapacker.h" +#include "lldelayedgestureerror.h" +#include "llfloaterreg.h" +#include "llgesturemgr.h" +#include "llinventorydefines.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorymodelbackgroundfetch.h" +#include "llkeyboard.h" +#include "llmultigesture.h" +#include "llnotificationsutil.h" +#include "llradiogroup.h" +#include "llresmgr.h" +#include "lltrans.h" +#include "llfilesystem.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewerassetupload.h" + +std::string NONE_LABEL; +std::string SHIFT_LABEL; +std::string CTRL_LABEL; + +void dialog_refresh_all(); + +// used for getting + +class LLInventoryGestureAvailable : public LLInventoryCompletionObserver +{ +public: + LLInventoryGestureAvailable() {} + +protected: + virtual void done(); +}; + +void LLInventoryGestureAvailable::done() +{ + for(uuid_vec_t::iterator it = mComplete.begin(); it != mComplete.end(); ++it) + { + LLPreviewGesture* preview = LLFloaterReg::findTypedInstance("preview_gesture", *it); + if(preview) + { + preview->refresh(); + } + } + gInventory.removeObserver(this); + delete this; +} + +// Used for sorting +struct SortItemPtrsByName +{ + bool operator()(const LLInventoryItem* i1, const LLInventoryItem* i2) + { + return (LLStringUtil::compareDict(i1->getName(), i2->getName()) < 0); + } +}; + +// static +LLPreviewGesture* LLPreviewGesture::show(const LLUUID& item_id, const LLUUID& object_id) +{ + LLPreviewGesture* preview = LLFloaterReg::showTypedInstance("preview_gesture", LLSD(item_id), TAKE_FOCUS_YES); + if (!preview) + { + return NULL; + } + + preview->setObjectID(object_id); + + // Start speculative download of sounds and animations + const LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ANIMATION); + LLInventoryModelBackgroundFetch::instance().start(animation_folder_id); + + const LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SOUND); + LLInventoryModelBackgroundFetch::instance().start(sound_folder_id); + + // this will call refresh when we have everything. + LLViewerInventoryItem* item = (LLViewerInventoryItem*)preview->getItem(); + if (item && !item->isFinished()) + { + LLInventoryGestureAvailable* observer; + observer = new LLInventoryGestureAvailable(); + observer->watchItem(item_id); + gInventory.addObserver(observer); + item->fetchFromServer(); + } + else + { + // not sure this is necessary. + preview->refresh(); + } + + return preview; +} + +void LLPreviewGesture::draw() +{ + // Skip LLPreview::draw() to avoid description update + LLFloater::draw(); +} + +// virtual +bool LLPreviewGesture::handleKeyHere(KEY key, MASK mask) +{ + if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL))) + { + saveIfNeeded(); + return true; + } + + return LLPreview::handleKeyHere(key, mask); +} + + +// virtual +bool LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + bool handled = true; + switch(cargo_type) + { + case DAD_ANIMATION: + case DAD_SOUND: + { + // TODO: Don't allow this if you can't transfer the sound/animation + + // make a script step + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + 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) + { + LLScrollListItem* line = NULL; + if (cargo_type == DAD_ANIMATION) + { + line = addStep( STEP_ANIMATION ); + LLGestureStepAnimation* anim = (LLGestureStepAnimation*)line->getUserdata(); + anim->mAnimAssetID = item->getAssetUUID(); + anim->mAnimName = item->getName(); + } + else if (cargo_type == DAD_SOUND) + { + line = addStep( STEP_SOUND ); + LLGestureStepSound* sound = (LLGestureStepSound*)line->getUserdata(); + sound->mSoundAssetID = item->getAssetUUID(); + sound->mSoundName = item->getName(); + } + updateLabel(line); + mDirty = true; + refresh(); + } + *accept = ACCEPT_YES_COPY_MULTI; + } + else + { + // Not in user's inventory means it was in object inventory + *accept = ACCEPT_NO; + } + break; + } + default: + *accept = ACCEPT_NO; + if (tooltip_msg.empty()) + { + tooltip_msg.assign("Only animations and sounds\n" + "can be added to a gesture."); + } + break; + } + return handled; +} + + +// virtual +bool LLPreviewGesture::canClose() +{ + + if(!mDirty || mForceClose) + { + return true; + } + else + { + if(!mSaveDialogShown) + { + mSaveDialogShown = true; + // Bring up view-modal dialog: Save changes? Yes, No, Cancel + LLNotificationsUtil::add("SaveChanges", LLSD(), LLSD(), + boost::bind(&LLPreviewGesture::handleSaveChangesDialog, this, _1, _2) ); + } + return false; + } +} + +// virtual +void LLPreviewGesture::onClose(bool app_quitting) +{ + LLGestureMgr::instance().stopGesture(mPreviewGesture); +} + +// virtual +void LLPreviewGesture::onUpdateSucceeded() +{ + refresh(); +} + +void LLPreviewGesture::onVisibilityChanged ( const LLSD& new_visibility ) +{ + if (new_visibility.asBoolean()) + { + refresh(); + } +} + + +bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const LLSD& response) +{ + mSaveDialogShown = false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch(option) + { + case 0: // "Yes" + LLGestureMgr::instance().stopGesture(mPreviewGesture); + mCloseAfterSave = true; + onClickSave(this); + break; + + case 1: // "No" + LLGestureMgr::instance().stopGesture(mPreviewGesture); + mDirty = false; // Force the dirty flag because user has clicked NO on confirm save dialog... + closeFloater(); + break; + + case 2: // "Cancel" + default: + // If we were quitting, we didn't really mean it. + LLAppViewer::instance()->abortQuit(); + break; + } + return false; +} + + +LLPreviewGesture::LLPreviewGesture(const LLSD& key) +: LLPreview(key), + mTriggerEditor(NULL), + mModifierCombo(NULL), + mKeyCombo(NULL), + mLibraryList(NULL), + mAddBtn(NULL), + mUpBtn(NULL), + mDownBtn(NULL), + mDeleteBtn(NULL), + mStepList(NULL), + mOptionsText(NULL), + mAnimationRadio(NULL), + mAnimationCombo(NULL), + mSoundCombo(NULL), + mChatEditor(NULL), + mSaveBtn(NULL), + mPreviewBtn(NULL), + mPreviewGesture(NULL), + mDirty(false) +{ + NONE_LABEL = LLTrans::getString("---"); + SHIFT_LABEL = LLTrans::getString("KBShift"); + CTRL_LABEL = LLTrans::getString("KBCtrl"); +} + + +LLPreviewGesture::~LLPreviewGesture() +{ + // Userdata for all steps is a LLGestureStep we need to clean up + std::vector data_list = mStepList->getAllData(); + std::vector::iterator data_itor; + for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) + { + LLScrollListItem* item = *data_itor; + LLGestureStep* step = (LLGestureStep*)item->getUserdata(); + delete step; + step = NULL; + } +} + + +bool LLPreviewGesture::postBuild() +{ + setVisibleCallback(boost::bind(&LLPreviewGesture::onVisibilityChanged, this, _2)); + + LLLineEditor* edit; + LLComboBox* combo; + LLButton* btn; + LLScrollListCtrl* list; + LLTextBox* text; + LLCheckBoxCtrl* check; + + edit = getChild("desc"); + edit->setKeystrokeCallback(onKeystrokeCommit, this); + + edit = getChild("trigger_editor"); + edit->setKeystrokeCallback(onKeystrokeCommit, this); + edit->setCommitCallback(onCommitSetDirty, this); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); + mTriggerEditor = edit; + + text = getChild("replace_text"); + text->setEnabled(false); + mReplaceText = text; + + edit = getChild("replace_editor"); + edit->setEnabled(false); + edit->setKeystrokeCallback(onKeystrokeCommit, this); + edit->setCommitCallback(onCommitSetDirty, this); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); + mReplaceEditor = edit; + + combo = getChild( "modifier_combo"); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this)); + mModifierCombo = combo; + + combo = getChild( "key_combo"); + combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this)); + mKeyCombo = combo; + + list = getChild("library_list"); + list->setCommitCallback(onCommitLibrary, this); + list->setDoubleClickCallback(onClickAdd, this); + mLibraryList = list; + + btn = getChild( "add_btn"); + btn->setClickedCallback(onClickAdd, this); + btn->setEnabled(false); + mAddBtn = btn; + + btn = getChild( "up_btn"); + btn->setClickedCallback(onClickUp, this); + btn->setEnabled(false); + mUpBtn = btn; + + btn = getChild( "down_btn"); + btn->setClickedCallback(onClickDown, this); + btn->setEnabled(false); + mDownBtn = btn; + + btn = getChild( "delete_btn"); + btn->setClickedCallback(onClickDelete, this); + btn->setEnabled(false); + mDeleteBtn = btn; + + list = getChild("step_list"); + list->setCommitCallback(onCommitStep, this); + mStepList = list; + + // Options + mOptionsText = getChild("options_text"); + + combo = getChild( "animation_list"); + combo->setVisible(false); + combo->setCommitCallback(onCommitAnimation, this); + mAnimationCombo = combo; + + LLRadioGroup* group; + group = getChild("animation_trigger_type"); + group->setVisible(false); + group->setCommitCallback(onCommitAnimationTrigger, this); + mAnimationRadio = group; + + combo = getChild( "sound_list"); + combo->setVisible(false); + combo->setCommitCallback(onCommitSound, this); + mSoundCombo = combo; + + edit = getChild("chat_editor"); + edit->setVisible(false); + edit->setCommitCallback(onCommitChat, this); + //edit->setKeystrokeCallback(onKeystrokeCommit, this); + edit->setCommitOnFocusLost(true); + edit->setIgnoreTab(true); + mChatEditor = edit; + + check = getChild( "wait_key_release_check"); + check->setVisible(false); + check->setCommitCallback(onCommitWait, this); + mWaitKeyReleaseCheck = check; + + check = getChild( "wait_anim_check"); + check->setVisible(false); + check->setCommitCallback(onCommitWait, this); + mWaitAnimCheck = check; + + check = getChild( "wait_time_check"); + check->setVisible(false); + check->setCommitCallback(onCommitWait, this); + mWaitTimeCheck = check; + + edit = getChild("wait_time_editor"); + edit->setEnabled(false); + edit->setVisible(false); + edit->setPrevalidate(LLTextValidate::validateFloat); +// edit->setKeystrokeCallback(onKeystrokeCommit, this); + edit->setCommitOnFocusLost(true); + edit->setCommitCallback(onCommitWaitTime, this); + edit->setIgnoreTab(true); + mWaitTimeEditor = edit; + + // Buttons at the bottom + check = getChild( "active_check"); + check->setCommitCallback(onCommitActive, this); + mActiveCheck = check; + + btn = getChild( "save_btn"); + btn->setClickedCallback(onClickSave, this); + mSaveBtn = btn; + + btn = getChild( "preview_btn"); + btn->setClickedCallback(onClickPreview, this); + mPreviewBtn = btn; + + + // Populate the comboboxes + addModifiers(); + addKeys(); + addAnimations(); + addSounds(); + + const LLInventoryItem* item = getItem(); + + if (item) + { + getChild("desc")->setValue(item->getDescription()); + getChild("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); + } + + return LLPreview::postBuild(); +} + + +void LLPreviewGesture::addModifiers() +{ + LLComboBox* combo = mModifierCombo; + + combo->add( NONE_LABEL, ADD_BOTTOM ); + combo->add( SHIFT_LABEL, ADD_BOTTOM ); + combo->add( CTRL_LABEL, ADD_BOTTOM ); + combo->setCurrentByIndex(0); +} + +void LLPreviewGesture::addKeys() +{ + LLComboBox* combo = mKeyCombo; + + combo->add( NONE_LABEL ); + for (KEY key = KEY_F2; key <= KEY_F12; key++) + { + combo->add( LLKeyboard::stringFromKey(key), ADD_BOTTOM ); + } + combo->setCurrentByIndex(0); +} + + +// TODO: Sort the legacy and non-legacy together? +void LLPreviewGesture::addAnimations() +{ + LLComboBox* combo = mAnimationCombo; + + combo->removeall(); + + std::string none_text = getString("none_text"); + + combo->add(none_text, LLUUID::null); + + // Add all the default (legacy) animations + S32 i; + for (i = 0; i < gUserAnimStatesCount; ++i) + { + // Use the user-readable name + std::string label = LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ); + const LLUUID& id = gUserAnimStates[i].mID; + combo->add(label, id); + } + + // Get all inventory items that are animations + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION, + PERM_ITEM_UNRESTRICTED, + gAgent.getID(), + gAgent.getGroupID()); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_copyable_animation); + + // Copy into something we can sort + std::vector animations; + + S32 count = items.size(); + for(i = 0; i < count; ++i) + { + animations.push_back( items.at(i) ); + } + + // Do the sort + std::sort(animations.begin(), animations.end(), SortItemPtrsByName()); + + // And load up the combobox + std::vector::iterator it; + for (it = animations.begin(); it != animations.end(); ++it) + { + LLInventoryItem* item = *it; + + combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM); + } +} + + +void LLPreviewGesture::addSounds() +{ + LLComboBox* combo = mSoundCombo; + combo->removeall(); + + std::string none_text = getString("none_text"); + + combo->add(none_text, LLUUID::null); + + // Get all inventory items that are sounds + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLIsTypeWithPermissions is_copyable_sound(LLAssetType::AT_SOUND, + PERM_ITEM_UNRESTRICTED, + gAgent.getID(), + gAgent.getGroupID()); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_copyable_sound); + + // Copy sounds into something we can sort + std::vector sounds; + + S32 i; + S32 count = items.size(); + for(i = 0; i < count; ++i) + { + sounds.push_back( items.at(i) ); + } + + // Do the sort + std::sort(sounds.begin(), sounds.end(), SortItemPtrsByName()); + + // And load up the combobox + std::vector::iterator it; + for (it = sounds.begin(); it != sounds.end(); ++it) + { + LLInventoryItem* item = *it; + + combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM); + } +} + + +void LLPreviewGesture::refresh() +{ + LLPreview::refresh(); + // If previewing or item is incomplete, all controls are disabled + LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem(); + bool is_complete = item && item->isFinished(); + if (mPreviewGesture || !is_complete) + { + + getChildView("desc")->setEnabled(false); + //mDescEditor->setEnabled(false); + mTriggerEditor->setEnabled(false); + mReplaceText->setEnabled(false); + mReplaceEditor->setEnabled(false); + mModifierCombo->setEnabled(false); + mKeyCombo->setEnabled(false); + mLibraryList->setEnabled(false); + mAddBtn->setEnabled(false); + mUpBtn->setEnabled(false); + mDownBtn->setEnabled(false); + mDeleteBtn->setEnabled(false); + mStepList->setEnabled(false); + mOptionsText->setEnabled(false); + mAnimationCombo->setEnabled(false); + mAnimationRadio->setEnabled(false); + mSoundCombo->setEnabled(false); + mChatEditor->setEnabled(false); + mWaitKeyReleaseCheck->setEnabled(false); + mWaitAnimCheck->setEnabled(false); + mWaitTimeCheck->setEnabled(false); + mWaitTimeEditor->setEnabled(false); + mActiveCheck->setEnabled(false); + mSaveBtn->setEnabled(false); + + // Make sure preview button is enabled, so we can stop it + mPreviewBtn->setEnabled(true); + return; + } + + bool modifiable = item->getPermissions().allowModifyBy(gAgent.getID()); + + getChildView("desc")->setEnabled(modifiable); + mTriggerEditor->setEnabled(true); + mLibraryList->setEnabled(modifiable); + mStepList->setEnabled(modifiable); + mOptionsText->setEnabled(modifiable); + mAnimationCombo->setEnabled(modifiable); + mAnimationRadio->setEnabled(modifiable); + mSoundCombo->setEnabled(modifiable); + mChatEditor->setEnabled(modifiable); + mWaitKeyReleaseCheck->setEnabled(modifiable); + mWaitAnimCheck->setEnabled(modifiable); + mWaitTimeCheck->setEnabled(modifiable); + mWaitTimeEditor->setEnabled(modifiable); + mActiveCheck->setEnabled(true); + + const std::string& trigger = mTriggerEditor->getText(); + bool have_trigger = !trigger.empty(); + + const std::string& replace = mReplaceEditor->getText(); + bool have_replace = !replace.empty(); + + LLScrollListItem* library_item = mLibraryList->getFirstSelected(); + bool have_library = (library_item != NULL); + + LLScrollListItem* step_item = mStepList->getFirstSelected(); + S32 step_index = mStepList->getFirstSelectedIndex(); + S32 step_count = mStepList->getItemCount(); + bool have_step = (step_item != NULL); + + mReplaceText->setEnabled(have_trigger || have_replace); + mReplaceEditor->setEnabled(have_trigger || have_replace); + + mModifierCombo->setEnabled(true); + mKeyCombo->setEnabled(true); + + mAddBtn->setEnabled(modifiable && have_library); + mUpBtn->setEnabled(modifiable && have_step && step_index > 0); + mDownBtn->setEnabled(modifiable && have_step && step_index < step_count-1); + mDeleteBtn->setEnabled(modifiable && have_step); + + // Assume all not visible + mAnimationCombo->setVisible(false); + mAnimationRadio->setVisible(false); + mSoundCombo->setVisible(false); + mChatEditor->setVisible(false); + mWaitKeyReleaseCheck->setVisible(false); + mWaitAnimCheck->setVisible(false); + mWaitTimeCheck->setVisible(false); + mWaitTimeEditor->setVisible(false); + + std::string optionstext; + + if (have_step) + { + // figure out the type, show proper options, update text + LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); + EStepType type = step->getType(); + + switch(type) + { + case STEP_ANIMATION: + { + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + optionstext = getString("step_anim"); + mAnimationCombo->setVisible(true); + mAnimationRadio->setVisible(true); + mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0); + mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID); + break; + } + case STEP_SOUND: + { + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + optionstext = getString("step_sound"); + mSoundCombo->setVisible(true); + mSoundCombo->setCurrentByID(sound_step->mSoundAssetID); + break; + } + case STEP_CHAT: + { + LLGestureStepChat* chat_step = (LLGestureStepChat*)step; + optionstext = getString("step_chat"); + mChatEditor->setVisible(true); + mChatEditor->setText(chat_step->mChatText); + break; + } + case STEP_WAIT: + { + LLGestureStepWait* wait_step = (LLGestureStepWait*)step; + optionstext = getString("step_wait"); + mWaitKeyReleaseCheck->setVisible(true); + mWaitKeyReleaseCheck->set(wait_step->mFlags & WAIT_FLAG_KEY_RELEASE); + mWaitAnimCheck->setVisible(true); + mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); + mWaitTimeCheck->setVisible(true); + mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME); + mWaitTimeEditor->setVisible(true); + std::string buffer = llformat("%.1f", (double)wait_step->mWaitSeconds); + mWaitTimeEditor->setText(buffer); + break; + } + default: + break; + } + } + + mOptionsText->setText(optionstext); + + bool active = LLGestureMgr::instance().isGestureActive(mItemUUID); + mActiveCheck->set(active); + + // Can only preview if there are steps + mPreviewBtn->setEnabled(step_count > 0); + + // And can only save if changes have been made + mSaveBtn->setEnabled(mDirty); + addAnimations(); + addSounds(); +} + + +void LLPreviewGesture::initDefaultGesture() +{ + LLScrollListItem* item; + item = addStep( STEP_ANIMATION ); + LLGestureStepAnimation* anim = (LLGestureStepAnimation*)item->getUserdata(); + anim->mAnimAssetID = ANIM_AGENT_HELLO; + anim->mAnimName = LLTrans::getString("Wave"); + updateLabel(item); + + item = addStep( STEP_WAIT ); + LLGestureStepWait* wait = (LLGestureStepWait*)item->getUserdata(); + wait->mFlags = WAIT_FLAG_ALL_ANIM; + updateLabel(item); + + item = addStep( STEP_CHAT ); + LLGestureStepChat* chat_step = (LLGestureStepChat*)item->getUserdata(); + chat_step->mChatText = LLTrans::getString("HelloAvatar"); + updateLabel(item); + + // Start with item list selected + mStepList->selectFirstItem(); + + // this is *new* content, so we are dirty + mDirty = true; +} + + +void LLPreviewGesture::loadAsset() +{ + const LLInventoryItem* item = getItem(); + if (!item) + { + // Don't set asset status here; we may not have set the item id yet + // (e.g. when this gets called initially) + //mAssetStatus = PREVIEW_ASSET_ERROR; + return; + } + + LLUUID asset_id = item->getAssetUUID(); + if (asset_id.isNull()) + { + // Freshly created gesture, don't need to load asset. + // Blank gesture will be fine. + initDefaultGesture(); + refresh(); + mAssetStatus = PREVIEW_ASSET_LOADED; + return; + } + + // TODO: Based on item->getPermissions().allow* + // could enable/disable UI. + + // Copy the UUID, because the user might close the preview + // window if the download gets stalled. + LLUUID* item_idp = new LLUUID(mItemUUID); + + const bool high_priority = true; + gAssetStorage->getAssetData(asset_id, + LLAssetType::AT_GESTURE, + onLoadComplete, + (void**)item_idp, + high_priority); + mAssetStatus = PREVIEW_ASSET_LOADING; +} + + +// static +void LLPreviewGesture::onLoadComplete(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + LLUUID* item_idp = (LLUUID*)user_data; + + LLPreviewGesture* self = LLFloaterReg::findTypedInstance("preview_gesture", *item_idp); + if (self) + { + if (0 == status) + { + LLFileSystem file(asset_uuid, type, LLFileSystem::READ); + S32 size = file.getSize(); + + std::vector buffer(size+1); + file.read((U8*)&buffer[0], size); + buffer[size] = '\0'; + + LLMultiGesture* gesture = new LLMultiGesture(); + + LLDataPackerAsciiBuffer dp(&buffer[0], size+1); + bool ok = gesture->deserialize(dp); + + if (ok) + { + // Everything has been successful. Load up the UI. + self->loadUIFromGesture(gesture); + + self->mStepList->selectFirstItem(); + + self->mDirty = false; + self->refresh(); + self->refreshFromItem(); // to update description and title + } + else + { + LL_WARNS() << "Unable to load gesture" << LL_ENDL; + } + + delete gesture; + gesture = NULL; + + self->mAssetStatus = PREVIEW_ASSET_LOADED; + } + else + { + if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLDelayedGestureError::gestureMissing( *item_idp ); + } + else + { + LLDelayedGestureError::gestureFailedToLoad( *item_idp ); + } + + LL_WARNS() << "Problem loading gesture: " << status << LL_ENDL; + self->mAssetStatus = PREVIEW_ASSET_ERROR; + } + } + delete item_idp; + item_idp = NULL; +} + + +void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture) +{ + /*LLInventoryItem* item = getItem(); + + + + if (item) + { + LLLineEditor* descEditor = getChild("desc"); + descEditor->setText(item->getDescription()); + }*/ + + mTriggerEditor->setText(gesture->mTrigger); + + mReplaceEditor->setText(gesture->mReplaceText); + + switch (gesture->mMask) + { + default: + case MASK_NONE: + mModifierCombo->setSimple( NONE_LABEL ); + break; + case MASK_SHIFT: + mModifierCombo->setSimple( SHIFT_LABEL ); + break; + case MASK_CONTROL: + mModifierCombo->setSimple( CTRL_LABEL ); + break; + } + + mModifierCombo->setEnabledByValue(CTRL_LABEL, gesture->mKey != KEY_F10); + + mKeyCombo->setCurrentByIndex(0); + if (gesture->mKey != KEY_NONE) + { + mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey)); + } + + mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), gesture->mMask != MASK_CONTROL); + + // Make UI steps for each gesture step + S32 i; + S32 count = gesture->mSteps.size(); + for (i = 0; i < count; ++i) + { + LLGestureStep* step = gesture->mSteps[i]; + + LLGestureStep* new_step = NULL; + + switch(step->getType()) + { + case STEP_ANIMATION: + { + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + LLGestureStepAnimation* new_anim_step = + new LLGestureStepAnimation(*anim_step); + new_step = new_anim_step; + break; + } + case STEP_SOUND: + { + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + LLGestureStepSound* new_sound_step = + new LLGestureStepSound(*sound_step); + new_step = new_sound_step; + break; + } + case STEP_CHAT: + { + LLGestureStepChat* chat_step = (LLGestureStepChat*)step; + LLGestureStepChat* new_chat_step = + new LLGestureStepChat(*chat_step); + new_step = new_chat_step; + break; + } + case STEP_WAIT: + { + LLGestureStepWait* wait_step = (LLGestureStepWait*)step; + LLGestureStepWait* new_wait_step = + new LLGestureStepWait(*wait_step); + new_step = new_wait_step; + break; + } + default: + { + break; + } + } + + if (!new_step) continue; + + // Create an enabled item with this step + LLSD row; + row["columns"][0]["value"] = getLabel( new_step->getLabel()); + row["columns"][0]["font"] = "SANSSERIF_SMALL"; + LLScrollListItem* item = mStepList->addElement(row); + item->setUserdata(new_step); + } +} + +// Helpful structure so we can look up the inventory item +// after the save finishes. +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; +}; + + +void LLPreviewGesture::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId) +{ + // If this gesture is active, then we need to update the in-memory + // active map with the new pointer. + if (LLGestureMgr::instance().isGestureActive(itemId)) + { + // Active gesture edited from menu. + LLGestureMgr::instance().replaceGesture(itemId, newAssetId); + gInventory.notifyObservers(); + } + + //gesture will have a new asset_id + LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance("preview_gesture", LLSD(itemId)); + if (previewp) + { + previewp->onUpdateSucceeded(); + } +} + + +void LLPreviewGesture::saveIfNeeded() +{ + if (!gAssetStorage) + { + LL_WARNS() << "Can't save gesture, no asset storage system." << LL_ENDL; + return; + } + + if (!mDirty) + { + return; + } + + // Copy the UI into a gesture + LLMultiGesture* gesture = createGesture(); + + // Serialize the gesture + S32 maxSize = gesture->getMaxSerialSize(); + char* buffer = new char[maxSize]; + + LLDataPackerAsciiBuffer dp(buffer, maxSize); + + bool ok = gesture->serialize(dp); + + if (dp.getCurrentSize() > 1000) + { + LLNotificationsUtil::add("GestureSaveFailedTooManySteps"); + + delete gesture; + gesture = NULL; + return; + } + else if (!ok) + { + LLNotificationsUtil::add("GestureSaveFailedTryAgain"); + delete gesture; + gesture = NULL; + return; + } + + LLAssetID assetId; + LLPreview::onCommit(); + bool delayedUpload(false); + + LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem(); + if (item) + { + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS() << "Not connected to a region, cannot save gesture." << LL_ENDL; + return; + } + std::string agent_url = region->getCapability("UpdateGestureAgentInventory"); + std::string task_url = region->getCapability("UpdateGestureTaskInventory"); + + if (!agent_url.empty() && !task_url.empty()) + { + std::string url; + LLResourceUploadInfo::ptr_t uploadInfo; + + if (mObjectUUID.isNull() && !agent_url.empty()) + { + //need to disable the preview floater so item + //isn't re-saved before new asset arrives + //fake out refresh. + item->setComplete(false); + refresh(); + item->setComplete(true); + + uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_GESTURE, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD) + { + LLPreviewGesture::finishInventoryUpload(itemId, newAssetId); + }, + nullptr); + url = agent_url; + } + else if (!mObjectUUID.isNull() && !task_url.empty()) + { + uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr, nullptr); + url = task_url; + } + + if (!url.empty() && uploadInfo) + { + delayedUpload = true; + + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); + } + + } + else if (gAssetStorage) + { + // Every save gets a new UUID. Yup. + LLTransactionID tid; + tid.generate(); + assetId = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLFileSystem file(assetId, LLAssetType::AT_GESTURE, LLFileSystem::APPEND); + + S32 size = dp.getCurrentSize(); + file.write((U8*)buffer, size); + + LLLineEditor* descEditor = getChild("desc"); + LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid); + gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, false); + } + + } + + // If this gesture is active, then we need to update the in-memory + // active map with the new pointer. + if (!delayedUpload && LLGestureMgr::instance().isGestureActive(mItemUUID)) + { + // gesture manager now owns the pointer + LLGestureMgr::instance().replaceGesture(mItemUUID, gesture, assetId); + + // replaceGesture may deactivate other gestures so let the + // inventory know. + gInventory.notifyObservers(); + } + else + { + // we're done with this gesture + delete gesture; + gesture = NULL; + } + + mDirty = false; + // refresh will be called when callback + // if triggered when delayedUpload + if(!delayedUpload) + { + refresh(); + } + +} + + +// TODO: This is very similar to LLPreviewNotecard::onSaveComplete. +// Could merge code. +// static +void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) +{ + LLSaveInfo* info = (LLSaveInfo*)user_data; + if (info && (status == 0)) + { + if(info->mObjectUUID.isNull()) + { + // Saving into user inventory + LLViewerInventoryItem* item; + item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID); + if(item) + { + LLPointer new_item = new LLViewerInventoryItem(item); + new_item->setDescription(info->mDesc); + new_item->setTransactionID(info->mTransactionID); + new_item->setAssetUUID(asset_uuid); + new_item->updateServer(false); + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + } + else + { + LL_WARNS() << "Inventory item for gesture " << info->mItemUUID + << " is no longer in agent inventory." << LL_ENDL; + } + } + else + { + // Saving into in-world object inventory + LLViewerObject* object = gObjectList.findObject(info->mObjectUUID); + LLViewerInventoryItem* item = NULL; + if(object) + { + item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID); + } + if(object && item) + { + item->setDescription(info->mDesc); + item->setAssetUUID(asset_uuid); + item->setTransactionID(info->mTransactionID); + object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false); + dialog_refresh_all(); + } + else + { + LLNotificationsUtil::add("GestureSaveFailedObjectNotFound"); + } + } + + // Find our window and close it if requested. + LLPreviewGesture* previewp = LLFloaterReg::findTypedInstance("preview_gesture", info->mItemUUID); + if (previewp && previewp->mCloseAfterSave) + { + previewp->closeFloater(); + } + } + else + { + LL_WARNS() << "Problem saving gesture: " << status << LL_ENDL; + LLSD args; + args["REASON"] = std::string(LLAssetStorage::getErrorString(status)); + LLNotificationsUtil::add("GestureSaveFailedReason", args); + } + delete info; + info = NULL; +} + + +LLMultiGesture* LLPreviewGesture::createGesture() +{ + LLMultiGesture* gesture = new LLMultiGesture(); + + gesture->mTrigger = mTriggerEditor->getText(); + gesture->mReplaceText = mReplaceEditor->getText(); + + const std::string& modifier = mModifierCombo->getSimple(); + if (modifier == CTRL_LABEL) + { + gesture->mMask = MASK_CONTROL; + } + else if (modifier == SHIFT_LABEL) + { + gesture->mMask = MASK_SHIFT; + } + else + { + gesture->mMask = MASK_NONE; + } + + if (mKeyCombo->getCurrentIndex() == 0) + { + gesture->mKey = KEY_NONE; + } + else + { + const std::string& key_string = mKeyCombo->getSimple(); + LLKeyboard::keyFromString(key_string, &(gesture->mKey)); + } + + std::vector data_list = mStepList->getAllData(); + std::vector::iterator data_itor; + for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor) + { + LLScrollListItem* item = *data_itor; + LLGestureStep* step = (LLGestureStep*)item->getUserdata(); + + switch(step->getType()) + { + case STEP_ANIMATION: + { + // Copy UI-generated step into actual gesture step + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + LLGestureStepAnimation* new_anim_step = + new LLGestureStepAnimation(*anim_step); + gesture->mSteps.push_back(new_anim_step); + break; + } + case STEP_SOUND: + { + // Copy UI-generated step into actual gesture step + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + LLGestureStepSound* new_sound_step = + new LLGestureStepSound(*sound_step); + gesture->mSteps.push_back(new_sound_step); + break; + } + case STEP_CHAT: + { + // Copy UI-generated step into actual gesture step + LLGestureStepChat* chat_step = (LLGestureStepChat*)step; + LLGestureStepChat* new_chat_step = + new LLGestureStepChat(*chat_step); + gesture->mSteps.push_back(new_chat_step); + break; + } + case STEP_WAIT: + { + // Copy UI-generated step into actual gesture step + LLGestureStepWait* wait_step = (LLGestureStepWait*)step; + LLGestureStepWait* new_wait_step = + new LLGestureStepWait(*wait_step); + gesture->mSteps.push_back(new_wait_step); + break; + } + default: + { + break; + } + } + } + + return gesture; +} + + +void LLPreviewGesture::onCommitKeyorModifier() +{ + // SL-14139: ctrl-F10 is currently used to access top menu, + // so don't allow to bound gestures to this combination. + + mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), mModifierCombo->getSimple() != CTRL_LABEL); + mModifierCombo->setEnabledByValue(CTRL_LABEL, mKeyCombo->getSimple() != LLKeyboard::stringFromKey(KEY_F10)); + mDirty = true; + refresh(); +} + +// static +void LLPreviewGesture::updateLabel(LLScrollListItem* item) +{ + LLGestureStep* step = (LLGestureStep*)item->getUserdata(); + + LLScrollListCell* cell = item->getColumn(0); + LLScrollListText* text_cell = (LLScrollListText*)cell; + std::string label = getLabel( step->getLabel()); + text_cell->setText(label); +} + +// static +void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + self->mDirty = true; + self->refresh(); +} + +// static +void LLPreviewGesture::onCommitLibrary(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + if (library_item) + { + self->mStepList->deselectAllItems(); + self->refresh(); + } +} + + +// static +void LLPreviewGesture::onCommitStep(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + if (!step_item) return; + + self->mLibraryList->deselectAllItems(); + self->refresh(); +} + + +// static +void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + if (step_item) + { + LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); + if (step->getType() == STEP_ANIMATION) + { + // Assign the animation name + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + if (self->mAnimationCombo->getCurrentIndex() == 0) + { + anim_step->mAnimName.clear(); + anim_step->mAnimAssetID.setNull(); + } + else + { + anim_step->mAnimName = self->mAnimationCombo->getSimple(); + anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID(); + } + //anim_step->mFlags = 0x0; + + // Update the UI label in the list + updateLabel(step_item); + + self->mDirty = true; + self->refresh(); + } + } +} + +// static +void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + if (step_item) + { + LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); + if (step->getType() == STEP_ANIMATION) + { + LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; + if (self->mAnimationRadio->getSelectedIndex() == 0) + { + // start + anim_step->mFlags &= ~ANIM_FLAG_STOP; + } + else + { + // stop + anim_step->mFlags |= ANIM_FLAG_STOP; + } + // Update the UI label in the list + updateLabel(step_item); + + self->mDirty = true; + self->refresh(); + } + } +} + +// static +void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* step_item = self->mStepList->getFirstSelected(); + if (step_item) + { + LLGestureStep* step = (LLGestureStep*)step_item->getUserdata(); + if (step->getType() == STEP_SOUND) + { + // Assign the sound name + LLGestureStepSound* sound_step = (LLGestureStepSound*)step; + sound_step->mSoundName = self->mSoundCombo->getSimple(); + sound_step->mSoundAssetID = self->mSoundCombo->getCurrentID(); + sound_step->mFlags = 0x0; + + // Update the UI label in the list + updateLabel(step_item); + + self->mDirty = true; + self->refresh(); + } + } +} + +// static +void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, 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_CHAT) return; + + LLGestureStepChat* chat_step = (LLGestureStepChat*)step; + chat_step->mChatText = self->mChatEditor->getText(); + chat_step->mFlags = 0x0; + + // Update the UI label in the list + updateLabel(step_item); + + self->mDirty = true; + self->refresh(); +} + +// static +void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, 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_WAIT) return; + + LLGestureStepWait* wait_step = (LLGestureStepWait*)step; + U32 flags = 0x0; + if (self->mWaitKeyReleaseCheck->get()) flags |= WAIT_FLAG_KEY_RELEASE; + if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; + if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; + wait_step->mFlags = flags; + + { + LLLocale locale(LLLocale::USER_LOCALE); + + F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str()); + if (wait_seconds < 0.f) wait_seconds = 0.f; + if (wait_seconds > 3600.f) wait_seconds = 3600.f; + wait_step->mWaitSeconds = wait_seconds; + } + + // Enable the input area if necessary + self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get()); + + // Update the UI label in the list + updateLabel(step_item); + + self->mDirty = true; + self->refresh(); +} + +// static +void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, 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_WAIT) return; + + self->mWaitTimeCheck->set(true); + onCommitWait(ctrl, data); +} + + +// static +void LLPreviewGesture::onKeystrokeCommit(LLLineEditor* caller, + void* data) +{ + // Just commit every keystroke + onCommitSetDirty(caller, data); +} + +// static +void LLPreviewGesture::onClickAdd(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* library_item = self->mLibraryList->getFirstSelected(); + if (!library_item) return; + + S32 library_item_index = self->mLibraryList->getFirstSelectedIndex(); + + const LLScrollListCell* library_cell = library_item->getColumn(0); + const std::string& library_text = library_cell->getValue().asString(); + + if( library_item_index >= STEP_EOF ) + { + LL_ERRS() << "Unknown step type: " << library_text << LL_ENDL; + return; + } + + self->addStep( (EStepType)library_item_index ); + self->mDirty = true; + self->refresh(); +} + +LLScrollListItem* LLPreviewGesture::addStep( const EStepType step_type ) +{ + // Order of enum EStepType MUST match the library_list element in floater_preview_gesture.xml + + LLGestureStep* step = NULL; + switch( step_type) + { + case STEP_ANIMATION: + step = new LLGestureStepAnimation(); + + break; + case STEP_SOUND: + step = new LLGestureStepSound(); + break; + case STEP_CHAT: + step = new LLGestureStepChat(); + break; + case STEP_WAIT: + step = new LLGestureStepWait(); + break; + default: + LL_ERRS() << "Unknown step type: " << (S32)step_type << LL_ENDL; + return NULL; + } + + + // Create an enabled item with this step + LLSD row; + row["columns"][0]["value"] = getLabel(step->getLabel()); + row["columns"][0]["font"] = "SANSSERIF_SMALL"; + LLScrollListItem* step_item = mStepList->addElement(row); + step_item->setUserdata(step); + + // And move selection to the list on the right + mLibraryList->deselectAllItems(); + mStepList->deselectAllItems(); + + step_item->setSelected(true); + + return step_item; +} + +// static +std::string LLPreviewGesture::getLabel(std::vector labels) +{ + std::vector v_labels = labels ; + std::string result(""); + + if( v_labels.size() != 2) + { + return result; + } + + if(v_labels[0]=="Chat") + { + result=LLTrans::getString("Chat Message"); + } + else if(v_labels[0]=="Sound") + { + result=LLTrans::getString("Sound"); + } + else if(v_labels[0]=="Wait") + { + result=LLTrans::getString("Wait"); + } + else if(v_labels[0]=="AnimFlagStop") + { + result=LLTrans::getString("AnimFlagStop"); + } + else if(v_labels[0]=="AnimFlagStart") + { + result=LLTrans::getString("AnimFlagStart"); + } + + // lets localize action value + std::string action = v_labels[1]; + if ("None" == action) + { + action = LLTrans::getString("GestureActionNone"); + } + else if ("until animations are done" == action) + { + action = LLFloaterReg::getInstance("preview_gesture")->getChild("wait_anim_check")->getLabel(); + } + result.append(action); + return result; + +} +// static +void LLPreviewGesture::onClickUp(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + S32 selected_index = self->mStepList->getFirstSelectedIndex(); + if (selected_index > 0) + { + self->mStepList->swapWithPrevious(selected_index); + self->mDirty = true; + self->refresh(); + } +} + +// static +void LLPreviewGesture::onClickDown(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + S32 selected_index = self->mStepList->getFirstSelectedIndex(); + if (selected_index < 0) return; + + S32 count = self->mStepList->getItemCount(); + if (selected_index < count-1) + { + self->mStepList->swapWithNext(selected_index); + self->mDirty = true; + self->refresh(); + } +} + +// static +void LLPreviewGesture::onClickDelete(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + LLScrollListItem* item = self->mStepList->getFirstSelected(); + S32 selected_index = self->mStepList->getFirstSelectedIndex(); + if (item && selected_index >= 0) + { + LLGestureStep* step = (LLGestureStep*)item->getUserdata(); + delete step; + step = NULL; + + self->mStepList->deleteSingleItem(selected_index); + + self->mDirty = true; + self->refresh(); + } +} + +// static +void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + if (!LLGestureMgr::instance().isGestureActive(self->mItemUUID)) + { + LLGestureMgr::instance().activateGesture(self->mItemUUID); + } + else + { + LLGestureMgr::instance().deactivateGesture(self->mItemUUID); + } + + // Make sure the (active) label in the inventory gets updated. + LLViewerInventoryItem* item = gInventory.getItem(self->mItemUUID); + if (item) + { + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + + self->refresh(); +} + +// static +void LLPreviewGesture::onClickSave(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + self->saveIfNeeded(); +} + +// static +void LLPreviewGesture::onClickPreview(void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + if (!self->mPreviewGesture) + { + // make temporary gesture + self->mPreviewGesture = self->createGesture(); + + // add a callback + self->mPreviewGesture->mDoneCallback = onDonePreview; + self->mPreviewGesture->mCallbackData = self; + + // set the button title + self->mPreviewBtn->setLabel(self->getString("stop_txt")); + + // play it, and delete when done + LLGestureMgr::instance().playGesture(self->mPreviewGesture); + + self->refresh(); + } + else + { + // Will call onDonePreview() below + LLGestureMgr::instance().stopGesture(self->mPreviewGesture); + + self->refresh(); + } +} + + +// static +void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data) +{ + LLPreviewGesture* self = (LLPreviewGesture*)data; + + self->mPreviewBtn->setLabel(self->getString("preview_txt")); + + delete self->mPreviewGesture; + self->mPreviewGesture = NULL; + + self->refresh(); +} -- cgit v1.2.3 From b42f9d836b4c0f7fbd4bdae1734021e2a09fdbe8 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 1 Jun 2024 15:49:26 +0200 Subject: Re-enable a lot of compiler warnings for MSVC and address the C4267 "possible loss of precision" warnings --- indra/newview/llpreviewgesture.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'indra/newview/llpreviewgesture.cpp') diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 56f23a0458..7cbbb89313 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -549,11 +549,9 @@ void LLPreviewGesture::addAnimations() // Copy into something we can sort std::vector animations; - - S32 count = items.size(); - for(i = 0; i < count; ++i) + for (auto& item : items) { - animations.push_back( items.at(i) ); + animations.emplace_back(item); } // Do the sort @@ -594,12 +592,9 @@ void LLPreviewGesture::addSounds() // Copy sounds into something we can sort std::vector sounds; - - S32 i; - S32 count = items.size(); - for(i = 0; i < count; ++i) + for (auto& item : items) { - sounds.push_back( items.at(i) ); + sounds.emplace_back(item); } // Do the sort @@ -951,8 +946,8 @@ void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture) mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), gesture->mMask != MASK_CONTROL); // Make UI steps for each gesture step - S32 i; - S32 count = gesture->mSteps.size(); + size_t i; + size_t count = gesture->mSteps.size(); for (i = 0; i < count; ++i) { LLGestureStep* step = gesture->mSteps[i]; -- cgit v1.2.3