From fe9719e8047e288bfb97068b7addd5dc50ffa739 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Wed, 21 Oct 2009 03:39:04 +0000 Subject: Merging revisions 2094-2099 of https://svn.aws.productengine.com/secondlife/pe/stable-2 into P:\svn\viewer-2.0.0, respecting ancestry * Bugs: EXT-1612 EXT-1604 EXT-1163 EXT-1163 EXT-1167 * Dev: EXT-1516 --- indra/newview/llchiclet.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) (limited to 'indra/newview/llchiclet.cpp') diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 340b0fa22c..69fa5cdfe7 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -468,6 +468,115 @@ void LLIMP2PChiclet::setShowSpeaker(bool show) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLAdHocChiclet::Params::Params() +: avatar_icon("avatar_icon") +, unread_notifications("unread_notifications") +, speaker("speaker") +, show_speaker("show_speaker") +{ + // *TODO Vadim: Get rid of hardcoded values. + rect(LLRect(0, 25, 45, 0)); + + avatar_icon.name("avatar_icon"); + avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM); + + // *NOTE dzaporozhan + // Changed icon height from 25 to 24 to fix ticket EXT-794. + // In some cases(after changing UI scale) 25 pixel height icon was + // drawn incorrectly, i'm not sure why. + avatar_icon.rect(LLRect(0, 24, 25, 0)); + avatar_icon.mouse_opaque(false); + + unread_notifications.name("unread"); + unread_notifications.rect(LLRect(25, 25, 45, 0)); + unread_notifications.font(LLFontGL::getFontSansSerif()); + unread_notifications.font_halign(LLFontGL::HCENTER); + unread_notifications.v_pad(5); + unread_notifications.text_color(LLColor4::white); + unread_notifications.mouse_opaque(false); + + speaker.name("speaker"); + speaker.rect(LLRect(45, 25, 65, 0)); + + show_speaker = false; +} + +LLAdHocChiclet::LLAdHocChiclet(const Params& p) +: LLIMChiclet(p) +, mChicletIconCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mPopupMenu(NULL) +{ + LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; + mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); + addChild(mChicletIconCtrl); + + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create(unread_params); + addChild(mCounterCtrl); + + setCounter(getCounter()); + setShowCounter(getShowCounter()); + + LLChicletSpeakerCtrl::Params speaker_params = p.speaker; + mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); + addChild(mSpeakerCtrl); + + setShowSpeaker(p.show_speaker); +} + +void LLAdHocChiclet::setSessionId(const LLUUID& session_id) +{ + LLChiclet::setSessionId(session_id); + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); + mChicletIconCtrl->setValue(im_session->mOtherParticipantID); +} + +void LLAdHocChiclet::setCounter(S32 counter) +{ + mCounterCtrl->setCounter(counter); + + if(getShowCounter()) + { + LLRect counter_rect = mCounterCtrl->getRect(); + LLRect required_rect = mCounterCtrl->getRequiredRect(); + bool needs_resize = required_rect.getWidth() != counter_rect.getWidth(); + + if(needs_resize) + { + counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth(); + mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight()); + mCounterCtrl->setRect(counter_rect); + + onChicletSizeChanged(); + } + } +} + +LLRect LLAdHocChiclet::getRequiredRect() +{ + LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0); + if(getShowCounter()) + { + rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); + } + if(getShowSpeaker()) + { + rect.mRight += mSpeakerCtrl->getRect().getWidth(); + } + return rect; +} + +BOOL LLAdHocChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + return TRUE; +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + LLIMGroupChiclet::Params::Params() : group_icon("group_icon") { -- cgit v1.3 From 6f41747bc4d8afcb2b19ac02295575031bcf9021 Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Wed, 21 Oct 2009 04:58:23 +0000 Subject: Merging revisions 2112-2128 of https://svn.aws.productengine.com/secondlife/pe/stable-2 into P:\svn\viewer-2.0.0, respecting ancestry * Bugs: EXT-1605 EXT-1506 EXT-1663 EXT-1616 EXT-1599 EXT-1587 * Dev: EXT-748 EXT-1447 * IM Cleanup --- indra/media_plugins/gstreamer010/CMakeLists.txt | 6 +- indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 33 +++++--- indra/newview/llavatarlist.cpp | 14 ++-- indra/newview/llavatarlist.h | 7 +- indra/newview/llavatarlistitem.cpp | 4 +- indra/newview/llavatarlistitem.h | 2 +- indra/newview/llchannelmanager.cpp | 2 +- indra/newview/llchiclet.cpp | 3 +- indra/newview/llfriendcard.cpp | 87 ++++++++++++++++++++++ indra/newview/llfriendcard.h | 6 ++ indra/newview/llimfloater.cpp | 32 +++++++- indra/newview/llimfloater.h | 5 ++ indra/newview/llimpanel.cpp | 4 +- indra/newview/llimpanel.h | 2 - indra/newview/llimview.cpp | 69 ++++++++++------- indra/newview/llimview.h | 30 ++++++-- indra/newview/llinventorybridge.cpp | 59 ++++++++++++++- indra/newview/llinventorybridge.h | 1 + indra/newview/llnearbychathandler.cpp | 2 +- indra/newview/llnotificationtiphandler.cpp | 1 + indra/newview/llpanellandmarks.cpp | 29 +++----- indra/newview/llpanelteleporthistory.cpp | 80 ++++++++++++++++++-- indra/newview/llpanelteleporthistory.h | 5 +- indra/newview/llparticipantlist.cpp | 56 ++++++++++++++ indra/newview/llparticipantlist.h | 48 ++++++++++++ indra/newview/llscreenchannel.cpp | 18 ++--- indra/newview/llsyswellwindow.cpp | 2 +- indra/newview/llteleporthistorystorage.cpp | 13 ++-- indra/newview/llteleporthistorystorage.h | 5 +- indra/newview/lltoast.cpp | 12 +-- indra/newview/lltoast.h | 9 ++- .../default/xui/en/menu_teleport_history_item.xml | 6 +- .../newview/skins/default/xui/en/panel_people.xml | 1 + 34 files changed, 519 insertions(+), 136 deletions(-) create mode 100644 indra/newview/llparticipantlist.cpp create mode 100644 indra/newview/llparticipantlist.h (limited to 'indra/newview/llchiclet.cpp') diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 5c0ce3ee17..a9f7938b41 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -42,12 +42,12 @@ set(media_plugin_gstreamer010_HEADER_FILES llmediaimplgstreamertriviallogging.h ) -if (${CXX_VERSION} MATCHES "4.[23]") +if (${CXX_VERSION} MATCHES "4[23].") # Work around a bad interaction between broken gstreamer headers and # g++ 4.3's increased strictness. set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES - COMPILE_FLAGS -Wno-error=write-strings) -endif (${CXX_VERSION} MATCHES "4.[23]") + COMPILE_FLAGS -Wno-write-strings) +endif (${CXX_VERSION} MATCHES "4[23].") add_library(media_plugin_gstreamer010 SHARED diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index df20651362..fbf14a7359 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -338,6 +338,7 @@ set(viewer_SOURCE_FILES llpanelteleporthistory.cpp llpanelvolume.cpp llparcelselection.cpp + llparticipantlist.cpp llpatchvertexarray.cpp llplacesinventorybridge.cpp llpolymesh.cpp @@ -803,6 +804,7 @@ set(viewer_HEADER_FILES llpanelteleporthistory.h llpanelvolume.h llparcelselection.h + llparticipantlist.h llpatchvertexarray.h llplacesinventorybridge.h llpolymesh.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4bfb472b93..7e368b0c9c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4842,10 +4842,10 @@ Value 350 - NotificationToastTime + NotificationToastLifeTime Comment - Width of notification messages + Number of seconds while a notification toast exists Persist 1 Type @@ -4853,21 +4853,32 @@ Value 5 + NotificationTipToastLifeTime + + Comment + Number of seconds while a notification tip toast exist + Persist + 1 + Type + S32 + Value + 10 + ToastOpaqueTime Comment - Width of notification messages + Number of seconds while a toast is fading Persist 1 Type S32 Value - 4 + 1 - StartUpToastTime + StartUpToastLifeTime Comment - Width of notification messages + Number of seconds while a StartUp toast exist Persist 1 Type @@ -4875,10 +4886,10 @@ Value 5 - ToastMargin + ToastGap Comment - Width of notification messages + Gap between toasts on a screen Persist 1 Type @@ -4889,7 +4900,7 @@ ChannelBottomPanelMargin Comment - Width of notification messages + Space from a lower toast to the Bottom Tray Persist 1 Type @@ -4900,7 +4911,7 @@ NotificationChannelRightMargin Comment - Width of notification messages + Space between toasts and a right border of an area where they can appear Persist 1 Type @@ -4911,7 +4922,7 @@ OverflowToastHeight Comment - Width of notification messages + Height of an overflow toast Persist 1 Type diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index ef48420490..2034f98517 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -57,17 +57,13 @@ static const LLAvatarItemNameComparator NAME_COMPARATOR; static const LLFlatListView::ItemReverseComparator REVERSE_NAME_COMPARATOR(NAME_COMPARATOR); LLAvatarList::Params::Params() -: -volume_column_width("volume_column_width", 0) -, online_go_first("online_go_first", true) +: ignore_online_status("ignore_online_status", false) { } - - LLAvatarList::LLAvatarList(const Params& p) : LLFlatListView(p) -, mOnlineGoFirst(p.online_go_first) +, mIgnoreOnlineStatus(p.ignore_online_status) , mContextMenu(NULL) , mDirty(true) // to force initial update { @@ -194,15 +190,15 @@ void LLAvatarList::refresh() } -void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos) +void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) { LLAvatarListItem* item = new LLAvatarListItem(); item->showStatus(false); item->showInfoBtn(true); item->showSpeakingIndicator(true); item->setName(name); - item->setAvatarId(id); - item->setOnline(is_bold); + item->setAvatarId(id, mIgnoreOnlineStatus); + item->setOnline(mIgnoreOnlineStatus ? true : is_online); item->setContextMenu(mContextMenu); item->childSetVisible("info_btn", false); diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index ec801645fe..7372538006 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -55,8 +55,7 @@ public: struct Params : public LLInitParam::Block { - Optional volume_column_width; - Optional online_go_first; + Optional ignore_online_status; // show all items as online Params(); }; @@ -76,7 +75,7 @@ public: protected: void refresh(); - void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM); + void addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos = ADD_BOTTOM); void computeDifference( const std::vector& vnew, std::vector& vadded, @@ -84,7 +83,7 @@ protected: private: - bool mOnlineGoFirst; + bool mIgnoreOnlineStatus; bool mDirty; std::string mNameFilter; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 90408beca0..732db90cdb 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -180,7 +180,7 @@ void LLAvatarListItem::setName(const std::string& name) mAvatarName->setToolTip(name); } -void LLAvatarListItem::setAvatarId(const LLUUID& id) +void LLAvatarListItem::setAvatarId(const LLUUID& id, bool ignore_status_changes) { if (mAvatarId.notNull()) LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this); @@ -190,7 +190,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id) mSpeakingIndicator->setSpeakerId(id); // We'll be notified on avatar online status changes - if (mAvatarId.notNull()) + if (!ignore_status_changes && mAvatarId.notNull()) LLAvatarTracker::instance().addParticularFriendObserver(mAvatarId, this); // Set avatar name. diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 2330db5249..ca75e3898f 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -64,7 +64,7 @@ public: void setStatus(const std::string& status); void setOnline(bool online); void setName(const std::string& name); - void setAvatarId(const LLUUID& id); + void setAvatarId(const LLUUID& id, bool ignore_status_changes = false); const LLUUID& getAvatarId() const; const std::string getAvatarName() const; diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index c4619dc57a..a75ae1d3b3 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -128,7 +128,7 @@ void LLChannelManager::onLoginCompleted() mStartUpChannel->setShowToasts(true); mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this)); - mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastTime")); + mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("ChannelBottomPanelMargin"), gSavedSettings.getS32("StartUpToastLifeTime")); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 69fa5cdfe7..43aca430a2 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -861,7 +861,8 @@ void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){ BOOL LLChicletPanel::postBuild() { LLPanel::postBuild(); - LLIMModel::instance().addChangedCallback(boost::bind(im_chiclet_callback, this, _1)); + LLIMModel::instance().addNewMsgCallback(boost::bind(im_chiclet_callback, this, _1)); + LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(im_chiclet_callback, this, _1)); LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLChicletPanel::findChiclet, this, _1)); return TRUE; diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 97b7f3e9ad..fbcaeee01f 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -166,6 +166,93 @@ bool LLFriendCardsManager::isItemInAnyFriendsList(const LLViewerInventoryItem* i return items.count() > 0; } + +bool LLFriendCardsManager::isObjDirectDescendentOfCategory(const LLInventoryObject* obj, + const LLViewerInventoryCategory* cat) const +{ + // we need both params to proceed. + if ( !obj || !cat ) + return false; + + // Need to check that target category is in the Calling Card/Friends folder. + // In other case function returns unpredictable result. + if ( !isCategoryInFriendFolder(cat) ) + return false; + + bool result = false; + + LLInventoryModel::item_array_t* items; + LLInventoryModel::cat_array_t* cats; + + gInventory.lockDirectDescendentArrays(cat->getUUID(), cats, items); + if ( items ) + { + if ( obj->getType() == LLAssetType::AT_CALLINGCARD ) + { + // For CALLINGCARD compare items by creator's id, if they are equal assume + // that it is same card and return true. Note: UUID's of compared items + // may be not equal. Also, we already know that obj should be type of LLInventoryItem, + // but in case inventory database is broken check what dynamic_cast returns. + const LLInventoryItem* item = dynamic_cast < const LLInventoryItem* > (obj); + if ( item ) + { + LLUUID creator_id = item->getCreatorUUID(); + LLViewerInventoryItem* cur_item = NULL; + for ( S32 i = items->count() - 1; i >= 0; --i ) + { + cur_item = items->get(i); + if ( creator_id == cur_item->getCreatorUUID() ) + { + result = true; + break; + } + } + } + } + else + { + // Else check that items have same type and name. + // Note: UUID's of compared items also may be not equal. + std::string obj_name = obj->getName(); + LLViewerInventoryItem* cur_item = NULL; + for ( S32 i = items->count() - 1; i >= 0; --i ) + { + cur_item = items->get(i); + if ( obj->getType() != cur_item->getType() ) + continue; + if ( obj_name == cur_item->getName() ) + { + result = true; + break; + } + } + } + } + if ( !result && cats ) + { + // There is no direct descendent in items, so check categories. + // If target obj and descendent category have same type and name + // then return true. Note: UUID's of compared items also may be not equal. + std::string obj_name = obj->getName(); + LLViewerInventoryCategory* cur_cat = NULL; + for ( S32 i = cats->count() - 1; i >= 0; --i ) + { + cur_cat = cats->get(i); + if ( obj->getType() != cur_cat->getType() ) + continue; + if ( obj_name == cur_cat->getName() ) + { + result = true; + break; + } + } + } + gInventory.unlockDirectDescendentArrays(cat->getUUID()); + + return result; +} + + bool LLFriendCardsManager::isCategoryInFriendFolder(const LLViewerInventoryCategory* cat) const { if (NULL == cat) diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index aa391ce2c1..6ada342831 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -71,6 +71,12 @@ public: */ bool isItemInAnyFriendsList(const LLViewerInventoryItem* item); + /** + * Checks if specified category is contained in the Calling Card/Friends folder and + * determines if specified Inventory Object exists in that category. + */ + bool isObjDirectDescendentOfCategory(const LLInventoryObject* obj, const LLViewerInventoryCategory* cat) const; + /** * Checks is the specified category is in the Calling Card/Friends folder */ diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 452943007d..8f0186ce24 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -83,13 +83,20 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id) } } +void LLIMFloater::onFocusLost() +{ + LLIMModel::getInstance()->resetActiveSessionID(); +} + +void LLIMFloater::onFocusReceived() +{ + LLIMModel::getInstance()->setActiveSessionID(mSessionID); +} + // virtual void LLIMFloater::onClose(bool app_quitting) { - LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID); - - //*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB) - gIMMgr->removeSession(mSessionID); + gIMMgr->leaveSession(mSessionID); } /* static */ @@ -114,6 +121,23 @@ void LLIMFloater::newIMCallback(const LLSD& data){ } } +void LLIMFloater::onVisibilityChange(const LLSD& new_visibility) +{ + bool visible = new_visibility.asBoolean(); + + LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID); + + if (visible && voice_channel && + voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED) + { + LLFloaterReg::showInstance("voice_call", mSessionID); + } + else + { + LLFloaterReg::hideInstance("voice_call", mSessionID); + } +} + void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata ) { LLIMFloater* self = (LLIMFloater*) userdata; diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index e2f59c3507..8fd0c7cde9 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -84,7 +84,12 @@ public: // called when docked floater's position has been set by chiclet void setPositioned(bool b) { mPositioned = b; }; + void onVisibilityChange(const LLSD& new_visibility); + private: + // process focus events to set a currently active session + /* virtual */ void onFocusLost(); + /* virtual */ void onFocusReceived(); static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata ); static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata); diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index ead74b72bf..163984f740 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1586,9 +1586,7 @@ void LLFloaterIMPanel::onClose(bool app_quitting) { setTyping(FALSE); - LLIMModel::instance().sendLeaveSession(mSessionUUID, mOtherParticipantUUID); - - gIMMgr->removeSession(mSessionUUID); + gIMMgr->leaveSession(mSessionUUID); // *HACK hide the voice floater LLFloaterReg::hideInstance("voice_call", mSessionUUID); diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index af50362f00..4e306c7fab 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -250,8 +250,6 @@ public: EInstantMessage getDialogType() const { return mDialog; } void setDialogType(EInstantMessage dialog) { mDialog = dialog; } - void requestAutoConnect(); - void sessionInitReplyReceived(const LLUUID& im_session_id); // Handle other participant in the session typing. diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 20b9cc1f8b..9974de0ef1 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -93,30 +93,45 @@ std::map LLIMModel::sSessionsMap; void toast_callback(const LLSD& msg){ - // do not show toast in busy mode - if (gAgent.getBusy()) + // do not show toast in busy mode or it goes from agent + if (gAgent.getBusy() || gAgent.getID() == msg["from_id"]) { return; } - - //we send notifications to reset counter also - if (msg["num_unread"].asInteger()) + + // check whether incoming IM belongs to an active session or not + if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"]) { - LLSD args; - args["MESSAGE"] = msg["message"]; - args["TIME"] = msg["time"]; - args["FROM"] = msg["from"]; - args["FROM_ID"] = msg["from_id"]; - args["SESSION_ID"] = msg["session_id"]; + return; + } + + LLSD args; + args["MESSAGE"] = msg["message"]; + args["TIME"] = msg["time"]; + args["FROM"] = msg["from"]; + args["FROM_ID"] = msg["from_id"]; + args["SESSION_ID"] = msg["session_id"]; - LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID())); + LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID())); +} + +void LLIMModel::setActiveSessionID(const LLUUID& session_id) +{ + // check if such an ID really exists + if (!findIMSession(session_id)) + { + llwarns << "Trying to set as active a non-existent session!" << llendl; + return; } + + mActiveSessionID = session_id; } LLIMModel::LLIMModel() { - addChangedCallback(LLIMFloater::newIMCallback); - addChangedCallback(toast_callback); + addNewMsgCallback(LLIMFloater::newIMCallback); + addNoUnreadMsgsCallback(LLIMFloater::newIMCallback); + addNewMsgCallback(toast_callback); } @@ -311,7 +326,7 @@ std::list LLIMModel::getMessages(LLUUID session_id, int start_index) LLSD arg; arg["session_id"] = session_id; arg["num_unread"] = 0; - mChangedSignal(arg); + mNoUnreadMsgsSignal(arg); // TODO: in the future is there a more efficient way to return these //of course there is - return as parameter (IB) @@ -390,7 +405,7 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, arg["from"] = from; arg["from_id"] = from_id; arg["time"] = LLLogChat::timestamp(false); - mChangedSignal(arg); + mNewMsgSignal(arg); return true; } @@ -623,11 +638,6 @@ void LLIMModel::sendMessage(const std::string& utf8_text, //*TODO should be deleted, because speaker manager updates through callback the recent list LLRecentPeople::instance().add(other_participant_id); } - -boost::signals2::connection LLIMModel::addChangedCallback( boost::function cb ) -{ - return mChangedSignal.connect(cb); -} void session_starter_helper( const LLUUID& temp_session_id, @@ -1274,13 +1284,6 @@ void LLIMMgr::addMessage( return; } - //not sure why...but if it is from ourselves we set the target_id - //to be NULL - if( other_participant_id == gAgent.getID() ) - { - other_participant_id = LLUUID::null; - } - LLFloaterIMPanel* floater; LLUUID new_session_id = session_id; if (new_session_id.isNull()) @@ -1549,6 +1552,16 @@ LLUUID LLIMMgr::addSession( return session_id; } +bool LLIMMgr::leaveSession(const LLUUID& session_id) +{ + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id); + if (!im_session) return false; + + LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID); + gIMMgr->removeSession(session_id); + return true; +} + // This removes the panel referenced by the uuid, and then restores // internal consistency. The internal pointer is not deleted? Did you mean // a pointer to the corresponding LLIMSession? Session data is cleared now. diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index d98b5ca297..f9db6d8ed2 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -75,10 +75,20 @@ public: LLIMModel(); + + //we should control the currently active session + LLUUID mActiveSessionID; + void setActiveSessionID(const LLUUID& session_id); + void resetActiveSessionID() { mActiveSessionID.setNull(); } + LLUUID getActiveSessionID() { return mActiveSessionID; } + //*TODO make it non-static as LLIMMOdel is a singleton (IB) static std::map sSessionsMap; //mapping session_id to session - boost::signals2::signal mChangedSignal; + typedef boost::signals2::signal session_signal_t; + typedef boost::function session_callback_t; + session_signal_t mNewMsgSignal; + session_signal_t mNoUnreadMsgsSignal; /** * Find an IM Session corresponding to session_id @@ -91,7 +101,8 @@ public: */ void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id); - boost::signals2::connection addChangedCallback( boost::function cb ); + boost::signals2::connection addNewMsgCallback( session_callback_t cb ) { return mNewMsgSignal.connect(cb); } + boost::signals2::connection addNoUnreadMsgsCallback( session_callback_t cb ) { return mNoUnreadMsgsSignal.connect(cb); } bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, const std::vector& ids = std::vector()); @@ -219,10 +230,12 @@ public: const std::string& voice_session_handle, const std::string& caller_uri = LLStringUtil::null); - // This removes the panel referenced by the uuid, and then - // restores internal consistency. The internal pointer is not - // deleted. - void removeSession(LLUUID session_id); + /** + * Leave the session with session id. Send leave session notification + * to the server and removes all associated session data + * @return false if the session with specified id was not exist + */ + bool leaveSession(const LLUUID& session_id); void inviteToSession( const LLUUID& session_id, @@ -295,6 +308,11 @@ public: bool endCall(const LLUUID& session_id); private: + // This removes the panel referenced by the uuid, and then + // restores internal consistency. The internal pointer is not + // deleted. + void removeSession(LLUUID session_id); + // create a panel and update internal representation for // consistency. Returns the pointer, caller (the class instance // since it is a private method) is not responsible for deleting diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b539715055..23f0c7c450 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1462,6 +1462,39 @@ BOOL LLFolderBridge::copyToClipboard() const return FALSE; } +BOOL LLFolderBridge::isClipboardPasteable() const +{ + if ( ! LLInvFVBridge::isClipboardPasteable() ) + return FALSE; + + // Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599 + if ( LLFriendCardsManager::instance().isCategoryInFriendFolder( getCategory() ) ) + { + LLInventoryModel* model = getInventoryModel(); + if ( !model ) + { + return FALSE; + } + + LLDynamicArray objects; + LLInventoryClipboard::instance().retrieve(objects); + const LLViewerInventoryCategory *current_cat = getCategory(); + + // Search for the direct descendent of current Friends subfolder among all pasted items, + // and return false if is found. + for(S32 i = objects.count() - 1; i >= 0; --i) + { + const LLUUID &obj_id = objects.get(i); + if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) ) + { + return FALSE; + } + } + + } + return TRUE; +} + BOOL LLFolderBridge::isClipboardPasteableAsLink() const { // Check normal paste-as-link permissions @@ -1479,13 +1512,15 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const const LLViewerInventoryCategory *current_cat = getCategory(); if (current_cat) { + const BOOL is_in_friend_folder = LLFriendCardsManager::instance().isCategoryInFriendFolder( current_cat ); const LLUUID ¤t_cat_id = current_cat->getUUID(); LLDynamicArray objects; LLInventoryClipboard::instance().retrieve(objects); S32 count = objects.count(); for(S32 i = 0; i < count; i++) { - const LLInventoryCategory *cat = model->getCategory(objects.get(i)); + const LLUUID &obj_id = objects.get(i); + const LLInventoryCategory *cat = model->getCategory(obj_id); if (cat) { const LLUUID &cat_id = cat->getUUID(); @@ -1496,6 +1531,17 @@ BOOL LLFolderBridge::isClipboardPasteableAsLink() const return FALSE; } } + // Don't allow pasting duplicates to the Calling Card/Friends subfolders, see bug EXT-1599 + if ( is_in_friend_folder ) + { + // If object is direct descendent of current Friends subfolder than return false. + // Note: We can't use 'const LLInventoryCategory *cat', because it may be null + // in case type of obj_id is LLInventoryItem. + if ( LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(model->getObject(obj_id), current_cat) ) + { + return FALSE; + } + } } } return TRUE; @@ -2819,6 +2865,17 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, break; } } + + if ( is_movable ) + { + // Don't allow creating duplicates in the Calling Card/Friends + // subfolders, see bug EXT-1599. Check is item direct descendent + // of target folder and forbid item's movement if it so. + // Note: isItemDirectDescendentOfCategory checks if + // passed category is in the Calling Card/Friends folder + is_movable = ! LLFriendCardsManager::instance() + .isObjDirectDescendentOfCategory (inv_item, getCategory()); + } LLUUID favorites_id = model->findCategoryUUIDForType(LLAssetType::AT_FAVORITE); diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index d1d2c57f07..6b2a2d32de 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -315,6 +315,7 @@ public: virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; virtual BOOL isItemCopyable() const; + virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; virtual BOOL copyToClipboard() const; diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 59b19b6dcb..4aefbd1a33 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -225,7 +225,7 @@ void LLNearbyChatScreenChannel::showToastsBottom() LLRect toast_rect; S32 bottom = getRect().mBottom; - S32 margin = gSavedSettings.getS32("ToastMargin"); + S32 margin = gSavedSettings.getS32("ToastGap"); for(std::vector::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) { diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index c08f92b983..7239f49b7f 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -91,6 +91,7 @@ bool LLTipHandler::processNotification(const LLSD& notify) LLToast::Params p; p.notif_id = notification->getID(); p.notification = notification; + p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime"); p.panel = notify_box; p.is_tip = true; p.can_be_stored = false; diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 93e58f3441..f05029582c 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -458,20 +458,8 @@ void LLLandmarksPanel::initListCommandsHandlers() void LLLandmarksPanel::updateListCommands() { - // TODO: should be false when "Received" folder is selected - bool add_folder_enabled = mCurrentSelectedList == mLandmarksInventoryPanel; - bool trash_enabled = false; // TODO: should be false when "Received" folder is selected - - LLFolderViewItem* current_item = getCurSelectedItem(); - - if (current_item) - { - LLFolderViewEventListener* listenerp = current_item->getListener(); - if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - trash_enabled = mCurrentSelectedList != mLibraryInventoryPanel; - } - } + bool add_folder_enabled = isActionEnabled("category"); + bool trash_enabled = isActionEnabled("delete"); // keep Options & Add Landmark buttons always enabled mListCommands->childSetEnabled(ADD_FOLDER_BUTTON_NAME, add_folder_enabled); @@ -635,7 +623,13 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const if("category" == command_name) { - return mCurrentSelectedList == mLandmarksInventoryPanel; + // we can add folder only in Landmarks Accordion + if (mCurrentSelectedList == mLandmarksInventoryPanel) + { + // ... but except Received folder + return !isReceivedFolderSelected(); + } + else return false; } else if("paste" == command_name || "rename" == command_name || "cut" == command_name || "delete" == command_name) { @@ -650,11 +644,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { return rootFolderView->getSelectedCount() == 1; } - // we can add folder, or change item/folder only in Landmarks Accordion - else if ("add_folder" == command_name) - { - return mLandmarksInventoryPanel == mCurrentSelectedList; - } else { llwarns << "Unprocessed command has come: " << command_name << llendl; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 207ed723b2..7dd9df674c 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -60,6 +60,7 @@ public: virtual BOOL postBuild(); S32 getIndex() { return mIndex; } + void setIndex(S32 index) { mIndex = index; } const std::string& getRegionName() { return mRegionName;} /*virtual*/ void setValue(const LLSD& value); @@ -180,7 +181,7 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this)); registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this)); - registrar.add("TeleportHistory.Copy", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this)); + registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this)); // create the context menu from the XUI return LLUICtrlFactory::getInstance()->createFromFile( @@ -203,11 +204,11 @@ void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& sl gClipboard.copyFromString(utf8str_to_wstring(slurl)); } -void LLTeleportHistoryPanel::ContextMenu::onCopy() +void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard() { LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos; LLLandmarkActions::getSLURLfromPosGlobal(globalPos, - boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false); + boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1)); } // Not yet implemented; need to remove buildPanel() from constructor when we switch @@ -237,7 +238,7 @@ BOOL LLTeleportHistoryPanel::postBuild() mTeleportHistory = LLTeleportHistoryStorage::getInstance(); if (mTeleportHistory) { - mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this)); + mTeleportHistory->setHistoryChangedCallback(boost::bind(&LLTeleportHistoryPanel::onTeleportHistoryChange, this, _1)); } mHistoryAccordion = getChild("history_accordion"); @@ -488,7 +489,7 @@ void LLTeleportHistoryPanel::refresh() if (mLastSelectedItemIndex == mCurrentItem) curr_flat_view->selectItem(item, true); } - + mCurrentItem--; if (++added_items >= ADD_LIMIT) @@ -503,10 +504,75 @@ void LLTeleportHistoryPanel::refresh() mDirty = false; } -void LLTeleportHistoryPanel::onTeleportHistoryChange() +void LLTeleportHistoryPanel::onTeleportHistoryChange(S32 removed_index) { mLastSelectedItemIndex = -1; - showTeleportHistory(); + + if (-1 == removed_index) + showTeleportHistory(); // recreate all items + else + replaceItem(removed_index); // replace removed item by most recent +} + +void LLTeleportHistoryPanel::replaceItem(S32 removed_index) +{ + // Flat list for 'Today' (mItemContainers keeps accordion tabs in reverse order) + LLFlatListView* fv = getFlatListViewFromTab(mItemContainers[mItemContainers.size() - 1]); + + // Empty flat list for 'Today' means that other flat lists are empty as well, + // so all items from teleport history should be added. + if (!fv || fv->size() == 0) + { + showTeleportHistory(); + return; + } + + const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems(); + LLTeleportHistoryFlatItem* item = new LLTeleportHistoryFlatItem(history_items.size(), // index will be decremented inside loop below + &mContextMenu, + history_items[history_items.size() - 1].mTitle); // Most recent item, it was + // added instead of removed + fv->addItem(item, LLUUID::null, ADD_TOP); + + // Index of each item, from last to removed item should be decremented + // to point to the right item in LLTeleportHistoryStorage + for (S32 tab_idx = mItemContainers.size() - 1; tab_idx >= 0; --tab_idx) + { + LLAccordionCtrlTab* tab = mItemContainers.get(tab_idx); + if (!tab->getVisible()) + continue; + + fv = getFlatListViewFromTab(tab); + if (!fv) + { + showTeleportHistory(); + return; + } + + std::vector items; + fv->getItems(items); + + S32 items_cnt = items.size(); + for (S32 n = 0; n < items_cnt; ++n) + { + LLTeleportHistoryFlatItem *item = (LLTeleportHistoryFlatItem*) items[n]; + + if (item->getIndex() == removed_index) + { + fv->removeItem(item); + + // If flat list becames empty, then accordion tab should be hidden + if (fv->size() == 0) + tab->setVisible(false); + + mHistoryAccordion->arrange(); + + return; // No need to decrement idexes for the rest of items + } + + item->setIndex(item->getIndex() - 1); + } + } } void LLTeleportHistoryPanel::showTeleportHistory() diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index 49a97c5022..7c1b403432 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -57,7 +57,7 @@ public: LLContextMenu* createMenu(); void onTeleport(); void onInfo(); - void onCopy(); + void onCopyToClipboard(); static void gotSLURLCallback(const std::string& slurl); @@ -90,7 +90,8 @@ private: void refresh(); void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date); - void onTeleportHistoryChange(); + void onTeleportHistoryChange(S32 removed_index); + void replaceItem(S32 removed_index); void showTeleportHistory(); void handleItemSelect(LLFlatListView* ); LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp new file mode 100644 index 0000000000..f1e585f285 --- /dev/null +++ b/indra/newview/llparticipantlist.cpp @@ -0,0 +1,56 @@ +/** + * @file llparticipantlist.cpp + * @brief LLParticipantList implementing LLSimpleListener listener + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llparticipantlist.h" +#include "llavatarlist.h" +#include "llfloateractivespeakers.h" + + +LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list): + mSpeakerMgr(data_source), + mAvatarList(avatar_list) +{ + mSpeakerMgr->addListener(this, "add"); + mSpeakerMgr->addListener(this, "remove"); + mSpeakerMgr->addListener(this, "clear"); + std::string str = "test"; + mAvatarList->setNoItemsCommentText(str); + + //LLAvatarList::uuid_vector_t& group_members = mAvatarList->getIDs(); +} + +bool LLParticipantList::handleEvent(LLPointer event, const LLSD& userdata) +{ + return true; +} diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h new file mode 100644 index 0000000000..2ec563a356 --- /dev/null +++ b/indra/newview/llparticipantlist.h @@ -0,0 +1,48 @@ +/** + * @file llparticipantlist.h + * @brief LLParticipantList implementing LLSimpleListener listener + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llevent.h" + +class LLSpeakerMgr; +class LLAvatarList; + +class LLParticipantList: public LLOldEvents::LLSimpleListener +{ + public: + LLParticipantList(LLSpeakerMgr* data_source, LLAvatarList* avatar_list); + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); + + private: + LLSpeakerMgr* mSpeakerMgr; + LLAvatarList* mAvatarList; +}; diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index a72100a9b3..816e161f65 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -381,7 +381,7 @@ void LLScreenChannel::showToastsBottom() if(it != mToastList.rbegin()) { bottom = (*(it-1)).toast->getRect().mTop; - toast_margin = gSavedSettings.getS32("ToastMargin"); + toast_margin = gSavedSettings.getS32("ToastGap"); } toast_rect = (*it).toast->getRect(); @@ -394,7 +394,7 @@ void LLScreenChannel::showToastsBottom() { if( it != mToastList.rend()-1) { - stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastMargin")) > getRect().mTop; + stop_showing_toasts = ((*it).toast->getRect().mTop + gSavedSettings.getS32("OverflowToastHeight") + gSavedSettings.getS32("ToastGap")) > getRect().mTop; } } @@ -412,7 +412,7 @@ void LLScreenChannel::showToastsBottom() (*it).toast->stopTimer(); mHiddenToastsNum++; } - createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastTime")); + createOverflowToast(bottom, gSavedSettings.getS32("NotificationToastLifeTime")); } } @@ -426,7 +426,7 @@ void LLScreenChannel::showToastsCentre() for(it = mToastList.rbegin(); it != mToastList.rend(); ++it) { toast_rect = (*it).toast->getRect(); - toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight()); + toast_rect.setLeftTopAndSize(getRect().mLeft - toast_rect.getWidth() / 2, bottom + toast_rect.getHeight() / 2 + gSavedSettings.getS32("ToastGap"), toast_rect.getWidth() ,toast_rect.getHeight()); (*it).toast->setRect(toast_rect); (*it).toast->setVisible(TRUE); @@ -443,7 +443,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) { LLRect toast_rect; LLToast::Params p; - p.timer_period = timer; + p.lifetime_secs = timer; mOverflowToastPanel = new LLToast(p); if(!mOverflowToastPanel) @@ -465,7 +465,7 @@ void LLScreenChannel::createOverflowToast(S32 bottom, F32 timer) toast_rect = mOverflowToastPanel->getRect(); mOverflowToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); - toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); + toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight()); mOverflowToastPanel->setRect(toast_rect); text_box->setValue(text); @@ -518,7 +518,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer) { LLRect toast_rect; LLToast::Params p; - p.timer_period = timer; + p.lifetime_secs = timer; mStartUpToastPanel = new LLToast(p); if(!mStartUpToastPanel) @@ -545,7 +545,7 @@ void LLScreenChannel::createStartUpToast(S32 notif_num, S32 bottom, F32 timer) toast_rect = mStartUpToastPanel->getRect(); mStartUpToastPanel->reshape(getRect().getWidth(), toast_rect.getHeight(), true); - toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), getRect().getWidth(), toast_rect.getHeight()); + toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastGap"), getRect().getWidth(), toast_rect.getHeight()); mStartUpToastPanel->setRect(toast_rect); text_box->setValue(text); @@ -703,7 +703,7 @@ void LLScreenChannel::updateShowToastsState() LLRect this_rect = getRect(); if(floater->getVisible() && floater->isDocked()) { - channel_bottom += (floater->getRect().getHeight() + gSavedSettings.getS32("ToastMargin")); + channel_bottom += (floater->getRect().getHeight() + gSavedSettings.getS32("ToastGap")); } if(channel_bottom != this_rect.mBottom) diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 9729281bac..86290e6695 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -528,7 +528,7 @@ LLSysWellWindow::RowPanel::~RowPanel() //--------------------------------------------------------------------------------- void LLSysWellWindow::RowPanel::onClosePanel() { - gIMMgr->removeSession(mChiclet->getSessionId()); + gIMMgr->leaveSession(mChiclet->getSessionId()); // This row panel will be removed from the list in LLSysWellWindow::sessionRemoved(). } diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index a588153ca2..d3bbda1c72 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -93,14 +93,12 @@ void LLTeleportHistoryStorage::onTeleportHistoryChange() addItem(item.mTitle, item.mGlobalPos); save(); - - mHistoryChangedSignal(); } void LLTeleportHistoryStorage::purgeItems() { mItems.clear(); - mHistoryChangedSignal(); + mHistoryChangedSignal(-1); } void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos) @@ -116,15 +114,16 @@ bool LLTeleportHistoryStorage::compareByTitleAndGlobalPos(const LLTeleportHistor void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos, const LLDate& date) { - LLTeleportHistoryPersistentItem item(title, global_pos, date); slurl_list_t::iterator item_iter = std::find_if(mItems.begin(), mItems.end(), boost::bind(&LLTeleportHistoryStorage::compareByTitleAndGlobalPos, this, _1, item)); // If there is such item already, remove it, since new item is more recent + S32 removed_index = -1; if (item_iter != mItems.end()) { + removed_index = item_iter - mItems.begin(); mItems.erase(item_iter); } @@ -141,9 +140,12 @@ void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d // If second to last item is more recent than last, then resort items if (item_iter->mDate > item.mDate) { + removed_index = -1; std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate()); } } + + mHistoryChangedSignal(removed_index); } void LLTeleportHistoryStorage::removeItem(S32 idx) @@ -211,6 +213,8 @@ void LLTeleportHistoryStorage::load() file.close(); std::sort(mItems.begin(), mItems.end(), LLSortItemsByDate()); + + mHistoryChangedSignal(-1); } void LLTeleportHistoryStorage::dump() const @@ -234,7 +238,6 @@ boost::signals2::connection LLTeleportHistoryStorage::setHistoryChangedCallback( } void LLTeleportHistoryStorage::goToItem(S32 idx) - { // Validate specified index. if (idx < 0 || idx >= (S32)mItems.size()) diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index f67c4e2fb9..2eaa94f2ed 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -80,8 +80,9 @@ public: typedef std::vector slurl_list_t; - typedef boost::function history_callback_t; - typedef boost::signals2::signal history_signal_t; + // removed_index is index of removed item, which replaced by more recent + typedef boost::function history_callback_t; + typedef boost::signals2::signal history_signal_t; LLTeleportHistoryStorage(); ~LLTeleportHistoryStorage(); diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 84931e4d2d..19f56a5cf0 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -43,7 +43,7 @@ using namespace LLNotificationsUI; //-------------------------------------------------------------------------- LLToast::LLToast(LLToast::Params p) : LLModalDialog(LLSD(), p.is_modal), mPanel(p.panel), - mTimerValue(p.timer_period), + mToastLifetime(p.lifetime_secs), mNotificationID(p.notif_id), mSessionID(p.session_id), mCanFade(p.can_fade), @@ -103,22 +103,22 @@ void LLToast::setAndStartTimer(F32 period) { if(mCanFade) { - mTimerValue = period; + mToastLifetime = period; mTimer.start(); } } //-------------------------------------------------------------------------- -bool LLToast::timerHasExpired() +bool LLToast::lifetimeHasExpired() { if (mTimer.getStarted()) { F32 elapsed_time = mTimer.getElapsedTimeF32(); - if (elapsed_time > gSavedSettings.getS32("ToastOpaqueTime")) + if ((mToastLifetime - elapsed_time) <= gSavedSettings.getS32("ToastOpaqueTime")) { setBackgroundOpaque(FALSE); } - if (elapsed_time > mTimerValue) + if (elapsed_time > mToastLifetime) { return true; } @@ -183,7 +183,7 @@ void LLToast::insertPanel(LLPanel* panel) //-------------------------------------------------------------------------- void LLToast::draw() { - if(timerHasExpired()) + if(lifetimeHasExpired()) { tick(); } diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 29c231a01d..504b83a660 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -63,7 +63,7 @@ public: LLUUID notif_id; //notification ID LLUUID session_id; //im session ID LLNotificationPtr notification; - F32 timer_period; + F32 lifetime_secs; toast_callback_t on_delete_toast; toast_callback_t on_mouse_enter; bool can_fade; @@ -82,7 +82,7 @@ public: force_show(false), force_store(false), panel(NULL), - timer_period(gSavedSettings.getS32("NotificationToastTime")) + lifetime_secs(gSavedSettings.getS32("NotificationToastLifeTime")) {}; }; @@ -153,7 +153,7 @@ public: private: // check timer - bool timerHasExpired(); + bool lifetimeHasExpired(); // on timer finished function void tick(); @@ -161,8 +161,9 @@ private: LLUUID mSessionID; LLNotificationPtr mNotification; + // timer counts a lifetime of a toast LLTimer mTimer; - F32 mTimerValue; + F32 mToastLifetime; // in seconds LLPanel* mPanel; LLButton* mHideBtn; diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml index 515278c23d..0160d52b17 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml @@ -17,10 +17,10 @@ function="TeleportHistory.MoreInformation" /> + name="CopyToClipboard"> + function="TeleportHistory.CopyToClipboard" /> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 8076b88a65..085b732473 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -68,6 +68,7 @@ background_visible="true" Date: Thu, 22 Oct 2009 00:21:18 +0000 Subject: Merging revisions 2129-2144 of https://svn.aws.productengine.com/secondlife/pe/stable-2 into P:\svn\viewer-2.0.0-3, respecting ancestry * Bugs: EXT-1293 EXT-1611 EXT-1613 EXT-1176 EXT-1724 EXT-1186 EXT-1662 EXT-1760 EXT-1720 * Dev: EXT-1575 EXT-1770 EXT-1232 EXT-1234 --- indra/newview/CMakeLists.txt | 4 + indra/newview/llagentpicksinfo.cpp | 130 ++++++++++ indra/newview/llagentpicksinfo.h | 106 ++++++++ indra/newview/llavatarpropertiesprocessor.cpp | 6 + indra/newview/llchiclet.cpp | 37 +-- indra/newview/llchiclet.h | 19 +- indra/newview/lldndbutton.cpp | 60 +++++ indra/newview/lldndbutton.h | 89 +++++++ indra/newview/llfloaterinventory.cpp | 33 +-- indra/newview/llfloaterinventory.h | 14 +- indra/newview/llimview.cpp | 9 +- indra/newview/llmutelist.h | 8 +- indra/newview/llnearbychat.cpp | 269 +++------------------ indra/newview/llnearbychat.h | 34 +-- indra/newview/llpanellandmarks.cpp | 69 ++++-- indra/newview/llpanellandmarks.h | 9 +- indra/newview/llpanelpick.cpp | 13 + indra/newview/llpanelpick.h | 1 + indra/newview/llpanelpicks.cpp | 12 +- indra/newview/llpanelpicks.h | 1 + indra/newview/llpanelplaceinfo.cpp | 77 +++++- indra/newview/llpanelplaceinfo.h | 14 +- indra/newview/llpanelplaces.cpp | 13 + indra/newview/llpanelplaces.h | 1 + indra/newview/llstartup.cpp | 3 +- indra/newview/llviewerfloaterreg.cpp | 1 - indra/newview/skins/default/textures/textures.xml | 2 + .../skins/default/xui/en/favorites_bar_button.xml | 2 +- .../skins/default/xui/en/floater_nearby_chat.xml | 36 +-- .../newview/skins/default/xui/en/menu_landmark.xml | 3 + indra/newview/skins/default/xui/en/menu_place.xml | 3 + .../default/xui/en/menu_places_gear_landmark.xml | 3 + .../skins/default/xui/en/panel_edit_profile.xml | 1 + .../skins/default/xui/en/panel_landmarks.xml | 5 +- .../skins/default/xui/en/panel_navigation_bar.xml | 2 +- .../skins/default/xui/en/panel_notification.xml | 2 + indra/newview/skins/default/xui/en/strings.xml | 16 ++ 37 files changed, 712 insertions(+), 395 deletions(-) create mode 100644 indra/newview/llagentpicksinfo.cpp create mode 100644 indra/newview/llagentpicksinfo.h create mode 100644 indra/newview/lldndbutton.cpp create mode 100644 indra/newview/lldndbutton.h (limited to 'indra/newview/llchiclet.cpp') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index fbf14a7359..26170d1713 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -70,6 +70,7 @@ set(viewer_SOURCE_FILES llagentaccess.cpp llagentdata.cpp llagentlanguage.cpp + llagentpicksinfo.cpp llagentpilot.cpp llagentui.cpp llagentwearables.cpp @@ -112,6 +113,7 @@ set(viewer_SOURCE_FILES lldebugview.cpp lldelayedgestureerror.cpp lldirpicker.cpp + lldndbutton.cpp lldrawable.cpp lldrawpoolalpha.cpp lldrawpoolavatar.cpp @@ -537,6 +539,7 @@ set(viewer_HEADER_FILES llagentaccess.h llagentdata.h llagentlanguage.h + llagentpicksinfo.h llagentpilot.h llagentui.h llagentwearables.h @@ -581,6 +584,7 @@ set(viewer_HEADER_FILES lldebugview.h lldelayedgestureerror.h lldirpicker.h + lldndbutton.h lldrawable.h lldrawpool.h lldrawpoolalpha.h diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp new file mode 100644 index 0000000000..6e5835bace --- /dev/null +++ b/indra/newview/llagentpicksinfo.cpp @@ -0,0 +1,130 @@ +/** + * @file llagentpicksinfo.cpp + * @brief LLAgentPicksInfo class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llagentpicksinfo.h" + +#include "llagent.h" +#include "llavatarconstants.h" +#include "llavatarpropertiesprocessor.h" + +class LLAgentPicksInfo::LLAgentPicksObserver : public LLAvatarPropertiesObserver +{ +public: + LLAgentPicksObserver() + { + LLAvatarPropertiesProcessor::getInstance()->addObserver(gAgent.getID(), this); + } + + ~LLAgentPicksObserver() + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(gAgent.getID(), this); + } + + void sendAgentPicksRequest() + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(gAgent.getID()); + } + + typedef boost::function server_respond_callback_t; + + void setServerRespondCallback(const server_respond_callback_t& cb) + { + mServerRespondCallback = cb; + } + + virtual void processProperties(void* data, EAvatarProcessorType type) + { + if(APT_PICKS == type) + { + LLAvatarPicks* picks = static_cast(data); + if(picks && gAgent.getID() == picks->target_id) + { + if(mServerRespondCallback) + { + mServerRespondCallback(picks); + } + } + } + } + +private: + + server_respond_callback_t mServerRespondCallback; +}; + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLAgentPicksInfo::LLAgentPicksInfo() + : mAgentPicksObserver(NULL) + , mMaxNumberOfPicks(MAX_AVATAR_PICKS) + // Disable Pick creation until we get number of Picks from server - in case + // avatar has maximum number of Picks. + , mNumberOfPicks(mMaxNumberOfPicks) +{ +} + +LLAgentPicksInfo::~LLAgentPicksInfo() +{ + delete mAgentPicksObserver; +} + +void LLAgentPicksInfo::requestNumberOfPicks() +{ + if(!mAgentPicksObserver) + { + mAgentPicksObserver = new LLAgentPicksObserver(); + + mAgentPicksObserver->setServerRespondCallback(boost::bind( + &LLAgentPicksInfo::onServerRespond, this, _1)); + } + + mAgentPicksObserver->sendAgentPicksRequest(); +} + +bool LLAgentPicksInfo::isPickLimitReached() +{ + return getNumberOfPicks() >= getMaxNumberOfPicks(); +} + +void LLAgentPicksInfo::onServerRespond(LLAvatarPicks* picks) +{ + if(!picks) + { + llerrs << "Unexpected value" << llendl; + return; + } + + setNumberOfPicks(picks->picks_list.size()); +} diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h new file mode 100644 index 0000000000..0e30f2c5a0 --- /dev/null +++ b/indra/newview/llagentpicksinfo.h @@ -0,0 +1,106 @@ +/** + * @file llagentpicksinfo.h + * @brief LLAgentPicksInfo class header file + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAGENTPICKS_H +#define LL_LLAGENTPICKS_H + +#include "llsingleton.h" + +struct LLAvatarPicks; + +/** + * Class that provides information about Agent Picks + */ +class LLAgentPicksInfo : public LLSingleton +{ + class LLAgentPicksObserver; + +public: + + LLAgentPicksInfo(); + + virtual ~LLAgentPicksInfo(); + + /** + * Requests number of picks from server. + * + * Number of Picks is requested from server, thus it is not available immediately. + */ + void requestNumberOfPicks(); + + /** + * Returns number of Picks. + */ + S32 getNumberOfPicks() { return mNumberOfPicks; } + + /** + * Returns maximum number of Picks. + */ + S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; } + + /** + * Returns TRUE if Agent has maximum allowed number of Picks. + */ + bool isPickLimitReached(); + + /** + * After creating or deleting a Pick we can assume operation on server will be + * completed successfully. Incrementing/decrementing number of picks makes new number + * of picks available immediately. Actual number of picks will be updated when we receive + * response from server. + */ + void incrementNumberOfPicks() { ++mNumberOfPicks; } + + void decrementNumberOfPicks() { --mNumberOfPicks; } + +private: + + void onServerRespond(LLAvatarPicks* picks); + + /** + * Sets number of Picks. + */ + void setNumberOfPicks(S32 number) { mNumberOfPicks = number; } + + /** + * Sets maximum number of Picks. + */ + void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; } + +private: + + LLAgentPicksObserver* mAgentPicksObserver; + S32 mMaxNumberOfPicks; + S32 mNumberOfPicks; +}; + +#endif //LL_LLAGENTPICKS_H diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index f58c85d8c5..fb43b5a7d7 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -36,6 +36,7 @@ // Viewer includes #include "llagent.h" +#include "llagentpicksinfo.h" #include "llviewergenericmessage.h" // Linden library includes @@ -438,6 +439,9 @@ void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id ) msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_PickID, pick_id); gAgent.sendReliableMessage(); + + LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); + LLAgentPicksInfo::getInstance()->decrementNumberOfPicks(); } void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick) @@ -470,6 +474,8 @@ void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick) msg->addBOOL(_PREHASH_Enabled, new_pick->enabled); gAgent.sendReliableMessage(); + + LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); } void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id) diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 43aca430a2..2ebbae33ad 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -868,19 +868,29 @@ BOOL LLChicletPanel::postBuild() return TRUE; } +S32 LLChicletPanel::calcChickletPanleWidth() +{ + S32 res = 0; + + for (chiclet_list_t::iterator it = mChicletList.begin(); it + != mChicletList.end(); it++) + { + res = (*it)->getRect().getWidth() + getChicletPadding(); + } + return res; +} + bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) { if(mScrollArea->addChild(chiclet)) { + // chicklets should be aligned to right edge of scroll panel S32 offset = 0; - // if index == 0 and chickelt list isn't empty insert chiclet before first in the list - // without scrolling, so other visible chicklets aren't change screen position - if (0 == index && !mChicletList.empty()) + if (!canScrollLeft()) { - offset = getChiclet(0)->getRect().mLeft - - (chiclet->getRequiredRect().getWidth() - + getChicletPadding()); + offset = mScrollArea->getRect().getWidth() + - chiclet->getRect().getWidth() - calcChickletPanleWidth(); } mChicletList.insert(mChicletList.begin() + index, chiclet); @@ -1073,25 +1083,16 @@ void LLChicletPanel::arrange() void LLChicletPanel::trimChiclets() { // trim right - if(canScrollLeft() && !canScrollRight()) + if(!mChicletList.empty()) { S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight; + S32 first_chiclet_left = getChiclet(0)->getRect().mLeft; S32 scroll_width = mScrollArea->getRect().getWidth(); - if(last_chiclet_right < scroll_width) + if(last_chiclet_right < scroll_width || first_chiclet_left > 0) { shiftChiclets(scroll_width - last_chiclet_right); } } - - // trim left - if(!mChicletList.empty()) - { - LLRect first_chiclet_rect = getChiclet(0)->getRect(); - if(first_chiclet_rect.mLeft > 0) - { - shiftChiclets( - first_chiclet_rect.mLeft); - } - } } void LLChicletPanel::showScrollButtonsIfNeeded() diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index 932e05d95a..1713c0258d 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -653,9 +653,14 @@ public: virtual ~LLChicletPanel(); /* - * Creates chiclet and adds it to chiclet list. + * Creates chiclet and adds it to chiclet list at specified index. */ - template T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0); + template T* createChiclet(const LLUUID& session_id, S32 index); + + /* + * Creates chiclet and adds it to chiclet list at right. + */ + template T* createChiclet(const LLUUID& session_id); /* * Returns pointer to chiclet of specified type at specified index. @@ -723,6 +728,8 @@ protected: LLChicletPanel(const Params&p); friend class LLUICtrlFactory; + S32 calcChickletPanleWidth(); + /* * Adds chiclet to list and rearranges all chiclets. */ @@ -863,7 +870,7 @@ private: }; template -T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/) +T* LLChicletPanel::createChiclet(const LLUUID& session_id, S32 index) { typename T::Params params; T* chiclet = LLUICtrlFactory::create(params); @@ -889,6 +896,12 @@ T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S3 return chiclet; } +template +T* LLChicletPanel::createChiclet(const LLUUID& session_id) +{ + return createChiclet(session_id, mChicletList.size()); +} + template T* LLChicletPanel::findChiclet(const LLUUID& im_session_id) { diff --git a/indra/newview/lldndbutton.cpp b/indra/newview/lldndbutton.cpp new file mode 100644 index 0000000000..22f2bb1d16 --- /dev/null +++ b/indra/newview/lldndbutton.cpp @@ -0,0 +1,60 @@ +/** + * @file lldndbutton.cpp + * @brief Implementation of the drag-n-drop button. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "lldndbutton.h" + + +static LLDefaultChildRegistry::Register r("dnd_button"); + +LLDragAndDropButton::Params::Params() +{ + +} + +LLDragAndDropButton::LLDragAndDropButton(Params& params) +: LLButton(params) +{ + +} + +BOOL LLDragAndDropButton::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) +{ + if (mDragDropHandler) + { + return mDragDropHandler(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg); + } + return false; +} + +// EOF diff --git a/indra/newview/lldndbutton.h b/indra/newview/lldndbutton.h new file mode 100644 index 0000000000..c888268187 --- /dev/null +++ b/indra/newview/lldndbutton.h @@ -0,0 +1,89 @@ +/** + * @file lldndbutton.h + * @brief Declaration of the drag-n-drop button. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLDNDBUTTON_H +#define LL_LLDNDBUTTON_H + +#include "llbutton.h" + +/** + * Class representing a button which can handle Drag-And-Drop event. + * + * LLDragAndDropButton does not contain any logic to handle Drag-And-Drop itself. + * Instead it provides drag_drop_handler_t which can be set to the button. + * Then each Drag-And-Drop will be delegated to this handler without any pre/post processing. + * + * All xml parameters are the same as LLButton has. + * + * @see LLLandmarksPanel for example of usage of this class. + */ +class LLDragAndDropButton : public LLButton +{ +public: + struct Params : public LLInitParam::Block + { + Params(); + }; + + LLDragAndDropButton(Params& params); + + typedef boost::function drag_drop_handler_t; + + + /** + * Sets a handler which should process Drag-And-Drop. + */ + void setDragAndDropHandler(drag_drop_handler_t handler) { mDragDropHandler = handler; } + + + /** + * Process Drag-And-Drop by delegating the event to drag_drop_handler_t. + * + * @return BOOL - value returned by drag_drop_handler_t if it is set, FALSE otherwise. + */ + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + +private: + drag_drop_handler_t mDragDropHandler; +}; + + +#endif // LL_LLDNDBUTTON_H diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 4013f52f10..4596ae7739 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1174,7 +1174,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) mHasInventoryConnection(false), mStartFolderString(p.start_folder) , mBuildDefaultHierarchy(true) -, mRootInventoryItemUUID(LLUUID::null) , mInvFVBridgeBuilder(NULL) { mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; @@ -1241,7 +1240,19 @@ BOOL LLInventoryPanel::postBuild() // determine the root folder, if any, so inventory contents show just the children // of that folder (i.e. not including the folder itself). const LLAssetType::EType preferred_type = LLAssetType::lookupHumanReadable(mStartFolderString); - mStartFolderID = (preferred_type != LLAssetType::AT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); + + if ("inventory" == mStartFolderString) + { + mStartFolderID = gInventory.getRootFolderID(); + } + else if ("library" == mStartFolderString) + { + mStartFolderID = gInventory.getLibraryRootFolderID(); + } + else + { + mStartFolderID = (preferred_type != LLAssetType::AT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null); + } // build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mHasInventoryConnection) @@ -1462,24 +1473,6 @@ void LLInventoryPanel::modelChanged(U32 mask) } } -void LLInventoryPanel::setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder) -{ - if (NULL == bridge_builder) - { - llwarns << "NULL is passed as Inventory Bridge Builder. Default will be used." << llendl; - } - else - { - mInvFVBridgeBuilder = bridge_builder; - } - - if (mInventory->isInventoryUsable() && !mHasInventoryConnection) - { - rebuildViewsFor(mRootInventoryItemUUID); - mHasInventoryConnection = true; - } -} - void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) { diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h index 1666f18c05..4c9ac5d4c6 100644 --- a/indra/newview/llfloaterinventory.h +++ b/indra/newview/llfloaterinventory.h @@ -175,9 +175,6 @@ protected: void rebuildViewsFor(const LLUUID& id); virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719 - // Be sure that passed pointer will be destroyed where it was created. - void setInvFVBridgeBuilder(const LLInventoryFVBridgeBuilder* bridge_builder); - protected: LLInventoryModel* mInventory; LLInventoryObserver* mInventoryObserver; @@ -187,6 +184,12 @@ protected: //private: // Can not make these private - needed by llinventorysubtreepanel LLFolderView* mFolders; std::string mStartFolderString; + + /** + * Contains UUID of Inventory item from which hierarchy should be built. + * Can be set with the "start_folder" xml property. + * Default is LLUUID::null that means total Inventory hierarchy. + */ LLUUID mStartFolderID; LLScrollContainer* mScroller; bool mHasInventoryConnection; @@ -196,11 +199,6 @@ protected: */ bool mBuildDefaultHierarchy; - /** - * Contains UUID of Inventory item from which hierarchy should be built. - * Should be set by derived class before modelChanged() is called. - * Default is LLUUID::null that means total Inventory hierarchy. - */ LLUUID mRootInventoryItemUUID; /** diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9974de0ef1..c6b04cbcc8 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -635,7 +635,6 @@ void LLIMModel::sendMessage(const std::string& utf8_text, } // Add the recipient to the recent people list. - //*TODO should be deleted, because speaker manager updates through callback the recent list LLRecentPeople::instance().add(other_participant_id); } @@ -1415,12 +1414,10 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess } else // going to IM session { - LLFloaterIMPanel* floaterp = findFloaterBySession(session_id); - if (floaterp) + if (hasSession(session_id)) { - message = floaterp->getString(message_name); + message = LLTrans::getString(message_name + "-im"); message.setArgs(args); - gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString()); } } @@ -1775,7 +1772,7 @@ LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id) BOOL LLIMMgr::hasSession(const LLUUID& session_id) { - return (findFloaterBySession(session_id) != NULL); + return LLIMModel::getInstance()->findIMSession(session_id) != NULL; } void LLIMMgr::clearPendingInvitation(const LLUUID& session_id) diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index dec8d7576e..409b637bf2 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -153,7 +153,13 @@ private: { bool operator()(const LLMute& a, const LLMute& b) const { - return a.mName < b.mName; + std::string name1 = a.mName; + std::string name2 = b.mName; + + LLStringUtil::toUpper(name1); + LLStringUtil::toUpper(name2); + + return name1 < name2; } }; struct compare_by_id diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 7160cce5cb..6e90d22d89 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -54,17 +54,15 @@ #include "llstylemap.h" #include "lldraghandle.h" - +#include "lltrans.h" static const S32 RESIZE_BAR_THICKNESS = 3; LLNearbyChat::LLNearbyChat(const LLSD& key) : - LLFloater(key), - mEChatTearofState(CHAT_PINNED), - mChatCaptionPanel(NULL), - mChatHistory(NULL) + LLFloater(key) + ,mChatHistory(NULL) { - m_isDirty = false; + } LLNearbyChat::~LLNearbyChat() @@ -73,25 +71,6 @@ LLNearbyChat::~LLNearbyChat() BOOL LLNearbyChat::postBuild() { - //resize bars - setCanResize(true); - - mResizeBar[LLResizeBar::BOTTOM]->setVisible(false); - mResizeBar[LLResizeBar::LEFT]->setVisible(false); - mResizeBar[LLResizeBar::RIGHT]->setVisible(false); - - mResizeBar[LLResizeBar::BOTTOM]->setResizeLimits(120,500); - mResizeBar[LLResizeBar::TOP]->setResizeLimits(120,500); - mResizeBar[LLResizeBar::LEFT]->setResizeLimits(220,600); - mResizeBar[LLResizeBar::RIGHT]->setResizeLimits(220,600); - - mResizeHandle[0]->setVisible(false); - mResizeHandle[1]->setVisible(false); - mResizeHandle[2]->setVisible(false); - mResizeHandle[3]->setVisible(false); - - getDragHandle()->setVisible(false); - //menu LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; @@ -101,17 +80,15 @@ BOOL LLNearbyChat::postBuild() LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if(menu) mPopupMenuHandle = menu->getHandle(); gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true); - mChatCaptionPanel = getChild("chat_caption", false); mChatHistory = getChild("chat_history"); - reshape(getRect().getWidth(), getRect().getHeight(), FALSE); - + setCanResize(true); + return LLFloater::postBuild(); } @@ -181,6 +158,22 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat) return text_color; } +std::string formatCurrentTime() +{ + time_t utc_time; + utc_time = time_corrected(); + std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:[" + +LLTrans::getString("TimeMin")+"] "; + + LLSD substitution; + + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (timeStr, substitution); + + return timeStr; +} + + void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color) { S32 font_size = gSavedSettings.getS32("ChatFontSize"); @@ -205,7 +198,7 @@ void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& colo style_params.font(fontp); LLUUID uuid = chat.mFromID; std::string from = chat.mFromName; - std::string time = ""; + std::string time = formatCurrentTime(); std::string message = chat.mText; mChatHistory->appendWidgetMessage(uuid, from, time, message, style_params); } @@ -239,193 +232,6 @@ void LLNearbyChat::onNearbySpeakers() LLSideTray::getInstance()->showPanel("panel_people",param); } -void LLNearbyChat::onTearOff() -{ - if(mEChatTearofState == CHAT_PINNED) - float_panel(); - else - pinn_panel(); -} - -void LLNearbyChat::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - - LLFloater::reshape(width, height, called_from_parent); - - LLRect resize_rect; - resize_rect.setLeftTopAndSize( 0, height, width, RESIZE_BAR_THICKNESS); - if (mResizeBar[LLResizeBar::TOP]) - { - mResizeBar[LLResizeBar::TOP]->reshape(width,RESIZE_BAR_THICKNESS); - mResizeBar[LLResizeBar::TOP]->setRect(resize_rect); - } - - resize_rect.setLeftTopAndSize( 0, RESIZE_BAR_THICKNESS, width, RESIZE_BAR_THICKNESS); - if (mResizeBar[LLResizeBar::BOTTOM]) - { - mResizeBar[LLResizeBar::BOTTOM]->reshape(width,RESIZE_BAR_THICKNESS); - mResizeBar[LLResizeBar::BOTTOM]->setRect(resize_rect); - } - - resize_rect.setLeftTopAndSize( 0, height, RESIZE_BAR_THICKNESS, height); - if (mResizeBar[LLResizeBar::LEFT]) - { - mResizeBar[LLResizeBar::LEFT]->reshape(RESIZE_BAR_THICKNESS,height); - mResizeBar[LLResizeBar::LEFT]->setRect(resize_rect); - } - - resize_rect.setLeftTopAndSize( width - RESIZE_BAR_THICKNESS, height, RESIZE_BAR_THICKNESS, height); - if (mResizeBar[LLResizeBar::RIGHT]) - { - mResizeBar[LLResizeBar::RIGHT]->reshape(RESIZE_BAR_THICKNESS,height); - mResizeBar[LLResizeBar::RIGHT]->setRect(resize_rect); - } - - // *NOTE: we must check mChatCaptionPanel and mChatHistory against NULL because reshape is called from the - // LLView::initFromParams BEFORE postBuild is called and child controls are not exist yet - LLRect caption_rect; - if (NULL != mChatCaptionPanel) - { - caption_rect = mChatCaptionPanel->getRect(); - caption_rect.setLeftTopAndSize( 2, height - RESIZE_BAR_THICKNESS, width - 4, caption_rect.getHeight()); - mChatCaptionPanel->reshape( width - 4, caption_rect.getHeight(), 1); - mChatCaptionPanel->setRect(caption_rect); - } - - if (NULL != mChatHistory) - { - LLRect scroll_rect = mChatHistory->getRect(); - scroll_rect.setLeftTopAndSize( 2, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS, width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2); - mChatHistory->reshape( width - 4, height - caption_rect.getHeight() - RESIZE_BAR_THICKNESS*2, 1); - mChatHistory->setRect(scroll_rect); - } - - // - if(mEChatTearofState == CHAT_PINNED) - { - const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); - - LLRect panel_rect; - panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+height+4, width, height); - setRect(panel_rect); - } - else - { - LLRect panel_rect; - panel_rect.setLeftTopAndSize( getRect().mLeft, getRect().mTop, width, height); - setRect(panel_rect); - } - -} - -BOOL LLNearbyChat::handleMouseDown (S32 x, S32 y, MASK mask) -{ - LLUICtrl* nearby_speakers_btn = mChatCaptionPanel->getChild("nearby_speakers_btn"); - LLUICtrl* tearoff_btn = mChatCaptionPanel->getChild("tearoff_btn"); - LLUICtrl* close_btn = mChatCaptionPanel->getChild("close_btn"); - - S32 caption_local_x = x - mChatCaptionPanel->getRect().mLeft; - S32 caption_local_y = y - mChatCaptionPanel->getRect().mBottom; - - S32 local_x = caption_local_x - nearby_speakers_btn->getRect().mLeft; - S32 local_y = caption_local_y - nearby_speakers_btn->getRect().mBottom; - if(nearby_speakers_btn->pointInView(local_x, local_y)) - { - - onNearbySpeakers(); - bringToFront( x, y ); - return true; - } - local_x = caption_local_x - tearoff_btn->getRect().mLeft; - local_y = caption_local_y- tearoff_btn->getRect().mBottom; - if(tearoff_btn->pointInView(local_x, local_y)) - { - onTearOff(); - bringToFront( x, y ); - return true; - } - - local_x = caption_local_x - close_btn->getRect().mLeft; - local_y = caption_local_y - close_btn->getRect().mBottom; - if(close_btn->pointInView(local_x, local_y)) - { - setVisible(false); - bringToFront( x, y ); - return true; - } - - if(mEChatTearofState == CHAT_UNPINNED && mChatCaptionPanel->pointInView(caption_local_x, caption_local_y) ) - { - //start draggind - gFocusMgr.setMouseCapture(this); - mStart_Y = y; - mStart_X = x; - bringToFront( x, y ); - return true; - } - - return LLFloater::handleMouseDown(x,y,mask); -} - -BOOL LLNearbyChat::handleMouseUp(S32 x, S32 y, MASK mask) -{ - if( hasMouseCapture() ) - { - // Release the mouse - gFocusMgr.setMouseCapture( NULL ); - mStart_X = 0; - mStart_Y = 0; - return true; - } - - return LLFloater::handleMouseUp(x,y,mask); -} - -BOOL LLNearbyChat::handleHover(S32 x, S32 y, MASK mask) -{ - if( hasMouseCapture() ) - { - translate(x-mStart_X,y-mStart_Y); - return true; - } - return LLFloater::handleHover(x,y,mask); -} - -void LLNearbyChat::pinn_panel() -{ - mEChatTearofState = CHAT_PINNED; - LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild("tearoff_btn",false); - - tearoff_btn->setValue("Inv_Landmark"); - - const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); - - LLRect panel_rect; - panel_rect.setLeftTopAndSize( parent_rect.mLeft+2, parent_rect.mBottom+getRect().getHeight()+4, getRect().getWidth(), getRect().getHeight()); - setRect(panel_rect); - - mResizeBar[LLResizeBar::BOTTOM]->setVisible(false); - mResizeBar[LLResizeBar::LEFT]->setVisible(false); - mResizeBar[LLResizeBar::RIGHT]->setVisible(false); - - getDragHandle()->setVisible(false); - -} - -void LLNearbyChat::float_panel() -{ - mEChatTearofState = CHAT_UNPINNED; - LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild("tearoff_btn", false); - - tearoff_btn->setValue("Inv_Landmark"); - mResizeBar[LLResizeBar::BOTTOM]->setVisible(true); - mResizeBar[LLResizeBar::LEFT]->setVisible(true); - mResizeBar[LLResizeBar::RIGHT]->setVisible(true); - - getDragHandle()->setVisible(true); - - translate(4,4); -} void LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata) { @@ -438,23 +244,6 @@ bool LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata) return false; } -BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if(mChatCaptionPanel->pointInView(x - mChatCaptionPanel->getRect().mLeft, y - mChatCaptionPanel->getRect().mBottom) ) - { - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); - - if(menu) - { - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, x, y); - } - return true; - } - return LLFloater::handleRightMouseDown(x, y, mask); -} - void LLNearbyChat::onOpen(const LLSD& key ) { LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); @@ -464,9 +253,15 @@ void LLNearbyChat::onOpen(const LLSD& key ) } } -void LLNearbyChat::draw () +void LLNearbyChat::setDocked (bool docked, bool pop_on_undock) { - LLFloater::draw(); -} + LLFloater::setDocked(docked, pop_on_undock); + if(docked) + { + //move nearby_chat to right bottom + LLRect rect = gFloaterView->getRect(); + setRect(LLRect(rect.mLeft,getRect().getHeight(),rect.mLeft+getRect().getWidth(),0)); + } +} diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h index 47cae8ed0d..63e780c4bf 100644 --- a/indra/newview/llnearbychat.h +++ b/indra/newview/llnearbychat.h @@ -43,55 +43,27 @@ class LLChatHistory; class LLNearbyChat: public LLFloater { public: - // enumerations used by the chat system - typedef enum e_chat_tearof_state - { - CHAT_PINNED = 0, - CHAT_UNPINNED = 1, - } EChatTearofState; - - enum { RESIZE_BAR_COUNT=4 }; - LLNearbyChat(const LLSD& key); ~LLNearbyChat(); BOOL postBuild (); - void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE); - - BOOL handleMouseDown (S32 x, S32 y, MASK mask); - BOOL handleMouseUp (S32 x, S32 y, MASK mask); - BOOL handleHover (S32 x, S32 y, MASK mask); - - BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - void addMessage (const LLChat& message); - void onNearbySpeakers (); - void onTearOff(); - void onNearbyChatContextMenuItemClicked(const LLSD& userdata); bool onNearbyChatCheckContextMenuItem(const LLSD& userdata); - /*virtual*/ void onOpen (const LLSD& key); + void setDocked (bool docked, bool pop_on_undock); - /*virtual*/ void draw (); + /*virtual*/ void onOpen (const LLSD& key); private: + void onNearbySpeakers (); void add_timestamped_line(const LLChat& chat, const LLColor4& color); - void pinn_panel(); - void float_panel(); private: - EChatTearofState mEChatTearofState; - S32 mStart_X; - S32 mStart_Y; - LLHandle mPopupMenuHandle; - LLPanel* mChatCaptionPanel; LLChatHistory* mChatHistory; - - bool m_isDirty; }; #endif diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index f05029582c..daeeb50561 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -39,7 +39,9 @@ #include "llaccordionctrltab.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llagentui.h" +#include "lldndbutton.h" #include "llfloaterworldmap.h" #include "llfolderviewitem.h" #include "llinventorysubtreepanel.h" @@ -57,7 +59,6 @@ static const std::string ADD_LANDMARK_BUTTON_NAME = "add_landmark_btn"; static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn"; static const std::string TRASH_BUTTON_NAME = "trash_btn"; -static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER; // helper functions static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string); @@ -327,9 +328,7 @@ void LLLandmarksPanel::initFavoritesInventroyPanel() { mFavoritesInventoryPanel = getChild("favorites_list"); - LLUUID start_folder_id = mFavoritesInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_FAVORITE); - - initLandmarksPanel(mFavoritesInventoryPanel, start_folder_id); + initLandmarksPanel(mFavoritesInventoryPanel); initAccordion("tab_favorites", mFavoritesInventoryPanel); } @@ -338,9 +337,8 @@ void LLLandmarksPanel::initLandmarksInventroyPanel() { mLandmarksInventoryPanel = getChild("landmarks_list"); - LLUUID start_folder_id = mLandmarksInventoryPanel->getModel()->findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + initLandmarksPanel(mLandmarksInventoryPanel); - initLandmarksPanel(mLandmarksInventoryPanel, start_folder_id); mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS); // subscribe to have auto-rename functionality while creating New Folder @@ -353,9 +351,7 @@ void LLLandmarksPanel::initMyInventroyPanel() { mMyInventoryPanel= getChild("my_inventory_list"); - LLUUID start_folder_id = mMyInventoryPanel->getModel()->getRootFolderID(); - - initLandmarksPanel(mMyInventoryPanel, start_folder_id); + initLandmarksPanel(mMyInventoryPanel); initAccordion("tab_inventory", mMyInventoryPanel); } @@ -364,18 +360,13 @@ void LLLandmarksPanel::initLibraryInventroyPanel() { mLibraryInventoryPanel = getChild("library_list"); - LLUUID start_folder_id = mLibraryInventoryPanel->getModel()->getLibraryRootFolderID(); - - initLandmarksPanel(mLibraryInventoryPanel, start_folder_id); + initLandmarksPanel(mLibraryInventoryPanel); initAccordion("tab_library", mLibraryInventoryPanel); } - -void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id) +void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list) { - inventory_list->buildSubtreeViewsFor(start_folder_id, &PLACES_INVENTORY_BUILDER); - inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); @@ -446,8 +437,15 @@ void LLLandmarksPanel::initListCommandsHandlers() mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); + LLDragAndDropButton* trash_btn = mListCommands->getChild(TRASH_BUTTON_NAME); + trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this + , _4 // BOOL drop + , _5 // EDragAndDropType cargo_type + , _7 // EAcceptance* accept + )); + mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2)); - mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onCopyPasteAction, this, _2)); + mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2)); mCommitCallbackRegistrar.add("Places.LandmarksGear.Folding.Action", boost::bind(&LLLandmarksPanel::onFoldingAction, this, _2)); mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2)); @@ -539,9 +537,7 @@ void LLLandmarksPanel::onAddFolderButtonClick() const void LLLandmarksPanel::onTrashButtonClick() const { - if(!mCurrentSelectedList) return; - - mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(), "delete"); + onClipboardAction("delete"); } void LLLandmarksPanel::onAddAction(const LLSD& userdata) const @@ -557,7 +553,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const } } -void LLLandmarksPanel::onCopyPasteAction(const LLSD& userdata) const +void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const { if(!mCurrentSelectedList) return; @@ -644,6 +640,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const { return rootFolderView->getSelectedCount() == 1; } + else if("create_pick" == command_name) + { + return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); + } else { llwarns << "Unprocessed command has come: " << command_name << llendl; @@ -791,6 +791,33 @@ void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* own pick_panel = NULL; } +bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept) +{ + *accept = ACCEPT_NO; + + switch (cargo_type) + { + + case DAD_LANDMARK: + case DAD_CATEGORY: + { + bool is_enabled = isActionEnabled("delete"); + + if (is_enabled) *accept = ACCEPT_YES_MULTI; + + if (is_enabled && drop) + { + onClipboardAction("delete"); + } + } + break; + default: + break; + } + + return true; +} + ////////////////////////////////////////////////////////////////////////// // HELPER FUNCTIONS diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 52ad317afe..11d703dcde 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -81,7 +81,7 @@ private: void initLandmarksInventroyPanel(); void initMyInventroyPanel(); void initLibraryInventroyPanel(); - void initLandmarksPanel(LLInventorySubTreePanel* inventory_list, const LLUUID& start_folder_id); + void initLandmarksPanel(LLInventorySubTreePanel* inventory_list); void initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list); void onAccordionExpandedCollapsed(const LLSD& param, LLInventorySubTreePanel* inventory_list); void deselectOtherThan(const LLInventorySubTreePanel* inventory_list); @@ -94,7 +94,7 @@ private: void onAddFolderButtonClick() const; void onTrashButtonClick() const; void onAddAction(const LLSD& command_name) const; - void onCopyPasteAction(const LLSD& command_name) const; + void onClipboardAction(const LLSD& command_name) const; void onFoldingAction(const LLSD& command_name); bool isActionEnabled(const LLSD& command_name) const; void onCustomAction(const LLSD& command_name); @@ -108,6 +108,11 @@ private: bool canSelectedBeModified(const std::string& command_name) const; void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params); + /** + * Processes drag-n-drop of the Landmarks and folders into trash button. + */ + bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept); + private: LLInventorySubTreePanel* mFavoritesInventoryPanel; LLInventorySubTreePanel* mLandmarksInventoryPanel; diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp index 664ebfd7a4..cb9f641bf8 100644 --- a/indra/newview/llpanelpick.cpp +++ b/indra/newview/llpanelpick.cpp @@ -38,6 +38,7 @@ #include "llpanel.h" #include "message.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llbutton.h" #include "lllineeditor.h" #include "llparcel.h" @@ -310,6 +311,7 @@ LLPanelPickEdit::LLPanelPickEdit() : LLPanelPickInfo() , mLocationChanged(false) , mNeedData(true) + , mNewPick(false) { } @@ -325,6 +327,8 @@ void LLPanelPickEdit::onOpen(const LLSD& key) // creating new Pick if(pick_id.isNull()) { + mNewPick = true; + setAvatarId(gAgent.getID()); resetData(); @@ -356,6 +360,7 @@ void LLPanelPickEdit::onOpen(const LLSD& key) // editing existing pick else { + mNewPick = false; LLPanelPickInfo::onOpen(key); enableSaveButton(false); @@ -463,6 +468,14 @@ void LLPanelPickEdit::sendUpdate() pick_data.enabled = TRUE; LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data); + + if(mNewPick) + { + // Assume a successful create pick operation, make new number of picks + // available immediately. Actual number of picks will be requested in + // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond. + LLAgentPicksInfo::getInstance()->incrementNumberOfPicks(); + } } void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl) diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h index c5b13c69ea..9b605cd6b1 100644 --- a/indra/newview/llpanelpick.h +++ b/indra/newview/llpanelpick.h @@ -235,6 +235,7 @@ protected: bool mLocationChanged; bool mNeedData; + bool mNewPick; }; #endif // LL_LLPANELPICK_H diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index d6040c497c..1219a08c6c 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llavatarconstants.h" #include "llflatlistview.h" #include "llfloaterreg.h" @@ -302,14 +303,13 @@ void LLPanelPicks::onDoubleClickItem(LLUICtrl* item) void LLPanelPicks::updateButtons() { - int picks_num = mPicksList->size(); bool has_selected = mPicksList->numSelected(); childSetEnabled(XML_BTN_INFO, has_selected); if (getAvatarId() == gAgentID) { - childSetEnabled(XML_BTN_NEW, picks_num < MAX_AVATAR_PICKS); + childSetEnabled(XML_BTN_NEW, !LLAgentPicksInfo::getInstance()->isPickLimitReached()); childSetEnabled(XML_BTN_DELETE, has_selected); } @@ -364,6 +364,12 @@ void LLPanelPicks::onPanelPickClose(LLPanel* panel) panel->setVisible(FALSE); } +void LLPanelPicks::onPanelPickSave(LLPanel* panel) +{ + onPanelPickClose(panel); + updateButtons(); +} + void LLPanelPicks::createPickInfoPanel() { if(!mPanelPickInfo) @@ -381,7 +387,7 @@ void LLPanelPicks::createPickEditPanel() { mPanelPickEdit = LLPanelPickEdit::create(); mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); - mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); + mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit)); mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit)); mPanelPickEdit->setVisible(FALSE); } diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index 6264a19318..7cf8f2de2a 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -86,6 +86,7 @@ private: void onClickNew(); void onClickInfo(); void onPanelPickClose(LLPanel* panel); + void onPanelPickSave(LLPanel* panel); void onPanelPickEdit(); void onClickMenuEdit(); diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index 2372063fbd..609b205920 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -56,10 +56,12 @@ #include "llagentui.h" #include "llavatarpropertiesprocessor.h" #include "llfloaterworldmap.h" +#include "llfloaterbuycurrency.h" #include "llinventorymodel.h" #include "lllandmarkactions.h" #include "llpanelpick.h" #include "lltexturectrl.h" +#include "llstatusbar.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" @@ -87,7 +89,10 @@ LLPanelPlaceInfo::LLPanelPlaceInfo() mMinHeight(0), mScrollingPanel(NULL), mInfoPanel(NULL), - mMediaPanel(NULL) + mMediaPanel(NULL), + mForSalePanel(NULL), + mYouAreHerePanel(NULL), + mSelectedParcelID(-1) {} LLPanelPlaceInfo::~LLPanelPlaceInfo() @@ -103,14 +108,15 @@ BOOL LLPanelPlaceInfo::postBuild() mTitle = getChild("panel_title"); mCurrentTitle = mTitle->getText(); - mForSaleIcon = getChild("icon_for_sale"); + mForSalePanel = getChild("for_sale_panel"); + mYouAreHerePanel = getChild("here_panel"); + LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLPanelPlaceInfo::updateYouAreHereBanner,this)); + + //Icon value should contain sale price of last selected parcel. + mForSalePanel->getChild("icon_for_sale")-> + setMouseDownCallback(boost::bind(&LLPanelPlaceInfo::onForSaleBannerClick, this)); - // Since this is only used in the directory browser, always - // disable the snapshot control. Otherwise clicking on it will - // open a texture picker. mSnapshotCtrl = getChild("logo"); - mSnapshotCtrl->setEnabled(FALSE); - mRegionName = getChild("region_title"); mParcelName = getChild("parcel_title"); mDescEditor = getChild("description"); @@ -266,7 +272,8 @@ void LLPanelPlaceInfo::resetLocation() mRequestedID.setNull(); mLandmarkID.setNull(); mPosRegion.clearVec(); - mForSaleIcon->setVisible(FALSE); + mForSalePanel->setVisible(FALSE); + mYouAreHerePanel->setVisible(FALSE); std::string not_available = getString("not_available"); mMaturityRatingText->setValue(not_available); mParcelOwner->setValue(not_available); @@ -479,9 +486,9 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) //update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE //because we deal with remote parcel response format - bool isForSale = (parcel_data.flags & DFQ_FOR_SALE) && + bool is_for_sale = (parcel_data.flags & DFQ_FOR_SALE) && mInfoType == AGENT ? TRUE : FALSE; - mForSaleIcon->setVisible(isForSale); + mForSalePanel->setVisible(is_for_sale); S32 region_x; S32 region_y; @@ -797,11 +804,11 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel, } } + mSelectedParcelID = parcel->getLocalID(); + mLastSelectedRegionID = region->getRegionID(); processParcelInfo(parcel_data); - // TODO: If agent is in currently within the selected parcel - // show the "You Are Here" banner. - + mYouAreHerePanel->setVisible(is_current_parcel); getChild("sales_tab")->setVisible(for_sale); } @@ -978,6 +985,50 @@ void LLPanelPlaceInfo::populateFoldersList() mFolderCombo->add(it->second, LLSD(it->first)); } +void LLPanelPlaceInfo::updateYouAreHereBanner() +{ + //YouAreHere Banner should be displayed only for selected places, + // If you want to display it for landmark or teleport history item, you should check by mParcelId + + bool is_you_are_here = false; + if (mSelectedParcelID != S32(-1) && !mLastSelectedRegionID.isNull()) + { + is_you_are_here = gAgent.getRegion()->getRegionID()== mLastSelectedRegionID && + mSelectedParcelID == LLViewerParcelMgr::getInstance()->getAgentParcel()->getLocalID(); + } + mYouAreHerePanel->setVisible(is_you_are_here); +} + +void LLPanelPlaceInfo::onForSaleBannerClick() +{ + LLViewerParcelMgr* mgr = LLViewerParcelMgr::getInstance(); + LLParcelSelectionHandle hParcel = mgr->getFloatingParcelSelection(); + LLViewerRegion* selected_region = mgr->getSelectionRegion(); + if(!hParcel.isNull() && selected_region) + { + if(hParcel->getParcel()->getLocalID() == mSelectedParcelID && + mLastSelectedRegionID ==selected_region->getRegionID()) + { + if(hParcel->getParcel()->getSalePrice() - gStatusBar->getBalance() > 0) + { + LLFloaterBuyCurrency::buyCurrency("Buying selected land ", hParcel->getParcel()->getSalePrice()); + } + else + { + LLViewerParcelMgr::getInstance()->startBuyLand(); + } + } + else + { + LL_WARNS("Places") << "User is trying to buy remote parcel.Operation is not supported"<< LL_ENDL; + } + + } + + +} + + static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) { return left.second < right.second; diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 06fee2224e..7b3a8f050b 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -135,7 +135,12 @@ public: private: void populateFoldersList(); + void updateYouAreHereBanner(); + void onForSaleBannerClick(); + /** + * mParcelID is valid only for remote places, in other cases it's null. See resetLocation() + */ LLUUID mParcelID; LLUUID mRequestedID; LLUUID mLandmarkID; @@ -144,8 +149,15 @@ private: S32 mMinHeight; INFO_TYPE mInfoType; + /** + * Hold last displayed parcel. Needs for YouAreHere banner. + */ + S32 mSelectedParcelID; + LLUUID mLastSelectedRegionID; + LLTextBox* mTitle; - LLIconCtrl* mForSaleIcon; + LLPanel* mForSalePanel; + LLPanel* mYouAreHerePanel; LLTextureCtrl* mSnapshotCtrl; LLTextBox* mRegionName; LLTextBox* mParcelName; diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index f30bb1a0a6..5ab823b6e5 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -50,6 +50,7 @@ #include "lluictrlfactory.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llavatarpropertiesprocessor.h" #include "llfloaterworldmap.h" #include "llinventorybridge.h" @@ -178,6 +179,8 @@ BOOL LLPanelPlaces::postBuild() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("Places.OverflowMenu.Action", boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2)); + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + enable_registrar.add("Places.OverflowMenu.Enable", boost::bind(&LLPanelPlaces::onOverflowMenuItemEnable, this, _2)); mPlaceMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_place.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if (!mPlaceMenu) @@ -606,6 +609,16 @@ void LLPanelPlaces::onOverflowButtonClicked() LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop); } +bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param) +{ + std::string value = param.asString(); + if("can_create_pick" == value) + { + return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); + } + return true; +} + void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param) { std::string item = param.asString(); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 70c50b2058..e2d281dd84 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -77,6 +77,7 @@ private: void onCancelButtonClicked(); void onOverflowButtonClicked(); void onOverflowMenuItemClicked(const LLSD& param); + bool onOverflowMenuItemEnable(const LLSD& param); void onCreateLandmarkButtonClicked(const LLUUID& folder_id); void onBackButtonClicked(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ac1d66157a..8793d22646 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -83,6 +83,7 @@ #include "v3math.h" #include "llagent.h" +#include "llagentpicksinfo.h" #include "llagentwearables.h" #include "llagentpilot.h" #include "llfloateravatarpicker.h" @@ -2602,7 +2603,7 @@ bool idle_startup() // reset timers now that we are running "logged in" logic LLFastTimer::reset(); - + LLAgentPicksInfo::getInstance()->requestNumberOfPicks(); return TRUE; } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 81917ec76e..9ccff0c44e 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -190,7 +190,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("syswell_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("notifications_console", "floater_notifications_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("nearby_chat", "floater_nearby_chat.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 546a06b93f..eca5130426 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -118,6 +118,8 @@ + + diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index a8d3f440c3..9cd7056866 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -18,6 +18,6 @@ left="0" name="favorites_bar_btn" tab_stop="false" - top="10" + top="0" use_ellipses="true" width="120" /> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index 6fbfed5f60..90c5463aa7 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -1,47 +1,31 @@ - - NEARBY CHAT - - - - + width="320"/> diff --git a/indra/newview/skins/default/xui/en/menu_landmark.xml b/indra/newview/skins/default/xui/en/menu_landmark.xml index 54a4095967..93b6db222a 100644 --- a/indra/newview/skins/default/xui/en/menu_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_landmark.xml @@ -28,6 +28,9 @@ + + diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index 9d2d162270..c60f670fa6 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -155,5 +155,8 @@ + diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index 7e78eb8291..b002034a08 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -1,5 +1,6 @@ @@ -127,7 +130,7 @@ picture_style="true" tool_tip="Add new folder" width="18" /> - + + + + + width="365" + can_resize="true" + min_width="200" + min_height="150"> - + width="189" + min_width="189" + user_resize="false" + auto_resize="true"> + width="189" /> - + \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml index be38492c82..9767a673f6 100644 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml @@ -4,7 +4,7 @@ width="146" height="215" border="false"> - + + @@ -131,12 +154,12 @@ diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 4219d9f58f..2fd82d8f3d 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -7,7 +7,13 @@ left="0" name="chat_bar" top="24" - width="510"> + width="310"> + + 310 + + + 320 + - - diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 085b732473..7b19ab1a1c 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -66,11 +66,13 @@ background_visible="true" top="0" width="313"> @@ -139,10 +143,12 @@ background_visible="true" name="tab_all" title="All"> @@ -288,10 +294,12 @@ background_visible="true" name="recent_panel" width="313"> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index ac2cf19a96..cbe1f11e3d 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -71,59 +71,60 @@ width="18" />