From 5612f13dc8693d89cb5c89f8b1a15115742fba8d Mon Sep 17 00:00:00 2001 From: Steven Bennetts Date: Wed, 2 Sep 2009 02:59:07 +0000 Subject: merge https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1516 https://svn.aws.productengine.com/secondlife/pe/stable-2@1526 -> viewer-2.0.0-3 * Bugs: EXT-622 EXT-702 EXT-626 EXT-638 EXT-600 EXT-543 EXT-656 EXT-801 * New Dev: EXT-282 EXT-782 EXT-694 EXT-797 EXT-798 EXT-799 EXT-453 --- indra/llcommon/llchat.h | 10 +- indra/llui/CMakeLists.txt | 2 + indra/llui/llscrollcontainer.cpp | 3 + indra/llui/lluictrl.cpp | 7 + indra/llui/lluictrl.h | 5 + indra/llui/llview.cpp | 14 + indra/llui/llview.h | 3 + indra/newview/CMakeLists.txt | 2 - indra/newview/llavatarlist.cpp | 9 + indra/newview/llbottomtray.cpp | 55 ++- indra/newview/llbottomtray.h | 9 +- indra/newview/llchatmsgbox.cpp | 5 +- indra/newview/llchiclet.cpp | 437 ++++++++++++--------- indra/newview/llchiclet.h | 280 +++++++++---- indra/newview/llimview.cpp | 11 +- indra/newview/llimview.h | 3 + indra/newview/llinventorymodel.cpp | 2 +- indra/newview/llnavigationbar.cpp | 4 +- indra/newview/llnearbychat.cpp | 10 +- indra/newview/llpanelgroup.cpp | 2 + indra/newview/llpanelgroupgeneral.cpp | 14 +- indra/newview/llpanelgrouproles.cpp | 6 + indra/newview/llpanelpeople.cpp | 80 ++++ indra/newview/llpanelpicks.cpp | 189 ++------- indra/newview/llpanelpicks.h | 25 +- indra/newview/llpanelplaceinfo.cpp | 248 +++++++++++- indra/newview/llpanelplaceinfo.h | 39 +- indra/newview/llpanelplaces.cpp | 14 +- indra/newview/llpanelplaces.h | 2 +- indra/newview/llpanelprofileview.cpp | 42 +- indra/newview/llpanelprofileview.h | 7 +- indra/newview/llsyswellwindow.cpp | 217 +++++++++- indra/newview/llsyswellwindow.h | 44 ++- indra/newview/llviewermessage.cpp | 24 ++ .../skins/default/textures/places_rating_adult.tga | Bin 0 -> 648 bytes .../default/textures/places_rating_mature.tga | Bin 0 -> 1068 bytes .../skins/default/textures/places_rating_pg.tga | Bin 0 -> 1068 bytes .../skins/default/xui/en/floater_activeim.xml | 7 +- .../skins/default/xui/en/floater_sys_well.xml | 52 ++- .../skins/default/xui/en/panel_activeim_row.xml | 64 +-- .../skins/default/xui/en/panel_bottomtray.xml | 36 +- .../default/xui/en/panel_group_info_sidetray.xml | 1 + .../newview/skins/default/xui/en/panel_people.xml | 20 +- indra/newview/skins/default/xui/en/panel_picks.xml | 4 +- .../skins/default/xui/en/panel_profile_view.xml | 8 + .../newview/skins/default/xui/en/widgets/list.xml | 9 + 46 files changed, 1392 insertions(+), 633 deletions(-) create mode 100644 indra/newview/skins/default/textures/places_rating_adult.tga create mode 100644 indra/newview/skins/default/textures/places_rating_mature.tga create mode 100644 indra/newview/skins/default/textures/places_rating_pg.tga create mode 100644 indra/newview/skins/default/xui/en/widgets/list.xml diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 7b010d6739..acd0da61a4 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -65,6 +65,12 @@ typedef enum e_chat_audible_level CHAT_AUDIBLE_FULLY = 1 } EChatAudible; +typedef enum e_chat_style +{ + CHAT_STYLE_NORMAL, + CHAT_STYLE_IRC +}EChatStyle; + // A piece of chat class LLChat { @@ -79,7 +85,8 @@ public: mMuted(FALSE), mTime(0.0), mPosAgent(), - mURL() + mURL(), + mChatStyle(CHAT_STYLE_NORMAL) { } std::string mText; // UTF-8 line of text @@ -92,6 +99,7 @@ public: F64 mTime; // viewer only, seconds from viewer start LLVector3 mPosAgent; std::string mURL; + EChatStyle mChatStyle; }; #endif diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 8b0fcc68c4..a7f899ce41 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -48,6 +48,7 @@ set(llui_SOURCE_FILES lllayoutstack.cpp lllineeditor.cpp lllink.cpp + lllistctrl.cpp llmenugl.cpp llmodaldialog.cpp llmultifloater.cpp @@ -124,6 +125,7 @@ set(llui_HEADER_FILES lllazyvalue.h lllineeditor.h lllink.h + lllistctrl.h llmenugl.h llmodaldialog.h llmultifloater.h diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 13f862f3af..556ff80991 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -66,9 +66,12 @@ static LLDefaultChildRegistry::Register r("scroll_container") #include "llscrollingpanellist.h" #include "llcontainerview.h" #include "llpanel.h" +#include "lllistctrl.h" + static ScrollContainerRegistry::Register r1("scrolling_panel_list"); static ScrollContainerRegistry::Register r2("container_view"); static ScrollContainerRegistry::Register r3("panel", &LLPanel::fromXML); +static ScrollContainerRegistry::Register r4("list"); LLScrollContainer::Params::Params() : is_opaque("opaque"), diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 7ff942268d..1ab04054ff 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -257,6 +257,13 @@ BOOL LLUICtrl::handleRightMouseUp(S32 x, S32 y, MASK mask) return handled; } +BOOL LLUICtrl::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + BOOL handled = LLView::handleDoubleClick(x, y, mask); + mDoubleClickSignal(this, x, y, mask); + return handled; +} + // can't tab to children of a non-tab-stop widget BOOL LLUICtrl::canFocusChildren() const { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 3e2e1f41a1..5011adcfe9 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -166,6 +166,7 @@ public: /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); + /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // From LLFocusableElement /*virtual*/ void setFocus( BOOL b ); @@ -239,6 +240,8 @@ public: boost::signals2::connection setRightMouseDownCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseDownSignal.connect(cb); } boost::signals2::connection setRightMouseUpCallback( const mouse_signal_t::slot_type& cb ) { return mRightMouseUpSignal.connect(cb); } + boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb ) { return mDoubleClickSignal.connect(cb); } + // *TODO: Deprecate; for backwards compatability only: boost::signals2::connection setCommitCallback( boost::function cb, void* data); boost::signals2::connection setValidateBeforeCommit( boost::function cb ); @@ -273,6 +276,8 @@ protected: mouse_signal_t mMouseUpSignal; mouse_signal_t mRightMouseDownSignal; mouse_signal_t mRightMouseUpSignal; + + mouse_signal_t mDoubleClickSignal; LLViewModelPtr mViewModel; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 4770807ac7..83d45f0dfa 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -2735,3 +2735,17 @@ LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const } return *mDefaultWidgets; } +void LLView::notifyParent(const LLSD& info) +{ + LLView* parent = getParent(); + if(parent) + parent->notifyParent(info); +} +void LLView::notifyChilds(const LLSD& info) +{ + for ( child_list_iter_t child_it = mChildList.begin(); child_it != mChildList.end(); ++child_it) + { + (*child_it)->notifyChilds(info); + } +} + diff --git a/indra/llui/llview.h b/indra/llui/llview.h index ecc6bf47da..87298b5292 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -549,6 +549,9 @@ public: virtual void handleReshape(const LLRect& rect, bool by_user); + virtual void notifyParent(const LLSD& info); + virtual void notifyChilds(const LLSD& info); + protected: void drawDebugRect(); void drawChild(LLView* childp, S32 x_offset = 0, S32 y_offset = 0, BOOL force_draw = FALSE); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b95c5d46dd..05459cfcac 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -66,7 +66,6 @@ include_directories( set(viewer_SOURCE_FILES llaccordionctrltab.cpp llaccordionctrl.cpp - llactiveimwindow.cpp llagent.cpp llagentaccess.cpp llagentdata.cpp @@ -518,7 +517,6 @@ set(viewer_HEADER_FILES ViewerInstall.cmake llaccordionctrltab.h llaccordionctrl.h - llactiveimwindow.h llagent.h llagentaccess.h llagentdata.h diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index f557adf6a6..080d540f4a 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -220,6 +220,15 @@ BOOL LLAvatarList::update(const std::vector& all_buddies, const std::str #endif setScrollPos(pos); + LLRect rect = getRequiredRect(); + + LLSD params; + params["action"] = "size_changes"; + params["width"] = rect.getWidth(); + params["height"] = rect.getHeight(); + + getParent()->notifyParent(params); + return have_names; } diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 2403e891f6..fe13d4f652 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -40,13 +40,12 @@ #include "lllayoutstack.h" #include "llnearbychatbar.h" #include "llsplitbutton.h" +#include "llsyswellwindow.h" #include "llfloatercamera.h" #include "llimpanel.h" -#include "llactiveimwindow.h" LLBottomTray::LLBottomTray(const LLSD&) : mChicletPanel(NULL), - mIMWell(NULL), mSysWell(NULL), mTalkBtn(NULL), mNearbyChatBar(NULL), @@ -58,10 +57,11 @@ LLBottomTray::LLBottomTray(const LLSD&) LLUICtrlFactory::getInstance()->buildPanel(this,"panel_bottomtray.xml"); mChicletPanel = getChild("chiclet_list"); - mIMWell = getChild("im_well"); mSysWell = getChild("sys_well"); mSysWell->setNotificationChicletWindow(LLFloaterReg::getInstance("syswell_window")); + LLFloaterReg::getTypedInstance("syswell_window")->setSysWell(mSysWell); + mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1)); LLSplitButton* presets = getChild("presets"); @@ -76,8 +76,6 @@ LLBottomTray::LLBottomTray(const LLSD&) // Necessary for focus movement among child controls setFocusRoot(TRUE); - - LLActiveIMWindow::init(mIMWell); } BOOL LLBottomTray::postBuild() @@ -119,6 +117,34 @@ void* LLBottomTray::createNearbyChatBar(void* userdata) return new LLNearbyChatBar(); } +LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id) +{ + if(session_id.isNull()) + { + return NULL; + } + + LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id); + if (!im) + { + return NULL; //should never happen + } + + switch(im->getDialogType()) + { + case IM_NOTHING_SPECIAL: + return getChicletPanel()->createChiclet(session_id); + break; + case IM_SESSION_GROUP_START: + case IM_SESSION_INVITE: + return getChicletPanel()->createChiclet(session_id); + break; + default: + return NULL; + break; + } +} + //virtual void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) { @@ -130,12 +156,18 @@ void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& nam } else { - LLIMChiclet* chiclet = getChicletPanel()->createChiclet(session_id); - chiclet->setIMSessionName(name); - chiclet->setOtherParticipantId(other_participant_id); + LLIMChiclet* chiclet = createIMChiclet(session_id); + if(chiclet) + { + chiclet->setIMSessionName(name); + chiclet->setOtherParticipantId(other_participant_id); + } + else + { + llerrs << "Could not create chiclet" << llendl; + } } } - updateImChicletCount(); } //virtual @@ -145,7 +177,6 @@ void LLBottomTray::sessionRemoved(const LLUUID& session_id) { getChicletPanel()->removeChiclet(session_id); } - updateImChicletCount(); } //virtual @@ -185,7 +216,3 @@ void LLBottomTray::setVisible(BOOL visible) } } -void LLBottomTray::updateImChicletCount() { - U32 chicletCount = mChicletPanel->getChicletCount(); - mIMWell->setCounter(chicletCount); -} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index 7f606339bc..a8fe65a9d3 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -42,6 +42,7 @@ class LLLayoutStack; class LLNotificationChiclet; class LLTalkButton; class LLNearbyChatBar; +class LLIMChiclet; class LLBottomTray : public LLSingleton @@ -55,7 +56,6 @@ public: BOOL postBuild(); LLChicletPanel* getChicletPanel() {return mChicletPanel;} - LLNotificationChiclet* getIMWell() {return mIMWell;} LLNotificationChiclet* getSysWell() {return mSysWell;} LLNearbyChatBar* getNearbyChatBar() {return mNearbyChatBar;} @@ -69,7 +69,6 @@ public: virtual void setVisible(BOOL visible); private: - void updateImChicletCount(); protected: @@ -79,8 +78,12 @@ protected: static void* createNearbyChatBar(void* userdata); + /** + * Creates IM Chiclet based on session type (IM chat or Group chat) + */ + LLIMChiclet* createIMChiclet(const LLUUID& session_id); + LLChicletPanel* mChicletPanel; - LLNotificationChiclet* mIMWell; LLNotificationChiclet* mSysWell; LLTalkButton* mTalkBtn; LLNearbyChatBar* mNearbyChatBar; diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index 9399e1f68d..fb5ab8ec5a 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -239,8 +239,9 @@ std::string LLChatMsgBox::wrapText(const LLStringExplicit& in_text, F32 max_widt { if (wtext[cur] == '\n') cur += 1; - else - final_wtext += '\n'; + + // There is no need to to cut line ending symbols found in origin string, see EXT-702. + final_wtext += '\n'; } } diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 6b4dfa73a4..1109d8174f 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -47,13 +47,11 @@ #include "llvoicecontrolpanel.h" #include "llgroupmgr.h" -static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu"; -static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu"; - static LLDefaultChildRegistry::Register t1("chiclet_panel"); static LLDefaultChildRegistry::Register t2("chiclet_talk"); static LLDefaultChildRegistry::Register t3("chiclet_notification"); -static LLDefaultChildRegistry::Register t4("chiclet_im"); +static LLDefaultChildRegistry::Register t4("chiclet_im_p2p"); +static LLDefaultChildRegistry::Register t5("chiclet_im_group"); S32 LLNotificationChiclet::mUreadSystemNotifications = 0; S32 LLNotificationChiclet::mUreadIMNotifications = 0; @@ -187,9 +185,48 @@ void LLChiclet::setValue(const LLSD& value) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -LLIMChiclet::Params::Params() +LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p) +: LLChiclet(p) +{ +} + +void LLIMChiclet::onMouseDown() +{ + LLIMFloater::toggle(getSessionId()); + setCounter(0); +} + +BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask) +{ + onMouseDown(); + return LLChiclet::handleMouseDown(x, y, mask); +} + +void LLIMChiclet::draw() +{ + LLUICtrl::draw(); + + //if we have a docked floater, we want to position it relative to us + LLIMFloater* im_floater = LLFloaterReg::findTypedInstance("impanel", getSessionId()); + + if (im_floater && im_floater->isDocked()) + { + S32 x, y; + getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y); + im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom); + //set this so the docked floater knows it's been positioned and can now draw + im_floater->setPositioned(true); + } + + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLIMP2PChiclet::Params::Params() : avatar_icon("avatar_icon") -, group_insignia("group_insignia") , unread_notifications("unread_notifications") , speaker("speaker") , show_speaker("show_speaker") @@ -197,14 +234,8 @@ LLIMChiclet::Params::Params() rect(LLRect(0, 25, 45, 0)); avatar_icon.name("avatar_icon"); - avatar_icon.visible(false); avatar_icon.rect(LLRect(0, 25, 25, 0)); - //it's an icon for a group in case there is a group chat created - group_insignia.name("group_icon"); - group_insignia.visible(false); - group_insignia.rect(LLRect(0, 25, 25, 0)); - unread_notifications.name("unread"); unread_notifications.rect(LLRect(25, 25, 45, 0)); unread_notifications.font(LLFontGL::getFontSansSerif()); @@ -218,25 +249,16 @@ LLIMChiclet::Params::Params() show_speaker = false; } -LLIMChiclet::LLIMChiclet(const Params& p) -: LLChiclet(p) -, LLGroupMgrObserver(LLUUID()) -, mAvatarCtrl(NULL) -, mGroupInsignia(NULL) +LLIMP2PChiclet::LLIMP2PChiclet(const Params& p) +: LLIMChiclet(p) +, mChicletIconCtrl(NULL) , mCounterCtrl(NULL) , mSpeakerCtrl(NULL) -, mShowSpeaker(p.show_speaker) , mPopupMenu(NULL) { LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon; - mAvatarCtrl = LLUICtrlFactory::create(avatar_params); - addChild(mAvatarCtrl); - - //Before setOtherParticipantId() we are UNAWARE which dialog type will it be - //so keeping both icons for all both p2p and group chat cases - LLIconCtrl::Params grop_icon_params = p.group_insignia; - mGroupInsignia = LLUICtrlFactory::create(grop_icon_params); - addChild(mGroupInsignia); + mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); + addChild(mChicletIconCtrl); LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; mCounterCtrl = LLUICtrlFactory::create(unread_params); @@ -249,16 +271,10 @@ LLIMChiclet::LLIMChiclet(const Params& p) mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); addChild(mSpeakerCtrl); - setShowSpeaker(getShowSpeaker()); -} - -LLIMChiclet::~LLIMChiclet() -{ - LLGroupMgr::getInstance()->removeObserver(this); + setShowSpeaker(p.show_speaker); } - -void LLIMChiclet::setCounter(S32 counter) +void LLIMP2PChiclet::setCounter(S32 counter) { mCounterCtrl->setCounter(counter); @@ -279,15 +295,9 @@ void LLIMChiclet::setCounter(S32 counter) } } -void LLIMChiclet::onMouseDown() +LLRect LLIMP2PChiclet::getRequiredRect() { - LLIMFloater::toggle(getSessionId()); - setCounter(0); -} - -LLRect LLIMChiclet::getRequiredRect() -{ - LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0); + LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0); if(getShowCounter()) { rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); @@ -299,169 +309,234 @@ LLRect LLIMChiclet::getRequiredRect() return rect; } -void LLIMChiclet::setShowCounter(bool show) +void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id) { - bool needs_resize = getShowCounter() != show; - - LLChiclet::setShowCounter(show); - mCounterCtrl->setVisible(getShowCounter()); - - if(needs_resize) - { - onChicletSizeChanged(); - } + LLIMChiclet::setOtherParticipantId(other_participant_id); + mChicletIconCtrl->setValue(getOtherParticipantId()); } - -void LLIMChiclet::setSessionId(const LLUUID& session_id) +void LLIMP2PChiclet::updateMenuItems() { - LLChiclet::setSessionId(session_id); + if(!mPopupMenu) + return; + if(getSessionId().isNull()) + return; - //for a group chat session_id = group_id - LLFloaterIMPanel* im = LLIMMgr::getInstance()->findFloaterBySession(session_id); - if (!im) return; //should never happen - - EInstantMessage type = im->getDialogType(); - if (type == IM_SESSION_INVITE || type == IM_SESSION_GROUP_START) - { - if (!gAgent.isInGroup(session_id)) return; + bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); - if (mGroupInsignia) { - LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); - LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); - if (group_data && group_data->mInsigniaID.notNull()) - { - mGroupInsignia->setVisible(TRUE); - mGroupInsignia->setValue(group_data->mInsigniaID); - } - else - { - mID = session_id; //needed for LLGroupMgrObserver - grp_mgr->addObserver(this); - grp_mgr->sendGroupPropertiesRequest(session_id); - } - } - } + mPopupMenu->getChild("Add Friend")->setEnabled(!is_friend); + mPopupMenu->getChild("Remove Friend")->setEnabled(is_friend); } -void LLIMChiclet::setIMSessionName(const std::string& name) +BOOL LLIMP2PChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - setToolTip(name); + if(!mPopupMenu) + { + createPopupMenu(); + } + + if (mPopupMenu) + { + updateMenuItems(); + mPopupMenu->arrangeAndClear(); + LLMenuGL::showPopup(this, mPopupMenu, x, y); + } + + return TRUE; } -//session id should be set before calling this -void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id) +void LLIMP2PChiclet::createPopupMenu() { - llassert(getSessionId().notNull()); + if(mPopupMenu) + { + llwarns << "Menu already exists" << llendl; + return; + } + if(getSessionId().isNull()) + { + return; + } - LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2)); - //all alive sessions have alive floater, haven't they? - llassert(floater); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +} - mOtherParticipantId = other_participant_id; +void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data) +{ + std::string level = user_data.asString(); + LLUUID other_participant_id = getOtherParticipantId(); - if (mAvatarCtrl && floater->getDialogType() == IM_NOTHING_SPECIAL) + if("profile" == level) + { + LLAvatarActions::showProfile(other_participant_id); + } + else if("im" == level) + { + LLAvatarActions::startIM(other_participant_id); + } + else if("add" == level) { - mAvatarCtrl->setVisible(TRUE); - mAvatarCtrl->setValue(other_participant_id); + LLAvatarActions::requestFriendshipDialog(other_participant_id); } } - -void LLIMChiclet::changed(LLGroupChange gc) +void LLIMP2PChiclet::setShowSpeaker(bool show) { - LLSD group_insignia = mGroupInsignia->getValue(); - if (group_insignia.isUUID() && group_insignia.asUUID().notNull()) return; + LLIMChiclet::setShowSpeaker(show); - if (GC_PROPERTIES == gc) + bool needs_resize = getShowSpeaker() != show; + mSpeakerCtrl->setVisible(getShowSpeaker()); + if(needs_resize) { - LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); - if (group_data && group_data->mInsigniaID.notNull()) - { - mGroupInsignia->setVisible(TRUE); - mGroupInsignia->setValue(group_data->mInsigniaID); - } + onChicletSizeChanged(); } } -LLUUID LLIMChiclet::getOtherParticipantId() +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +LLIMGroupChiclet::Params::Params() +: group_icon("group_icon") { - return mOtherParticipantId; + rect(LLRect(0, 25, 45, 0)); + + group_icon.name("group_icon"); + group_icon.rect(LLRect(0, 25, 25, 0)); + + 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); + + speaker.name("speaker"); + speaker.rect(LLRect(45, 25, 65, 0)); + + show_speaker = false; } -void LLIMChiclet::updateMenuItems() +LLIMGroupChiclet::LLIMGroupChiclet(const Params& p) +: LLIMChiclet(p) +, LLGroupMgrObserver(LLUUID::null) +, mChicletIconCtrl(NULL) +, mCounterCtrl(NULL) +, mSpeakerCtrl(NULL) +, mPopupMenu(NULL) { - if(!mPopupMenu) - return; - if(getSessionId().isNull()) - return; + LLChicletGroupIconCtrl::Params avatar_params = p.group_icon; + mChicletIconCtrl = LLUICtrlFactory::create(avatar_params); + addChild(mChicletIconCtrl); - if(P2P_MENU_NAME == mPopupMenu->getName()) - { - bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId()); + LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications; + mCounterCtrl = LLUICtrlFactory::create(unread_params); + addChild(mCounterCtrl); - mPopupMenu->getChild("Add Friend")->setEnabled(!is_friend); - mPopupMenu->getChild("Remove Friend")->setEnabled(is_friend); - } + setCounter(getCounter()); + setShowCounter(getShowCounter()); + + LLChicletSpeakerCtrl::Params speaker_params = p.speaker; + mSpeakerCtrl = LLUICtrlFactory::create(speaker_params); + addChild(mSpeakerCtrl); + + setShowSpeaker(p.show_speaker); } -BOOL LLIMChiclet::handleMouseDown(S32 x, S32 y, MASK mask) +LLIMGroupChiclet::~LLIMGroupChiclet() { - onMouseDown(); - return LLChiclet::handleMouseDown(x, y, mask); + LLGroupMgr::getInstance()->removeObserver(this); } -void LLIMChiclet::setShowSpeaker(bool show) +void LLIMGroupChiclet::setCounter(S32 counter) { - bool needs_resize = getShowSpeaker() != show; - - mShowSpeaker = show; - mSpeakerCtrl->setVisible(getShowSpeaker()); + mCounterCtrl->setCounter(counter); - if(needs_resize) + if(getShowCounter()) { - onChicletSizeChanged(); + 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(); + } } } -void LLIMChiclet::draw() +LLRect LLIMGroupChiclet::getRequiredRect() { - LLUICtrl::draw(); + LLRect rect(0, 0, mChicletIconCtrl->getRect().getWidth(), 0); + if(getShowCounter()) + { + rect.mRight += mCounterCtrl->getRequiredRect().getWidth(); + } + if(getShowSpeaker()) + { + rect.mRight += mSpeakerCtrl->getRect().getWidth(); + } + return rect; +} - //if we have a docked floater, we want to position it relative to us - LLIMFloater* im_floater = LLFloaterReg::findTypedInstance("impanel", getSessionId()); +void LLIMGroupChiclet::setSessionId(const LLUUID& session_id) +{ + LLChiclet::setSessionId(session_id); - if (im_floater && im_floater->isDocked()) + LLGroupMgr* grp_mgr = LLGroupMgr::getInstance(); + LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id); + if (group_data && group_data->mInsigniaID.notNull()) { - S32 x, y; - getParent()->localPointToScreen(getRect().getCenterX(), 0, &x, &y); - im_floater->translate(x - im_floater->getRect().getCenterX(), 10 - im_floater->getRect().mBottom); - //set this so the docked floater knows it's been positioned and can now draw - im_floater->setPositioned(true); + mChicletIconCtrl->setValue(group_data->mInsigniaID); } + else + { + if(getSessionId() != mID) + { + grp_mgr->removeObserver(this); + mID = getSessionId(); + grp_mgr->addObserver(this); + } + grp_mgr->sendGroupPropertiesRequest(session_id); + } +} - gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE); +void LLIMGroupChiclet::changed(LLGroupChange gc) +{ + if (GC_PROPERTIES == gc) + { + LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId()); + if (group_data) + { + mChicletIconCtrl->setValue(group_data->mInsigniaID); + } + } } -BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) +BOOL LLIMGroupChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { if(!mPopupMenu) + { createPopupMenu(); - - updateMenuItems(); + } if (mPopupMenu) { mPopupMenu->arrangeAndClear(); + LLMenuGL::showPopup(this, mPopupMenu, x, y); } - - LLMenuGL::showPopup(this, mPopupMenu, x, y); return TRUE; } -void LLIMChiclet::createPopupMenu() +void LLIMGroupChiclet::createPopupMenu() { if(mPopupMenu) { @@ -469,55 +544,41 @@ void LLIMChiclet::createPopupMenu() return; } if(getSessionId().isNull()) + { return; - - LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId()); - if(!floater) - return; + } LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2)); + registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2)); - switch(floater->getDialogType()) - { - case IM_SESSION_GROUP_START: - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - break; - case IM_NOTHING_SPECIAL: - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile - ("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - break; - default: - llwarns << "Unexpected dialog type" << llendl; - break; - } + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile + ("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); } -void LLIMChiclet::onMenuItemClicked(const LLSD& user_data) +void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data) { std::string level = user_data.asString(); - LLUUID other_participant_id = getOtherParticipantId(); + LLUUID group_id = getSessionId(); - if("profile" == level) + if("group chat" == level) { - LLAvatarActions::showProfile(other_participant_id); + LLGroupActions::startChat(group_id); } - else if("im" == level) - { - LLAvatarActions::startIM(other_participant_id); - } - else if("add" == level) - { - LLAvatarActions::requestFriendshipDialog(other_participant_id); - } - else if("group chat" == level) + else if("info" == level) { - LLGroupActions::startChat(other_participant_id); + LLGroupActions::show(group_id); } - else if("info" == level) +} + +void LLIMGroupChiclet::setShowSpeaker(bool show) +{ + LLIMChiclet::setShowSpeaker(show); + + bool needs_resize = getShowSpeaker() != show; + mSpeakerCtrl->setVisible(getShowSpeaker()); + if(needs_resize) { - LLGroupActions::show(other_participant_id); + onChicletSizeChanged(); } } @@ -1178,6 +1239,28 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p) ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p) +: LLIconCtrl(p) +, mDefaultIcon(p.default_icon) +{ +} + +void LLChicletGroupIconCtrl::setValue(const LLSD& value ) +{ + if(value.asUUID().isNull()) + { + LLIconCtrl::setValue(mDefaultIcon); + } + else + { + LLIconCtrl::setValue(value); + } +} + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p) : LLIconCtrl(p) { diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index b1e73c9d8d..ba202515a8 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -95,7 +95,7 @@ private: }; /* - * Class for displaying avatar's icon. + * Class for displaying avatar's icon in P2P chiclet. */ class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl { @@ -116,6 +116,36 @@ protected: friend class LLUICtrlFactory; }; +/** + * Class for displaying group's icon in Group chiclet. + */ +class LLChicletGroupIconCtrl : public LLIconCtrl +{ +public: + + struct Params : public LLInitParam::Block + { + Optional default_icon; + + Params() + : default_icon("default_icon", "default_land_picture.j2c") + { + }; + }; + + /** + * Sets icon, if value is LLUUID::null - default icon will be set. + */ + virtual void setValue(const LLSD& value ); + +protected: + + LLChicletGroupIconCtrl(const Params& p); + friend class LLUICtrlFactory; + + std::string mDefaultIcon; +}; + /* * Class for displaying status of Voice Chat */ @@ -231,75 +261,46 @@ private: chiclet_size_changed_signal_t mChicletSizeChangedSignal; }; + /* -* Implements Instant Message chiclet. -* IMChiclet displays avatar's icon, number of unread messages(optional) +* Base class for Instant Message chiclets. +* IMChiclet displays icon, number of unread messages(optional) * and voice chat status(optional). +* Every chiclet should override LLUICtrl::getRequiredRect and return +* desired width. */ -class LLIMChiclet : public LLChiclet, LLGroupMgrObserver +class LLIMChiclet : public LLChiclet { public: - struct Params : public LLInitParam::Block - { - Optional avatar_icon; - - Optional group_insignia; - - Optional unread_notifications; - - Optional speaker; - - Optional show_speaker; - - Params(); - }; - - /*virtual*/ ~LLIMChiclet(); - - virtual void setSessionId(const LLUUID& session_id); + + /*virtual*/ ~LLIMChiclet() {}; /* * Sets IM session name. This name will be displayed in chiclet tooltip. */ - virtual void setIMSessionName(const std::string& name); + virtual void setIMSessionName(const std::string& name) { setToolTip(name); } /* * Sets id of person/group user is chatting with. * Session id should be set before calling this */ - virtual void setOtherParticipantId(const LLUUID& other_participant_id); + virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; } /* * Gets id of person/group user is chatting with. */ - virtual LLUUID getOtherParticipantId(); + virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; } /* * Shows/hides voice chat status control. */ - virtual void setShowSpeaker(bool show); + virtual void setShowSpeaker(bool show) { mShowSpeaker = show; } /* * Returns voice chat status control visibility. */ virtual bool getShowSpeaker() {return mShowSpeaker;}; - /* - * Sets number of unread messages. Will update chiclet's width if number text - * exceeds size of counter and notify it's parent about size change. - */ - /*virtual*/ void setCounter(S32); - - /* - * Returns number of unread messages. - */ - /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } - - /* - * Shows/hides number of unread messages. - */ - /*virtual*/ void setShowCounter(bool show); - /* * Draws border around chiclet. */ @@ -313,52 +314,13 @@ public: */ void onMouseDown(); - /* - * Returns rect, required to display chiclet. - * Width is the only valid value. - */ - /*virtual*/ LLRect getRequiredRect(); - - /** comes from LLGroupMgrObserver */ - virtual void changed(LLGroupChange gc); - protected: - LLIMChiclet(const Params& p); - friend class LLUICtrlFactory; - - /* - * Creates chiclet popup menu. Will create P2P or Group IM Chat menu - * based on other participant's id. - */ - virtual void createPopupMenu(); - - /* - * Processes clicks on chiclet popup menu. - */ - virtual void onMenuItemClicked(const LLSD& user_data); - - /* - * Enables/disables menus based on relationship with other participant. - */ - virtual void updateMenuItems(); - - /* - * Displays popup menu. - */ - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + LLIMChiclet(const LLChiclet::Params& p); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); protected: - LLChicletAvatarIconCtrl* mAvatarCtrl; - - /** the icon of a group in case of group chat */ - LLIconCtrl* mGroupInsignia; - LLChicletNotificationCounterCtrl* mCounterCtrl; - LLChicletSpeakerCtrl* mSpeakerCtrl; - - LLMenuGL* mPopupMenu; bool mShowSpeaker; @@ -387,6 +349,160 @@ public: sFindChicletsSignal; }; +/** + * Implements P2P chiclet. + */ +class LLIMP2PChiclet : public LLIMChiclet +{ +public: + struct Params : public LLInitParam::Block + { + Optional avatar_icon; + + Optional unread_notifications; + + Optional speaker; + + Optional show_speaker; + + Params(); + }; + + void setOtherParticipantId(const LLUUID& other_participant_id); + + /*virtual*/ void setShowSpeaker(bool show); + + /* + * Sets number of unread messages. Will update chiclet's width if number text + * exceeds size of counter and notify it's parent about size change. + */ + /*virtual*/ void setCounter(S32); + + /* + * Returns number of unread messages. + */ + /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + + /* + * Returns rect, required to display chiclet. + * Width is the only valid value. + */ + /*virtual*/ LLRect getRequiredRect(); + +protected: + LLIMP2PChiclet(const Params& p); + friend class LLUICtrlFactory; + + /* + * Creates chiclet popup menu. Will create P2P or Group IM Chat menu + * based on other participant's id. + */ + virtual void createPopupMenu(); + + /* + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); + + /* + * Displays popup menu. + */ + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + + /* + * Enables/disables menus based on relationship with other participant. + */ + virtual void updateMenuItems(); + +private: + + LLChicletAvatarIconCtrl* mChicletIconCtrl; + LLChicletNotificationCounterCtrl* mCounterCtrl; + LLChicletSpeakerCtrl* mSpeakerCtrl; + LLMenuGL* mPopupMenu; +}; + +/** + * Implements Group chat chiclet. + */ +class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver +{ +public: + + struct Params : public LLInitParam::Block + { + Optional group_icon; + + Optional unread_notifications; + + Optional speaker; + + Optional show_speaker; + + Params(); + }; + + /** + * Sets session id. + * Session ID for group chat is actually Group ID. + */ + /*virtual*/ void setSessionId(const LLUUID& session_id); + + /** + * Callback for LLGroupMgrObserver, we get this when group data is available or changed. + * Sets group icon. + */ + /*virtual*/ void changed(LLGroupChange gc); + + /*virtual*/ void setShowSpeaker(bool show); + + /* + * Sets number of unread messages. Will update chiclet's width if number text + * exceeds size of counter and notify it's parent about size change. + */ + /*virtual*/ void setCounter(S32); + + /* + * Returns number of unread messages. + */ + /*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); } + + /* + * Returns rect, required to display chiclet. + * Width is the only valid value. + */ + /*virtual*/ LLRect getRequiredRect(); + + ~LLIMGroupChiclet(); + +protected: + LLIMGroupChiclet(const Params& p); + friend class LLUICtrlFactory; + + /* + * Creates chiclet popup menu. Will create P2P or Group IM Chat menu + * based on other participant's id. + */ + virtual void createPopupMenu(); + + /* + * Processes clicks on chiclet popup menu. + */ + virtual void onMenuItemClicked(const LLSD& user_data); + + /* + * Displays popup menu. + */ + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + +private: + + LLChicletGroupIconCtrl* mChicletIconCtrl; + LLChicletNotificationCounterCtrl* mCounterCtrl; + LLChicletSpeakerCtrl* mSpeakerCtrl; + LLMenuGL* mPopupMenu; +}; + /* * Implements notification chiclet. Used to display total amount of unread messages * across all IM sessions, total amount of system notifications. diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 5272bc2165..c1a5f21010 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1338,7 +1338,10 @@ S32 LLIMMgr::getNumberOfUnreadIM() S32 num = 0; for(it = LLIMModel::sSessionsMap.begin(); it != LLIMModel::sSessionsMap.end(); ++it) { - num += (*it).second->mNumUnread; + if((*it).first != mBeingRemovedSessionID) + { + num += (*it).second->mNumUnread; + } } return num; @@ -1460,6 +1463,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id) clearPendingInvitation(session_id); clearPendingAgentListUpdates(session_id); } + + // for some purposes storing ID of a sessios that is being removed + mBeingRemovedSessionID = session_id; notifyObserverSessionRemoved(session_id); //if we don't clear session data on removing the session @@ -1467,6 +1473,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id) //creating chiclets only on session created even, we need to handle chiclets creation //the same way as LLFloaterIMPanels were managed. LLIMModel::getInstance()->clearSession(session_id); + + // now this session is completely removed + mBeingRemovedSessionID.setNull(); } void LLIMMgr::inviteToSession( diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index ce6f0394dd..aed3b68471 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -264,6 +264,9 @@ private: LLSD mPendingInvitations; LLSD mPendingAgentListUpdates; + // ID of a session that is being removed: observers are already told + // that this session is being removed, but it is still present in the sessions' map + LLUUID mBeingRemovedSessionID; }; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index aadda3fbfd..8062da0dfe 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1112,7 +1112,7 @@ void LLInventoryModel::notifyObservers(const std::string service_name) observer->changed(mModifyMask); } - // safe way to incrament since changed may delete entries! (@!##%@!@&*!) + // safe way to increment since changed may delete entries! (@!##%@!@&*!) iter = mObservers.upper_bound(observer); } diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index e40568a0cb..28e9c93779 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -413,7 +413,9 @@ void LLNavigationBar::rebuildTeleportHistoryMenu() LLTeleportHistoryMenuItem::Params item_params(type, hist_items[i].getTitle()); item_params.on_click.function(boost::bind(&LLNavigationBar::onTeleportHistoryMenuItemClicked, this, i)); - mTeleportHistoryMenu->addChild(LLUICtrlFactory::create(item_params)); + LLTeleportHistoryMenuItem* new_itemp = LLUICtrlFactory::create(item_params); + //new_itemp->setFont() + mTeleportHistoryMenu->addChild(new_itemp); } } diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 3856a86da0..6150d5da37 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -183,9 +183,13 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat) void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color) { - std::string line = chat.mFromName; - line +=": "; - line +=chat.mText; + std::string line = chat.mText; + + //chat.mText starts with Avatar Name if entered message was "/me ". + // In this case output chat message should be " ". See EXT-656 + // See also process_chat_from_simulator() in the llviewermessage.cpp where ircstyle = TRUE; + if (CHAT_STYLE_IRC != chat.mChatStyle) + line = chat.mFromName + ": " + line; bool prepend_newline = true; if (gSavedSettings.getBOOL("ChatShowTimestamps")) diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 4cbb018ce9..d1ce6b14ed 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -298,6 +298,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) if(button_create) button_create->setVisible(is_null_group_id); + getChild("prepend_founded_by")->setVisible(!is_null_group_id); + LLAccordionCtrlTab* tab_general = findChild("group_general_tab"); LLAccordionCtrlTab* tab_roles = findChild("group_roles_tab"); LLAccordionCtrlTab* tab_notices = findChild("group_notices_tab"); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 73ea990b3f..4b2a1a4e48 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -769,11 +769,6 @@ void LLPanelGroupGeneral::updateMembers() } // Owners show up in bold. std::string style = "NORMAL"; - if ( member->isOwner() ) - { - style = "BOLD"; - } - sd_timer.reset(); LLSD row; row["id"] = member->getID(); @@ -793,7 +788,14 @@ void LLPanelGroupGeneral::updateMembers() sSDTime += sd_timer.getElapsedTimeF32(); element_timer.reset(); - mListVisibleMembers->addElement(row);//, ADD_SORTED); + LLScrollListItem* member_row = mListVisibleMembers->addElement(row);//, ADD_SORTED); + + if ( member->isOwner() ) + { + LLScrollListText* name_textp = dynamic_cast(member_row->getColumn(0)); + if (name_textp) + name_textp->setFontStyle(LLFontGL::BOLD); + } sElementTime += element_timer.getElapsedTimeF32(); } sAllTime += all_timer.getElapsedTimeF32(); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 4618b49df4..59f7319b2b 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -659,6 +659,12 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][1]["font"]["style"] = "BOLD"; LLScrollListItem* title_row = ctrl->addElement(row, ADD_BOTTOM, action_set->mActionSetData); + + LLScrollListText* name_textp = dynamic_cast(title_row->getColumn(1)); + if (name_textp) + name_textp->setFontStyle(LLFontGL::BOLD); + + bool category_matches_filter = (filter) ? matchesActionSearchFilter(action_set->mActionSetData->mName) : true; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 697182c8fc..34d5ef8f86 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -133,18 +133,23 @@ public: class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver { LOG_CLASS(LLFriendListUpdater); + class LLInventoryFriendCardObserver; public: + friend class LLInventoryFriendCardObserver; LLFriendListUpdater(callback_t cb) : LLAvatarListUpdater(cb, FRIEND_LIST_UPDATE_TIMEOUT) { LLAvatarTracker::instance().addObserver(this); + // For notification when SIP online status changes. LLVoiceClient::getInstance()->addObserver(this); + mInvObserver = new LLInventoryFriendCardObserver(this); } ~LLFriendListUpdater() { + delete mInvObserver; LLVoiceClient::getInstance()->removeObserver(this); LLAvatarTracker::instance().removeObserver(this); } @@ -166,6 +171,7 @@ public: mMask |= mask; } + /*virtual*/ BOOL tick() { if (updateList(mMask)) @@ -180,6 +186,75 @@ public: private: U32 mMask; + LLInventoryFriendCardObserver* mInvObserver; + + /** + * This class is intended for updating Friend List when Inventory Friend Card is added/removed. + * + * The main usage is when Inventory Friends/All content is added while synchronizing with + * friends list on startup is performed. In this case Friend Panel should be updated when + * missing Inventory Friend Card is created. + * *NOTE: updating is fired when Inventory item is added into CallingCards/Friends subfolder. + * Otherwise LLFriendObserver functionality is enough to keep Friends Panel synchronized. + */ + class LLInventoryFriendCardObserver : public LLInventoryObserver + { + LOG_CLASS(LLFriendListUpdater::LLInventoryFriendCardObserver); + + friend class LLFriendListUpdater; + + private: + LLInventoryFriendCardObserver(LLFriendListUpdater* updater) : mUpdater(updater) + { + gInventory.addObserver(this); + } + ~LLInventoryFriendCardObserver() + { + gInventory.removeObserver(this); + } + /*virtual*/ void changed(U32 mask) + { + lldebugs << "Inventory changed: " << mask << llendl; + + // *NOTE: deleting of InventoryItem is performed via moving to Trash. + // That means LLInventoryObserver::STRUCTURE is present in MASK instead of LLInventoryObserver::REMOVE + if ((CALLINGCARD_ADDED & mask) == CALLINGCARD_ADDED) + { + lldebugs << "Calling card added: count: " << gInventory.getChangedIDs().size() + << ", first Inventory ID: "<< (*gInventory.getChangedIDs().begin()) + << llendl; + + bool friendFound = false; + std::set changedIDs = gInventory.getChangedIDs(); + for (std::set::const_iterator it = changedIDs.begin(); it != changedIDs.end(); ++it) + { + if (isDescendentOfInventoryFriends(*it)) + { + friendFound = true; + break; + } + } + + if (friendFound) + { + lldebugs << "friend found, panel should be updated" << llendl; + mUpdater->changed(LLFriendObserver::ADD); + } + } + } + + bool isDescendentOfInventoryFriends(const LLUUID& invItemID) + { + LLViewerInventoryItem * item = gInventory.getItem(invItemID); + if (NULL == item) + return false; + + return LLFriendCardsManager::instance().isItemInAnyFriendsList(item); + } + LLFriendListUpdater* mUpdater; + + static const U32 CALLINGCARD_ADDED = LLInventoryObserver::ADD | LLInventoryObserver::CALLING_CARD; + }; }; /** @@ -438,8 +513,13 @@ bool LLPanelPeople::updateFriendList(U32 changed_mask) LLFriendCardsManager::instance().collectFriendsLists(listMap); if (listMap.size() > 0) { + lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl; mAllFriendVec = listMap.begin()->second; } + else + { + lldebugs << "Friends Cards were not found" << llendl; + } LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin(); for (; buddy_it != all_buddies.end(); ++buddy_it) diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 973afae73b..bd6ca4746c 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -46,6 +46,7 @@ #include "llpanelprofile.h" #include "llpanelpick.h" #include "llscrollcontainer.h" +#include "lllistctrl.h" static const std::string XML_BTN_NEW = "new_btn"; static const std::string XML_BTN_DELETE = "trash_btn"; @@ -53,10 +54,6 @@ static const std::string XML_BTN_INFO = "info_btn"; static const std::string XML_BTN_TELEPORT = "teleport_btn"; static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn"; -static const std::string XML_PICKS_LIST = "back_panel"; - -#define PICK_ITEMS_BETWEEN 5 - static LLRegisterPanelClassWrapper t_panel_picks("panel_picks"); //----------------------------------------------------------------------------- @@ -65,9 +62,9 @@ static LLRegisterPanelClassWrapper t_panel_picks("panel_picks"); LLPanelPicks::LLPanelPicks() : LLPanelProfileTab(), mPopupMenu(NULL), - mSelectedPickItem(NULL), mProfilePanel(NULL), - mPickPanel(NULL) + mPickPanel(NULL), + mPicksList(NULL) { } @@ -100,16 +97,13 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) gCacheName->getName(getAvatarId(),name,second_name); childSetTextArg("pick_title", "[NAME]",name); - LLView* picks_list = getPicksList(); - // to restore selection of the same item later LLUUID pick_id_selected(LLUUID::null); - if (mSelectedPickItem) pick_id_selected = mSelectedPickItem->getPickId(); + if (getSelectedPickItem()) pick_id_selected = getSelectedPickItem()->getPickId(); - clear(); + mPicksList->clear(); //*TODO move it somewhere else? - picks_list->setEnabled(FALSE); childSetEnabled(XML_BTN_NEW, false); childSetEnabled(XML_BTN_DELETE, false); childSetEnabled(XML_BTN_INFO, false); @@ -124,109 +118,38 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) LLPickItem* picture = LLPickItem::create(); picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this)); - - picks_list->addChild(picture); - picture->setPickName(pick_name); picture->setPickId(pick_id); picture->setCreatorId(getAvatarId()); LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture); picture->update(); - mPickItemList.push_back(picture); + mPicksList->addItem(picture); if (pick_id_selected != LLUUID::null && - pick_id == pick_id_selected) setSelectedPickItem(picture); + pick_id == pick_id_selected) mPicksList->toggleSelection(picture); + + picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1)); + picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4)); } - reshapePicksList(); LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this); - updateButtons(); - if (!mSelectedPickItem && mPickItemList.size()) setSelectedPickItem(mPickItemList.back()); - picks_list->setEnabled(TRUE); - } } } -void LLPanelPicks::clear() -{ - LLView* scroll = getPicksList(); - picture_list_t::const_iterator it = mPickItemList.begin(); - for(; mPickItemList.end() != it; ++it) - { - scroll->removeChild(*it); - delete *it; - } - mPickItemList.clear(); - mSelectedPickItem = NULL; -} - - LLPickItem* LLPanelPicks::getSelectedPickItem() { - return mSelectedPickItem; -} - - -void LLPanelPicks::removePickItem( LLPickItem* pick_item ) -{ - LLView* scroll = getPicksList(); - scroll->removeChild(pick_item); - mPickItemList.remove(pick_item); - if (mPickItemList.size() == 0) - { - mSelectedPickItem = NULL; - } - else - { - setSelectedPickItem(mPickItemList.back()); - } - - reshapePicksList(); -} - -void LLPanelPicks::reshapePicksList() -{ - if (!mPickItemList.size()) return; - LLView* pickList = getPicksList(); - - //We don't need to update size of the 'pick list' before reshaping pick items. Don't need to reshape the pick list - S32 height = mPickItemList.size() * (mPickItemList.front()->getRect().getHeight() + PICK_ITEMS_BETWEEN); - LLRect rc = pickList->getRect(); - rc.setLeftTopAndSize(rc.mLeft, rc.mTop, rc.getWidth(), height); - pickList->setRect(rc); - - S32 last_bottom = pickList->getRect().getHeight(); - std::list::const_iterator pick_it, pick_first_it = mPickItemList.begin(); - for ( pick_it = pick_first_it; pick_it != mPickItemList.end(); ++pick_it) - { - LLView* const pick = *pick_it; - if(pick_it != pick_first_it) - { - last_bottom -= pick->getRect().getHeight(); - last_bottom -= PICK_ITEMS_BETWEEN; - } - reshapePickItem(pick, last_bottom,pickList->getRect().getWidth()); - } -} - -void LLPanelPicks::reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth) -{ - LLRect rc = pick_item->getRect(); - rc.mBottom = last_bottom - rc.getHeight(); - rc.mTop = last_bottom; - pick_item->setRect(rc); - pick_item->reshape(newWidth, rc.getHeight()); -} + std::list selected_items = mPicksList->getSelectedItems(); -LLView* LLPanelPicks::getPicksList() const -{ - return getChild(XML_PICKS_LIST); + if (selected_items.empty()) return NULL; + return dynamic_cast(selected_items.front()); } BOOL LLPanelPicks::postBuild() { + mPicksList = getChild("picks_list"); + childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this)); childSetAction("teleport_btn", boost::bind(&LLPanelPicks::onClickTeleport, this)); @@ -295,7 +218,7 @@ bool LLPanelPicks::callbackDelete(const LLSD& notification, const LLSD& response if (0 == option) { LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_item->getPickId()); - removePickItem(pick_item); + mPicksList->removeItem(pick_item); } updateButtons(); return false; @@ -329,47 +252,29 @@ void LLPanelPicks::onClickMap() } -BOOL LLPanelPicks::handleRightMouseDown(S32 x, S32 y, MASK mask) +void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask) { - if (isMouseInPick(x, y)) + if (mPopupMenu) { - if (mPopupMenu) - { - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); - ((LLContextMenu*)mPopupMenu)->show(x, y); - LLMenuGL::showPopup(this, mPopupMenu, x, y); - } - return TRUE; + mPopupMenu->buildDrawLabels(); + mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + ((LLContextMenu*)mPopupMenu)->show(x, y); + LLMenuGL::showPopup(item, mPopupMenu, x, y); } - return LLPanel::handleRightMouseDown(x, y, mask); -} - -BOOL LLPanelPicks::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - isMouseInPick(x, y); - return LLPanel::handleMouseDown(x, y, mask); } -BOOL LLPanelPicks::handleDoubleClick(S32 x, S32 y, MASK mask) +void LLPanelPicks::onDoubleClickItem(LLUICtrl* item) { - if (isMouseInPick(x, y)) - { - LLPickItem* pick_item = getSelectedPickItem(); - if (pick_item) - { - LLSD args; - args["PICK"] = pick_item->getPickName(); - LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); - } - return TRUE; - } - return LLPanel::handleDoubleClick(x, y, mask); + LLPickItem* pick_item = dynamic_cast(item); + if (!pick_item) return; + LLSD args; + args["PICK"] = pick_item->getPickName(); + LLNotifications::instance().add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2)); } void LLPanelPicks::updateButtons() { - int picks_num = mPickItemList.size(); + int picks_num = mPicksList->size(); childSetEnabled(XML_BTN_INFO, picks_num > 0); if (getAvatarId() == gAgentID) @@ -388,42 +293,6 @@ void LLPanelPicks::updateButtons() } -void LLPanelPicks::setSelectedPickItem(LLPickItem* item) -{ - if (!item) return; - if (mSelectedPickItem == item) return; - if (mSelectedPickItem && mSelectedPickItem->isBackgroundVisible()) - { - mSelectedPickItem->setBackgroundVisible(FALSE); - } - item->setBackgroundVisible(TRUE); - mSelectedPickItem = item; -} - -BOOL LLPanelPicks::isMouseInPick( S32 x, S32 y ) -{ - S32 x_l = x; - S32 y_l = y; - - if(!getChild("profile_scroll")->getRect().pointInRect(x, y)) - { - return FALSE; - } - - picture_list_t::const_iterator it = mPickItemList.begin(); - for(; mPickItemList.end() != it; ++it) - { - localPointToOtherView(x, y, &x_l, &y_l, (*it)); - if ((*it)->pointInView(x_l, y_l)) - { - setSelectedPickItem(*it); - return TRUE; - } - } - return FALSE; -} - - void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel) { mProfilePanel = profile_panel; diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h index da7bc32ab1..5860354902 100644 --- a/indra/newview/llpanelpicks.h +++ b/indra/newview/llpanelpicks.h @@ -48,7 +48,7 @@ class LLPanelPick; class LLAgent; class LLMenuGL; class LLPickItem; - +class LLListCtrl; class LLPanelPicks : public LLPanelProfileTab @@ -67,18 +67,9 @@ public: void updateData(); - void clear(); - // returns the selected pick item LLPickItem* getSelectedPickItem(); - // removes the specified pick item - void removePickItem(LLPickItem* pick_item); - - /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); - //*NOTE top down approch when panel toggling is done only by // parent panels failed to work (picks related code was in me profile panel) void setProfilePanel(LLPanelProfile* profile_panel); @@ -106,25 +97,17 @@ private: bool callbackDelete(const LLSD& notification, const LLSD& response); bool callbackTeleport(const LLSD& notification, const LLSD& response); - void reshapePicksList(); - void reshapePickItem(LLView* const pick_item, const S32 last_bottom, const S32 newWidth); - LLView* getPicksList() const; void updateButtons(); - void setSelectedPickItem(LLPickItem* item); - - BOOL isMouseInPick(S32 x, S32 y); + virtual void onDoubleClickItem(LLUICtrl* item); + virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask); LLPanelProfile* getProfilePanel(); - - typedef std::list picture_list_t; - picture_list_t mPickItemList; - LLMenuGL* mPopupMenu; - LLPickItem* mSelectedPickItem; LLPanelProfile* mProfilePanel; LLPanelPick* mPickPanel; + LLListCtrl* mPicksList; }; class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index a01977c9b5..73e09a36f9 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -48,6 +48,7 @@ #include "llscrollcontainer.h" #include "lltextbox.h" +#include "llaccordionctrl.h" #include "llagent.h" #include "llavatarpropertiesprocessor.h" #include "llfloaterworldmap.h" @@ -93,14 +94,42 @@ BOOL LLPanelPlaceInfo::postBuild() mSnapshotCtrl = getChild("logo"); mSnapshotCtrl->setEnabled(FALSE); - mRegionName = getChild("region_name"); - mParcelName = getChild("parcel_name"); + mRegionName = getChild("region_title"); + mParcelName = getChild("parcel_title"); mDescEditor = getChild("description"); - mRating = getChild("maturity"); - mRegionInfoDrillIn = getChild("region_info_drill_in"); - mMediaDrillIn = getChild("media_drill_in"); - mMediaDrillIn->setClickedCallback(boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, this, TRUE)); + mMaturityRatingIcon = getChild("maturity"); + mMaturityRatingText = getChild("maturity_value"); + + mParcelOwner = getChild("owner_value"); + + mLastVisited = getChild("last_visited_value"); + + mRatingIcon = getChild("rating_icon"); + mRatingText = getChild("rating_value"); + mVoiceIcon = getChild("voice_icon"); + mVoiceText = getChild("voice_value"); + mFlyIcon = getChild("fly_icon"); + mFlyText = getChild("fly_value"); + mPushIcon = getChild("push_icon"); + mPushText = getChild("push_value"); + mBuildIcon = getChild("build_icon"); + mBuildText = getChild("build_value"); + mScriptsIcon = getChild("scripts_icon"); + mScriptsText = getChild("scripts_value"); + mDamageIcon = getChild("damage_icon"); + mDamageText = getChild("damage_value"); + + mRegionNameText = getChild("region_name"); + mRegionTypeText = getChild("region_type"); + mRegionRatingText = getChild("region_rating"); + mRegionOwnerText = getChild("region_owner"); + mRegionGroupText = getChild("region_group"); + + mEstateNameText = getChild("estate_name"); + mEstateRatingText = getChild("estate_rating"); + mEstateOwnerText = getChild("estate_owner"); + mCovenantText = getChild("covenant"); mOwner = getChild("owner"); mCreator = getChild("creator"); @@ -224,7 +253,10 @@ void LLPanelPlaceInfo::resetLocation() mLandmarkID.setNull(); mPosRegion.clearVec(); std::string not_available = getString("not_available"); - mRating->setValue(not_available); + mMaturityRatingIcon->setValue(not_available); + mMaturityRatingText->setValue(not_available); + mParcelOwner->setValue(not_available); + mLastVisited->setValue(not_available); mRegionName->setText(not_available); mParcelName->setText(not_available); mDescEditor->setText(not_available); @@ -235,6 +267,32 @@ void LLPanelPlaceInfo::resetLocation() mNotesEditor->setText(LLStringUtil::null); mSnapshotCtrl->setImageAssetID(LLUUID::null); mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c"); + + mRatingIcon->setValue(not_available); + mRatingText->setText(not_available); + mVoiceIcon->setValue(not_available); + mVoiceText->setText(not_available); + mFlyIcon->setValue(not_available); + mFlyText->setText(not_available); + mPushIcon->setValue(not_available); + mPushText->setText(not_available); + mBuildIcon->setValue(not_available); + mBuildText->setText(not_available); + mScriptsIcon->setValue(not_available); + mScriptsText->setText(not_available); + mDamageIcon->setValue(not_available); + mDamageText->setText(not_available); + + mRegionNameText->setValue(not_available); + mRegionTypeText->setValue(not_available); + mRegionRatingText->setValue(not_available); + mRegionOwnerText->setValue(not_available); + mRegionGroupText->setValue(not_available); + + mEstateNameText->setValue(not_available); + mEstateRatingText->setValue(not_available); + mEstateOwnerText->setValue(not_available); + mCovenantText->setValue(not_available); } //virtual @@ -251,12 +309,22 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) bool is_info_type_agent = type == AGENT; bool is_info_type_landmark = type == LANDMARK; + bool is_info_type_teleport_history = type == TELEPORT_HISTORY; + + getChild("maturity_label")->setVisible(!is_info_type_agent); + mMaturityRatingIcon->setVisible(!is_info_type_agent); + mMaturityRatingText->setVisible(!is_info_type_agent); + + getChild("owner_label")->setVisible(is_info_type_agent); + mParcelOwner->setVisible(is_info_type_agent); + + getChild("last_visited_label")->setVisible(is_info_type_teleport_history); + mLastVisited->setVisible(is_info_type_teleport_history); landmark_info_panel->setVisible(is_info_type_landmark); landmark_edit_panel->setVisible(is_info_type_landmark || type == CREATE_LANDMARK); - mRegionInfoDrillIn->setVisible(is_info_type_agent); - mMediaDrillIn->setVisible(is_info_type_agent); + getChild("advanced_info_accordion")->setVisible(is_info_type_agent); switch(type) { @@ -274,14 +342,15 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type) } break; - // Hide Media Panel if showing information about - // a landmark or a teleport history item case LANDMARK: mCurrentTitle = getString("title_landmark"); break; case TELEPORT_HISTORY: - mCurrentTitle = getString("title_place"); + mCurrentTitle = getString("title_teleport_history"); + + // *TODO: Add last visited timestamp. + mLastVisited->setText(getString("unknown")); break; } @@ -293,7 +362,7 @@ BOOL LLPanelPlaceInfo::isMediaPanelVisible() { if (!mMediaPanel) return FALSE; - + return mMediaPanel->getVisible(); } @@ -363,18 +432,23 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data) // HACK: Flag 0x2 == adult region, // Flag 0x1 == mature region, otherwise assume PG std::string rating = LLViewerRegion::accessToString(SIM_ACCESS_PG); - std::string rating_icon = "icon_event.tga"; + std::string rating_icon = "places_rating_pg.tga"; if (parcel_data.flags & 0x2) { rating = LLViewerRegion::accessToString(SIM_ACCESS_ADULT); - rating_icon = "icon_event_adult.tga"; + rating_icon = "places_rating_adult.tga"; } else if (parcel_data.flags & 0x1) { rating = LLViewerRegion::accessToString(SIM_ACCESS_MATURE); - rating_icon = "icon_event_mature.tga"; + rating_icon = "places_rating_mature.tga"; } - mRating->setValue(rating_icon); + + mMaturityRatingIcon->setValue(rating_icon); + mMaturityRatingText->setValue(rating); + + mRatingIcon->setValue(rating_icon); + mRatingText->setValue(rating); //update for_sale banner, here we should use DFQ_FOR_SALE instead of PF_FOR_SALE //because we deal with remote parcel response format @@ -450,6 +524,14 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() if (!region || !parcel) return; + // send EstateCovenantInfo message + LLMessageSystem *msg = gMessageSystem; + msg->newMessage("EstateCovenantRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->sendReliable(region->getHost()); + LLParcelData parcel_data; // HACK: Converting sim access flags to the format @@ -481,9 +563,139 @@ void LLPanelPlaceInfo::displayAgentParcelInfo() parcel_data.global_y = global_pos.mdV[1]; parcel_data.global_z = global_pos.mdV[2]; + processParcelInfo(parcel_data); + + // Processing parcel characteristics + if (parcel->getParcelFlagAllowVoice()) + { + mVoiceIcon->setValue("places_voice_on.tga"); + mVoiceText->setText(getString("on")); + } + else + { + mVoiceIcon->setValue("places_voice_off.tga"); + mVoiceText->setText(getString("off")); + } + if (!region->getBlockFly() && parcel->getAllowFly()) + { + mFlyIcon->setValue("places_fly_on.tga"); + mFlyText->setText(getString("on")); + } + else + { + mFlyIcon->setValue("places_fly_off.tga"); + mFlyText->setText(getString("off")); + } - processParcelInfo(parcel_data); + if (region->getRestrictPushObject() || parcel->getRestrictPushObject()) + { + mPushIcon->setValue("places_push_off.tga"); + mPushText->setText(getString("off")); + } + else + { + mPushIcon->setValue("places_push_on.tga"); + mPushText->setText(getString("on")); + } + + if (parcel->getAllowModify()) + { + mBuildIcon->setValue("places_build_on.tga"); + mBuildText->setText(getString("on")); + } + else + { + mBuildIcon->setValue("places_build_off.tga"); + mBuildText->setText(getString("off")); + } + + if((region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS) || + (region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS) || + !parcel->getAllowOtherScripts()) + { + mScriptsIcon->setValue("places_scripts_off.tga"); + mScriptsText->setText(getString("off")); + } + else + { + mScriptsIcon->setValue("places_scripts_on.tga"); + mScriptsText->setText(getString("on")); + } + + if (region->getAllowDamage() || parcel->getAllowDamage()) + { + mDamageIcon->setValue("places_damage_on.tga"); + mDamageText->setText(getString("on")); + } + else + { + mDamageIcon->setValue("places_damage_off.tga"); + mDamageText->setText(getString("off")); + } + + mRegionNameText->setText(region->getName()); + mRegionTypeText->setText(region->getSimProductName()); + mRegionRatingText->setText(region->getSimAccessString()); + + // Determine parcel owner + if (parcel->isPublic()) + { + mParcelOwner->setText(getString("public")); + mRegionOwnerText->setText(getString("public")); + } + else + { + if (parcel->getIsGroupOwned()) + { + mRegionOwnerText->setText(getString("group_owned_text")); + + if(!parcel->getGroupID().isNull()) + { + // FIXME: Using parcel group as region group. + gCacheName->get(parcel->getGroupID(), TRUE, + boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionGroupText, _2, _3)); + + mParcelOwner->setText(mRegionGroupText->getText()); + } + else + { + std::string owner = getString("none_text"); + mRegionGroupText->setText(owner); + mParcelOwner->setText(owner); + } + } + else + { + // Figure out the owner's name + gCacheName->get(parcel->getOwnerID(), FALSE, + boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mParcelOwner, _2, _3)); + gCacheName->get(region->getOwner(), FALSE, + boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, this, mRegionOwnerText, _2, _3)); + } + + if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) + { + mRegionOwnerText->setText(mRegionOwnerText->getText() + getString("sale_pending_text")); + } + } + + mEstateRatingText->setText(region->getSimAccessString()); +} + +void LLPanelPlaceInfo::updateEstateName(const std::string& name) +{ + mEstateNameText->setText(name); +} + +void LLPanelPlaceInfo::updateEstateOwnerName(const std::string& name) +{ + mEstateOwnerText->setText(name); +} + +void LLPanelPlaceInfo::updateCovenantText(const std::string &text) +{ + mCovenantText->setText(text); } void LLPanelPlaceInfo::onCommitTitleOrNote(LANDMARK_INFO_TYPE type) diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 77ce2c6619..0cdeaab2b7 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -105,6 +105,10 @@ public: // without sending a request to the server. void displayAgentParcelInfo(); + void updateEstateName(const std::string& name); + void updateEstateOwnerName(const std::string& name); + void updateCovenantText(const std::string &text); + void nameUpdatedCallback(LLTextBox* text, const std::string& first, const std::string& last); @@ -133,15 +137,42 @@ private: LLTextBox* mRegionName; LLTextBox* mParcelName; LLTextEditor* mDescEditor; - LLIconCtrl* mRating; - LLButton* mRegionInfoDrillIn; - LLButton* mMediaDrillIn; + LLIconCtrl* mMaturityRatingIcon; + LLTextBox* mMaturityRatingText; + LLTextBox* mParcelOwner; + LLTextBox* mLastVisited; + + LLIconCtrl* mRatingIcon; + LLTextBox* mRatingText; + LLIconCtrl* mVoiceIcon; + LLTextBox* mVoiceText; + LLIconCtrl* mFlyIcon; + LLTextBox* mFlyText; + LLIconCtrl* mPushIcon; + LLTextBox* mPushText; + LLIconCtrl* mBuildIcon; + LLTextBox* mBuildText; + LLIconCtrl* mScriptsIcon; + LLTextBox* mScriptsText; + LLIconCtrl* mDamageIcon; + LLTextBox* mDamageText; + + LLTextBox* mRegionNameText; + LLTextBox* mRegionTypeText; + LLTextBox* mRegionRatingText; + LLTextBox* mRegionOwnerText; + LLTextBox* mRegionGroupText; + + LLTextBox* mEstateNameText; + LLTextBox* mEstateRatingText; + LLTextBox* mEstateOwnerText; + LLTextEditor* mCovenantText; + LLTextBox* mOwner; LLTextBox* mCreator; LLTextBox* mCreated; LLLineEditor* mTitleEditor; LLTextEditor* mNotesEditor; - LLTextBox* mLocationEditor; LLPanel* mScrollingPanel; LLPanel* mInfoPanel; LLMediaPanel* mMediaPanel; diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 7cb9e61e72..2aebfdabfa 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -119,9 +119,6 @@ BOOL LLPanelPlaces::postBuild() //mShareBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onShareButtonClicked, this)); mOverflowBtn = getChild("overflow_btn"); - - // *TODO: Assign the action to an appropriate event. - //mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this)); mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -156,20 +153,17 @@ BOOL LLPanelPlaces::postBuild() LLButton* back_btn = mPlaceInfo->getChild("back_btn"); back_btn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this)); - // *TODO: Assign the action to an appropriate event. - mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::toggleMediaPanel, this)); - return TRUE; } void LLPanelPlaces::onOpen(const LLSD& key) { - mFilterEditor->clear(); - onFilterEdit(""); - if(mPlaceInfo == NULL || key.size() == 0) return; + mFilterEditor->clear(); + onFilterEdit(""); + mPlaceInfoType = key["type"].asString(); mPosGlobal.setZero(); togglePlaceInfoPanel(TRUE); @@ -228,8 +222,6 @@ void LLPanelPlaces::onOpen(const LLSD& key) hist_items[index].mRegionID, mPosGlobal); } - - } void LLPanelPlaces::setItem(LLInventoryItem* item) diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 089a854762..057c430230 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -79,7 +79,7 @@ private: void onAgentParcelChange(); void updateVerbs(); - + void showLandmarkFoldersMenu(); LLFilterEditor* mFilterEditor; diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index 18184a6476..0762bbeb87 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -31,12 +31,16 @@ */ #include "llviewerprecompiledheaders.h" + +#include "lluserrelations.h" + #include "llpanelprofileview.h" +#include "llcallingcard.h" #include "llpanelavatar.h" #include "llpanelpicks.h" -#include "llsidetraypanelcontainer.h" #include "llpanelprofile.h" +#include "llsidetraypanelcontainer.h" static LLRegisterPanelClassWrapper t_panel_target_profile("panel_profile_view"); @@ -45,6 +49,7 @@ static const std::string PANEL_PROFILE = "panel_profile"; LLPanelProfileView::LLPanelProfileView() : LLPanelProfile() +, mStatusText(NULL) { } @@ -65,6 +70,10 @@ void LLPanelProfileView::onOpen(const LLSD& key) setAvatarId(id); } + // status should only show if viewer has permission to view online/offline. EXT-453 + mStatusText->setVisible(isGrantedToSeeOnlineStatus()); + updateOnlineStatus(); + LLPanelProfile::onOpen(key); } @@ -78,6 +87,8 @@ BOOL LLPanelProfileView::postBuild() getTabContainer()[PANEL_PROFILE]->childSetVisible("online_me_status_text", FALSE); getTabContainer()[PANEL_PROFILE]->childSetVisible("status_combo", FALSE); + mStatusText = getChild("status"); + childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL); return TRUE; @@ -94,3 +105,32 @@ void LLPanelProfileView::onBackBtnClick() parent->openPreviousPanel(); } } + +bool LLPanelProfileView::isGrantedToSeeOnlineStatus() +{ + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + if (NULL == relationship) + return false; + + // *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status. + // When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer + // see comments for ChangeUserRights template message. EXT-453. +// return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS); + return true; +} + +void LLPanelProfileView::updateOnlineStatus() +{ + const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); + if (NULL == relationship) + return; + + bool online = relationship->isOnline(); +// std::string statusName(); + + std::string status = getString(online ? "status_online" : "status_offline"); + + mStatusText->setValue(status); +} + +// EOF diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h index 92def7b7ca..533ab94cc3 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -39,7 +39,7 @@ class LLPanelProfile; class LLPanelProfileTab; - +class LLTextBox; /** * Panel for displaying Avatar's profile. It consists of three sub panels - Profile, @@ -63,6 +63,11 @@ public: protected: void onBackBtnClick(); + bool isGrantedToSeeOnlineStatus(); + void updateOnlineStatus(); + +private: + LLTextBox* mStatusText; }; #endif //LL_LLPANELPROFILEVIEW_H diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 2bbb5a2767..15d77dbf88 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -40,29 +40,36 @@ //--------------------------------------------------------------------------------- LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLFloater(LLSD()), + mSysWell(NULL), mChannel(NULL), mScrollContainer(NULL), mNotificationList(NULL) { + LLIMMgr::getInstance()->addSessionObserver(this); + LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLSysWellWindow::findIMChiclet, this, _1)); } //--------------------------------------------------------------------------------- BOOL LLSysWellWindow::postBuild() { mScrollContainer = getChild("notification_list_container"); + mTwinListPanel = getChild("twin_list_panel"); mNotificationList = getChild("notification_list"); + mIMRowList = getChild("im_row_panel_list"); gViewerWindow->setOnBottomTrayWidthChanged(boost::bind(&LLSysWellWindow::adjustWindowPosition, this)); // *TODO: won't be necessary after docking is realized mScrollContainer->setBorderVisible(FALSE); mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png"); + return TRUE; } //--------------------------------------------------------------------------------- LLSysWellWindow::~LLSysWellWindow() { + LLIMMgr::getInstance()->removeSessionObserver(this); } //--------------------------------------------------------------------------------- @@ -121,10 +128,9 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id) reshapeWindow(); adjustWindowPosition(); // *TODO: won't be necessary after docking is realized + // hide chiclet window if there are no items left - S32 items_left = mNotificationList->getPanelList().size(); - if(items_left == 0) - setVisible(FALSE); + setVisible(!isWindowEmpty()); } //--------------------------------------------------------------------------------- @@ -177,6 +183,7 @@ void LLSysWellWindow::adjustWindowPosition() // *TODO: won't be necessary after LLRect this_rect = getRect(); setOrigin(btm_rect.mRight - this_rect.getWidth() - WINDOW_MARGIN, WINDOW_MARGIN); } + //--------------------------------------------------------------------------------- void LLSysWellWindow::reshapeWindow() { @@ -184,30 +191,210 @@ void LLSysWellWindow::reshapeWindow() const LLUICachedControl SCROLLBAR_SIZE("UIScrollbarSize", 0); const LLUICachedControl HEADER_SIZE("UIFloaterHeaderSize", 0); - // Get item list - const LLScrollingPanelList::panel_list_t list = mNotificationList->getPanelList(); + LLRect notif_list_rect = mNotificationList->getRect(); + LLRect im_list_rect = mIMRowList->getRect(); + LLRect panel_rect = mTwinListPanel->getRect(); + + S32 notif_list_height = notif_list_rect.getHeight(); + S32 im_list_height = im_list_rect.getHeight(); - // Get height for a scrolling panel list - S32 list_height = mNotificationList->getRect().getHeight(); + S32 new_panel_height = notif_list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + im_list_height; + S32 new_window_height = new_panel_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE; - // Check that the floater doesn't exceed its parent view limits after reshape - S32 new_height = list_height + LLScrollingPanelList::GAP_BETWEEN_PANELS + HEADER_SIZE; + U32 twinListWidth = 0; - if(new_height > MAX_WINDOW_HEIGHT) + if (new_window_height > MAX_WINDOW_HEIGHT) { - reshape(MIN_WINDOW_WIDTH, MAX_WINDOW_HEIGHT, FALSE); - mNotificationList->reshape(MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE, list_height, TRUE); + twinListWidth = MIN_PANELLIST_WIDTH - SCROLLBAR_SIZE; + new_window_height = MAX_WINDOW_HEIGHT; } else { - reshape(MIN_WINDOW_WIDTH, new_height, FALSE); - mNotificationList->reshape(MIN_PANELLIST_WIDTH, list_height, TRUE); + twinListWidth = MIN_PANELLIST_WIDTH; } - + + reshape(MIN_WINDOW_WIDTH, new_window_height, FALSE); + mTwinListPanel->reshape(twinListWidth, new_panel_height, TRUE); + mNotificationList->reshape(twinListWidth, notif_list_height, TRUE); + mIMRowList->reshape(twinListWidth, im_list_height, TRUE); + + // arrange panel and lists + // move panel + panel_rect.setLeftTopAndSize(1, new_panel_height, twinListWidth, new_panel_height); + mTwinListPanel->setRect(panel_rect); + // move notif list panel + notif_list_rect.setLeftTopAndSize(notif_list_rect.mLeft, new_panel_height, twinListWidth, notif_list_height); + mNotificationList->setRect(notif_list_rect); + // move IM list panel + im_list_rect.setLeftTopAndSize(im_list_rect.mLeft, notif_list_rect.mBottom - LLScrollingPanelList::GAP_BETWEEN_PANELS, twinListWidth, im_list_height); + mIMRowList->setRect(im_list_rect); + mNotificationList->updatePanels(TRUE); + mIMRowList->updatePanels(TRUE); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel * LLSysWellWindow::findIMRow(const LLUUID& sessionId) +{ + RowPanel * res = NULL; + const LLScrollingPanelList::panel_list_t &list = mIMRowList->getPanelList(); + if (!list.empty()) + { + for (LLScrollingPanelList::panel_list_t::const_iterator iter = list.begin(); iter != list.end(); ++iter) + { + RowPanel *panel = static_cast (*iter); + if (panel->mChiclet->getSessionId() == sessionId) + { + res = panel; + break; + } + } + } + return res; +} + +//--------------------------------------------------------------------------------- +LLChiclet* LLSysWellWindow::findIMChiclet(const LLUUID& sessionId) +{ + LLChiclet* res = NULL; + RowPanel* panel = findIMRow(sessionId); + if (panel != NULL) + { + res = panel->mChiclet; + } + + return res; +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter, + const std::string& name, const LLUUID& otherParticipantId) +{ + + mIMRowList->addPanel(new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId)); + adjustWindowPosition(); // *TODO: won't be necessary after docking is realized +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::delIMRow(const LLUUID& sessionId) +{ + RowPanel *panel = findIMRow(sessionId); + if (panel != NULL) + { + mIMRowList->removePanel(panel); + } + + // hide chiclet window if there are no items left + setVisible(!isWindowEmpty()); + + adjustWindowPosition(); // *TODO: won't be necessary after docking is realized +} + +//--------------------------------------------------------------------------------- +bool LLSysWellWindow::isWindowEmpty() +{ + if(mIMRowList->getPanelList().size() == 0 && mNotificationList->getPanelList().size() == 0) + { + return true; + } + else + { + return false; + } +} + +//--------------------------------------------------------------------------------- +//virtual +void LLSysWellWindow::sessionAdded(const LLUUID& sessionId, + const std::string& name, const LLUUID& otherParticipantId) +{ + if (findIMRow(sessionId) == NULL) + { + S32 chicletCounter = 0; + LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap, + sessionId, (LLIMModel::LLIMSession*) NULL); + if (session != NULL) + { + chicletCounter = session->mNumUnread; + } + addIMRow(sessionId, chicletCounter, name, otherParticipantId); + reshapeWindow(); + } +} + +//--------------------------------------------------------------------------------- +//virtual +void LLSysWellWindow::sessionRemoved(const LLUUID& sessionId) +{ + delIMRow(sessionId); + reshapeWindow(); + mSysWell->updateUreadIMNotifications(); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, + S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) : + LLScrollingPanel(LLPanel::Params()), mParent(parent) +{ + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_activeim_row.xml", NULL); + + mChiclet = getChild("chiclet"); + mChiclet->setCounter(chicletCounter); + mChiclet->setSessionId(sessionId); + mChiclet->setIMSessionName(name); + mChiclet->setOtherParticipantId(otherParticipantId); + + LLTextBox* contactName = getChild("contact_name"); + contactName->setValue(name); + + mCloseBtn = getChild("hide_btn"); + mCloseBtn->setCommitCallback(boost::bind(&LLSysWellWindow::RowPanel::onClose, this)); +} + +//--------------------------------------------------------------------------------- +LLSysWellWindow::RowPanel::~RowPanel() +{ +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onClose() +{ + mParent->mIMRowList->removePanel(this); + gIMMgr->removeSession(mChiclet->getSessionId()); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask) +{ + setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected")); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask) +{ + setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected")); } //--------------------------------------------------------------------------------- +// virtual +BOOL LLSysWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // Pass the mouse down event to the chiclet (EXT-596). + if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown() + mChiclet->onMouseDown(); + return LLPanel::handleMouseDown(x, y, mask); +} + +//--------------------------------------------------------------------------------- +void LLSysWellWindow::RowPanel::updatePanel(BOOL allow_modify) +{ + S32 parent_width = getParent()->getRect().getWidth(); + S32 panel_height = getRect().getHeight(); + + reshape(parent_width, panel_height, TRUE); +} + +//--------------------------------------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 7a107af0d1..d9fdf77a04 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -39,20 +39,26 @@ #include "llbutton.h" #include "llscreenchannel.h" #include "llscrollcontainer.h" +#include "llchiclet.h" +#include "llimview.h" #include "boost/shared_ptr.hpp" -class LLSysWellWindow : public LLFloater +class LLSysWellWindow : public LLFloater, LLIMSessionObserver { public: LLSysWellWindow(const LLSD& key); ~LLSysWellWindow(); BOOL postBuild(); + // other interface functions + bool isWindowEmpty(); + // change attributes void setChannel(LLNotificationsUI::LLScreenChannel* channel) {mChannel = channel;} + void setSysWell(LLNotificationChiclet* sys_well) {mSysWell = sys_well;} // Operating with items void addItem(LLSysWellItem::Params p); @@ -75,15 +81,49 @@ public: static const S32 MIN_PANELLIST_WIDTH = 318; private: - + class RowPanel; void reshapeWindow(); + RowPanel * findIMRow(const LLUUID& sessionId); + LLChiclet * findIMChiclet(const LLUUID& sessionId); + void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId); + void delIMRow(const LLUUID& sessionId); + // LLIMSessionObserver observe triggers + virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id); + virtual void sessionRemoved(const LLUUID& session_id); // pointer to a corresponding channel's instance LLNotificationsUI::LLScreenChannel* mChannel; + LLNotificationChiclet* mSysWell; LLUIImagePtr mDockTongue; + LLPanel* mTwinListPanel; LLScrollContainer* mScrollContainer; + LLScrollingPanelList* mIMRowList; LLScrollingPanelList* mNotificationList; + +private: + /** + * Scrolling row panel. + */ + class RowPanel: public LLScrollingPanel + { + public: + RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter, + const std::string& name, const LLUUID& otherParticipantId); + virtual ~RowPanel(); + /*virtual*/ + void updatePanel(BOOL allow_modify); + void onMouseEnter(S32 x, S32 y, MASK mask); + void onMouseLeave(S32 x, S32 y, MASK mask); + BOOL handleMouseDown(S32 x, S32 y, MASK mask); + private: + void onClose(); + public: + LLIMChiclet* mChiclet; + private: + LLButton* mCloseBtn; + const LLSysWellWindow* mParent; + }; }; #endif // LL_LLSYSWELLWINDOW_H diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index abe5fd8ce8..18fab3ec2e 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -138,6 +138,8 @@ #include "llkeythrottle.h" #include "llgroupactions.h" #include "llagentui.h" +#include "llsidetray.h" +#include "llpanelplaceinfo.h" #include #include @@ -2397,6 +2399,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) // Look for IRC-style emotes if (ircstyle) { + // set CHAT_STYLE_IRC to avoid adding Avatar Name as author of message. See EXT-656 + chat.mChatStyle = CHAT_STYLE_IRC; + // Do nothing, ircstyle is fixed above for chat bubbles } else @@ -5565,6 +5570,12 @@ void process_covenant_reply(LLMessageSystem* msg, void**) LLPanelLandCovenant::updateEstateName(estate_name); LLFloaterBuyLand::updateEstateName(estate_name); + LLPanelPlaceInfo* panel = dynamic_cast(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); + if (panel) + { + panel->updateEstateName(estate_name); + } + // standard message, not from system std::string last_modified; if (covenant_timestamp == 0) @@ -5621,6 +5632,7 @@ void process_covenant_reply(LLMessageSystem* msg, void**) LLPanelEstateCovenant::updateCovenantText(covenant_text, covenant_id); LLPanelLandCovenant::updateCovenantText(covenant_text); LLFloaterBuyLand::updateCovenantText(covenant_text, covenant_id); + panel->updateCovenantText(covenant_text); } } @@ -5641,6 +5653,12 @@ void callbackCacheEstateOwnerName(const LLUUID& id, LLPanelEstateCovenant::updateEstateOwnerName(name); LLPanelLandCovenant::updateEstateOwnerName(name); LLFloaterBuyLand::updateEstateOwnerName(name); + + LLPanelPlaceInfo* panel = dynamic_cast(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); + if (panel) + { + panel->updateEstateOwnerName(name); + } } void onCovenantLoadComplete(LLVFS *vfs, @@ -5708,6 +5726,12 @@ void onCovenantLoadComplete(LLVFS *vfs, LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid); LLPanelLandCovenant::updateCovenantText(covenant_text); LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid); + + LLPanelPlaceInfo* panel = dynamic_cast(LLSideTray::getInstance()->showPanel("panel_place_info", LLSD())); + if (panel) + { + panel->updateCovenantText(covenant_text); + } } diff --git a/indra/newview/skins/default/textures/places_rating_adult.tga b/indra/newview/skins/default/textures/places_rating_adult.tga new file mode 100644 index 0000000000..c344fb1e78 Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_adult.tga differ diff --git a/indra/newview/skins/default/textures/places_rating_mature.tga b/indra/newview/skins/default/textures/places_rating_mature.tga new file mode 100644 index 0000000000..61c879bc92 Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_mature.tga differ diff --git a/indra/newview/skins/default/textures/places_rating_pg.tga b/indra/newview/skins/default/textures/places_rating_pg.tga new file mode 100644 index 0000000000..7805dbce60 Binary files /dev/null and b/indra/newview/skins/default/textures/places_rating_pg.tga differ diff --git a/indra/newview/skins/default/xui/en/floater_activeim.xml b/indra/newview/skins/default/xui/en/floater_activeim.xml index 38c6d44fdf..0af4e1db54 100644 --- a/indra/newview/skins/default/xui/en/floater_activeim.xml +++ b/indra/newview/skins/default/xui/en/floater_activeim.xml @@ -5,7 +5,7 @@ top="26" left="0" height="22" - width="350" + width="320" follows="right|bottom" background_visible="true" can_close="true" @@ -18,13 +18,14 @@ layout="topleft" top="20" left="1" - width="349" + width="320" height="2" name="panel_list_container"> + width="318"/> \ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml index 46c8960fbd..d76ea398d5 100644 --- a/indra/newview/skins/default/xui/en/floater_sys_well.xml +++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml @@ -4,16 +4,16 @@ background_visible="true" bevel_style="in" bg_alpha_color="0.0 0.0 0.0 0.0" - height="30" left="0" top="0" follows="right|bottom" layout="topleft" name="notification_chiclet" save_rect="true" - title="NOTIFICATIONS" + title="NOTIFICATIONS" width="320" min_width="320" + height="60" can_minimize="false" can_tear_off="false" can_resize="false" @@ -21,20 +21,36 @@ can_close="false" can_dock="true" > - - - + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml index 8977f30a51..f5af8e7b30 100644 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml @@ -1,47 +1,53 @@ - - - + Contact Name - + follows="right|left" + font="SansSerifBold" + text_color="White"> + Contact Name + +