From 8ceca3943a1c843b5fa67d0133f22df47efbe6fd Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Wed, 21 Jul 2010 15:22:58 -0700 Subject: Added area search files missing from 8524a4228 --- linden/indra/newview/jcfloaterareasearch.cpp | 342 +++++++++++++++++++++ linden/indra/newview/jcfloaterareasearch.h | 99 ++++++ .../default/xui/en-us/floater_area_search.xml | 50 +++ 3 files changed, 491 insertions(+) create mode 100644 linden/indra/newview/jcfloaterareasearch.cpp create mode 100644 linden/indra/newview/jcfloaterareasearch.h create mode 100644 linden/indra/newview/skins/default/xui/en-us/floater_area_search.xml (limited to 'linden/indra') diff --git a/linden/indra/newview/jcfloaterareasearch.cpp b/linden/indra/newview/jcfloaterareasearch.cpp new file mode 100644 index 0000000..5b269fa --- /dev/null +++ b/linden/indra/newview/jcfloaterareasearch.cpp @@ -0,0 +1,342 @@ +/* Copyright (c) 2009 + * + * Modular Systems Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. Neither the name Modular Systems Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS LTD AND CONTRIBUTORS “AS IS” + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Modified, debugged, optimized and improved by Henri Beauchamp Feb 2010. + */ + +#include "llviewerprecompiledheaders.h" + +#include "lluuid.h" +#include "lluictrlfactory.h" +#include "llscrolllistctrl.h" + +#include "llagent.h" +#include "lltracker.h" +#include "llviewerobjectlist.h" +#include "llviewercontrol.h" +#include "jcfloaterareasearch.h" + +JCFloaterAreaSearch* JCFloaterAreaSearch::sInstance = NULL; +LLViewerRegion* JCFloaterAreaSearch::sLastRegion = NULL; +S32 JCFloaterAreaSearch::sRequested = 0; +std::map JCFloaterAreaSearch::sObjectDetails; +std::string JCFloaterAreaSearch::sSearchedName; +std::string JCFloaterAreaSearch::sSearchedDesc; +std::string JCFloaterAreaSearch::sSearchedOwner; +std::string JCFloaterAreaSearch::sSearchedGroup; + +const std::string request_string = "JCFloaterAreaSearch::Requested_ø§µ"; +const F32 min_refresh_interval = 0.25f; // Minimum interval between list refreshes in seconds. + +JCFloaterAreaSearch::JCFloaterAreaSearch() : +LLFloater(), +mCounterText(0), +mResultList(0) +{ + llassert_always(sInstance == NULL); + sInstance = this; + mLastUpdateTimer.reset(); +} + +JCFloaterAreaSearch::~JCFloaterAreaSearch() +{ + sInstance = NULL; +} + +void JCFloaterAreaSearch::close(bool app) +{ + if (app) + { + LLFloater::close(app); + } + else + { + if (sInstance) + { + sInstance->setVisible(FALSE); + } + } +} + +BOOL JCFloaterAreaSearch::postBuild() +{ + mResultList = getChild("result_list"); + mResultList->setCallbackUserData(this); + mResultList->setDoubleClickCallback(onDoubleClick); + mResultList->sortByColumn("Name", TRUE); + + mCounterText = getChild("counter"); + + childSetAction("Refresh", search, this); + childSetAction("Stop", cancel, this); + + childSetKeystrokeCallback("Name query chunk", onCommitLine, 0); + childSetKeystrokeCallback("Description query chunk", onCommitLine, 0); + childSetKeystrokeCallback("Owner query chunk", onCommitLine, 0); + childSetKeystrokeCallback("Group query chunk", onCommitLine, 0); + + return TRUE; +} + +// static +void JCFloaterAreaSearch::checkRegion() +{ + // Check if we changed region, and if we did, clear the object details cache. + LLViewerRegion* region = gAgent.getRegion(); + if (region != sLastRegion) + { + sLastRegion = region; + sRequested = 0; + sObjectDetails.clear(); + if (sInstance) + { + sInstance->mResultList->deleteAllItems(); + sInstance->mCounterText->setText(std::string("Listed/Pending/Total")); + } + } +} + +// static +void JCFloaterAreaSearch::toggle() +{ + if (sInstance) + { + if (sInstance->getVisible()) + { + sInstance->setVisible(FALSE); + } + else + { + checkRegion(); + sInstance->setVisible(TRUE); + } + } + else + { + sInstance = new JCFloaterAreaSearch(); + LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_area_search.xml"); + } +} + +// static +void JCFloaterAreaSearch::onDoubleClick(void *userdata) +{ + JCFloaterAreaSearch *self = (JCFloaterAreaSearch*)userdata; + LLScrollListItem *item = self->mResultList->getFirstSelected(); + if (!item) return; + LLUUID object_id = item->getUUID(); + LLViewerObject* objectp = gObjectList.findObject(object_id); + if (objectp) + { + LLTracker::trackLocation(objectp->getPositionGlobal(), sObjectDetails[object_id].name, "", LLTracker::LOCATION_ITEM); + } +} + +// static +void JCFloaterAreaSearch::cancel(void* data) +{ + checkRegion(); + if (sInstance) + { + sInstance->close(TRUE); + } + sSearchedName = ""; + sSearchedDesc = ""; + sSearchedOwner = ""; + sSearchedGroup = ""; +} + +// static +void JCFloaterAreaSearch::search(void* data) +{ + //llinfos << "Clicked search" << llendl; + checkRegion(); + results(); +} + +// static +void JCFloaterAreaSearch::onCommitLine(LLLineEditor* line, void* user_data) +{ + std::string name = line->getName(); + std::string text = line->getText(); + LLStringUtil::toLower(text); + line->setText(text); + if (name == "Name query chunk") sSearchedName = text; + else if (name == "Description query chunk") sSearchedDesc = text; + else if (name == "Owner query chunk") sSearchedOwner = text; + else if (name == "Group query chunk") sSearchedGroup = text; + //llinfos << "loaded " << name << " with "<< text << llendl; + + if (text.length() > 3) + { + checkRegion(); + results(); + } +} + +// static +void JCFloaterAreaSearch::requestIfNeeded(LLViewerObject *objectp) +{ + LLUUID object_id = objectp->getID(); + if (sObjectDetails.count(object_id) == 0) + { + //llinfos << "not in list" << llendl; + AObjectDetails* details = &sObjectDetails[object_id]; + details->name = request_string; + details->desc = request_string; + details->owner_id = LLUUID::null; + details->group_id = LLUUID::null; + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_RequestFlags, 0 ); + msg->addUUIDFast(_PREHASH_ObjectID, object_id); + gAgent.sendReliableMessage(); + //llinfos << "Sent data request for object " << object_id << llendl; + sRequested++; + } +} + +// static +void JCFloaterAreaSearch::results() +{ + if (!sInstance) return; + if (!(sInstance->getVisible())) return; + if (sRequested > 0 && sInstance->mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return; + //llinfos << "results()" << llendl; + LLDynamicArray selected = sInstance->mResultList->getSelectedIDs(); + S32 scrollpos = sInstance->mResultList->getScrollPos(); + sInstance->mResultList->deleteAllItems(); + S32 i; + S32 total = gObjectList.getNumObjects(); + + LLViewerRegion* our_region = gAgent.getRegion(); + for (i = 0; i < total; i++) + { + LLViewerObject *objectp = gObjectList.getObject(i); + if (objectp) + { + if (objectp->getRegion() == our_region && !objectp->isAvatar() && objectp->isRoot() && + !objectp->flagTemporary() && !objectp->flagTemporaryOnRez()) + { + LLUUID object_id = objectp->getID(); + if (sObjectDetails.count(object_id) == 0) + { + //llinfos << "not all entries are \"\"" << llendl; + requestIfNeeded(objectp); + } + else + { + //llinfos << "all entries are \"\" or we have data" << llendl; + AObjectDetails* details = &sObjectDetails[object_id]; + std::string object_name = details->name; + std::string object_desc = details->desc; + std::string object_owner; + std::string object_group; + gCacheName->getFullName(details->owner_id, object_owner); + gCacheName->getGroupName(details->group_id, object_group); + if (object_name != request_string) + { + //llinfos << "both names are loaded or aren't needed" << llendl; + std::string onU = object_owner; + std::string cnU = object_group; + LLStringUtil::toLower(object_name); + LLStringUtil::toLower(object_desc); + LLStringUtil::toLower(object_owner); + LLStringUtil::toLower(object_group); + if ((sSearchedName == "" || object_name.find(sSearchedName) != -1) && + (sSearchedDesc == "" || object_desc.find(sSearchedDesc) != -1) && + (sSearchedOwner == "" || object_owner.find(sSearchedOwner) != -1) && + (sSearchedGroup == "" || object_group.find(sSearchedGroup) != -1)) + { + //llinfos << "pass" << llendl; + LLSD element; + element["id"] = object_id; + element["columns"][LIST_OBJECT_NAME]["column"] = "Name"; + element["columns"][LIST_OBJECT_NAME]["type"] = "text"; + element["columns"][LIST_OBJECT_NAME]["value"] = details->name; //item->getName();//ai->second//"avatar_icon"; + element["columns"][LIST_OBJECT_DESC]["column"] = "Description"; + element["columns"][LIST_OBJECT_DESC]["type"] = "text"; + element["columns"][LIST_OBJECT_DESC]["value"] = details->desc; //ai->second; + element["columns"][LIST_OBJECT_OWNER]["column"] = "Owner"; + element["columns"][LIST_OBJECT_OWNER]["type"] = "text"; + element["columns"][LIST_OBJECT_OWNER]["value"] = onU; //ai->first; + element["columns"][LIST_OBJECT_GROUP]["column"] = "Group"; + element["columns"][LIST_OBJECT_GROUP]["type"] = "text"; + element["columns"][LIST_OBJECT_GROUP]["value"] = cnU; //ai->second; + sInstance->mResultList->addElement(element, ADD_BOTTOM); + } + } + } + } + } + } + + sInstance->mResultList->sortItems(); + sInstance->mResultList->selectMultiple(selected); + sInstance->mResultList->setScrollPos(scrollpos); + sInstance->mCounterText->setText(llformat("%d listed/%d pending/%d total", sInstance->mResultList->getItemCount(), sRequested, sObjectDetails.size())); + sInstance->mLastUpdateTimer.reset(); +} + +// static +void JCFloaterAreaSearch::callbackLoadOwnerName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) +{ + results(); +} + +// static +void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data) +{ + checkRegion(); + + LLUUID object_id; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, object_id); + + bool exists = (sObjectDetails.count(object_id) != 0); + AObjectDetails* details = &sObjectDetails[object_id]; + if (!exists || details->name == request_string) + { + // We cache unknown objects (to avoid having to request them later) + // and requested objects. + if (exists && sRequested > 0) sRequested--; + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, details->owner_id); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, details->group_id); + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, details->name); + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, details->desc); + gCacheName->get(details->owner_id, FALSE, callbackLoadOwnerName); + gCacheName->get(details->group_id, TRUE, callbackLoadOwnerName); + //llinfos << "Got info for " << (exists ? "requested" : "unknown") << " object " << object_id << llendl; + } +} diff --git a/linden/indra/newview/jcfloaterareasearch.h b/linden/indra/newview/jcfloaterareasearch.h new file mode 100644 index 0000000..9feb9aa --- /dev/null +++ b/linden/indra/newview/jcfloaterareasearch.h @@ -0,0 +1,99 @@ +/* Copyright (c) 2009 + * + * Modular Systems. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. Neither the name Modular Systems nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS AND CONTRIBUTORS “AS IS” + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * Modified, debugged, optimized and improved by Henri Beauchamp Feb 2010. + */ + +#include "llfloater.h" +#include "lluuid.h" +#include "llstring.h" +#include "llframetimer.h" + +class LLTextBox; +class LLScrollListCtrl; +class LLViewerRegion; + +struct AObjectDetails +{ + LLUUID id; + std::string name; + std::string desc; + LLUUID owner_id; + LLUUID group_id; +}; + +class JCFloaterAreaSearch : public LLFloater +{ +public: + JCFloaterAreaSearch(); + virtual ~JCFloaterAreaSearch(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void close(bool app = false); + + static void results(); + static void toggle(); + static JCFloaterAreaSearch* getInstance() { return sInstance; } + static void callbackLoadOwnerName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data); + static void processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data); + +private: + static void checkRegion(); + static void cancel(void* data); + static void search(void* data); + static void onCommitLine(LLLineEditor* line, void* user_data); + static void requestIfNeeded(LLViewerObject *objectp); + static void onDoubleClick(void *userdata); + + enum OBJECT_COLUMN_ORDER + { + LIST_OBJECT_NAME, + LIST_OBJECT_DESC, + LIST_OBJECT_OWNER, + LIST_OBJECT_GROUP + }; + + static JCFloaterAreaSearch* sInstance; + + static S32 sRequested; + + LLTextBox* mCounterText; + LLScrollListCtrl* mResultList; + LLFrameTimer mLastUpdateTimer; + + static std::map sObjectDetails; + + static std::string sSearchedName; + static std::string sSearchedDesc; + static std::string sSearchedOwner; + static std::string sSearchedGroup; + + static LLViewerRegion* sLastRegion; +}; diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_area_search.xml b/linden/indra/newview/skins/default/xui/en-us/floater_area_search.xml new file mode 100644 index 0000000..4fa8117 --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_area_search.xml @@ -0,0 +1,50 @@ + + + + Name search string: + + + Description search string: + + + + + Owner search string: + + + Group search string: + + + + + + + + + +