From 88cce61b09d225df0bcd8aab9dbd2c5a01ee7e19 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Thu, 19 Nov 2009 11:21:20 +0200 Subject: related to EXT-700 '"Offer" notifications should be accessible via chiclet' made 'FriendshipAccepted' notification show correct avatar icon; avoided empty avatar name on 'OfferFriendship' notifiaction; avoided creating IM session on offer from objects; --HG-- branch : product-engine --- indra/newview/llnotificationofferhandler.cpp | 26 +++++++++++++++------- indra/newview/llviewermessage.cpp | 7 ++++-- .../newview/skins/default/xui/en/notifications.xml | 9 ++++---- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 94e733913d..dea3a0c169 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -92,16 +92,26 @@ bool LLOfferHandler::processNotification(const LLSD& notify) if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change") { // add message to IM - LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, notification->getPayload()["from_id"]); - if (!LLIMMgr::instance().hasSession(session_id)) + const std::string + name = + notification->getSubstitutions().has("NAME") ? notification->getSubstitutions()["NAME"] + : notification->getSubstitutions()["[NAME]"]; + + // don't create IM session with objects + if (notification->getName() != "ObjectGiveItem" + && notification->getName() != "ObjectGiveItemUnknownUser") { - session_id = LLIMMgr::instance().addSession( - notification->getSubstitutions()["OBJECTFROMNAME"], IM_NOTHING_SPECIAL, - notification->getPayload()["from_id"]); + LLUUID from_id = notification->getPayload()["from_id"]; + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, + from_id); + if (!LLIMMgr::instance().hasSession(session_id)) + { + session_id = LLIMMgr::instance().addSession(name, + IM_NOTHING_SPECIAL, from_id); + } + LLIMMgr::instance().addMessage(session_id, LLUUID(), name, + notification->getMessage()); } - LLIMMgr::instance().addMessage(session_id, LLUUID(), - notification->getSubstitutions()["OBJECTFROMNAME"], - notification->getMessage()); LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 11b2f07f1b..8db6d5917a 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1372,7 +1372,8 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task) payload["from_id"] = info->mFromID; args["OBJECTFROMNAME"] = info->mFromName; - args["NAME"] = LLSLURL::buildCommand("agent", info->mFromID, "about"); + args["NAME"] = info->mFromName; + args["NAME_SLURL"] = LLSLURL::buildCommand("agent", info->mFromID, "about"); std::string verb = "highlight?name=" + msg; args["ITEM_SLURL"] = LLSLURL::buildCommand("inventory", info->mObjectID, verb.c_str()); @@ -2115,7 +2116,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) send_generic_message("requestonlinenotification", strings); args["NAME"] = name; - LLNotifications::instance().add("FriendshipAccepted", args); + LLSD payload; + payload["from_id"] = from_id; + LLNotifications::instance().add("FriendshipAccepted", args, payload); } break; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 56cb54c975..4897a4c8ab 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4959,7 +4959,7 @@ No valid parcel could be found. icon="notify.tga" name="ObjectGiveItem" type="offer"> -An object named [OBJECTFROMNAME] owned by [NAME] has offered you [OBJECTTYPE]: +An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has offered you [OBJECTTYPE]: [ITEM_SLURL]
+ + + + Date: Thu, 19 Nov 2009 18:34:37 -0800 Subject: Push the policy that "back", "forward" and "stop" do different things out of LLViewerMedia. Now, LLViewerMedia has explicit skipBack() and skipForward() functions, and the buttons in LLPanelPrimMediaControls now map onto those functions neatly. --- indra/newview/llpanelprimmediacontrols.cpp | 21 ++++-- indra/newview/llpanelprimmediacontrols.h | 2 + indra/newview/llviewermedia.cpp | 79 +++++++++++----------- indra/newview/llviewermedia.h | 2 + indra/newview/llviewerparcelmedia.cpp | 5 +- .../default/xui/en/panel_prim_media_controls.xml | 3 +- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 80d2a9425c..aca0e1d5c7 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -54,6 +54,7 @@ #include "llpanelprimmediacontrols.h" #include "llpluginclassmedia.h" #include "llprogressbar.h" +#include "llstring.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" #include "llviewermedia.h" @@ -92,6 +93,7 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mCommitCallbackRegistrar.add("MediaCtrl.Forward", boost::bind(&LLPanelPrimMediaControls::onClickForward, this)); mCommitCallbackRegistrar.add("MediaCtrl.Home", boost::bind(&LLPanelPrimMediaControls::onClickHome, this)); mCommitCallbackRegistrar.add("MediaCtrl.Stop", boost::bind(&LLPanelPrimMediaControls::onClickStop, this)); + mCommitCallbackRegistrar.add("MediaCtrl.MediaStop", boost::bind(&LLPanelPrimMediaControls::onClickMediaStop, this)); mCommitCallbackRegistrar.add("MediaCtrl.Reload", boost::bind(&LLPanelPrimMediaControls::onClickReload, this)); mCommitCallbackRegistrar.add("MediaCtrl.Play", boost::bind(&LLPanelPrimMediaControls::onClickPlay, this)); mCommitCallbackRegistrar.add("MediaCtrl.Pause", boost::bind(&LLPanelPrimMediaControls::onClickPause, this)); @@ -149,6 +151,7 @@ BOOL LLPanelPrimMediaControls::postBuild() mLeftBookend = getChild("left_bookend"); mRightBookend = getChild("right_bookend"); mBackgroundImage = LLUI::getUIImage(getString("control_background_image_name")); + LLStringUtil::convertToF32(getString("skip_step"), mSkipStep); // These are currently removed...but getChild creates a "dummy" widget. // This class handles them missing. @@ -873,6 +876,18 @@ void LLPanelPrimMediaControls::onClickStop() LLViewerMediaImpl* impl = getTargetMediaImpl(); + if(impl) + { + impl->navigateStop(); + } +} + +void LLPanelPrimMediaControls::onClickMediaStop() +{ + focusOnTarget(); + + LLViewerMediaImpl* impl = getTargetMediaImpl(); + if(impl) { impl->stop(); @@ -887,8 +902,7 @@ void LLPanelPrimMediaControls::onClickSkipBack() if (impl) { - // XXX Oddly, the impl has the policy that "skipping" is really navigating - impl->navigateBack(); + impl->skipBack(mSkipStep); } } @@ -900,8 +914,7 @@ void LLPanelPrimMediaControls::onClickSkipForward() if (impl) { - // XXX Oddly, the impl has the policy that "skipping" is really navigating - impl->navigateForward(); + impl->skipForward(mSkipStep); } } diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index aeee3685ed..54fc4e343f 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -97,6 +97,7 @@ private: void onClickZoom(); void onClickSkipBack(); void onClickSkipForward(); + void onClickMediaStop(); void onCommitURL(); void updateZoom(); @@ -158,6 +159,7 @@ private: LLUICtrl *mLeftBookend; LLUICtrl *mRightBookend; LLUIImage* mBackgroundImage; + F32 mSkipStep; LLUICtrl *mMediaPanelScroll; LLButton *mScrollUpCtrl; diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 3a7c54479b..e55523c11e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -278,7 +278,7 @@ viewer_media_t LLViewerMedia::newMediaImpl( } else { - media_impl->stop(); + media_impl->unload(); media_impl->mTextureId = texture_id; media_impl->mMediaWidth = media_width; media_impl->mMediaHeight = media_height; @@ -1092,15 +1092,7 @@ void LLViewerMediaImpl::stop() { if(mMediaSource) { - if(mMediaSource->pluginSupportsMediaBrowser()) - { - mMediaSource->browse_stop(); - } - else - { - mMediaSource->stop(); - } - + mMediaSource->stop(); // destroyMediaSource(); } } @@ -1132,6 +1124,40 @@ void LLViewerMediaImpl::seek(F32 time) } } +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::skipBack(F32 step_scale) +{ + if(mMediaSource) + { + if(mMediaSource->pluginSupportsMediaTime()) + { + F64 back_step = mMediaSource->getCurrentTime() - (mMediaSource->getDuration()*step_scale); + if(back_step < 0.0) + { + back_step = 0.0; + } + mMediaSource->seek(back_step); + } + } +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::skipForward(F32 step_scale) +{ + if(mMediaSource) + { + if(mMediaSource->pluginSupportsMediaTime()) + { + F64 forward_step = mMediaSource->getCurrentTime() + (mMediaSource->getDuration()*step_scale); + if(forward_step > mMediaSource->getDuration()) + { + forward_step = mMediaSource->getDuration(); + } + mMediaSource->seek(forward_step); + } + } +} + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::setVolume(F32 volume) { @@ -1339,21 +1365,7 @@ void LLViewerMediaImpl::navigateBack() { if (mMediaSource) { - if(mMediaSource->pluginSupportsMediaTime()) - { - F64 step_scale = 0.02; // temp , can be changed - F64 back_step = mMediaSource->getCurrentTime() - (mMediaSource->getDuration()*step_scale); - if(back_step < 0.0) - { - back_step = 0.0; - } - mMediaSource->seek(back_step); - //mMediaSource->start(-2.0); - } - else - { - mMediaSource->browse_back(); - } + mMediaSource->browse_back(); } } @@ -1362,21 +1374,7 @@ void LLViewerMediaImpl::navigateForward() { if (mMediaSource) { - if(mMediaSource->pluginSupportsMediaTime()) - { - F64 step_scale = 0.02; // temp , can be changed - F64 forward_step = mMediaSource->getCurrentTime() + (mMediaSource->getDuration()*step_scale); - if(forward_step > mMediaSource->getDuration()) - { - forward_step = mMediaSource->getDuration(); - } - mMediaSource->seek(forward_step); - //mMediaSource->start(2.0); - } - else - { - mMediaSource->browse_forward(); - } + mMediaSource->browse_forward(); } } @@ -1525,7 +1523,6 @@ void LLViewerMediaImpl::navigateStop() { mMediaSource->browse_stop(); } - } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index f4afce6c4c..ac12112ed4 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -149,6 +149,8 @@ public: void pause(); void start(); void seek(F32 time); + void skipBack(F32 step_scale); + void skipForward(F32 step_scale); void setVolume(F32 volume); void updateVolume(); F32 getVolume(); diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 7559fd8e72..cb2099b3b0 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -218,7 +218,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel) LL_DEBUGS("Media") << "new media impl with mime type " << mime_type << ", url " << media_url << LL_ENDL; // Delete the old one first so they don't fight over the texture. - sMediaImpl->stop(); + sMediaImpl->unload(); sMediaImpl = LLViewerMedia::newMediaImpl( placeholder_texture_id, @@ -261,8 +261,7 @@ void LLViewerParcelMedia::stop() // We need to remove the media HUD if it is up. LLViewerMediaFocus::getInstance()->clearFocus(); - // This will kill the media instance. - sMediaImpl->stop(); + // This will unload & kill the media instance. sMediaImpl = NULL; } diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index 00e3116217..88049fe7d1 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -8,6 +8,7 @@ mouse_opaque="false" width="800"> Inspector_Background + 0.2 + function="MediaCtrl.MediaStop" /> Date: Fri, 20 Nov 2009 12:19:29 +0200 Subject: fixed EXT-2457 "Remove unresolved notifications counter from the Login/Startup toast"; --HG-- branch : product-engine --- indra/newview/llscreenchannel.cpp | 12 +----------- indra/newview/skins/default/xui/en/strings.xml | 3 +-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index d1cf4a0810..c4d3fb9d7d 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -535,17 +535,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) std::string mStartUpFormatString; - if(notif_num == 1) - { - mStartUpFormatString = LLTrans::getString("StartUpNotification"); - } - else - { - mStartUpFormatString = LLTrans::getString("StartUpNotifications"); - } - - - std::string text = llformat(mStartUpFormatString.c_str(), notif_num); + std::string text = LLTrans::getString("StartUpNotifications"); toast_rect = mStartUpToastPanel->getRect(); mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e76763d7eb..b3728cb425 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -1782,8 +1782,7 @@ Clears (deletes) the media and all params from the given face. Save Attachment Teleport offering - %d new notification arrived while you were away... - %d new notifications arrived while you were away... + New notifications arrived while you were away. You have %d more notification -- cgit v1.2.3 From a995c494d4a3c7750532f01d2c8c693e7ff32ea3 Mon Sep 17 00:00:00 2001 From: Alexei Arabadji Date: Fri, 20 Nov 2009 12:52:40 +0200 Subject: removed redundant local variable --HG-- branch : product-engine --- indra/newview/llscreenchannel.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index c4d3fb9d7d..24505f6bd6 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -533,8 +533,6 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, F32 timer) LLTextBox* text_box = mStartUpToastPanel->getChild("toast_text"); - std::string mStartUpFormatString; - std::string text = LLTrans::getString("StartUpNotifications"); toast_rect = mStartUpToastPanel->getRect(); -- cgit v1.2.3 From 8dd743e783464f59b1d80763d8e2e8c52e048cb1 Mon Sep 17 00:00:00 2001 From: Denis Serdjuk Date: Fri, 20 Nov 2009 13:53:23 +0200 Subject: implemented task EXT-1900 Add options to Gestures gear menu --HG-- branch : product-engine --- indra/newview/llfloatergesture.cpp | 313 ++++++++++++++++----- indra/newview/llfloatergesture.h | 42 ++- .../skins/default/xui/en/floater_gesture.xml | 12 +- .../skins/default/xui/en/menu_gesture_gear.xml | 75 +++++ 4 files changed, 350 insertions(+), 92 deletions(-) create mode 100644 indra/newview/skins/default/xui/en/menu_gesture_gear.xml diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index af86274472..0f8e4c10d7 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -34,32 +34,24 @@ #include "llfloatergesture.h" -#include "lldir.h" #include "llinventory.h" -#include "llmultigesture.h" +#include "llinventorybridge.h" +#include "llinventorymodel.h" +#include "llinventoryclipboard.h" #include "llagent.h" -#include "llviewerwindow.h" -#include "llbutton.h" -#include "llcombobox.h" +#include "llappearancemgr.h" +#include "llclipboard.h" #include "llgesturemgr.h" -#include "llinventorymodel.h" -#include "llinventorypanel.h" -#include "llfloaterinventory.h" #include "llkeyboard.h" -#include "lllineeditor.h" +#include "llmenugl.h" +#include "llmultigesture.h" #include "llpreviewgesture.h" -#include "llresizehandle.h" -#include "llscrollbar.h" -#include "llscrollcontainer.h" #include "llscrolllistctrl.h" -#include "lltextbox.h" #include "lltrans.h" -#include "lluictrlfactory.h" #include "llviewergesture.h" -#include "llviewertexturelist.h" +#include "llviewermenu.h" #include "llviewerinventory.h" -#include "llvoavatar.h" #include "llviewercontrol.h" BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b ) @@ -77,6 +69,35 @@ public: private: LLFloaterGesture* mFloater; }; +//----------------------------- +// GestureCallback +//----------------------------- + +class GestureShowCallback : public LLInventoryCallback +{ +public: + void fire(const LLUUID &inv_item) + { + LLPreviewGesture::show(inv_item, LLUUID::null); + } +}; + +class GestureCopiedCallback : public LLInventoryCallback +{ +private: + LLFloaterGesture* mFloater; + +public: + GestureCopiedCallback(LLFloaterGesture* floater): mFloater(floater) + {} + void fire(const LLUUID &inv_item) + { + if(mFloater) + { + mFloater->addGesture(inv_item,NULL,mFloater->getChild("gesture_list")); + } + } +}; //--------------------------------------------------------------------------- // LLFloaterGesture @@ -86,7 +107,13 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key) { mObserver = new LLFloaterGestureObserver(this); LLGestureManager::instance().addObserver(mObserver); - //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_gesture.xml"); + + mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this)); + mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this)); + mCommitCallbackRegistrar.add("Gesture.Action.CopyPast", boost::bind(&LLFloaterGesture::onCopyPastAction, this, _2)); + mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this)); + + mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2)); } void LLFloaterGesture::done() @@ -151,19 +178,18 @@ BOOL LLFloaterGesture::postBuild() label = getTitle(); setTitle(label); - - getChild("gesture_list")->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this)); - getChild("gesture_list")->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); - - getChild("inventory_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickInventory, this)); + mGestureList = getChild("gesture_list"); + mGestureList->setCommitCallback(boost::bind(&LLFloaterGesture::onCommitList, this)); + mGestureList->setDoubleClickCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); getChild("edit_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickEdit, this)); getChild("play_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); getChild("stop_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickPlay, this)); getChild("activate_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onActivateBtnClick, this)); - + getChild("new_gesture_btn")->setCommitCallback(boost::bind(&LLFloaterGesture::onClickNew, this)); + getChild("del_btn")->setClickedCallback(boost::bind(&LLFloaterGesture::onDeleteSelected, this)); childSetVisible("play_btn", true); childSetVisible("stop_btn", false); @@ -178,14 +204,13 @@ BOOL LLFloaterGesture::postBuild() buildGestureList(); - childSetFocus("gesture_list"); + mGestureList->setFocus(TRUE); - LLCtrlListInterface *list = getGestureList(); - if (list) + if (mGestureList) { const BOOL ascending = TRUE; - list->sortByColumn(std::string("name"), ascending); - list->selectFirstItem(); + mGestureList->sortByColumn(std::string("name"), ascending); + mGestureList->selectFirstItem(); } // Update button labels @@ -199,18 +224,17 @@ void LLFloaterGesture::refreshAll() { buildGestureList(); - LLCtrlListInterface *list = getGestureList(); - if (!list) return; + if (!mGestureList) return; if (mSelectedID.isNull()) { - list->selectFirstItem(); + mGestureList->selectFirstItem(); } else { - if (! list->setCurrentByID(mSelectedID)) + if (! mGestureList->setCurrentByID(mSelectedID)) { - list->selectFirstItem(); + mGestureList->selectFirstItem(); } } @@ -220,20 +244,16 @@ void LLFloaterGesture::refreshAll() void LLFloaterGesture::buildGestureList() { - LLCtrlListInterface *list = getGestureList(); - LLCtrlScrollInterface *scroll = childGetScrollInterface("gesture_list"); - - if (! (list && scroll)) return; - - LLUUID selected_item = list->getCurrentID(); + std::vector selected_items; + getSelectedIds(selected_items); LL_DEBUGS("Gesture")<< "Rebuilding gesture list "<< LL_ENDL; - list->operateOnAll(LLCtrlListInterface::OP_DELETE); + mGestureList->deleteAllItems(); LLGestureManager::item_map_t::const_iterator it; const LLGestureManager::item_map_t& active_gestures = LLGestureManager::instance().getActiveGestures(); for (it = active_gestures.begin(); it != active_gestures.end(); ++it) { - addGesture(it->first,it->second, list); + addGesture(it->first,it->second, mGestureList); } if (gInventory.isCategoryComplete(mGestureFolderID)) { @@ -249,16 +269,17 @@ void LLFloaterGesture::buildGestureList() if (active_gestures.find(item->getUUID()) == active_gestures.end()) { // if gesture wasn't loaded yet, we can display only name - addGesture(item->getUUID(), NULL, list); + addGesture(item->getUUID(), NULL, mGestureList); } } } // attempt to preserve scroll position through re-builds // since we do re-build any time anything dirties - if(list->selectByValue(LLSD(selected_item))) + for(std::vector::iterator it = selected_items.begin(); it != selected_items.end(); it++) { - scroll->scrollToShowSelected(); + mGestureList->selectByID(*it); } + mGestureList->scrollToShowSelected(); } void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gesture,LLCtrlListInterface * list ) @@ -346,33 +367,59 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur list->addElement(element, ADD_BOTTOM); } -void LLFloaterGesture::onClickInventory() +void LLFloaterGesture::getSelectedIds(std::vector& ids) +{ + std::vector items = mGestureList->getAllSelected(); + for(std::vector::const_iterator it = items.begin(); it != items.end(); it++) + { + ids.push_back((*it)->getUUID()); + } +} + +bool LLFloaterGesture::isActionEnabled(const LLSD& command) { - LLCtrlListInterface *list = getGestureList(); - if (!list) return; - const LLUUID& item_id = list->getCurrentID(); + // paste copy_uuid edit_gesture + std::string command_name = command.asString(); + if("paste" == command_name) + { + if(!LLInventoryClipboard::instance().hasContents()) + return false; - LLFloaterInventory* inv = LLFloaterInventory::showAgentInventory(); - if (!inv) return; - inv->getPanel()->setSelection(item_id, TRUE); + LLDynamicArray ids; + LLInventoryClipboard::instance().retrieve(ids); + for(LLDynamicArray::iterator it = ids.begin(); it != ids.end(); it++) + { + LLInventoryItem* item = gInventory.getItem(*it); + + if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) + { + return true; + } + } + return false; + } + else if("copy_uuid" == command_name || "edit_gesture" == command_name + || "inspect" == command_name) + { + return mGestureList->getAllSelected().size() == 1; + } + return true; } void LLFloaterGesture::onClickPlay() { - LLCtrlListInterface *list = getGestureList(); - if (!list) return; - const LLUUID& item_id = list->getCurrentID(); + const LLUUID& item_id = mGestureList->getCurrentID(); if(item_id.isNull()) return; LL_DEBUGS("Gesture")<<" Trying to play gesture id: "<< item_id <getAssetUUID(), inform_server, deactivate_similar); LL_DEBUGS("Gesture")<< "Activating gesture with inventory ID: " << item_id < cb = new GestureShowCallback(); @@ -399,27 +437,96 @@ void LLFloaterGesture::onClickNew() void LLFloaterGesture::onActivateBtnClick() { - LLCtrlListInterface* list = getGestureList(); - - LLUUID gesture_inv_id = list->getSelectedValue(); + std::vector ids; + getSelectedIds(ids); + if(ids.empty()) + return; + LLGestureManager* gm = LLGestureManager::getInstance(); - - if(gm->isGestureActive(gesture_inv_id)) + std::vector::const_iterator it = ids.begin(); + BOOL first_gesture_state = gm->isGestureActive(*it); + BOOL is_mixed = FALSE; + while( ++it != ids.end() ) { - gm->deactivateGesture(gesture_inv_id); + if(first_gesture_state != gm->isGestureActive(*it)) + { + is_mixed = TRUE; + break; + } } - else + for(std::vector::const_iterator it = ids.begin(); it != ids.end(); it++) { - gm->activateGesture(gesture_inv_id); + if(is_mixed) + { + gm->activateGesture(*it); + } + else + { + if(first_gesture_state) + { + gm->deactivateGesture(*it); + } + else + { + gm->activateGesture(*it); + } + } } } +void LLFloaterGesture::onCopyPastAction(const LLSD& command) +{ + std::string command_name = command.asString(); + // since we select this comman inventory item had already arrived . + if("copy_gesture" == command_name) + { + std::vector ids; + getSelectedIds(ids); + // make sure that clopboard is empty + LLInventoryClipboard::instance().reset(); + for(std::vector::iterator it = ids.begin(); it != ids.end(); it++) + { + LLInventoryItem* item = gInventory.getItem(*it); + if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) + { + LLInventoryClipboard::instance().add(item->getUUID()); + } + } + } + else if ("paste" == command_name) + { + LLInventoryClipboard& clipbord = LLInventoryClipboard::instance(); + LLDynamicArray ids; + clipbord.retrieve(ids); + if(ids.empty() || !gInventory.isCategoryComplete(mGestureFolderID)) + return; + LLInventoryCategory* gesture_dir = gInventory.getCategory(mGestureFolderID); + LLPointer cb = new GestureCopiedCallback(this); + + for(LLDynamicArray::iterator it = ids.begin(); it != ids.end(); it++) + { + LLInventoryItem* item = gInventory.getItem(*it); + LLStringUtil::format_map_t string_args; + string_args["[COPY_NAME]"] = item->getName(); + if(item && item->getInventoryType() == LLInventoryType::IT_GESTURE) + { + LL_DEBUGS("Gesture")<< "Copying gesture " << item->getName() << " "<< item->getUUID() << " into " + << gesture_dir->getName() << " "<< gesture_dir->getUUID() << LL_ENDL; + copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), + gesture_dir->getUUID(), getString("copy_name", string_args), cb); + } + } + clipbord.reset(); + } + else if ("copy_uuid" == command_name) + { + gClipboard.copyFromString(utf8str_to_wstring(mGestureList->getCurrentID().asString()), mGestureList->getCurrentID()); + } +} void LLFloaterGesture::onClickEdit() { - LLCtrlListInterface *list = getGestureList(); - if (!list) return; - const LLUUID& item_id = list->getCurrentID(); + const LLUUID& item_id = mGestureList->getCurrentID(); LLInventoryItem* item = gInventory.getItem(item_id); if (!item) return; @@ -433,7 +540,7 @@ void LLFloaterGesture::onClickEdit() void LLFloaterGesture::onCommitList() { - const LLUUID& item_id = childGetValue("gesture_list").asUUID(); + const LLUUID& item_id = mGestureList->getCurrentID(); mSelectedID = item_id; if (LLGestureManager::instance().isGesturePlaying(item_id)) @@ -447,8 +554,60 @@ void LLFloaterGesture::onCommitList() childSetVisible("stop_btn", false); } } + +void LLFloaterGesture::onDeleteSelected() +{ + std::vector ids; + getSelectedIds(ids); + if(ids.empty()) + return; + + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + LLGestureManager* gm = LLGestureManager::getInstance(); + for(std::vector::const_iterator it = ids.begin(); it != ids.end(); it++) + { + const LLUUID& selected_item = *it; + LLInventoryItem* inv_item = gInventory.getItem(selected_item); + if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_GESTURE) + { + if(gm->isGestureActive(selected_item)) + { + gm->deactivateGesture(selected_item); + } + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); + + LLPointer new_item = new LLViewerInventoryItem(inv_item); + new_item->setParent(trash_id); + // no need to restamp it though it's a move into trash because + // it's a brand new item already. + new_item->updateParentOnServer(FALSE); + gInventory.updateItem(new_item); + } + } + gInventory.notifyObservers(); + buildGestureList(); +} + +void LLFloaterGesture::addToCurrentOutFit() +{ + std::vector ids; + getSelectedIds(ids); + LLAppearanceManager* am = LLAppearanceManager::getInstance(); + for(std::vector::const_iterator it = ids.begin(); it != ids.end(); it++) + { + am->addCOFItemLink(*it); + } +} + void LLFloaterGesture::playGesture(LLUUID item_id) { + LL_DEBUGS("Gesture")<<"Playing gesture "<< item_id< #include "llfloater.h" -#include "llinventorymodel.h" #include "llinventoryobserver.h" -#include "lldarray.h" class LLScrollContainer; class LLView; @@ -53,6 +52,7 @@ class LLScrollListCtrl; class LLFloaterGestureObserver; class LLFloaterGestureInventoryObserver; class LLMultiGesture; +class LLMenuGL; class LLFloaterGesture : public LLFloater, LLInventoryFetchDescendentsObserver @@ -65,26 +65,46 @@ public: virtual BOOL postBuild(); virtual void done (); void refreshAll(); + /** + * @brief Add new scrolllistitem into gesture_list. + * @param item_id inventory id of gesture + * @param gesture can be NULL , if item was not loaded yet + */ + void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list); protected: // Reads from the gesture manager's list of active gestures // and puts them in this list. void buildGestureList(); - void addGesture(const LLUUID& item_id, LLMultiGesture* gesture, LLCtrlListInterface * list); - void onClickInventory(); + void playGesture(LLUUID item_id); +private: + void addToCurrentOutFit(); + /** + * @brief This method is using to collect selected items. + * In some places gesture_list can be rebuilt by gestureObservers during iterating data from LLScrollListCtrl::getAllSelected(). + * Therefore we have to copy these items to avoid viewer crash. + * @see LLFloaterGesture::onActivateBtnClick + */ + void getSelectedIds(std::vector& ids); + bool isActionEnabled(const LLSD& command); + /** + * @brief Activation rules: + * According to Gesture Spec: + * 1. If all selected gestures are active: set to inactive + * 2. If all selected gestures are inactive: set to active + * 3. If selected gestures are in a mixed state: set all to active + */ + void onActivateBtnClick(); void onClickEdit(); void onClickPlay(); void onClickNew(); void onCommitList(); - void playGesture(LLUUID item_id); - LLCtrlListInterface* getGestureList() const - { - return childGetListInterface("gesture_list"); - } - void onActivateBtnClick(); -protected: + void onCopyPastAction(const LLSD& command); + void onDeleteSelected(); + LLUUID mSelectedID; LLUUID mGestureFolderID; + LLScrollListCtrl* mGestureList; LLFloaterGestureObserver* mObserver; }; diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 21d292847a..9f5e6828d2 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -21,12 +21,16 @@ name="playing"> (Playing) + + Copy of [COPY_NAME] -