diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 2174d952c..5d87bdfab 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -129,7 +129,9 @@ public: void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } LLFontGL::HAlign getHAlign() const { return mHAlign; } void setLeftHPad( S32 pad ) { mLeftHPad = pad; } + S32 getLeftHPad() const { return mLeftHPad; } void setRightHPad( S32 pad ) { mRightHPad = pad; } + S32 getRightHPad() const { return mRightHPad; } const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); } const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 51ef3dbac..b41263d97 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -344,7 +344,10 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLWS if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER ) { - while( *cur && !cur_delimiter->isHead(cur)) + LLWString str = cur_delimiter->getToken(); + std::reverse(str.begin(),str.end()); //Flip the delim around (/* changes to */) + LLKeywordToken reverse_delimiter(cur_delimiter->getType(),cur_delimiter->getColor(),str,cur_delimiter->getToolTip()); + while( *cur && !reverse_delimiter.isHead(cur)) { // Check for an escape sequence. if (*cur == '\\') @@ -358,7 +361,7 @@ void LLKeywords::findSegments(std::vector* seg_list, const LLWS cur++; } // Is the next character the end delimiter? - if (cur_delimiter->isHead(cur)) + if (reverse_delimiter.isHead(cur)) { // Is there was an odd number of backslashes, then this delimiter // does not end the sequence. diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index fd4867b13..b1184ed4f 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -430,7 +430,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col switch(mFontAlignment) { case LLFontGL::LEFT: - start_x = 0.f; + start_x = (mFontStyle & LLFontGL::ITALIC) ? 2.f : 0.f; //Italic text seems need a little padding. break; case LLFontGL::RIGHT: start_x = (F32)getWidth(); @@ -1301,6 +1301,7 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) if (index <= 0) { // At beginning of list, don't do anything + return; } LLScrollListItem *cur_itemp = mItemList[index]; @@ -1308,6 +1309,18 @@ void LLScrollListCtrl::swapWithPrevious(S32 index) mItemList[index - 1] = cur_itemp; } +void LLScrollListCtrl::moveToFront(S32 index) +{ + if(index == 0 || index >= (S32)mItemList.size()) + { + return; + } + + LLScrollListCtrl::item_list::iterator it = mItemList.begin(); + std::advance(it,index); + mItemList.push_front(*it); + mItemList.erase(it); +} void LLScrollListCtrl::deleteSingleItem(S32 target_index) { @@ -3002,6 +3015,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac std::string imagename; child->getAttributeString("image", imagename); + std::string imageoverlay; + child->getAttributeString("image_overlay", imageoverlay); + BOOL columndynamicwidth = FALSE; child->getAttributeBOOL("dynamicwidth", columndynamicwidth); @@ -3021,6 +3037,7 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac columns[index]["sort"] = sortname; columns[index]["sort_ascending"] = sort_ascending; columns[index]["image"] = imagename; + columns[index]["image_overlay"] = imageoverlay; columns[index]["label"] = labelname; columns[index]["width"] = columnwidth; columns[index]["relwidth"] = columnrelwidth; @@ -3229,6 +3246,10 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos) //new_column->mHeader->setScaleImage(false); new_column->mHeader->setImage(column["image"].asString()); } + else if(column["image_overlay"].asString() != "") + { + new_column->mHeader->setImageOverlay(column["image_overlay"].asString()); + } else { new_column->mHeader->setLabel(new_column->mLabel); @@ -3683,6 +3704,9 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS addChild(mResizeBar); mResizeBar->setEnabled(FALSE); + + mImageOverlayAlignment = LLFontGL::HCENTER; + mImageOverlayColor = LLColor4::white; } LLColumnHeader::~LLColumnHeader() @@ -3706,6 +3730,95 @@ void LLColumnHeader::draw() // Draw children LLComboBox::draw(); + if (mImageOverlay.notNull()) //Ugly dupe code from llbutton... + { + BOOL pressed_by_keyboard = FALSE; + if (mButton->hasFocus()) + { + pressed_by_keyboard = gKeyboard->getKeyDown(' ') || (mButton->getCommitOnReturn() && gKeyboard->getKeyDown(KEY_RETURN)); + } + + // Unselected image assignments + S32 local_mouse_x; + S32 local_mouse_y; + LLUI::getCursorPositionLocal(mButton, &local_mouse_x, &local_mouse_y); + + BOOL pressed = pressed_by_keyboard + || (mButton->hasMouseCapture() && mButton->pointInView(local_mouse_x, local_mouse_y)) + || mButton->getToggleState(); + + // Now draw special overlay.. + // let overlay image and text play well together + S32 button_width = mButton->getRect().getWidth(); + S32 button_height = mButton->getRect().getHeight(); + S32 text_left = mButton->getLeftHPad(); + S32 text_right = button_width - mButton->getRightHPad(); + S32 text_width = text_right - text_left; + + // draw overlay image + + // get max width and height (discard level 0) + S32 overlay_width = mImageOverlay->getWidth(); + S32 overlay_height = mImageOverlay->getHeight(); + + F32 scale_factor = llmin((F32)button_width / (F32)overlay_width, (F32)button_height / (F32)overlay_height, 1.f); + overlay_width = llround((F32)overlay_width * scale_factor); + overlay_height = llround((F32)overlay_height * scale_factor); + + S32 center_x = mButton->getLocalRect().getCenterX(); + S32 center_y = mButton->getLocalRect().getCenterY(); + + //FUGLY HACK FOR "DEPRESSED" BUTTONS + if (pressed) + { + center_y--; + center_x++; + } + + // fade out overlay images on disabled buttons + LLColor4 overlay_color = mImageOverlayColor; + if (!mButton->getEnabled()) + { + overlay_color.mV[VALPHA] = 0.5f; + } + + switch(mImageOverlayAlignment) + { + case LLFontGL::LEFT: + text_left += overlay_width + 1; + text_width -= overlay_width + 1; + mImageOverlay->draw( + text_left, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + case LLFontGL::HCENTER: + mImageOverlay->draw( + center_x - (overlay_width / 2), + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + case LLFontGL::RIGHT: + text_right -= overlay_width + 1; + text_width -= overlay_width + 1; + mImageOverlay->draw( + text_right - overlay_width, + center_y - (overlay_height / 2), + overlay_width, + overlay_height, + overlay_color); + break; + default: + // draw nothing + break; + } + } + + if (mList->getVisible()) { // sync sort order with list selection every frame @@ -3738,6 +3851,20 @@ void LLColumnHeader::setImage(const std::string &image_name) } } +void LLColumnHeader::setImageOverlay(const std::string &image_name, LLFontGL::HAlign alignment, const LLColor4& color) +{ + if (image_name.empty()) + { + mImageOverlay = NULL; + } + else + { + mImageOverlay = LLUI::getUIImage(image_name); + mImageOverlayAlignment = alignment; + mImageOverlayColor = color; + } +} + //static void LLColumnHeader::onClick(void* user_data) { diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index bb0d87d67..7861bd536 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -274,6 +274,7 @@ public: /*virtual*/ void userSetShape(const LLRect& new_rect); void setImage(const std::string &image_name); + void setImageOverlay(const std::string &overlay_image, LLFontGL::HAlign alignment = LLFontGL::HCENTER, const LLColor4& color = LLColor4::white); LLScrollListColumn* getColumn() { return mColumn; } void setHasResizableElement(BOOL resizable); void updateResizeBars(); @@ -294,6 +295,10 @@ private: LLUIString mDescendingText; BOOL mShowSortOptions; BOOL mHasResizableElement; + + LLPointer mImageOverlay; + LLFontGL::HAlign mImageOverlayAlignment; + LLColor4 mImageOverlayColor; }; class LLScrollListItem @@ -467,6 +472,7 @@ public: void swapWithNext(S32 index); void swapWithPrevious(S32 index); + void moveToFront(S32 index); void setCanSelect(BOOL can_select) { mCanSelect = can_select; } virtual BOOL getCanSelect() const { return mCanSelect; } diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 36a4cdc30..75c1740aa 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -644,11 +644,12 @@ return Leave current function or event handler # Comment [one_sided_delimiter .8, .3, .15] // Comment:Non-functional commentary or disabled code +# for now two_sided_delimiter spans from the token to the token, reversed. (eg: /* to */) [two_sided_delimiter .8, .3, .15] -/* */ Comment:Non-functional commentary or disabled code +/* Comment:Non-functional commentary or disabled code # String literals [two_sided_delimiter_esc 0, .2, 0] -" " String literal +" String literal #functions are supplied by the program now. diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 12132d4d4..000f4067e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2493,10 +2493,11 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO S32 count = mGroups.count(); for(S32 i = 0; i < count; ++i) { - if(mGroups.get(i).mID == group_id) + LLGroupData &group = mGroups.get(i); + if(group.mID == group_id) { - mGroups.get(i).mAcceptNotices = accept_notices; - mGroups.get(i).mListInProfile = list_in_profile; + group.mAcceptNotices = accept_notices; + group.mListInProfile = list_in_profile; LLMessageSystem* msg = gMessageSystem; msg->newMessage("SetGroupAcceptNotices"); msg->nextBlock("AgentData"); @@ -2508,6 +2509,9 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO msg->nextBlock("NewData"); msg->addBOOL("ListInProfile", list_in_profile); sendReliableMessage(); + + update_group_floaters(group.mID); + return TRUE; } } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 37f52d643..ff109d2ea 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -873,4 +873,5 @@ extern std::string gAuthString; extern LLUUID gReSitTargetID; extern LLVector3 gReSitOffset; // +void update_group_floaters(const LLUUID& group_id); #endif diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 67ffe1b1b..fe0c476d1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1569,6 +1569,7 @@ bool LLAppViewer::cleanup() end_messaging_system(); llinfos << "Message system deleted." << llendflush; + LLUserAuth::getInstance()->reset(); //reset before LLCurl::cleanupClass, else LLCURL::sHandleMutex == NULL // *NOTE:Mani - The following call is not thread safe. LLCurl::cleanupClass(); llinfos << "LLCurl cleaned up." << llendflush; diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 2febd9769..501c7d203 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -1486,7 +1486,7 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); mDummyAvatar->hideSkirt(); - gPipeline.markVisible(mDummyAvatar->mDrawable, *LLViewerCamera::getInstance()); + //gPipeline.markVisible(mDummyAvatar->mDrawable, *LLViewerCamera::getInstance()); // stop extraneous animations mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 132c2abec..72455bb8b 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -67,6 +67,9 @@ std::map LLFloaterGroupPicker::sInstances; // helper functions void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask = GP_ALL_POWERS); +//callbacks +void onGroupSortChanged(void* user_data); + ///---------------------------------------------------------------------------- /// Class LLFloaterGroupPicker ///---------------------------------------------------------------------------- @@ -198,15 +201,9 @@ LLPanelGroups::~LLPanelGroups() // clear the group list, and get a fresh set of info. void LLPanelGroups::reset() { - LLCtrlListInterface *group_list = childGetListInterface("group list"); - if (group_list) - { - group_list->operateOnAll(LLCtrlListInterface::OP_DELETE); - } childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count())); childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); - const std::string none_text = getString("none"); init_group_list(getChild("group list"), gAgent.getGroupID(), none_text); enableButtons(); @@ -220,7 +217,9 @@ BOOL LLPanelGroups::postBuild() childSetTextArg("groupcount", "[MAX]", llformat("%d", gHippoLimits->getMaxAgentGroups())); const std::string none_text = getString("none"); - init_group_list(getChild("group list"), gAgent.getGroupID(), none_text); + LLScrollListCtrl *group_list = getChild("group list"); + init_group_list(group_list, gAgent.getGroupID(), none_text); + group_list->setSortChangedCallback(onGroupSortChanged); //Force 'none' to always be first entry. childSetAction("Activate", onBtnActivate, this); @@ -478,8 +477,97 @@ bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& res void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata) { - LLPanelGroups* self = (LLPanelGroups*)userdata; - if(self) self->enableButtons(); + LLPanelGroups *self = (LLPanelGroups*)userdata; + if(!self) + return; + + self->enableButtons(); + + LLScrollListCtrl *group_list = (LLScrollListCtrl*)self->getChild("group list"); + if(!group_list) + return; + + LLScrollListItem *item = group_list->getFirstSelected(); + if(!item) + return; + + const LLUUID group_id = item->getValue().asUUID(); + if(group_id.isNull()) + return; + + LLGroupData group_data; + if(!gAgent.getGroupData(group_id,group_data)) + return; + + bool list_in_profile = item->getColumn(1)->getValue().asBoolean(); + bool receive_chat = item->getColumn(2)->getValue().asBoolean(); + bool recieve_notify = item->getColumn(3)->getValue().asBoolean(); + bool update_floaters = false; + if(gIMMgr->getIgnoreGroup(group_id) == receive_chat) + { + gIMMgr->updateIgnoreGroup(group_id, !receive_chat); + update_floaters = true; + } + if( (bool)group_data.mListInProfile != list_in_profile || + (bool)group_data.mAcceptNotices != recieve_notify ) + { + gAgent.setUserGroupFlags(group_id, recieve_notify, list_in_profile); + } + else if(update_floaters) //gAgent.setUserGroupFlags already calls update_group_floaters + update_group_floaters(group_id); +} + +LLSD create_group_element(const LLGroupData *group_datap, const LLUUID &active_group, const std::string& none_text, const U64 &powers_mask) +{ + if(group_datap && !((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0))) + return LLSD(); + const LLUUID &id = group_datap ? group_datap->mID : LLUUID::null; + const bool enabled = !!group_datap; + + std::string style = (group_datap && group_datap->mListInProfile) ? "BOLD" : "NORMAL"; + if(active_group == id) + { + style.append("|ITALIC"); + } + LLSD element; + element["id"] = id; + LLSD& name_column = element["columns"][0]; + name_column["column"] = "name"; + name_column["value"] = group_datap ? group_datap->mName : none_text; + name_column["font"] = "SANSSERIF"; + name_column["font-style"] = style; + + LLSD& show_column = element["columns"][1]; + show_column["column"] = "is_listed_group"; + show_column["type"] = "checkbox"; + show_column["enabled"] = enabled; + show_column["value"] = enabled && group_datap->mListInProfile; + + LLSD& chat_column = element["columns"][2]; + chat_column["column"] = "is_chattable_group"; + chat_column["type"] = "checkbox"; + chat_column["enabled"] = enabled; + chat_column["value"] = enabled && !gIMMgr->getIgnoreGroup(id); + + LLSD& notice_column = element["columns"][3]; + notice_column["column"] = "is_notice_group"; + notice_column["type"] = "checkbox"; + notice_column["enabled"] = enabled; + notice_column["value"] = enabled && group_datap->mAcceptNotices; + + return element; +} + +void onGroupSortChanged(void* user_data) +{ + LLPanelGroups *panel = (LLPanelGroups*)user_data; + if(!panel) + return; + LLScrollListCtrl *group_list = (LLScrollListCtrl*)panel->getChild("group list"); + if(!group_list) + return; + + group_list->moveToFront(group_list->getItemIndex(LLUUID::null)); } void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const std::string& none_text, U64 powers_mask) @@ -489,48 +577,29 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s LLCtrlListInterface *group_list = ctrl->getListInterface(); if (!group_list) return; + const LLUUID selected_id = group_list->getSelectedValue(); + const S32 selected_idx = group_list->getFirstSelectedIndex(); + const S32 scroll_pos = ctrl->getScrollPos(); + group_list->operateOnAll(LLCtrlListInterface::OP_DELETE); for(S32 i = 0; i < count; ++i) { - id = gAgent.mGroups.get(i).mID; - LLGroupData* group_datap = &gAgent.mGroups.get(i); - if ((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0)) - { - std::string style = "NORMAL"; - if(highlight_id == id) - { - style = "BOLD"; - } - - LLSD element; - element["id"] = id; - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = group_datap->mName; - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][0]["font-style"] = style; - + LLSD element = create_group_element(&gAgent.mGroups.get(i), highlight_id, none_text, powers_mask); + if(element.size()) group_list->addElement(element, ADD_SORTED); - } } // add "none" to list at top - { - std::string style = "NORMAL"; - if (highlight_id.isNull()) - { - style = "BOLD"; - } - LLSD element; - element["id"] = LLUUID::null; - element["columns"][0]["column"] = "name"; - element["columns"][0]["value"] = none_text; - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][0]["font-style"] = style; + group_list->addElement(create_group_element(NULL, highlight_id, none_text, powers_mask), ADD_TOP); - group_list->addElement(element, ADD_TOP); - } - - group_list->selectByValue(highlight_id); + if(selected_id.notNull()) + group_list->selectByValue(selected_id); + else + group_list->selectByValue(highlight_id); //highlight is actually active group + if(selected_idx!=group_list->getFirstSelectedIndex()) //if index changed then our stored pos is pointless. + ctrl->scrollToShowSelected(); + else + ctrl->setScrollPos(scroll_pos); } diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index fa6ba162e..76ea40008 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llbutton.h" #include "llfloatergodtools.h" +#include "llfloateravatarinfo.h" #include "llparcel.h" #include "llscrolllistctrl.h" #include "lllineeditor.h" @@ -50,6 +51,10 @@ #include "llviewerregion.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "llagentcamera.h" +#include "llviewerobjectlist.h" + +void cmdline_printchat(std::string message); LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL; @@ -104,6 +109,11 @@ BOOL LLFloaterTopObjects::postBuild() childSetAction("disable_all_btn", onDisableAll, this); childSetAction("refresh_btn", onRefresh, this); + childSetAction("lagwarning", onLagWarningBtn, this); + childSetAction("profile", onProfileBtn, this); + childSetAction("kick", onKickBtn, this); + childSetAction("tpto", onTPBtn, this); + childSetAction("filter_object_btn", onGetByObjectNameClicked, this); childSetAction("filter_owner_btn", onGetByOwnerNameClicked, this); @@ -202,6 +212,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) element["columns"][1]["column"] = "name"; element["columns"][1]["value"] = name_buf; element["columns"][1]["font"] = "SANSSERIF"; + if (name_buf == owner_buf) + { + element["columns"][1]["color"] = LLColor4::red.getValue(); + } element["columns"][2]["column"] = "owner"; element["columns"][2]["value"] = owner_buf; element["columns"][2]["font"] = "SANSSERIF"; @@ -292,6 +306,28 @@ void LLFloaterTopObjects::onDoubleClickObjectsList(void* data) { LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; self->showBeacon(); + self->lookAtAvatar(); +} + +void LLFloaterTopObjects::lookAtAvatar() +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + LLUUID taskid = first_selected->getUUID(); + + LLVOAvatar* voavatar = gObjectList.findAvatar(taskid); + if(voavatar) + { + gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + gAgentCamera.changeCameraToThirdPerson(); + gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),taskid); + gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() + + LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(), + voavatar->getPositionGlobal(), + taskid ); + } } // static @@ -381,6 +417,126 @@ void LLFloaterTopObjects::onReturnSelected(void* data) sInstance->doToObjects(ACTION_RETURN, false); } +void LLFloaterTopObjects::onLagWarningBtn(void* data) +{ + LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; + + self->onLagWarning(data); +} + +void LLFloaterTopObjects::onLagWarning(void* data) +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + LLUUID taskid = first_selected->getUUID(); + + std::string name = first_selected->getColumn(1)->getValue().asString(); + std::string score = first_selected->getColumn(0)->getValue().asString(); + + std::istringstream stm; + stm.str(score); + F32 f_score; + stm >> f_score; + F32 percentage = 100.f * (f_score / 22); + + std::string message = llformat( + "Hello %s, you are receiving this automated message because you are wearing heavily scripted attachments/HUDs, " + "causing excessive script lag (%5.2f ms, that's ca. %5.2f%% of the region's resources.)\n\n" + "Please remove resizer scripts or attachments to reduce your script time, thank you.", + name.c_str(), + (F32)f_score, + (F32)percentage + ); + + std::string my_name; + gAgent.buildFullname(my_name); + + cmdline_printchat(llformat("Script time warning sent to %s: (%5.2f ms)", + name.c_str(),(F32)f_score)); + + send_improved_im(LLUUID(taskid), + my_name, + message, + IM_ONLINE, + IM_NOTHING_SPECIAL, + LLUUID::null, + NO_TIMESTAMP, + (U8*)EMPTY_BINARY_BUCKET, + EMPTY_BINARY_BUCKET_SIZE); +} + +void LLFloaterTopObjects::onProfileBtn(void* data) +{ + LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; + self->onProfile(data); +} + +void LLFloaterTopObjects::onProfile(void* data) +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + LLUUID taskid = first_selected->getUUID(); + LLFloaterAvatarInfo::showFromDirectory(taskid); +} + +void LLFloaterTopObjects::onKickBtn(void* data) +{ + LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; + self->onKick(data); +} + +void LLFloaterTopObjects::onKick(void* data) +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + LLUUID taskid = first_selected->getUUID(); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + msg->nextBlock("MethodData"); + msg->addString("Method", "kickestate"); + msg->addUUID("Invoice", LLUUID::null); + msg->nextBlock("ParamList"); + msg->addString("Parameter", taskid.asString().c_str()); + msg->sendReliable(gAgent.getRegionHost()); +} +void LLFloaterTopObjects::onTPBtn(void* data) +{ + LLFloaterTopObjects* self = (LLFloaterTopObjects*)data; + self->onTP(data); +} + +void LLFloaterTopObjects::onTP(void* data) +{ + LLScrollListCtrl* list = getChild("objects_list"); + if (!list) return; + LLScrollListItem* first_selected = list->getFirstSelected(); + if (!first_selected) return; + + std::string name = first_selected->getColumn(1)->getValue().asString(); + std::string pos_string = first_selected->getColumn(3)->getValue().asString(); + + F32 x, y, z; + S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z); + if (matched != 3) return; + + LLVector3 pos_agent(x, y, z); + LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent); + + gAgent.teleportViaLocation( pos_global ); +} + + //static bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 58cbf5d2c..74a7ed611 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -56,6 +56,11 @@ public: static void setMode(U32 mode) { if (sInstance) sInstance->mCurrentMode = mode; } + void onProfile(void* data); + void onKick(void* data); + void onTP(void* data); + void onLagWarning(void* data); + private: LLFloaterTopObjects(); ~LLFloaterTopObjects(); @@ -64,6 +69,7 @@ private: static void onCommitObjectsList(LLUICtrl* ctrl, void* data); static void onDoubleClickObjectsList(void* data); + void lookAtAvatar(); static void onClickShowBeacon(void* data); void doToObjects(int action, bool all); @@ -73,6 +79,11 @@ private: static void onDisableAll(void* data); static void onDisableSelected(void* data); + static void onProfileBtn(void* data); + static void onKickBtn(void* data); + static void onTPBtn(void* data); + static void onLagWarningBtn(void* data); + static bool callbackReturnAll(const LLSD& notification, const LLSD& response); static bool callbackDisableAll(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index c7f8fc9d2..6e1f6de57 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -221,7 +221,6 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mOpenEnrollment(FALSE), mMembershipFee(0), mAllowPublish(FALSE), - mListInProfile(FALSE), mMaturePublish(FALSE), mChanged(FALSE), mMemberCount(0), diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index a0604be57..f3b32964b 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -255,7 +255,6 @@ public: BOOL mOpenEnrollment; S32 mMembershipFee; BOOL mAllowPublish; - BOOL mListInProfile; BOOL mMaturePublish; BOOL mChanged; S32 mMemberCount; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 164d3a950..3564db2f5 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -123,6 +123,8 @@ LLNetMap::LLNetMap(const std::string& name) : (new mmsetblue())->registerListener(this, "MiniMap.setblue"); (new mmsetyellow())->registerListener(this, "MiniMap.setyellow"); (new mmsetcustom())->registerListener(this, "MiniMap.setcustom"); + (new mmsetunmark())->registerListener(this, "MiniMap.setunmark"); + (new mmenableunmark())->registerListener(this, "MiniMap.enableunmark"); LLUICtrlFactory::getInstance()->buildPanel(this, "panel_mini_map.xml"); @@ -176,18 +178,15 @@ void LLNetMap::translatePan( F32 delta_x, F32 delta_y ) /////////////////////////////////////////////////////////////////////////////////// -LLColor4 mm_mapcols[1024]; -LLUUID mm_mapkeys[1024]; -U32 mm_netmapnum; +std::size_t hash_value(const LLUUID& uuid) +{ + return (std::size_t)uuid.getCRC32(); +} +boost::unordered_map mm_MarkerColors; -void LLNetMap::mm_setcolor(LLUUID key,LLColor4 col){ - if(mm_netmapnum>1023){ - llinfos << "Minimap color buffer filled, relog or something to clear it" << llendl; - return; - } - mm_mapcols[mm_netmapnum]=col; - mm_mapkeys[mm_netmapnum]=key; - mm_netmapnum+=1; +void LLNetMap::mm_setcolor(LLUUID key,LLColor4 col) +{ + mm_MarkerColors[key] = col; } void LLNetMap::draw() { @@ -376,7 +375,6 @@ void LLNetMap::draw() std::vector avatar_ids; std::vector positions; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); - U32 a; for(U32 i=0; i::const_iterator it = mm_MarkerColors.find(avatar_ids[i]); + if(it != mm_MarkerColors.end()) { - if(avatar_ids[i]==mm_mapkeys[a]) - { - avColor = mm_mapcols[a]; - } + avColor = it->second; } } @@ -1090,6 +1086,18 @@ bool LLNetMap::mmsetcustom::handleEvent(LLPointer event, const LLSD& us //} return true; } +bool LLNetMap::mmsetunmark::handleEvent(LLPointer event, const LLSD& userdata) +{ + mm_MarkerColors.erase(mPtr->mClosestAgentAtLastRightClick); + return true; +} +bool LLNetMap::mmenableunmark::handleEvent(LLPointer event, const LLSD& userdata) +{ + LLNetMap *self = mPtr; + BOOL enabled = mPtr->mClosestAgentAtLastRightClick.notNull() && mm_MarkerColors.find(mPtr->mClosestAgentAtLastRightClick) != mm_MarkerColors.end(); + self->findControl(userdata["control"].asString())->setValue(enabled); + return true; +} bool LLNetMap::LLCenterMap::handleEvent(LLPointer event, const LLSD& userdata) { EMiniMapCenter center = (EMiniMapCenter)userdata.asInteger(); diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 308ec11b4..2efae83dd 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -210,7 +210,16 @@ private: public: /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); }; - + class mmsetunmark : public LLMemberListener //moymod + { + public: + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); + }; + class mmenableunmark : public LLMemberListener //moymod + { + public: + /*virtual*/ bool handleEvent(LLPointer event, const LLSD& userdata); + }; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index e4c00dcf6..db52949c7 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -1689,6 +1689,10 @@ void LLPanelAvatar::resetGroupList() LLScrollListCtrl* group_list = mPanelSecondLife->getChild("groups"); if (group_list) { + const LLUUID selected_id = group_list->getSelectedValue(); + const S32 selected_idx = group_list->getFirstSelectedIndex(); + const S32 scroll_pos = group_list->getScrollPos(); + group_list->deleteAllItems(); S32 count = gAgent.mGroups.count(); @@ -1717,11 +1721,19 @@ void LLPanelAvatar::resetGroupList() row["id"] = id ; row["columns"][0]["value"] = group_string; row["columns"][0]["font"] = "SANSSERIF_SMALL"; - row["columns"][0]["font-style"] = group_data.mListInProfile ? "BOLD" : "NORMAL"; + std::string font_style = group_data.mListInProfile ? "BOLD" : "NORMAL"; + if(group_data.mID == gAgent.getGroupID()) + font_style.append("|ITALIC"); + row["columns"][0]["font-style"] = font_style; row["columns"][0]["width"] = 0; - group_list->addElement(row); + group_list->addElement(row,ADD_SORTED); } - group_list->sortByColumnIndex(0, TRUE); + if(selected_id.notNull()) + group_list->selectByValue(selected_id); + if(selected_idx!=group_list->getFirstSelectedIndex()) //if index changed then our stored pos is pointless. + group_list->scrollToShowSelected(); + else + group_list->setScrollPos(scroll_pos); } } } @@ -2248,22 +2260,23 @@ void LLPanelAvatar::processAvatarGroupsReply(LLMessageSystem *msg, void**) } } // Set normal color if not found or if group is visible in profile - if (!group_data || group_data->mListInProfile) + if (group_data) { - row["columns"][0]["font-style"] = "BOLD"; + std::string font_style = group_data->mListInProfile ? "BOLD" : "NORMAL"; + if(group_data->mID == gAgent.getGroupID()) + font_style.append("|ITALIC"); + row["columns"][0]["font-style"] = font_style; } + else + row["columns"][0]["font-style"] = "NORMAL"; } - - - if (group_list) { - group_list->addElement(row); + group_list->addElement(row,ADD_SORTED); } } } - if(group_list) group_list->sortByColumnIndex(0, TRUE); } } diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index fdef5380c..1c05d340f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -220,6 +220,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveNotices->setCallbackUserData(this); mCtrlReceiveNotices->set(accept_notices); mCtrlReceiveNotices->setEnabled(data.mID.notNull()); + mCtrlReceiveNotices->resetDirty(); } mCtrlReceiveChat = getChild("receive_chat", recurse); @@ -229,6 +230,7 @@ BOOL LLPanelGroupGeneral::postBuild() mCtrlReceiveChat->setCallbackUserData(this); mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); mCtrlReceiveChat->setEnabled(mGroupID.notNull()); + mCtrlReceiveChat->resetDirty(); } mCtrlListGroup = getChild("list_groups_in_profile", recurse); @@ -549,9 +551,17 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) BOOL receive_notices = false; BOOL list_in_profile = false; if (mCtrlReceiveNotices) + { receive_notices = mCtrlReceiveNotices->get(); + mCtrlReceiveNotices->resetDirty(); //resetDirty() here instead of in update because this is where the settings + //are actually being applied. onCommitUserOnly doesn't call updateChanged directly. + } if (mCtrlListGroup) + { list_in_profile = mCtrlListGroup->get(); + mCtrlListGroup->resetDirty(); //resetDirty() here instead of in update because this is where the settings + //are actually being applied. onCommitUserOnly doesn't call updateChanged directly. + } gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile); @@ -561,6 +571,7 @@ bool LLPanelGroupGeneral::apply(std::string& mesg) gIMMgr->updateIgnoreGroup(mGroupID, !receive_chat); // Save here too in case we crash somewhere down the road -- MC gIMMgr->saveIgnoreGroup(); + mCtrlReceiveChat->resetDirty(); } mChanged = FALSE; @@ -769,53 +780,80 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) mBtnInfo->setVisible(is_member && !mAllowEdit); } - if (mCtrlReceiveNotices) + if(gc == GC_ALL || gc == GC_PROPERTIES) { - mCtrlReceiveNotices->setVisible(is_member); - if (is_member) + if (mCtrlReceiveNotices) { - mCtrlReceiveNotices->setEnabled(mAllowEdit); + mCtrlReceiveNotices->setVisible(is_member); + if (is_member) + { + mCtrlReceiveNotices->setEnabled(mAllowEdit); + if(!mCtrlReceiveNotices->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlReceiveNotices->set(agent_gdatap.mAcceptNotices); + mCtrlReceiveNotices->resetDirty(); + } + } } - mCtrlReceiveNotices->resetDirty(); - } - if (mCtrlReceiveChat) - { - mCtrlReceiveChat->setVisible(is_member); - mCtrlReceiveChat->setEnabled(TRUE); - mCtrlReceiveChat->resetDirty(); - } + if (mCtrlListGroup) + { + mCtrlListGroup->setVisible(is_member); + if (is_member) + { + mCtrlListGroup->setEnabled(mAllowEdit); + if(!mCtrlListGroup->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlListGroup->set(agent_gdatap.mListInProfile); + mCtrlListGroup->resetDirty(); + } + } + } + if (mCtrlReceiveChat) + { + mCtrlReceiveChat->setVisible(is_member); + if (is_member) + { + mCtrlReceiveChat->setEnabled(mAllowEdit); + if(!mCtrlReceiveChat->isDirty()) //If the user hasn't edited this then refresh it. Value may have changed in groups panel, etc. + { + mCtrlReceiveChat->set(!gIMMgr->getIgnoreGroup(mGroupID)); + mCtrlReceiveChat->resetDirty(); + } + } + } - if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); - if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); + if (mInsignia) mInsignia->setEnabled(mAllowEdit && can_change_ident); + if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); - if (mGroupName) mGroupName->setText(gdatap->mName); - if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE); - if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE); + if (mGroupName) mGroupName->setText(gdatap->mName); + if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE); + if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE); - LLNameEditor* key_edit = getChild("group_key"); - if(key_edit) - { - key_edit->setText(gdatap->getID().asString()); - } - - if (mInsignia) - { - if (gdatap->mInsigniaID.notNull()) + LLNameEditor* key_edit = getChild("group_key"); + if(key_edit) { - mInsignia->setImageAssetID(gdatap->mInsigniaID); + key_edit->setText(gdatap->getID().asString()); } - else - { - mInsignia->setImageAssetID(mDefaultIconID); - } - } - if (mEditCharter) - { - mEditCharter->setText(gdatap->mCharter); - mEditCharter->resetDirty(); + if (mInsignia) + { + if (gdatap->mInsigniaID.notNull()) + { + mInsignia->setImageAssetID(gdatap->mInsigniaID); + } + else + { + mInsignia->setImageAssetID(mDefaultIconID); + } + } + + if (mEditCharter) + { + mEditCharter->setText(gdatap->mCharter); + mEditCharter->resetDirty(); + } } if (mListVisibleMembers) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3c1a73cc0..0ce93e3cc 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3759,10 +3759,10 @@ void process_teleport_finish(LLMessageSystem* msg, void**) */ //Reset the windlight profile to default - LLWLParamManager::instance()->mAnimator.mIsRunning = false; + /*LLWLParamManager::instance()->mAnimator.mIsRunning = false; LLWLParamManager::instance()->mAnimator.mUseLindenTime = false; LLWLParamManager::instance()->loadPreset("Default", true); - LLWaterParamManager::instance()->loadPreset("Default",true); + LLWaterParamManager::instance()->loadPreset("Default",true);*/ // now, use the circuit info to tell simulator about us! LL_INFOS("Messaging") << "process_teleport_finish() Enabling " diff --git a/indra/newview/skins/default/textures/icn_chat_overlay.tga b/indra/newview/skins/default/textures/icn_chat_overlay.tga new file mode 100644 index 000000000..fddaed1f3 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_chat_overlay.tga differ diff --git a/indra/newview/skins/default/xui/en-us/floater_top_objects.xml b/indra/newview/skins/default/xui/en-us/floater_top_objects.xml index 1b6051088..6b59ee391 100644 --- a/indra/newview/skins/default/xui/en-us/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en-us/floater_top_objects.xml @@ -1,28 +1,29 @@ + height="400" min_height="300" min_width="580" name="top_objects" + title="loading..." width="580"> Loading... - - - - - - - - + + + + + + + + + Object ID: + name="id_editor" width="385" />