From db2f409ef4854a38cea4feb7c6eeb0302a6d55df Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 18 Jun 2011 22:36:44 -0500 Subject: [PATCH 01/47] Preventing crash if shutting down while in login process. --- indra/newview/llappviewer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1448b7dd8..1b8cc8dd3 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; From b852a77a79af613601c576d6a65a78cb04eed5ef Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 21 Jun 2011 02:49:34 +0200 Subject: [PATCH 02/47] AIFilePicker related bug fixes. Bug fix in LLPreviewAnim::gotAssetForSave_continued: the if() that tests if the result from the filepicker can be used was accidently negated, mostly causing a crash when cancelling an animation preview download (open animation, File -> Save Texture As..), and canceling the save when a filename is picked. The lifetime of AIFileUpload is actually till the very end of the main(), causing it's member mPicker to be reused. This leads to problems. When someone tries to open a file picker for a file upload of the same time before the previous filepicker called the callback function (ie, when two filepickers are opened at the same time, or when the plugin crashes). With this fix it is possible to open any number of file pickers. Finally, for linux, LLFastTimers was using assembly with gives rather random results on multicore machines. Since AIStateMachine is using this for wait timing, it had a negative effect on how well the file picker worked (the last message wasn't flushed for several seconds). --- indra/llcommon/llfasttimer.cpp | 175 +----------------- indra/llcommon/llfasttimer.h | 1 - indra/newview/llpreviewanim.cpp | 2 +- indra/newview/llviewermenufile.cpp | 26 ++- indra/newview/statemachine/aistatemachine.cpp | 4 +- 5 files changed, 20 insertions(+), 188 deletions(-) diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index d3783c582..f1d7eb305 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -29,33 +29,22 @@ * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ */ + #include "linden_common.h" #include "llfasttimer.h" - #include "llmemory.h" #include "llprocessor.h" - #if LL_WINDOWS #define WIN32_LEAN_AND_MEAN #include -#include "lltimer.h" -#elif LL_LINUX || LL_SOLARIS -#include -#include -#include "lltimer.h" -#elif LL_DARWIN -#include -#include "lltimer.h" // get_clock_count() -#else -#error "architecture not supported" #endif +#include "lltimer.h" ////////////////////////////////////////////////////////////////////////////// // statics - LLFastTimer::EFastTimerType LLFastTimer::sCurType = LLFastTimer::FTM_OTHER; int LLFastTimer::sCurDepth = 0; U64 LLFastTimer::sStart[LLFastTimer::FTM_MAX_DEPTH]; @@ -70,44 +59,12 @@ S32 LLFastTimer::sLastFrameIndex = -1; int LLFastTimer::sPauseHistory = 0; int LLFastTimer::sResetHistory = 0; -#define USE_RDTSC 0 +U64 LLFastTimer::sClockResolution = calc_clock_frequency(50U); // Resolution of get_clock_count() -#if LL_LINUX || LL_SOLARIS -U64 LLFastTimer::sClockResolution = 1000000000; // 1e9, Nanosecond resolution -#else -U64 LLFastTimer::sClockResolution = 1000000; // 1e6, Microsecond resolution -#endif - - -//static -#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer { return sClockResolution >> 8; } -#else // windows or x86-mac or x86-linux or x86-solaris -U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer -{ -#if USE_RDTSC || !LL_WINDOWS - //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz - static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0); - - // we drop the low-order byte in our timers, so report a lower frequency -#else - // If we're not using RDTSC, each fasttimer tick is just a performance counter tick. - // Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency()) - // since that would change displayed MHz stats for CPUs - static bool firstcall = true; - static U64 sCPUClockFrequency; - if (firstcall) - { - QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency); - firstcall = false; - } -#endif - return sCPUClockFrequency >> 8; -} -#endif void LLFastTimer::reset() { @@ -162,139 +119,17 @@ void LLFastTimer::reset() // Important note: These implementations must be FAST! // - -#if LL_WINDOWS -// -// Windows implementation of CPU clock -// - -// -// NOTE: put back in when we aren't using platform sdk anymore -// -// because MS has different signatures for these functions in winnt.h -// need to rename them to avoid conflicts -//#define _interlockedbittestandset _renamed_interlockedbittestandset -//#define _interlockedbittestandreset _renamed_interlockedbittestandreset -//#include -//#undef _interlockedbittestandset -//#undef _interlockedbittestandreset - -//inline U32 LLFastTimer::getCPUClockCount32() -//{ -// U64 time_stamp = __rdtsc(); -// return (U32)(time_stamp >> 8); -//} -// -//// return full timer value, *not* shifted by 8 bits -//inline U64 LLFastTimer::getCPUClockCount64() -//{ -// return __rdtsc(); -//} - // shift off lower 8 bits for lower resolution but longer term timing // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing -#if USE_RDTSC -U32 LLFastTimer::getCPUClockCount32() -{ - U32 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax - } - return ret_val; -} -// return full timer value, *not* shifted by 8 bits -U64 LLFastTimer::getCPUClockCount64() -{ - U64 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax - } - return ret_val; -} - -std::string LLFastTimer::sClockType = "rdtsc"; - -#else //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp -// These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures. +// On windows these use QueryPerformanceCounter, which is arguably fine and also works on amd architectures. U32 LLFastTimer::getCPUClockCount32() { - return (U32)(get_clock_count()>>8); + return get_clock_count() >> 8; } U64 LLFastTimer::getCPUClockCount64() { return get_clock_count(); } - -std::string LLFastTimer::sClockType = "QueryPerformanceCounter"; -#endif - -#endif - - -#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -// -// Linux and Solaris implementation of CPU clock - non-x86. -// This is accurate but SLOW! Only use out of desperation. -// -// Try to use the MONOTONIC clock if available, this is a constant time counter -// with nanosecond resolution (but not necessarily accuracy) and attempts are -// made to synchronize this value between cores at kernel start. It should not -// be affected by CPU frequency. If not available use the REALTIME clock, but -// this may be affected by NTP adjustments or other user activity affecting -// the system time. -U64 LLFastTimer::getCPUClockCount64() -{ - struct timespec tp; - -#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time? - if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME -#endif - clock_gettime(CLOCK_REALTIME,&tp); - - return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec; -} - -U32 LLFastTimer::getCPUClockCount32() -{ - return (U32)(LLFastTimer::getCPUClockCount64() >> 8); -} - -std::string LLFastTimer::sClockType = "clock_gettime"; - -#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) - - -#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) -// -// Mac+Linux+Solaris FAST x86 implementation of CPU clock -U32 LLFastTimer::getCPUClockCount32() -{ - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return (U32)(x >> 8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return x; -} - -std::string LLFastTimer::sClockType = "rdtsc"; -#endif \ No newline at end of file diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 3a7f30511..5b34d361c 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -256,7 +256,6 @@ public: static void reset(); static U64 countsPerSecond(); - static std::string sClockType; public: static int sCurDepth; static U64 sStart[FTM_MAX_DEPTH]; diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 845129a38..6963f6a84 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -400,7 +400,7 @@ void LLPreviewAnim::gotAssetForSave(LLVFS *vfs, // static void LLPreviewAnim::gotAssetForSave_continued(char* buffer, S32 size, AIFilePicker* filepicker) { - if (!filepicker->hasFilename()) + if (filepicker->hasFilename()) { std::string filename = filepicker->getFilename(); std::ofstream export_file(filename.c_str(), std::ofstream::binary); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index d0b6d61c6..3eddf6df5 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -154,16 +154,13 @@ std::string build_extensions_string(ELoadFilter filter) } class AIFileUpload { - protected: - AIFilePicker* mPicker; - public: - AIFileUpload(void) : mPicker(NULL) { } - virtual ~AIFileUpload() { llassert(!mPicker); if (mPicker) { mPicker->abort(); mPicker = NULL; } } + AIFileUpload(void) { } + virtual ~AIFileUpload() { } public: bool is_valid(std::string const& filename, ELoadFilter type); - void filepicker_callback(ELoadFilter type); + void filepicker_callback(ELoadFilter type, AIFilePicker* picker); void start_filepicker(ELoadFilter type, char const* context); protected: @@ -179,21 +176,22 @@ void AIFileUpload::start_filepicker(ELoadFilter filter, char const* context) // display(); } - llassert(!mPicker); - mPicker = AIFilePicker::create(); - mPicker->open(filter, "", context); - mPicker->run(boost::bind(&AIFileUpload::filepicker_callback, this, filter)); + AIFilePicker* picker = AIFilePicker::create(); + picker->open(filter, "", context); + // Note that when the call back is called then we're still in the main loop of + // the viewer and therefore the AIFileUpload still exists, since that is only + // destructed at the end of main when exiting the viewer. + picker->run(boost::bind(&AIFileUpload::filepicker_callback, this, filter, picker)); } -void AIFileUpload::filepicker_callback(ELoadFilter type) +void AIFileUpload::filepicker_callback(ELoadFilter type, AIFilePicker* picker) { - if (mPicker->hasFilename()) + if (picker->hasFilename()) { - std::string filename = mPicker->getFilename(); + std::string filename = picker->getFilename(); if (is_valid(filename, type)) handle_event(filename); } - mPicker = NULL; } bool AIFileUpload::is_valid(std::string const& filename, ELoadFilter type) diff --git a/indra/newview/statemachine/aistatemachine.cpp b/indra/newview/statemachine/aistatemachine.cpp index 2eccfb53e..bdf43fcdc 100644 --- a/indra/newview/statemachine/aistatemachine.cpp +++ b/indra/newview/statemachine/aistatemachine.cpp @@ -79,7 +79,7 @@ AITHREADSAFESIMPLE(U64, AIStateMachine::sMaxCount, ); void AIStateMachine::updateSettings(void) { Dout(dc::statemachine, "Initializing AIStateMachine::sMaxCount"); - *AIAccess(sMaxCount) = LLFastTimer::countsPerSecond() * gSavedSettings.getU32("StateMachineMaxTime") / 1000; + *AIAccess(sMaxCount) = LLFastTimer::sClockResolution * gSavedSettings.getU32("StateMachineMaxTime") / 1000; } //---------------------------------------------------------------------------- @@ -319,7 +319,7 @@ void AIStateMachine::mainloop(void*) if (total_clocks >= max_count) { #ifndef LL_RELEASE_FOR_DOWNLOAD - llwarns << "AIStateMachine::mainloop did run for " << (total_clocks * 1000 / LLFastTimer::countsPerSecond()) << " ms." << llendl; + llwarns << "AIStateMachine::mainloop did run for " << (total_clocks * 1000 / LLFastTimer::sClockResolution) << " ms." << llendl; #endif std::sort(active_statemachines.begin(), active_statemachines.end(), QueueElementComp()); break; From a5522c204e560d9139462f880484e073e6cddbd3 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Tue, 21 Jun 2011 03:05:34 +0200 Subject: [PATCH 03/47] Save Preview As... Replace 'Save Texture As...' in File menu with 'Save Preview As...', since it's used for textures, sounds, animations, notecards and scripts, which ever type you have open at the moment. This fix addresses http://code.google.com/p/singularity-viewer/issues/detail?id=12 --- indra/newview/llviewermenufile.cpp | 5 ++--- indra/newview/skins/default/xui/en-us/menu_viewer.xml | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 3eddf6df5..e859d0d3d 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -476,7 +476,7 @@ class LLFileMinimizeAllWindows : public view_listener_t }; // -class LLFileSaveTexture : public view_listener_t +class LLFileSavePreview : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { @@ -1266,12 +1266,11 @@ void init_menu_file() // (new LLFileMinimizeAllWindows())->registerListener(gMenuHolder, "File.MinimizeAllWindows"); // - (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); + (new LLFileSavePreview())->registerListener(gMenuHolder, "File.SavePreview"); (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); (new LLFileLogOut())->registerListener(gMenuHolder, "File.LogOut"); - //Emerald has a second llFileSaveTexture here... Same as the original. Odd. -HgB (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs"); } diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml index afba100cc..4a49daede 100644 --- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml @@ -52,9 +52,9 @@ - - + + Date: Tue, 21 Jun 2011 12:03:28 -0500 Subject: [PATCH 04/47] Groups/agent profile floaters now update when a group visbility changes. Apply button in group settings doesn't behave quite as badly after changing notices/chat/show in profile settings. Groups floater now bolds visible groups, italicized if active (this may need to be something more noticeable) --- indra/newview/llagent.cpp | 12 +++++++--- indra/newview/llfloatergroups.cpp | 25 ++++++++++++-------- indra/newview/llpanelavatar.cpp | 33 +++++++++++++++++++-------- indra/newview/llpanelgroupgeneral.cpp | 23 +++++++++++++++++-- 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 12132d4d4..97f21d5ef 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2488,15 +2488,18 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution) return FALSE; } +void update_group_floaters(const LLUUID& group_id); + BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile) { 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 +2511,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/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 132c2abec..31f1328aa 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -198,15 +198,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(); @@ -489,6 +483,10 @@ 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) @@ -497,10 +495,10 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s LLGroupData* group_datap = &gAgent.mGroups.get(i); if ((powers_mask == GP_ALL_POWERS) || ((group_datap->mPowers & powers_mask) != 0)) { - std::string style = "NORMAL"; + std::string style = group_datap->mListInProfile ? "BOLD" : "NORMAL"; if(highlight_id == id) { - style = "BOLD"; + style.append("|ITALIC"); } LLSD element; @@ -519,7 +517,7 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s std::string style = "NORMAL"; if (highlight_id.isNull()) { - style = "BOLD"; + style = "ITALIC"; } LLSD element; element["id"] = LLUUID::null; @@ -531,6 +529,13 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s 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/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..fd76249c7 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; @@ -776,14 +787,22 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) { mCtrlReceiveNotices->setEnabled(mAllowEdit); } - mCtrlReceiveNotices->resetDirty(); + //mCtrlReceiveNotices->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. + } + + if (mCtrlListGroup) + { + mCtrlListGroup->setVisible(is_member); + if (is_member) + mCtrlListGroup->setEnabled(mAllowEdit); + //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. } if (mCtrlReceiveChat) { mCtrlReceiveChat->setVisible(is_member); mCtrlReceiveChat->setEnabled(TRUE); - mCtrlReceiveChat->resetDirty(); + //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. } From 9a224f2b5c18f903bcc776eb51955505d0ce148f Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Wed, 22 Jun 2011 01:22:52 +0200 Subject: [PATCH 05/47] Fix to problems with regex characters in group names. Stolen from https://bitbucket.org/squire_linden/viewer-dev-chop-662/changeset/6f971899f351 --- indra/llvfs/lldiriterator.cpp | 11 ++++++++--- indra/newview/lllogchat.cpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp index 9434efd40..cef016e0c 100644 --- a/indra/llvfs/lldiriterator.cpp +++ b/indra/llvfs/lldiriterator.cpp @@ -142,9 +142,6 @@ std::string glob_to_regex(const std::string& glob) switch (c) { - case '.': - regex+="\\."; - break; case '*': if (glob.begin() == i) { @@ -177,6 +174,14 @@ std::string glob_to_regex(const std::string& glob) case '!': regex+= square_brace_open ? '^' : c; break; + case '.': // This collection have different regex meaning + case '^': // And so need escaping + case '(': + case ')': + case '+': + case '|': + case '$': + regex+='\\'; default: regex+=c; break; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index cf52896e8..574d70f4b 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -66,7 +66,7 @@ std::string LLLogChat::makeLogFileName(std::string filename) std::string LLLogChat::cleanFileName(std::string filename) { - std::string invalidChars = "\"\'\\/?*:<>|"; + std::string invalidChars = "\"\'\\/?*:<>|[]{}~"; // Cannot match glob or illegal filename chars S32 position = filename.find_first_of(invalidChars); while (position != filename.npos) { From 0663a3f028270b11813bbe9741256ad69088fc63 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Thu, 23 Jun 2011 03:56:09 -0500 Subject: [PATCH 06/47] Added checkboxes to groups list for visibility, groupchat, and notices... -Required addition of an extra texture overlay for list headers, as normal button overlay is used for sort arrows. -Added padding to italic text in scroll list, as the text clipped outside of the element. -Groups list is now sortable and has header visible. -'none' entry always be first in the list, regardless of sort order. -LLGroupMgrGroupData::mListInProfile removed. Was unreferenced and always false. LLGroupMgrGroupData doesn't handle show/chat/notify properties --- indra/llui/llbutton.h | 2 + indra/llui/llscrolllistctrl.cpp | 129 ++++++++++++++++- indra/llui/llscrolllistctrl.h | 6 + indra/newview/llagent.cpp | 2 - indra/newview/llagent.h | 1 + indra/newview/llfloatergroups.cpp | 136 +++++++++++++----- indra/newview/llgroupmgr.cpp | 1 - indra/newview/llgroupmgr.h | 1 - indra/newview/llpanelgroupgeneral.cpp | 107 ++++++++------ .../skins/default/xui/en-us/panel_groups.xml | 16 ++- 10 files changed, 312 insertions(+), 89 deletions(-) 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/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/llagent.cpp b/indra/newview/llagent.cpp index 97f21d5ef..000f4067e 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2488,8 +2488,6 @@ BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution) return FALSE; } -void update_group_floaters(const LLUUID& group_id); - BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile) { S32 count = mGroups.count(); 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/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 31f1328aa..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 ///---------------------------------------------------------------------------- @@ -214,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); @@ -472,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) @@ -491,43 +585,13 @@ void init_group_list(LLScrollListCtrl* ctrl, const LLUUID& highlight_id, const s 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 = group_datap->mListInProfile ? "BOLD" : "NORMAL"; - if(highlight_id == id) - { - style.append("|ITALIC"); - } - - 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 = "ITALIC"; - } - 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(element, ADD_TOP); - } + group_list->addElement(create_group_element(NULL, highlight_id, none_text, powers_mask), ADD_TOP); if(selected_id.notNull()) group_list->selectByValue(selected_id); 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/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index fd76249c7..1c05d340f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -780,61 +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(); Don't resetDirty. This ctrl is decoupled from update. - } - if (mCtrlListGroup) - { - mCtrlListGroup->setVisible(is_member); - if (is_member) - mCtrlListGroup->setEnabled(mAllowEdit); - //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. - } + 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); - mCtrlReceiveChat->setEnabled(TRUE); - //mCtrlReceiveChat->resetDirty(); Don't resetDirty. This ctrl is decoupled from update. - } + 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/skins/default/xui/en-us/panel_groups.xml b/indra/newview/skins/default/xui/en-us/panel_groups.xml index 75ad985fb..f4acca0af 100644 --- a/indra/newview/skins/default/xui/en-us/panel_groups.xml +++ b/indra/newview/skins/default/xui/en-us/panel_groups.xml @@ -1,18 +1,26 @@ - - + + + + + - Your currently active group is displayed in bold. + Your currently active group is displayed in italics. Date: Thu, 23 Jun 2011 03:58:41 -0500 Subject: [PATCH 07/47] New asset. Overlay icon for list header: Receive group chat. --- .../skins/default/textures/icn_chat_overlay.tga | Bin 0 -> 4140 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 indra/newview/skins/default/textures/icn_chat_overlay.tga 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 0000000000000000000000000000000000000000..fddaed1f37691ccd7778797d2b1eb173fb6e5a7b GIT binary patch literal 4140 zcmeH}drXyO9LJ%6D7wLlh2=Uhi$Nqs2rauT3>0h~E?y3nIkx~cJT90BLdnHz48}!n zCpLizV}d9s!tlUJ3*0oL!%g4-Zs^P5vUm^C{6pvL`+fHwV}uG@ZngQGefB=@d!Fa_ zecs>Yd0q>P$1KcEVS%5m`R>v6Kkos?>PcX}{vFDPyL20ve-11LuYuRWtH1&9KTGhi z8sFC$ybV5bc6MIt;o+e|e+BRcOTg3M-)>eg$ahwNcR|?7l`CUvYHG3?8yj;sZrm7e zV`CGJ=kEg-U=J9VC*&*pmn7x;e_;2JsJUB0q!hB12ya4iqYnP)JD{(c7pdU|?p&Ck!zn3|e8MqTie zOv}xiH)|>?Dsn?YLgKx>y|?=N`$xh@kpTe#kwHO0QDI?WTfMxzzN8(n9B@63z#7ce z`21zC+}74s6&e~E+uGWi3%y#P1I>W%-vqdp7EnJnHdb=!(xn1}!Jz5y@7G+paz)eE z*Z0HKt5=Jgo0|`Rhvw?)8UeejfhTwY%#O$7c*eCY1)=b5^5o=XxvX^_*K0_4&(|EmOlb*YE~l?aYh?bA_>6<>%+8HX4m(nAdvo;>C{i^z^QT zgoKW`xH!Fx)Ze*tXGdaUV(0$-`@1owCo?m%CnqPTN2Ag7l$V$HK(pua<;(rIZr$pK ztzV8GKYrBR-TiB5FsEDrHO-B2_jPe``Re4!lbIM_kN0nnjEo#YECrQHH4+gKA;ibW z3%hsk7NVk}gxJ_v0qYXBY}q2H)oLLrDM^Tli4pef*&`Ge7Yj#@91%)OOO1%35%z|` z&xM7B8BR`4%n2XxEMUH~v3@?-ym@mH##IAdS67!F_C`xeN<_q1#IwnTf;#yFa9%H9 z9IH`FiO~8GFb^1a!us%sAJZ|0`E|ant?f7Xcf6&gWeWEua^S!LQ*v^$)IWXtvdMka@otwXB4{axjLuME!Q; z;b?VrHSO^IMZ`~3C=}wv#Ds`=h<0{%;=sUwn3k3%!iL!0-7RKkXG?vgJ?Bh=-$4gp z4r{Bbs`BjZ?bl#D_i$=+4T?pJ7Ok(Xtu4S9=J2_>^gBB{MZI1xt>yal>muq->LXV~ zl5ISH;59WhRnpJR z&7DhM+tAQZg#BOxHD!JJfbYMKYl8;s`>y|~f8)lD2kM&Fh8mUhkt?(HnSU+RpcXX& zwYlHF0)kL8S+n&S|ApwIHYI)J?wtD6pq8vjZTg>kpC8tq2K_pqLr&{a-{V@X_HO>; zxs>nsyI#0(!G!(7gxr{!|I9z;RUL9VjasrMwb`Br%YA%&qM@6IaShk5UF*VLGgety zxuE!C?#x&*|9RgBnsho{zOSz@_duRU)HF9cbh!7g4i69i24ky0C+d3`=h!G}dlY+| zar^e|#^~tif57KEcI+_1f5xn=EF)rOM4cH=oH#Mw+uJ)1TLRDq2M5PNgXbZ&sA+D@ z11I2RWo5O#tgP&NoL}{Ib#=cM6%`o{9y~ahl9FOTZqEto->`4rJ_EKd1M=R0J=1XJ z%$b4q_IAVI;9wW_&$hh0ykgkr_rhDU7B$U{`!I8X-!dz3{(g@4{C0SFm}el*T=Q9{ zLw`P)$DbV<8mic~ZCi@9wKezsPh<^hQFC_VnXm-Bhc&E09;tDrCBvVGus38N7c=qw zbx&~SN&lTXbt(gU=^@l$vQnv3!>6IJ$!{durpEmmQ9UUD*a1Fj6 z9OK~NpyV8RE^W}30?dp#ZtvL`8;)g;vNm~E5bhK6!91RGX@j Date: Thu, 23 Jun 2011 17:32:19 -0500 Subject: [PATCH 08/47] Agent pie-menu -> tools -> anims... crash fix. http://code.google.com/p/singularity-viewer/issues/detail?id=89 --- indra/newview/llfloateranimpreview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ); From 378053bd4884a69502180fc81094a2a43832d0e3 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 25 Jun 2011 00:28:28 -0500 Subject: [PATCH 09/47] two_sided_delimiter workaround (Broken comment blocks in LSL '/*comment*/') Didn't want to mess with the token class for one single case. This fix is pretty straight-forward and self-contained. --- indra/llui/llkeywords.cpp | 7 +++++-- indra/newview/app_settings/keywords.ini | 5 +++-- indra/newview/skins/gemini/keywords.ini | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) 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/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/skins/gemini/keywords.ini b/indra/newview/skins/gemini/keywords.ini index 58044b9a8..474c5351f 100644 --- a/indra/newview/skins/gemini/keywords.ini +++ b/indra/newview/skins/gemini/keywords.ini @@ -603,11 +603,12 @@ return Leave current function or event handler # Comment [one_sided_delimiter .86, .69, .50] // 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 .86, .69, .50] -/* */ Comment:Non-functional commentary or disabled code +/* Comment:Non-functional commentary or disabled code # String literals [two_sided_delimiter_esc .57, .83, .52] -" " String literal +" String literal #functions are supplied by the program now. From d476daba7160f069475138d4313a6fccdce86111 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sat, 25 Jun 2011 04:53:01 -0500 Subject: [PATCH 10/47] Added contextual 'unmark' selection to minimap rightclick menu --- indra/newview/llnetmap.cpp | 42 +++++++++++-------- indra/newview/llnetmap.h | 11 ++++- .../skins/default/xui/en-us/menu_mini_map.xml | 8 +++- 3 files changed, 41 insertions(+), 20 deletions(-) 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/skins/default/xui/en-us/menu_mini_map.xml b/indra/newview/skins/default/xui/en-us/menu_mini_map.xml index 185c9f489..c870268ce 100644 --- a/indra/newview/skins/default/xui/en-us/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en-us/menu_mini_map.xml @@ -64,6 +64,10 @@ left="0" mouse_opaque="true" name="Custom" width="128"> - - + + + + + From fae8f7803ef0fba03f61b98dab9203412ca96ab2 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Sat, 25 Jun 2011 13:45:04 +0200 Subject: [PATCH 11/47] Fix for Communicate flyout button. Remove erroneously linked control variable. The 'value' of a LLFlyoutButton is the (last) selected value: a string. Linking it to some random boolean control variable causes this value to be (re)assigned to the flyout button list through LLControlVariable::setValue (whenever said boolean changes, in this case when the floater is made to appear) which calls getComparableValue with the string value (ie "mute list") and tries to convert that to a boolean. Obviously That fails and the value is set to "", effectively having nothing selected anymore. This fixes http://code.google.com/p/singularity-viewer/issues/detail?id=21 --- indra/newview/lltoolbar.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 593a382cd..44fc368f3 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -126,7 +126,6 @@ LLToolBar::LLToolBar() BOOL LLToolBar::postBuild() { childSetCommitCallback("communicate_btn", onClickCommunicate, this); - childSetControlName("communicate_btn", "ShowCommunicate"); childSetAction("chat_btn", onClickChat, this); childSetControlName("chat_btn", "ChatVisible"); From 9c971ac4e7c1699448a81a918aa68c69c03961d7 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Mon, 27 Jun 2011 01:10:56 -0500 Subject: [PATCH 12/47] Added myraid of additional options to top scripts/top collisions floaters. --- indra/newview/llfloatertopobjects.cpp | 156 ++++++++++++++++++ indra/newview/llfloatertopobjects.h | 11 ++ .../default/xui/en-us/floater_top_objects.xml | 52 +++--- 3 files changed, 198 insertions(+), 21 deletions(-) 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/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" />