aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/jcfloaterareasearch.cpp
diff options
context:
space:
mode:
authorMcCabe Maxsted2010-07-21 15:22:58 -0700
committerMcCabe Maxsted2010-07-21 15:22:58 -0700
commit8ceca3943a1c843b5fa67d0133f22df47efbe6fd (patch)
tree6a0eb1ed3d46a16ced397da7877f9cba65c8d5dd /linden/indra/newview/jcfloaterareasearch.cpp
parentFixed event search layout being off (diff)
downloadmeta-impy-8ceca3943a1c843b5fa67d0133f22df47efbe6fd.zip
meta-impy-8ceca3943a1c843b5fa67d0133f22df47efbe6fd.tar.gz
meta-impy-8ceca3943a1c843b5fa67d0133f22df47efbe6fd.tar.bz2
meta-impy-8ceca3943a1c843b5fa67d0133f22df47efbe6fd.tar.xz
Added area search files missing from 8524a4228
Diffstat (limited to 'linden/indra/newview/jcfloaterareasearch.cpp')
-rw-r--r--linden/indra/newview/jcfloaterareasearch.cpp342
1 files changed, 342 insertions, 0 deletions
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 @@
1/* Copyright (c) 2009
2 *
3 * Modular Systems Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or
6 * without modification, are permitted provided that the following
7 * conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
15 * 3. Neither the name Modular Systems Ltd nor the names of its contributors
16 * may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY MODULAR SYSTEMS LTD AND CONTRIBUTORS “AS IS”
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MODULAR SYSTEMS OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 * THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Modified, debugged, optimized and improved by Henri Beauchamp Feb 2010.
32 */
33
34#include "llviewerprecompiledheaders.h"
35
36#include "lluuid.h"
37#include "lluictrlfactory.h"
38#include "llscrolllistctrl.h"
39
40#include "llagent.h"
41#include "lltracker.h"
42#include "llviewerobjectlist.h"
43#include "llviewercontrol.h"
44#include "jcfloaterareasearch.h"
45
46JCFloaterAreaSearch* JCFloaterAreaSearch::sInstance = NULL;
47LLViewerRegion* JCFloaterAreaSearch::sLastRegion = NULL;
48S32 JCFloaterAreaSearch::sRequested = 0;
49std::map<LLUUID, AObjectDetails> JCFloaterAreaSearch::sObjectDetails;
50std::string JCFloaterAreaSearch::sSearchedName;
51std::string JCFloaterAreaSearch::sSearchedDesc;
52std::string JCFloaterAreaSearch::sSearchedOwner;
53std::string JCFloaterAreaSearch::sSearchedGroup;
54
55const std::string request_string = "JCFloaterAreaSearch::Requested_ø§µ";
56const F32 min_refresh_interval = 0.25f; // Minimum interval between list refreshes in seconds.
57
58JCFloaterAreaSearch::JCFloaterAreaSearch() :
59LLFloater(),
60mCounterText(0),
61mResultList(0)
62{
63 llassert_always(sInstance == NULL);
64 sInstance = this;
65 mLastUpdateTimer.reset();
66}
67
68JCFloaterAreaSearch::~JCFloaterAreaSearch()
69{
70 sInstance = NULL;
71}
72
73void JCFloaterAreaSearch::close(bool app)
74{
75 if (app)
76 {
77 LLFloater::close(app);
78 }
79 else
80 {
81 if (sInstance)
82 {
83 sInstance->setVisible(FALSE);
84 }
85 }
86}
87
88BOOL JCFloaterAreaSearch::postBuild()
89{
90 mResultList = getChild<LLScrollListCtrl>("result_list");
91 mResultList->setCallbackUserData(this);
92 mResultList->setDoubleClickCallback(onDoubleClick);
93 mResultList->sortByColumn("Name", TRUE);
94
95 mCounterText = getChild<LLTextBox>("counter");
96
97 childSetAction("Refresh", search, this);
98 childSetAction("Stop", cancel, this);
99
100 childSetKeystrokeCallback("Name query chunk", onCommitLine, 0);
101 childSetKeystrokeCallback("Description query chunk", onCommitLine, 0);
102 childSetKeystrokeCallback("Owner query chunk", onCommitLine, 0);
103 childSetKeystrokeCallback("Group query chunk", onCommitLine, 0);
104
105 return TRUE;
106}
107
108// static
109void JCFloaterAreaSearch::checkRegion()
110{
111 // Check if we changed region, and if we did, clear the object details cache.
112 LLViewerRegion* region = gAgent.getRegion();
113 if (region != sLastRegion)
114 {
115 sLastRegion = region;
116 sRequested = 0;
117 sObjectDetails.clear();
118 if (sInstance)
119 {
120 sInstance->mResultList->deleteAllItems();
121 sInstance->mCounterText->setText(std::string("Listed/Pending/Total"));
122 }
123 }
124}
125
126// static
127void JCFloaterAreaSearch::toggle()
128{
129 if (sInstance)
130 {
131 if (sInstance->getVisible())
132 {
133 sInstance->setVisible(FALSE);
134 }
135 else
136 {
137 checkRegion();
138 sInstance->setVisible(TRUE);
139 }
140 }
141 else
142 {
143 sInstance = new JCFloaterAreaSearch();
144 LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_area_search.xml");
145 }
146}
147
148// static
149void JCFloaterAreaSearch::onDoubleClick(void *userdata)
150{
151 JCFloaterAreaSearch *self = (JCFloaterAreaSearch*)userdata;
152 LLScrollListItem *item = self->mResultList->getFirstSelected();
153 if (!item) return;
154 LLUUID object_id = item->getUUID();
155 LLViewerObject* objectp = gObjectList.findObject(object_id);
156 if (objectp)
157 {
158 LLTracker::trackLocation(objectp->getPositionGlobal(), sObjectDetails[object_id].name, "", LLTracker::LOCATION_ITEM);
159 }
160}
161
162// static
163void JCFloaterAreaSearch::cancel(void* data)
164{
165 checkRegion();
166 if (sInstance)
167 {
168 sInstance->close(TRUE);
169 }
170 sSearchedName = "";
171 sSearchedDesc = "";
172 sSearchedOwner = "";
173 sSearchedGroup = "";
174}
175
176// static
177void JCFloaterAreaSearch::search(void* data)
178{
179 //llinfos << "Clicked search" << llendl;
180 checkRegion();
181 results();
182}
183
184// static
185void JCFloaterAreaSearch::onCommitLine(LLLineEditor* line, void* user_data)
186{
187 std::string name = line->getName();
188 std::string text = line->getText();
189 LLStringUtil::toLower(text);
190 line->setText(text);
191 if (name == "Name query chunk") sSearchedName = text;
192 else if (name == "Description query chunk") sSearchedDesc = text;
193 else if (name == "Owner query chunk") sSearchedOwner = text;
194 else if (name == "Group query chunk") sSearchedGroup = text;
195 //llinfos << "loaded " << name << " with "<< text << llendl;
196
197 if (text.length() > 3)
198 {
199 checkRegion();
200 results();
201 }
202}
203
204// static
205void JCFloaterAreaSearch::requestIfNeeded(LLViewerObject *objectp)
206{
207 LLUUID object_id = objectp->getID();
208 if (sObjectDetails.count(object_id) == 0)
209 {
210 //llinfos << "not in list" << llendl;
211 AObjectDetails* details = &sObjectDetails[object_id];
212 details->name = request_string;
213 details->desc = request_string;
214 details->owner_id = LLUUID::null;
215 details->group_id = LLUUID::null;
216
217 LLMessageSystem* msg = gMessageSystem;
218 msg->newMessageFast(_PREHASH_RequestObjectPropertiesFamily);
219 msg->nextBlockFast(_PREHASH_AgentData);
220 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
221 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
222 msg->nextBlockFast(_PREHASH_ObjectData);
223 msg->addU32Fast(_PREHASH_RequestFlags, 0 );
224 msg->addUUIDFast(_PREHASH_ObjectID, object_id);
225 gAgent.sendReliableMessage();
226 //llinfos << "Sent data request for object " << object_id << llendl;
227 sRequested++;
228 }
229}
230
231// static
232void JCFloaterAreaSearch::results()
233{
234 if (!sInstance) return;
235 if (!(sInstance->getVisible())) return;
236 if (sRequested > 0 && sInstance->mLastUpdateTimer.getElapsedTimeF32() < min_refresh_interval) return;
237 //llinfos << "results()" << llendl;
238 LLDynamicArray<LLUUID> selected = sInstance->mResultList->getSelectedIDs();
239 S32 scrollpos = sInstance->mResultList->getScrollPos();
240 sInstance->mResultList->deleteAllItems();
241 S32 i;
242 S32 total = gObjectList.getNumObjects();
243
244 LLViewerRegion* our_region = gAgent.getRegion();
245 for (i = 0; i < total; i++)
246 {
247 LLViewerObject *objectp = gObjectList.getObject(i);
248 if (objectp)
249 {
250 if (objectp->getRegion() == our_region && !objectp->isAvatar() && objectp->isRoot() &&
251 !objectp->flagTemporary() && !objectp->flagTemporaryOnRez())
252 {
253 LLUUID object_id = objectp->getID();
254 if (sObjectDetails.count(object_id) == 0)
255 {
256 //llinfos << "not all entries are \"\"" << llendl;
257 requestIfNeeded(objectp);
258 }
259 else
260 {
261 //llinfos << "all entries are \"\" or we have data" << llendl;
262 AObjectDetails* details = &sObjectDetails[object_id];
263 std::string object_name = details->name;
264 std::string object_desc = details->desc;
265 std::string object_owner;
266 std::string object_group;
267 gCacheName->getFullName(details->owner_id, object_owner);
268 gCacheName->getGroupName(details->group_id, object_group);
269 if (object_name != request_string)
270 {
271 //llinfos << "both names are loaded or aren't needed" << llendl;
272 std::string onU = object_owner;
273 std::string cnU = object_group;
274 LLStringUtil::toLower(object_name);
275 LLStringUtil::toLower(object_desc);
276 LLStringUtil::toLower(object_owner);
277 LLStringUtil::toLower(object_group);
278 if ((sSearchedName == "" || object_name.find(sSearchedName) != -1) &&
279 (sSearchedDesc == "" || object_desc.find(sSearchedDesc) != -1) &&
280 (sSearchedOwner == "" || object_owner.find(sSearchedOwner) != -1) &&
281 (sSearchedGroup == "" || object_group.find(sSearchedGroup) != -1))
282 {
283 //llinfos << "pass" << llendl;
284 LLSD element;
285 element["id"] = object_id;
286 element["columns"][LIST_OBJECT_NAME]["column"] = "Name";
287 element["columns"][LIST_OBJECT_NAME]["type"] = "text";
288 element["columns"][LIST_OBJECT_NAME]["value"] = details->name; //item->getName();//ai->second//"avatar_icon";
289 element["columns"][LIST_OBJECT_DESC]["column"] = "Description";
290 element["columns"][LIST_OBJECT_DESC]["type"] = "text";
291 element["columns"][LIST_OBJECT_DESC]["value"] = details->desc; //ai->second;
292 element["columns"][LIST_OBJECT_OWNER]["column"] = "Owner";
293 element["columns"][LIST_OBJECT_OWNER]["type"] = "text";
294 element["columns"][LIST_OBJECT_OWNER]["value"] = onU; //ai->first;
295 element["columns"][LIST_OBJECT_GROUP]["column"] = "Group";
296 element["columns"][LIST_OBJECT_GROUP]["type"] = "text";
297 element["columns"][LIST_OBJECT_GROUP]["value"] = cnU; //ai->second;
298 sInstance->mResultList->addElement(element, ADD_BOTTOM);
299 }
300 }
301 }
302 }
303 }
304 }
305
306 sInstance->mResultList->sortItems();
307 sInstance->mResultList->selectMultiple(selected);
308 sInstance->mResultList->setScrollPos(scrollpos);
309 sInstance->mCounterText->setText(llformat("%d listed/%d pending/%d total", sInstance->mResultList->getItemCount(), sRequested, sObjectDetails.size()));
310 sInstance->mLastUpdateTimer.reset();
311}
312
313// static
314void JCFloaterAreaSearch::callbackLoadOwnerName(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
315{
316 results();
317}
318
319// static
320void JCFloaterAreaSearch::processObjectPropertiesFamily(LLMessageSystem* msg, void** user_data)
321{
322 checkRegion();
323
324 LLUUID object_id;
325 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, object_id);
326
327 bool exists = (sObjectDetails.count(object_id) != 0);
328 AObjectDetails* details = &sObjectDetails[object_id];
329 if (!exists || details->name == request_string)
330 {
331 // We cache unknown objects (to avoid having to request them later)
332 // and requested objects.
333 if (exists && sRequested > 0) sRequested--;
334 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_OwnerID, details->owner_id);
335 msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_GroupID, details->group_id);
336 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, details->name);
337 msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Description, details->desc);
338 gCacheName->get(details->owner_id, FALSE, callbackLoadOwnerName);
339 gCacheName->get(details->group_id, TRUE, callbackLoadOwnerName);
340 //llinfos << "Got info for " << (exists ? "requested" : "unknown") << " object " << object_id << llendl;
341 }
342}