00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include <algorithm>
00035
00036 #include "llpreviewgesture.h"
00037
00038
00039 #include "lldatapacker.h"
00040 #include "lldarray.h"
00041 #include "llstring.h"
00042 #include "lldir.h"
00043 #include "llmultigesture.h"
00044 #include "llvfile.h"
00045
00046
00047 #include "llagent.h"
00048 #include "llassetuploadresponders.h"
00049 #include "llbutton.h"
00050 #include "llcheckboxctrl.h"
00051 #include "llcombobox.h"
00052 #include "llfloatergesture.h"
00053 #include "llgesturemgr.h"
00054 #include "llinventorymodel.h"
00055 #include "llkeyboard.h"
00056 #include "lllineeditor.h"
00057 #include "llnotify.h"
00058 #include "llradiogroup.h"
00059 #include "llscrolllistctrl.h"
00060 #include "lltextbox.h"
00061 #include "llvieweruictrlfactory.h"
00062 #include "llviewerinventory.h"
00063 #include "llviewerobject.h"
00064 #include "llviewerobjectlist.h"
00065 #include "llviewerregion.h"
00066 #include "llviewerstats.h"
00067 #include "llviewerwindow.h"
00068 #include "viewer.h"
00069
00070 #include "llresmgr.h"
00071
00072
00073 const char NONE_LABEL[] = "---";
00074 const char SHIFT_LABEL[] = "Shift";
00075 const char CTRL_LABEL[] = "Ctrl";
00076
00077 void dialog_refresh_all();
00078
00079
00080
00081 class LLInventoryGestureAvailable : public LLInventoryCompletionObserver
00082 {
00083 public:
00084 LLInventoryGestureAvailable() {}
00085
00086 protected:
00087 virtual void done();
00088 };
00089
00090 void LLInventoryGestureAvailable::done()
00091 {
00092 LLPreview* preview = NULL;
00093 item_ref_t::iterator it = mComplete.begin();
00094 item_ref_t::iterator end = mComplete.end();
00095 for(; it < end; ++it)
00096 {
00097 preview = LLPreview::find((*it));
00098 if(preview)
00099 {
00100 preview->refresh();
00101 }
00102 }
00103 gInventory.removeObserver(this);
00104 delete this;
00105 }
00106
00107
00108 struct SortItemPtrsByName
00109 {
00110 bool operator()(const LLInventoryItem* i1, const LLInventoryItem* i2)
00111 {
00112 return (LLString::compareDict(i1->getName(), i2->getName()) < 0);
00113 }
00114 };
00115
00116
00117 LLPreviewGesture* LLPreviewGesture::show(const std::string& title, const LLUUID& item_id, const LLUUID& object_id, BOOL take_focus)
00118 {
00119 LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
00120 if (previewp)
00121 {
00122 previewp->open();
00123 if (take_focus)
00124 {
00125 previewp->setFocus(TRUE);
00126 }
00127 return previewp;
00128 }
00129
00130 LLPreviewGesture* self = new LLPreviewGesture();
00131
00132
00133 self->init(item_id, object_id);
00134
00135
00136 gUICtrlFactory->buildFloater(self, "floater_preview_gesture.xml");
00137 self->setTitle(title);
00138
00139
00140 LLMultiFloater* hostp = self->getHost();
00141 if (hostp == NULL)
00142 {
00143 LLRect r = self->getRect();
00144 LLRect screen = gFloaterView->getRect();
00145 r.setLeftTopAndSize(0, screen.getHeight(), r.getWidth(), r.getHeight());
00146 self->setRect(r);
00147 }
00148 else
00149 {
00150
00151 hostp->addFloater(self, TRUE);
00152 }
00153
00154
00155 LLUUID animation_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_ANIMATION);
00156 gInventory.startBackgroundFetch(animation_folder_id);
00157
00158 LLUUID sound_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_SOUND);
00159 gInventory.startBackgroundFetch(sound_folder_id);
00160
00161
00162 LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem();
00163 if(item && !item->isComplete())
00164 {
00165 LLInventoryGestureAvailable* observer;
00166 observer = new LLInventoryGestureAvailable();
00167 observer->watchItem(item_id);
00168 gInventory.addObserver(observer);
00169 item->fetchFromServer();
00170 }
00171 else
00172 {
00173
00174 self->refresh();
00175 }
00176
00177 if (take_focus)
00178 {
00179 self->setFocus(TRUE);
00180 }
00181
00182 return self;
00183 }
00184
00185
00186
00187 BOOL LLPreviewGesture::handleKeyHere(KEY key, MASK mask,
00188 BOOL called_from_parent)
00189 {
00190 if(getVisible() && getEnabled())
00191 {
00192 if(('S' == key) && (MASK_CONTROL == (mask & MASK_CONTROL)))
00193 {
00194 saveIfNeeded();
00195 return TRUE;
00196 }
00197 }
00198 return LLPreview::handleKeyHere(key, mask, called_from_parent);
00199 }
00200
00201
00202
00203 BOOL LLPreviewGesture::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
00204 EDragAndDropType cargo_type,
00205 void* cargo_data,
00206 EAcceptance* accept,
00207 LLString& tooltip_msg)
00208 {
00209 BOOL handled = TRUE;
00210 switch(cargo_type)
00211 {
00212 case DAD_ANIMATION:
00213 case DAD_SOUND:
00214 {
00215
00216
00217
00218 LLInventoryItem* item = (LLInventoryItem*)cargo_data;
00219 if (item
00220 && gInventory.getItem(item->getUUID()))
00221 {
00222 LLPermissions perm = item->getPermissions();
00223 if (!((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED))
00224 {
00225 *accept = ACCEPT_NO;
00226 if (tooltip_msg.empty())
00227 {
00228 tooltip_msg.assign("Only animations and sounds\n"
00229 "with unrestricted permissions\n"
00230 "can be added to a gesture.");
00231 }
00232 break;
00233 }
00234 else if (drop)
00235 {
00236 LLScrollListItem* line = NULL;
00237 if (cargo_type == DAD_ANIMATION)
00238 {
00239 line = addStep("Animation");
00240 LLGestureStepAnimation* anim = (LLGestureStepAnimation*)line->getUserdata();
00241 anim->mAnimAssetID = item->getAssetUUID();
00242 anim->mAnimName = item->getName();
00243 }
00244 else if (cargo_type == DAD_SOUND)
00245 {
00246 line = addStep("Sound");
00247 LLGestureStepSound* sound = (LLGestureStepSound*)line->getUserdata();
00248 sound->mSoundAssetID = item->getAssetUUID();
00249 sound->mSoundName = item->getName();
00250 }
00251 updateLabel(line);
00252 mDirty = TRUE;
00253 refresh();
00254 }
00255 *accept = ACCEPT_YES_COPY_MULTI;
00256 }
00257 else
00258 {
00259
00260 *accept = ACCEPT_NO;
00261 }
00262 break;
00263 }
00264 default:
00265 *accept = ACCEPT_NO;
00266 if (tooltip_msg.empty())
00267 {
00268 tooltip_msg.assign("Only animations and sounds\n"
00269 "can be added to a gesture.");
00270 }
00271 break;
00272 }
00273 return handled;
00274 }
00275
00276
00277
00278 BOOL LLPreviewGesture::canClose()
00279 {
00280
00281 if(!mDirty || mForceClose)
00282 {
00283 return TRUE;
00284 }
00285 else
00286 {
00287
00288 gViewerWindow->alertXml("SaveChanges",
00289 handleSaveChangesDialog,
00290 this );
00291 return FALSE;
00292 }
00293 }
00294
00295
00296 void LLPreviewGesture::onClose(bool app_quitting)
00297 {
00298 gGestureManager.stopGesture(mPreviewGesture);
00299 LLPreview::onClose(app_quitting);
00300 }
00301
00302
00303 void LLPreviewGesture::onUpdateSucceeded()
00304 {
00305 refresh();
00306 }
00307
00308
00309 void LLPreviewGesture::setMinimized(BOOL minimize)
00310 {
00311 if (minimize != isMinimized())
00312 {
00313 LLFloater::setMinimized(minimize);
00314
00315
00316 if (!minimize)
00317 {
00318 refresh();
00319 }
00320 }
00321 }
00322
00323
00324
00325 void LLPreviewGesture::handleSaveChangesDialog(S32 option, void* data)
00326 {
00327 LLPreviewGesture* self = (LLPreviewGesture*)data;
00328 switch(option)
00329 {
00330 case 0:
00331 gGestureManager.stopGesture(self->mPreviewGesture);
00332 self->mCloseAfterSave = TRUE;
00333 onClickSave(data);
00334 break;
00335
00336 case 1:
00337 gGestureManager.stopGesture(self->mPreviewGesture);
00338 self->mDirty = FALSE;
00339 self->close();
00340 break;
00341
00342 case 2:
00343 default:
00344
00345 app_abort_quit();
00346 break;
00347 }
00348 }
00349
00350
00351 LLPreviewGesture::LLPreviewGesture()
00352 : LLPreview("Gesture Preview"),
00353 mTriggerEditor(NULL),
00354 mModifierCombo(NULL),
00355 mKeyCombo(NULL),
00356 mLibraryList(NULL),
00357 mAddBtn(NULL),
00358 mUpBtn(NULL),
00359 mDownBtn(NULL),
00360 mDeleteBtn(NULL),
00361 mStepList(NULL),
00362 mOptionsText(NULL),
00363 mAnimationRadio(NULL),
00364 mAnimationCombo(NULL),
00365 mSoundCombo(NULL),
00366 mChatEditor(NULL),
00367 mSaveBtn(NULL),
00368 mPreviewBtn(NULL),
00369 mPreviewGesture(NULL),
00370 mDirty(FALSE)
00371 {
00372 }
00373
00374
00375 LLPreviewGesture::~LLPreviewGesture()
00376 {
00377
00378 std::vector<LLScrollListItem*> data_list = mStepList->getAllData();
00379 std::vector<LLScrollListItem*>::iterator data_itor;
00380 for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor)
00381 {
00382 LLScrollListItem* item = *data_itor;
00383 LLGestureStep* step = (LLGestureStep*)item->getUserdata();
00384 delete step;
00385 step = NULL;
00386 }
00387 }
00388
00389
00390 BOOL LLPreviewGesture::postBuild()
00391 {
00392 LLLineEditor* edit;
00393 LLComboBox* combo;
00394 LLButton* btn;
00395 LLScrollListCtrl* list;
00396 LLTextBox* text;
00397 LLCheckBoxCtrl* check;
00398
00399 edit = LLViewerUICtrlFactory::getLineEditorByName(this, "trigger_editor");
00400 edit->setKeystrokeCallback(onKeystrokeCommit);
00401 edit->setCommitCallback(onCommitSetDirty);
00402 edit->setCommitOnFocusLost(TRUE);
00403 edit->setCallbackUserData(this);
00404 edit->setIgnoreTab(TRUE);
00405 mTriggerEditor = edit;
00406
00407 text = LLViewerUICtrlFactory::getTextBoxByName(this, "replace_text");
00408 text->setEnabled(FALSE);
00409 mReplaceText = text;
00410
00411 edit = LLViewerUICtrlFactory::getLineEditorByName(this, "replace_editor");
00412 edit->setEnabled(FALSE);
00413 edit->setKeystrokeCallback(onKeystrokeCommit);
00414 edit->setCommitCallback(onCommitSetDirty);
00415 edit->setCommitOnFocusLost(TRUE);
00416 edit->setCallbackUserData(this);
00417 edit->setIgnoreTab(TRUE);
00418 mReplaceEditor = edit;
00419
00420 combo = LLViewerUICtrlFactory::getComboBoxByName(this, "modifier_combo");
00421 combo->setCommitCallback(onCommitSetDirty);
00422 combo->setCallbackUserData(this);
00423 mModifierCombo = combo;
00424
00425 combo = LLViewerUICtrlFactory::getComboBoxByName(this, "key_combo");
00426 combo->setCommitCallback(onCommitSetDirty);
00427 combo->setCallbackUserData(this);
00428 mKeyCombo = combo;
00429
00430 list = LLViewerUICtrlFactory::getScrollListByName(this, "library_list");
00431 list->setCommitCallback(onCommitLibrary);
00432 list->setDoubleClickCallback(onClickAdd);
00433 list->setCallbackUserData(this);
00434 mLibraryList = list;
00435
00436 btn = LLViewerUICtrlFactory::getButtonByName(this, "add_btn");
00437 btn->setClickedCallback(onClickAdd);
00438 btn->setCallbackUserData(this);
00439 btn->setEnabled(FALSE);
00440 mAddBtn = btn;
00441
00442 btn = LLViewerUICtrlFactory::getButtonByName(this, "up_btn");
00443 btn->setClickedCallback(onClickUp);
00444 btn->setCallbackUserData(this);
00445 btn->setEnabled(FALSE);
00446 mUpBtn = btn;
00447
00448 btn = LLViewerUICtrlFactory::getButtonByName(this, "down_btn");
00449 btn->setClickedCallback(onClickDown);
00450 btn->setCallbackUserData(this);
00451 btn->setEnabled(FALSE);
00452 mDownBtn = btn;
00453
00454 btn = LLViewerUICtrlFactory::getButtonByName(this, "delete_btn");
00455 btn->setClickedCallback(onClickDelete);
00456 btn->setCallbackUserData(this);
00457 btn->setEnabled(FALSE);
00458 mDeleteBtn = btn;
00459
00460 list = LLViewerUICtrlFactory::getScrollListByName(this, "step_list");
00461 list->setCommitCallback(onCommitStep);
00462 list->setCallbackUserData(this);
00463 mStepList = list;
00464
00465
00466 text = LLViewerUICtrlFactory::getTextBoxByName(this, "options_text");
00467 text->setBorderVisible(TRUE);
00468 mOptionsText = text;
00469
00470 combo = LLViewerUICtrlFactory::getComboBoxByName(this, "animation_list");
00471 combo->setVisible(FALSE);
00472 combo->setCommitCallback(onCommitAnimation);
00473 combo->setCallbackUserData(this);
00474 mAnimationCombo = combo;
00475
00476 LLRadioGroup* group;
00477 group = LLViewerUICtrlFactory::getRadioGroupByName(this, "animation_trigger_type");
00478 group->setVisible(FALSE);
00479 group->setCommitCallback(onCommitAnimationTrigger);
00480 group->setCallbackUserData(this);
00481 mAnimationRadio = group;
00482
00483 combo = LLViewerUICtrlFactory::getComboBoxByName(this, "sound_list");
00484 combo->setVisible(FALSE);
00485 combo->setCommitCallback(onCommitSound);
00486 combo->setCallbackUserData(this);
00487 mSoundCombo = combo;
00488
00489 edit = LLViewerUICtrlFactory::getLineEditorByName(this, "chat_editor");
00490 edit->setVisible(FALSE);
00491 edit->setCommitCallback(onCommitChat);
00492
00493 edit->setCommitOnFocusLost(TRUE);
00494 edit->setCallbackUserData(this);
00495 edit->setIgnoreTab(TRUE);
00496 mChatEditor = edit;
00497
00498 check = LLViewerUICtrlFactory::getCheckBoxByName(this, "wait_anim_check");
00499 check->setVisible(FALSE);
00500 check->setCommitCallback(onCommitWait);
00501 check->setCallbackUserData(this);
00502 mWaitAnimCheck = check;
00503
00504 check = LLViewerUICtrlFactory::getCheckBoxByName(this, "wait_time_check");
00505 check->setVisible(FALSE);
00506 check->setCommitCallback(onCommitWait);
00507 check->setCallbackUserData(this);
00508 mWaitTimeCheck = check;
00509
00510 edit = LLViewerUICtrlFactory::getLineEditorByName(this, "wait_time_editor");
00511 edit->setEnabled(FALSE);
00512 edit->setVisible(FALSE);
00513 edit->setPrevalidate(LLLineEditor::prevalidateFloat);
00514
00515 edit->setCommitOnFocusLost(TRUE);
00516 edit->setCommitCallback(onCommitWaitTime);
00517 edit->setCallbackUserData(this);
00518 edit->setIgnoreTab(TRUE);
00519 mWaitTimeEditor = edit;
00520
00521
00522 check = LLViewerUICtrlFactory::getCheckBoxByName(this, "active_check");
00523 check->setCommitCallback(onCommitActive);
00524 check->setCallbackUserData(this);
00525 mActiveCheck = check;
00526
00527 btn = LLViewerUICtrlFactory::getButtonByName(this, "save_btn");
00528 btn->setClickedCallback(onClickSave);
00529 btn->setCallbackUserData(this);
00530 mSaveBtn = btn;
00531
00532 btn = LLViewerUICtrlFactory::getButtonByName(this, "preview_btn");
00533 btn->setClickedCallback(onClickPreview);
00534 btn->setCallbackUserData(this);
00535 mPreviewBtn = btn;
00536
00537
00538
00539 addModifiers();
00540 addKeys();
00541 addAnimations();
00542 addSounds();
00543
00544
00545 const LLInventoryItem* item = getItem();
00546
00547 if (item)
00548 {
00549 childSetCommitCallback("desc", LLPreview::onText, this);
00550 childSetText("desc", item->getDescription());
00551 childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
00552 }
00553
00554 return TRUE;
00555 }
00556
00557
00558 void LLPreviewGesture::addModifiers()
00559 {
00560 LLComboBox* combo = mModifierCombo;
00561
00562 combo->add( NONE_LABEL, ADD_BOTTOM );
00563 combo->add( SHIFT_LABEL, ADD_BOTTOM );
00564 combo->add( CTRL_LABEL, ADD_BOTTOM );
00565 combo->setCurrentByIndex(0);
00566 }
00567
00568 void LLPreviewGesture::addKeys()
00569 {
00570 LLComboBox* combo = mKeyCombo;
00571
00572 combo->add( NONE_LABEL );
00573 for (KEY key = KEY_F2; key <= KEY_F12; key++)
00574 {
00575 combo->add( LLKeyboard::stringFromKey(key), ADD_BOTTOM );
00576 }
00577 combo->setCurrentByIndex(0);
00578 }
00579
00580
00581
00582 void LLPreviewGesture::addAnimations()
00583 {
00584 LLComboBox* combo = mAnimationCombo;
00585
00586 combo->removeall();
00587
00588 LLString none_text = childGetText("none_text");
00589
00590 combo->add(none_text, LLUUID::null);
00591
00592
00593 S32 i;
00594 for (i = 0; i < gUserAnimStatesCount; ++i)
00595 {
00596
00597 const char* label = gUserAnimStates[i].mLabel;
00598 const LLUUID& id = gUserAnimStates[i].mID;
00599 combo->add(label, id);
00600 }
00601
00602
00603 LLViewerInventoryCategory::cat_array_t cats;
00604 LLViewerInventoryItem::item_array_t items;
00605 LLIsTypeWithPermissions is_copyable_animation(LLAssetType::AT_ANIMATION,
00606 PERM_ITEM_UNRESTRICTED,
00607 gAgent.getID(),
00608 gAgent.getGroupID());
00609 gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
00610 cats,
00611 items,
00612 LLInventoryModel::EXCLUDE_TRASH,
00613 is_copyable_animation);
00614
00615
00616 std::vector<LLInventoryItem*> animations;
00617
00618 S32 count = items.count();
00619 for(i = 0; i < count; ++i)
00620 {
00621 animations.push_back( items.get(i) );
00622 }
00623
00624
00625 std::sort(animations.begin(), animations.end(), SortItemPtrsByName());
00626
00627
00628 std::vector<LLInventoryItem*>::iterator it;
00629 for (it = animations.begin(); it != animations.end(); ++it)
00630 {
00631 LLInventoryItem* item = *it;
00632
00633 combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM);
00634 }
00635 }
00636
00637
00638 void LLPreviewGesture::addSounds()
00639 {
00640 LLComboBox* combo = mSoundCombo;
00641 combo->removeall();
00642
00643 LLString none_text = childGetText("none_text");
00644
00645 combo->add(none_text, LLUUID::null);
00646
00647
00648 LLViewerInventoryCategory::cat_array_t cats;
00649 LLViewerInventoryItem::item_array_t items;
00650 LLIsTypeWithPermissions is_copyable_sound(LLAssetType::AT_SOUND,
00651 PERM_ITEM_UNRESTRICTED,
00652 gAgent.getID(),
00653 gAgent.getGroupID());
00654 gInventory.collectDescendentsIf(gAgent.getInventoryRootID(),
00655 cats,
00656 items,
00657 LLInventoryModel::EXCLUDE_TRASH,
00658 is_copyable_sound);
00659
00660
00661 std::vector<LLInventoryItem*> sounds;
00662
00663 S32 i;
00664 S32 count = items.count();
00665 for(i = 0; i < count; ++i)
00666 {
00667 sounds.push_back( items.get(i) );
00668 }
00669
00670
00671 std::sort(sounds.begin(), sounds.end(), SortItemPtrsByName());
00672
00673
00674 std::vector<LLInventoryItem*>::iterator it;
00675 for (it = sounds.begin(); it != sounds.end(); ++it)
00676 {
00677 LLInventoryItem* item = *it;
00678
00679 combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM);
00680 }
00681 }
00682
00683
00684 void LLPreviewGesture::init(const LLUUID& item_id, const LLUUID& object_id)
00685 {
00686
00687 setItemID(item_id);
00688 setObjectID(object_id);
00689 }
00690
00691
00692 void LLPreviewGesture::refresh()
00693 {
00694
00695 LLViewerInventoryItem* item = (LLViewerInventoryItem*)getItem();
00696 bool is_complete = (item && item->isComplete()) ? true : false;
00697 if (mPreviewGesture || !is_complete)
00698 {
00699
00700 childSetEnabled("desc", FALSE);
00701
00702 mTriggerEditor->setEnabled(FALSE);
00703 mReplaceText->setEnabled(FALSE);
00704 mReplaceEditor->setEnabled(FALSE);
00705 mModifierCombo->setEnabled(FALSE);
00706 mKeyCombo->setEnabled(FALSE);
00707 mLibraryList->setEnabled(FALSE);
00708 mAddBtn->setEnabled(FALSE);
00709 mUpBtn->setEnabled(FALSE);
00710 mDownBtn->setEnabled(FALSE);
00711 mDeleteBtn->setEnabled(FALSE);
00712 mStepList->setEnabled(FALSE);
00713 mOptionsText->setEnabled(FALSE);
00714 mAnimationCombo->setEnabled(FALSE);
00715 mAnimationRadio->setEnabled(FALSE);
00716 mSoundCombo->setEnabled(FALSE);
00717 mChatEditor->setEnabled(FALSE);
00718 mWaitAnimCheck->setEnabled(FALSE);
00719 mWaitTimeCheck->setEnabled(FALSE);
00720 mWaitTimeEditor->setEnabled(FALSE);
00721 mActiveCheck->setEnabled(FALSE);
00722 mSaveBtn->setEnabled(FALSE);
00723
00724
00725 mPreviewBtn->setEnabled(TRUE);
00726 return;
00727 }
00728
00729 BOOL modifiable = item->getPermissions().allowModifyBy(gAgent.getID());
00730
00731 childSetEnabled("desc", modifiable);
00732 mTriggerEditor->setEnabled(TRUE);
00733 mLibraryList->setEnabled(modifiable);
00734 mStepList->setEnabled(modifiable);
00735 mOptionsText->setEnabled(modifiable);
00736 mAnimationCombo->setEnabled(modifiable);
00737 mAnimationRadio->setEnabled(modifiable);
00738 mSoundCombo->setEnabled(modifiable);
00739 mChatEditor->setEnabled(modifiable);
00740 mWaitAnimCheck->setEnabled(modifiable);
00741 mWaitTimeCheck->setEnabled(modifiable);
00742 mWaitTimeEditor->setEnabled(modifiable);
00743 mActiveCheck->setEnabled(TRUE);
00744
00745 const std::string& trigger = mTriggerEditor->getText();
00746 BOOL have_trigger = !trigger.empty();
00747
00748 const std::string& replace = mReplaceEditor->getText();
00749 BOOL have_replace = !replace.empty();
00750
00751 LLScrollListItem* library_item = mLibraryList->getFirstSelected();
00752 BOOL have_library = (library_item != NULL);
00753
00754 LLScrollListItem* step_item = mStepList->getFirstSelected();
00755 S32 step_index = mStepList->getFirstSelectedIndex();
00756 S32 step_count = mStepList->getItemCount();
00757 BOOL have_step = (step_item != NULL);
00758
00759 mReplaceText->setEnabled(have_trigger || have_replace);
00760 mReplaceEditor->setEnabled(have_trigger || have_replace);
00761
00762 mModifierCombo->setEnabled(TRUE);
00763 mKeyCombo->setEnabled(TRUE);
00764
00765 mAddBtn->setEnabled(modifiable && have_library);
00766 mUpBtn->setEnabled(modifiable && have_step && step_index > 0);
00767 mDownBtn->setEnabled(modifiable && have_step && step_index < step_count-1);
00768 mDeleteBtn->setEnabled(modifiable && have_step);
00769
00770
00771 mAnimationCombo->setVisible(FALSE);
00772 mAnimationRadio->setVisible(FALSE);
00773 mSoundCombo->setVisible(FALSE);
00774 mChatEditor->setVisible(FALSE);
00775 mWaitAnimCheck->setVisible(FALSE);
00776 mWaitTimeCheck->setVisible(FALSE);
00777 mWaitTimeEditor->setVisible(FALSE);
00778
00779 LLString optionstext;
00780
00781 if (have_step)
00782 {
00783
00784 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
00785 EStepType type = step->getType();
00786
00787 switch(type)
00788 {
00789 case STEP_ANIMATION:
00790 {
00791 LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
00792 optionstext = childGetText("step_anim");
00793 mAnimationCombo->setVisible(TRUE);
00794 mAnimationRadio->setVisible(TRUE);
00795 mAnimationRadio->setSelectedIndex((anim_step->mFlags & ANIM_FLAG_STOP) ? 1 : 0);
00796 mAnimationCombo->setCurrentByID(anim_step->mAnimAssetID);
00797 break;
00798 }
00799 case STEP_SOUND:
00800 {
00801 LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
00802 optionstext = childGetText("step_sound");
00803 mSoundCombo->setVisible(TRUE);
00804 mSoundCombo->setCurrentByID(sound_step->mSoundAssetID);
00805 break;
00806 }
00807 case STEP_CHAT:
00808 {
00809 LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
00810 optionstext = childGetText("step_chat");
00811 mChatEditor->setVisible(TRUE);
00812 mChatEditor->setText(chat_step->mChatText);
00813 break;
00814 }
00815 case STEP_WAIT:
00816 {
00817 LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
00818 optionstext = childGetText("step_wait");
00819 mWaitAnimCheck->setVisible(TRUE);
00820 mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM);
00821 mWaitTimeCheck->setVisible(TRUE);
00822 mWaitTimeCheck->set(wait_step->mFlags & WAIT_FLAG_TIME);
00823 mWaitTimeEditor->setVisible(TRUE);
00824 std::string buffer = llformat("%.1f", (double)wait_step->mWaitSeconds);
00825 mWaitTimeEditor->setText(buffer);
00826 break;
00827 }
00828 default:
00829 break;
00830 }
00831 }
00832
00833 mOptionsText->setText(optionstext);
00834
00835 BOOL active = gGestureManager.isGestureActive(mItemUUID);
00836 mActiveCheck->set(active);
00837
00838
00839 mPreviewBtn->setEnabled(step_count > 0);
00840
00841
00842 mSaveBtn->setEnabled(mDirty);
00843 addAnimations();
00844 addSounds();
00845 }
00846
00847
00848 void LLPreviewGesture::initDefaultGesture()
00849 {
00850 LLScrollListItem* item;
00851 item = addStep("Animation");
00852 LLGestureStepAnimation* anim = (LLGestureStepAnimation*)item->getUserdata();
00853 anim->mAnimAssetID = ANIM_AGENT_HELLO;
00854 anim->mAnimName = "Wave";
00855 updateLabel(item);
00856
00857 item = addStep("Wait");
00858 LLGestureStepWait* wait = (LLGestureStepWait*)item->getUserdata();
00859 wait->mFlags = WAIT_FLAG_ALL_ANIM;
00860 updateLabel(item);
00861
00862 item = addStep("Chat");
00863 LLGestureStepChat* chat_step = (LLGestureStepChat*)item->getUserdata();
00864 chat_step->mChatText = "Hello, avatar!";
00865 updateLabel(item);
00866
00867
00868 mStepList->selectFirstItem();
00869
00870
00871 mDirty = TRUE;
00872 }
00873
00874
00875 void LLPreviewGesture::loadAsset()
00876 {
00877 const LLInventoryItem* item = getItem();
00878 if (!item) return;
00879
00880 LLUUID asset_id = item->getAssetUUID();
00881 if (asset_id.isNull())
00882 {
00883
00884
00885 initDefaultGesture();
00886 refresh();
00887 return;
00888 }
00889
00890
00891
00892
00893
00894
00895 LLUUID* item_idp = new LLUUID(mItemUUID);
00896
00897 const BOOL high_priority = TRUE;
00898 gAssetStorage->getAssetData(asset_id,
00899 LLAssetType::AT_GESTURE,
00900 onLoadComplete,
00901 (void**)item_idp,
00902 high_priority);
00903 mAssetStatus = PREVIEW_ASSET_LOADING;
00904 }
00905
00906
00907
00908 void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
00909 const LLUUID& asset_uuid,
00910 LLAssetType::EType type,
00911 void* user_data, S32 status, LLExtStat ext_status)
00912 {
00913 LLUUID* item_idp = (LLUUID*)user_data;
00914 LLPreview* preview = LLPreview::find(*item_idp);
00915 if (preview)
00916 {
00917 LLPreviewGesture* self = (LLPreviewGesture*)preview;
00918
00919 if (0 == status)
00920 {
00921 LLVFile file(vfs, asset_uuid, type, LLVFile::READ);
00922 S32 size = file.getSize();
00923
00924 char* buffer = new char[size+1];
00925 file.read((U8*)buffer, size);
00926 buffer[size] = '\0';
00927
00928 LLMultiGesture* gesture = new LLMultiGesture();
00929
00930 LLDataPackerAsciiBuffer dp(buffer, size+1);
00931 BOOL ok = gesture->deserialize(dp);
00932
00933 if (ok)
00934 {
00935
00936 self->loadUIFromGesture(gesture);
00937
00938 self->mStepList->selectFirstItem();
00939
00940 self->mDirty = FALSE;
00941 self->refresh();
00942 }
00943 else
00944 {
00945 llwarns << "Unable to load gesture" << llendl;
00946 }
00947
00948 delete gesture;
00949 gesture = NULL;
00950
00951 delete [] buffer;
00952 buffer = NULL;
00953
00954 self->mAssetStatus = PREVIEW_ASSET_LOADED;
00955 }
00956 else
00957 {
00958 if( gViewerStats )
00959 {
00960 gViewerStats->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
00961 }
00962
00963 if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
00964 LL_ERR_FILE_EMPTY == status)
00965 {
00966 LLNotifyBox::showXml("GestureMissing");
00967 }
00968 else
00969 {
00970 LLNotifyBox::showXml("UnableToLoadGesture");
00971 }
00972
00973 llwarns << "Problem loading gesture: " << status << llendl;
00974 self->mAssetStatus = PREVIEW_ASSET_ERROR;
00975 }
00976 }
00977 delete item_idp;
00978 item_idp = NULL;
00979 }
00980
00981
00982 void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
00983 {
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 mTriggerEditor->setText(gesture->mTrigger);
00995
00996 mReplaceEditor->setText(gesture->mReplaceText);
00997
00998 switch (gesture->mMask)
00999 {
01000 default:
01001 case MASK_NONE:
01002 mModifierCombo->setSimple( LLString(NONE_LABEL) );
01003 break;
01004 case MASK_SHIFT:
01005 mModifierCombo->setSimple( LLString(SHIFT_LABEL) );
01006 break;
01007 case MASK_CONTROL:
01008 mModifierCombo->setSimple( LLString(CTRL_LABEL) );
01009 break;
01010 }
01011
01012 mKeyCombo->setCurrentByIndex(0);
01013 if (gesture->mKey != KEY_NONE)
01014 {
01015 mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey));
01016 }
01017
01018
01019 S32 i;
01020 S32 count = gesture->mSteps.size();
01021 for (i = 0; i < count; ++i)
01022 {
01023 LLGestureStep* step = gesture->mSteps[i];
01024
01025 LLGestureStep* new_step = NULL;
01026
01027 switch(step->getType())
01028 {
01029 case STEP_ANIMATION:
01030 {
01031 LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
01032 LLGestureStepAnimation* new_anim_step =
01033 new LLGestureStepAnimation(*anim_step);
01034 new_step = new_anim_step;
01035 break;
01036 }
01037 case STEP_SOUND:
01038 {
01039 LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
01040 LLGestureStepSound* new_sound_step =
01041 new LLGestureStepSound(*sound_step);
01042 new_step = new_sound_step;
01043 break;
01044 }
01045 case STEP_CHAT:
01046 {
01047 LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
01048 LLGestureStepChat* new_chat_step =
01049 new LLGestureStepChat(*chat_step);
01050 new_step = new_chat_step;
01051 break;
01052 }
01053 case STEP_WAIT:
01054 {
01055 LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
01056 LLGestureStepWait* new_wait_step =
01057 new LLGestureStepWait(*wait_step);
01058 new_step = new_wait_step;
01059 break;
01060 }
01061 default:
01062 {
01063 break;
01064 }
01065 }
01066
01067 if (!new_step) continue;
01068
01069
01070 LLSD row;
01071 row["columns"][0]["value"] = new_step->getLabel();
01072 row["columns"][0]["font"] = "SANSSERIF_SMALL";
01073 LLScrollListItem* item = mStepList->addElement(row);
01074 item->setUserdata(new_step);
01075 }
01076 }
01077
01078
01079
01080 struct LLSaveInfo
01081 {
01082 LLSaveInfo(const LLUUID& item_id, const LLUUID& object_id, const LLString& desc,
01083 const LLTransactionID tid)
01084 : mItemUUID(item_id), mObjectUUID(object_id), mDesc(desc), mTransactionID(tid)
01085 {
01086 }
01087
01088 LLUUID mItemUUID;
01089 LLUUID mObjectUUID;
01090 LLString mDesc;
01091 LLTransactionID mTransactionID;
01092 };
01093
01094
01095 void LLPreviewGesture::saveIfNeeded()
01096 {
01097 if (!gAssetStorage)
01098 {
01099 llwarns << "Can't save gesture, no asset storage system." << llendl;
01100 return;
01101 }
01102
01103 if (!mDirty)
01104 {
01105 return;
01106 }
01107
01108
01109 LLMultiGesture* gesture = createGesture();
01110
01111
01112 S32 max_size = gesture->getMaxSerialSize();
01113 char* buffer = new char[max_size];
01114
01115 LLDataPackerAsciiBuffer dp(buffer, max_size);
01116
01117 BOOL ok = gesture->serialize(dp);
01118
01119 if (dp.getCurrentSize() > 1000)
01120 {
01121 gViewerWindow->alertXml("GestureSaveFailedTooManySteps");
01122
01123 delete gesture;
01124 gesture = NULL;
01125 }
01126 else if (!ok)
01127 {
01128 gViewerWindow->alertXml("GestureSaveFailedTryAgain");
01129 delete gesture;
01130 gesture = NULL;
01131 }
01132 else
01133 {
01134
01135 LLTransactionID tid;
01136 LLAssetID asset_id;
01137 tid.generate();
01138 asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
01139
01140 LLVFile file(gVFS, asset_id, LLAssetType::AT_GESTURE, LLVFile::APPEND);
01141
01142 S32 size = dp.getCurrentSize();
01143 file.setMaxSize(size);
01144 file.write((U8*)buffer, size);
01145
01146 BOOL delayedUpload = FALSE;
01147
01148
01149 LLViewerInventoryItem* item = (LLViewerInventoryItem*) getItem();
01150 if (item)
01151 {
01152 std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
01153 std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
01154 if (mObjectUUID.isNull() && !agent_url.empty())
01155 {
01156
01157
01158
01159 item->setComplete(FALSE);
01160 refresh();
01161 item->setComplete(TRUE);
01162
01163
01164 LLSD body;
01165 body["item_id"] = mItemUUID;
01166 LLHTTPClient::post(agent_url, body,
01167 new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
01168 delayedUpload = TRUE;
01169 }
01170 else if (!mObjectUUID.isNull() && !task_url.empty())
01171 {
01172
01173 LLSD body;
01174 body["task_id"] = mObjectUUID;
01175 body["item_id"] = mItemUUID;
01176 LLHTTPClient::post(task_url, body,
01177 new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
01178 }
01179 else if (gAssetStorage)
01180 {
01181 LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
01182 LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
01183 gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
01184 }
01185 }
01186
01187
01188
01189 if (!delayedUpload && gGestureManager.isGestureActive(mItemUUID))
01190 {
01191
01192 gGestureManager.replaceGesture(mItemUUID, gesture, asset_id);
01193
01194
01195
01196 gInventory.notifyObservers();
01197 }
01198 else
01199 {
01200
01201 delete gesture;
01202 gesture = NULL;
01203 }
01204
01205 mDirty = FALSE;
01206
01207
01208 if(!delayedUpload)
01209 {
01210 refresh();
01211 }
01212 }
01213
01214 delete [] buffer;
01215 buffer = NULL;
01216 }
01217
01218
01219
01220
01221
01222 void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status)
01223 {
01224 LLSaveInfo* info = (LLSaveInfo*)user_data;
01225 if (info && (status == 0))
01226 {
01227 if(info->mObjectUUID.isNull())
01228 {
01229
01230 LLViewerInventoryItem* item;
01231 item = (LLViewerInventoryItem*)gInventory.getItem(info->mItemUUID);
01232 if(item)
01233 {
01234 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
01235 new_item->setDescription(info->mDesc);
01236 new_item->setTransactionID(info->mTransactionID);
01237 new_item->setAssetUUID(asset_uuid);
01238 new_item->updateServer(FALSE);
01239 gInventory.updateItem(new_item);
01240 gInventory.notifyObservers();
01241 }
01242 else
01243 {
01244 llwarns << "Inventory item for gesture " << info->mItemUUID
01245 << " is no longer in agent inventory." << llendl
01246 }
01247 }
01248 else
01249 {
01250
01251 LLViewerObject* object = gObjectList.findObject(info->mObjectUUID);
01252 LLViewerInventoryItem* item = NULL;
01253 if(object)
01254 {
01255 item = (LLViewerInventoryItem*)object->getInventoryObject(info->mItemUUID);
01256 }
01257 if(object && item)
01258 {
01259 item->setDescription(info->mDesc);
01260 item->setAssetUUID(asset_uuid);
01261 item->setTransactionID(info->mTransactionID);
01262 object->updateInventory(item, TASK_INVENTORY_ITEM_KEY, false);
01263 dialog_refresh_all();
01264 }
01265 else
01266 {
01267 gViewerWindow->alertXml("GestureSaveFailedObjectNotFound");
01268 }
01269 }
01270
01271
01272 LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(info->mItemUUID);
01273 if (previewp && previewp->mCloseAfterSave)
01274 {
01275 previewp->close();
01276 }
01277 }
01278 else
01279 {
01280 llwarns << "Problem saving gesture: " << status << llendl;
01281 LLStringBase<char>::format_map_t args;
01282 args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
01283 gViewerWindow->alertXml("GestureSaveFailedReason",args);
01284 }
01285 delete info;
01286 info = NULL;
01287 }
01288
01289
01290 LLMultiGesture* LLPreviewGesture::createGesture()
01291 {
01292 LLMultiGesture* gesture = new LLMultiGesture();
01293
01294 gesture->mTrigger = mTriggerEditor->getText();
01295 gesture->mReplaceText = mReplaceEditor->getText();
01296
01297 const LLString& modifier = mModifierCombo->getSimple();
01298 if (modifier == CTRL_LABEL)
01299 {
01300 gesture->mMask = MASK_CONTROL;
01301 }
01302 else if (modifier == SHIFT_LABEL)
01303 {
01304 gesture->mMask = MASK_SHIFT;
01305 }
01306 else
01307 {
01308 gesture->mMask = MASK_NONE;
01309 }
01310
01311 if (mKeyCombo->getCurrentIndex() == 0)
01312 {
01313 gesture->mKey = KEY_NONE;
01314 }
01315 else
01316 {
01317 const LLString& key_string = mKeyCombo->getSimple();
01318 LLKeyboard::keyFromString(key_string.c_str(), &(gesture->mKey));
01319 }
01320
01321 std::vector<LLScrollListItem*> data_list = mStepList->getAllData();
01322 std::vector<LLScrollListItem*>::iterator data_itor;
01323 for (data_itor = data_list.begin(); data_itor != data_list.end(); ++data_itor)
01324 {
01325 LLScrollListItem* item = *data_itor;
01326 LLGestureStep* step = (LLGestureStep*)item->getUserdata();
01327
01328 switch(step->getType())
01329 {
01330 case STEP_ANIMATION:
01331 {
01332
01333 LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
01334 LLGestureStepAnimation* new_anim_step =
01335 new LLGestureStepAnimation(*anim_step);
01336 gesture->mSteps.push_back(new_anim_step);
01337 break;
01338 }
01339 case STEP_SOUND:
01340 {
01341
01342 LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
01343 LLGestureStepSound* new_sound_step =
01344 new LLGestureStepSound(*sound_step);
01345 gesture->mSteps.push_back(new_sound_step);
01346 break;
01347 }
01348 case STEP_CHAT:
01349 {
01350
01351 LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
01352 LLGestureStepChat* new_chat_step =
01353 new LLGestureStepChat(*chat_step);
01354 gesture->mSteps.push_back(new_chat_step);
01355 break;
01356 }
01357 case STEP_WAIT:
01358 {
01359
01360 LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
01361 LLGestureStepWait* new_wait_step =
01362 new LLGestureStepWait(*wait_step);
01363 gesture->mSteps.push_back(new_wait_step);
01364 break;
01365 }
01366 default:
01367 {
01368 break;
01369 }
01370 }
01371 }
01372
01373 return gesture;
01374 }
01375
01376
01377
01378 void LLPreviewGesture::updateLabel(LLScrollListItem* item)
01379 {
01380 LLGestureStep* step = (LLGestureStep*)item->getUserdata();
01381
01382 LLScrollListCell* cell = item->getColumn(0);
01383 LLScrollListText* text_cell = (LLScrollListText*)cell;
01384 std::string label = step->getLabel();
01385 text_cell->setText(label);
01386 }
01387
01388
01389 void LLPreviewGesture::onCommitSetDirty(LLUICtrl* ctrl, void* data)
01390 {
01391 LLPreviewGesture* self = (LLPreviewGesture*)data;
01392 self->mDirty = TRUE;
01393 self->refresh();
01394 }
01395
01396
01397 void LLPreviewGesture::onCommitLibrary(LLUICtrl* ctrl, void* data)
01398 {
01399 LLPreviewGesture* self = (LLPreviewGesture*)data;
01400
01401 LLScrollListItem* library_item = self->mLibraryList->getFirstSelected();
01402 if (library_item)
01403 {
01404 self->mStepList->deselectAllItems();
01405 self->refresh();
01406 }
01407 }
01408
01409
01410
01411 void LLPreviewGesture::onCommitStep(LLUICtrl* ctrl, void* data)
01412 {
01413 LLPreviewGesture* self = (LLPreviewGesture*)data;
01414
01415 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01416 if (!step_item) return;
01417
01418 self->mLibraryList->deselectAllItems();
01419 self->refresh();
01420 }
01421
01422
01423
01424 void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data)
01425 {
01426 LLPreviewGesture* self = (LLPreviewGesture*)data;
01427
01428 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01429 if (step_item)
01430 {
01431 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01432 if (step->getType() == STEP_ANIMATION)
01433 {
01434
01435 LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
01436 if (self->mAnimationCombo->getCurrentIndex() == 0)
01437 {
01438 anim_step->mAnimName.clear();
01439 anim_step->mAnimAssetID.setNull();
01440 }
01441 else
01442 {
01443 anim_step->mAnimName = self->mAnimationCombo->getSimple();
01444 anim_step->mAnimAssetID = self->mAnimationCombo->getCurrentID();
01445 }
01446
01447
01448
01449 updateLabel(step_item);
01450
01451 self->mDirty = TRUE;
01452 self->refresh();
01453 }
01454 }
01455 }
01456
01457
01458 void LLPreviewGesture::onCommitAnimationTrigger(LLUICtrl* ctrl, void *data)
01459 {
01460 LLPreviewGesture* self = (LLPreviewGesture*)data;
01461
01462 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01463 if (step_item)
01464 {
01465 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01466 if (step->getType() == STEP_ANIMATION)
01467 {
01468 LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
01469 if (self->mAnimationRadio->getSelectedIndex() == 0)
01470 {
01471
01472 anim_step->mFlags &= ~ANIM_FLAG_STOP;
01473 }
01474 else
01475 {
01476
01477 anim_step->mFlags |= ANIM_FLAG_STOP;
01478 }
01479
01480 updateLabel(step_item);
01481
01482 self->mDirty = TRUE;
01483 self->refresh();
01484 }
01485 }
01486 }
01487
01488
01489 void LLPreviewGesture::onCommitSound(LLUICtrl* ctrl, void* data)
01490 {
01491 LLPreviewGesture* self = (LLPreviewGesture*)data;
01492
01493 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01494 if (step_item)
01495 {
01496 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01497 if (step->getType() == STEP_SOUND)
01498 {
01499
01500 LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
01501 sound_step->mSoundName = self->mSoundCombo->getSimple();
01502 sound_step->mSoundAssetID = self->mSoundCombo->getCurrentID();
01503 sound_step->mFlags = 0x0;
01504
01505
01506 updateLabel(step_item);
01507
01508 self->mDirty = TRUE;
01509 self->refresh();
01510 }
01511 }
01512 }
01513
01514
01515 void LLPreviewGesture::onCommitChat(LLUICtrl* ctrl, void* data)
01516 {
01517 LLPreviewGesture* self = (LLPreviewGesture*)data;
01518
01519 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01520 if (!step_item) return;
01521
01522 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01523 if (step->getType() != STEP_CHAT) return;
01524
01525 LLGestureStepChat* chat_step = (LLGestureStepChat*)step;
01526 chat_step->mChatText = self->mChatEditor->getText();
01527 chat_step->mFlags = 0x0;
01528
01529
01530 updateLabel(step_item);
01531
01532 self->mDirty = TRUE;
01533 self->refresh();
01534 }
01535
01536
01537 void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data)
01538 {
01539 LLPreviewGesture* self = (LLPreviewGesture*)data;
01540
01541 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01542 if (!step_item) return;
01543
01544 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01545 if (step->getType() != STEP_WAIT) return;
01546
01547 LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
01548 U32 flags = 0x0;
01549 if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM;
01550 if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME;
01551 wait_step->mFlags = flags;
01552
01553 {
01554 LLLocale locale(LLLocale::USER_LOCALE);
01555
01556 F32 wait_seconds = (F32)atof(self->mWaitTimeEditor->getText().c_str());
01557 if (wait_seconds < 0.f) wait_seconds = 0.f;
01558 if (wait_seconds > 3600.f) wait_seconds = 3600.f;
01559 wait_step->mWaitSeconds = wait_seconds;
01560 }
01561
01562
01563 self->mWaitTimeEditor->setEnabled(self->mWaitTimeCheck->get());
01564
01565
01566 updateLabel(step_item);
01567
01568 self->mDirty = TRUE;
01569 self->refresh();
01570 }
01571
01572
01573 void LLPreviewGesture::onCommitWaitTime(LLUICtrl* ctrl, void* data)
01574 {
01575 LLPreviewGesture* self = (LLPreviewGesture*)data;
01576
01577 LLScrollListItem* step_item = self->mStepList->getFirstSelected();
01578 if (!step_item) return;
01579
01580 LLGestureStep* step = (LLGestureStep*)step_item->getUserdata();
01581 if (step->getType() != STEP_WAIT) return;
01582
01583 self->mWaitTimeCheck->set(TRUE);
01584 onCommitWait(ctrl, data);
01585 }
01586
01587
01588
01589 void LLPreviewGesture::onKeystrokeCommit(LLLineEditor* caller,
01590 void* data)
01591 {
01592
01593 onCommitSetDirty(caller, data);
01594 }
01595
01596
01597 void LLPreviewGesture::onClickAdd(void* data)
01598 {
01599 LLPreviewGesture* self = (LLPreviewGesture*)data;
01600
01601 LLScrollListItem* library_item = self->mLibraryList->getFirstSelected();
01602 if (!library_item) return;
01603
01604 const LLScrollListCell* library_cell = library_item->getColumn(0);
01605 const std::string& library_text = library_cell->getText();
01606
01607 self->addStep(library_text);
01608
01609 self->mDirty = TRUE;
01610 self->refresh();
01611 }
01612
01613 LLScrollListItem* LLPreviewGesture::addStep(const std::string& library_text)
01614 {
01615 LLGestureStep* step = NULL;
01616 if (!LLString::compareInsensitive(library_text.c_str(), "Animation"))
01617 {
01618 step = new LLGestureStepAnimation();
01619 }
01620 else if (!LLString::compareInsensitive(library_text.c_str(), "Sound"))
01621 {
01622 step = new LLGestureStepSound();
01623 }
01624 else if (!LLString::compareInsensitive(library_text.c_str(), "Chat"))
01625 {
01626 step = new LLGestureStepChat();
01627 }
01628 else if (!LLString::compareInsensitive(library_text.c_str(), "Wait"))
01629 {
01630 step = new LLGestureStepWait();
01631 }
01632 else
01633 {
01634 llerrs << "Unknown step type: " << library_text << llendl;;
01635 return NULL;
01636 }
01637
01638
01639 LLSD row;
01640 row["columns"][0]["value"] = step->getLabel();
01641 row["columns"][0]["font"] = "SANSSERIF_SMALL";
01642 LLScrollListItem* step_item = mStepList->addElement(row);
01643 step_item->setUserdata(step);
01644
01645
01646 mLibraryList->deselectAllItems();
01647 mStepList->deselectAllItems();
01648
01649 step_item->setSelected(TRUE);
01650
01651 return step_item;
01652 }
01653
01654
01655 void LLPreviewGesture::onClickUp(void* data)
01656 {
01657 LLPreviewGesture* self = (LLPreviewGesture*)data;
01658
01659 S32 selected_index = self->mStepList->getFirstSelectedIndex();
01660 if (selected_index > 0)
01661 {
01662 self->mStepList->swapWithPrevious(selected_index);
01663 self->mDirty = TRUE;
01664 self->refresh();
01665 }
01666 }
01667
01668
01669 void LLPreviewGesture::onClickDown(void* data)
01670 {
01671 LLPreviewGesture* self = (LLPreviewGesture*)data;
01672
01673 S32 selected_index = self->mStepList->getFirstSelectedIndex();
01674 if (selected_index < 0) return;
01675
01676 S32 count = self->mStepList->getItemCount();
01677 if (selected_index < count-1)
01678 {
01679 self->mStepList->swapWithNext(selected_index);
01680 self->mDirty = TRUE;
01681 self->refresh();
01682 }
01683 }
01684
01685
01686 void LLPreviewGesture::onClickDelete(void* data)
01687 {
01688 LLPreviewGesture* self = (LLPreviewGesture*)data;
01689
01690 LLScrollListItem* item = self->mStepList->getFirstSelected();
01691 S32 selected_index = self->mStepList->getFirstSelectedIndex();
01692 if (item && selected_index >= 0)
01693 {
01694 LLGestureStep* step = (LLGestureStep*)item->getUserdata();
01695 delete step;
01696 step = NULL;
01697
01698 self->mStepList->deleteSingleItem(selected_index);
01699
01700 self->mDirty = TRUE;
01701 self->refresh();
01702 }
01703 }
01704
01705
01706 void LLPreviewGesture::onCommitActive(LLUICtrl* ctrl, void* data)
01707 {
01708 LLPreviewGesture* self = (LLPreviewGesture*)data;
01709 if (!gGestureManager.isGestureActive(self->mItemUUID))
01710 {
01711 gGestureManager.activateGesture(self->mItemUUID);
01712 }
01713 else
01714 {
01715 gGestureManager.deactivateGesture(self->mItemUUID);
01716 }
01717
01718
01719 LLViewerInventoryItem* item = gInventory.getItem(self->mItemUUID);
01720 if (item)
01721 {
01722 gInventory.updateItem(item);
01723 gInventory.notifyObservers();
01724 }
01725
01726 self->refresh();
01727 }
01728
01729
01730 void LLPreviewGesture::onClickSave(void* data)
01731 {
01732 LLPreviewGesture* self = (LLPreviewGesture*)data;
01733 self->saveIfNeeded();
01734 }
01735
01736
01737 void LLPreviewGesture::onClickPreview(void* data)
01738 {
01739 LLPreviewGesture* self = (LLPreviewGesture*)data;
01740
01741 if (!self->mPreviewGesture)
01742 {
01743
01744 self->mPreviewGesture = self->createGesture();
01745
01746
01747 self->mPreviewGesture->mDoneCallback = onDonePreview;
01748 self->mPreviewGesture->mCallbackData = self;
01749
01750
01751 self->mPreviewBtn->setLabel(self->childGetText("stop_txt"));
01752
01753
01754 gGestureManager.playGesture(self->mPreviewGesture);
01755
01756 self->refresh();
01757 }
01758 else
01759 {
01760
01761 gGestureManager.stopGesture(self->mPreviewGesture);
01762
01763 self->refresh();
01764 }
01765 }
01766
01767
01768
01769 void LLPreviewGesture::onDonePreview(LLMultiGesture* gesture, void* data)
01770 {
01771 LLPreviewGesture* self = (LLPreviewGesture*)data;
01772
01773 self->mPreviewBtn->setLabel(self->childGetText("preview_txt"));
01774
01775 delete self->mPreviewGesture;
01776 self->mPreviewGesture = NULL;
01777
01778 self->refresh();
01779 }