aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llpanelpick.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llpanelpick.cpp513
1 files changed, 513 insertions, 0 deletions
diff --git a/linden/indra/newview/llpanelpick.cpp b/linden/indra/newview/llpanelpick.cpp
new file mode 100644
index 0000000..4c9d5c3
--- /dev/null
+++ b/linden/indra/newview/llpanelpick.cpp
@@ -0,0 +1,513 @@
1/**
2 * @file llpanelpick.cpp
3 * @brief LLPanelPick class implementation
4 *
5 * Copyright (c) 2004-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28// Display of a "Top Pick" used both for the global top picks in the
29// Find directory, and also for each individual user's picks in their
30// profile.
31
32#include "llviewerprecompiledheaders.h"
33
34#include "llpanelpick.h"
35
36#include "lldir.h"
37#include "llparcel.h"
38#include "message.h"
39
40#include "llagent.h"
41#include "llbutton.h"
42#include "llcheckboxctrl.h"
43#include "llviewercontrol.h"
44#include "lllineeditor.h"
45#include "lltabcontainervertical.h"
46#include "lltextbox.h"
47#include "llviewertexteditor.h"
48#include "lltexturectrl.h"
49#include "lluiconstants.h"
50#include "llvieweruictrlfactory.h"
51#include "llviewerparcelmgr.h"
52#include "llworldmap.h"
53#include "llfloaterworldmap.h"
54#include "llviewerregion.h"
55#include "llviewerwindow.h"
56
57//static
58LLLinkedList<LLPanelPick> LLPanelPick::sAllPanels;
59
60LLPanelPick::LLPanelPick(BOOL top_pick)
61: LLPanel("Top Picks Panel"),
62 mTopPick(top_pick),
63 mPickID(),
64 mCreatorID(),
65 mParcelID(),
66 mDataRequested(FALSE),
67 mDataReceived(FALSE),
68 mPosGlobal(),
69 mSnapshotCtrl(NULL),
70 mNameEditor(NULL),
71 mDescEditor(NULL),
72 mLocationEditor(NULL),
73 mTeleportBtn(NULL),
74 mMapBtn(NULL),
75 //mLandmarkBtn(NULL),
76 mSortOrderText(NULL),
77 mSortOrderEditor(NULL),
78 mEnabledCheck(NULL),
79 mSetBtn(NULL)
80{
81 sAllPanels.addData(this);
82
83 std::string pick_def_file;
84 if (top_pick)
85 {
86 gUICtrlFactory->buildPanel(this, "panel_top_pick.xml");
87 }
88 else
89 {
90 gUICtrlFactory->buildPanel(this, "panel_avatar_pick.xml");
91 }
92}
93
94
95LLPanelPick::~LLPanelPick()
96{
97 sAllPanels.removeData(this);
98}
99
100
101void LLPanelPick::reset()
102{
103 mPickID.setNull();
104 mCreatorID.setNull();
105 mParcelID.setNull();
106
107 // Don't request data, this isn't valid
108 mDataRequested = TRUE;
109 mDataReceived = FALSE;
110
111 mPosGlobal.clearVec();
112
113 clearCtrls();
114}
115
116
117BOOL LLPanelPick::postBuild()
118{
119 mSnapshotCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl");
120 mSnapshotCtrl->setCommitCallback(onCommitAny);
121 mSnapshotCtrl->setCallbackUserData(this);
122
123 mNameEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "given_name_editor");
124 mNameEditor->setCommitOnFocusLost(TRUE);
125 mNameEditor->setCommitCallback(onCommitAny);
126 mNameEditor->setCallbackUserData(this);
127
128 mDescEditor = LLUICtrlFactory::getTextEditorByName(this, "desc_editor");
129 mDescEditor->setCommitOnFocusLost(TRUE);
130 mDescEditor->setCommitCallback(onCommitAny);
131 mDescEditor->setCallbackUserData(this);
132 mDescEditor->setTabToNextField(TRUE);
133
134 mLocationEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "location_editor");
135
136 mSetBtn = LLViewerUICtrlFactory::getButtonByName(this, "set_location_btn");
137 mSetBtn->setClickedCallback(onClickSet);
138 mSetBtn->setCallbackUserData(this);
139
140 mTeleportBtn = LLViewerUICtrlFactory::getButtonByName(this, "pick_teleport_btn");
141 mTeleportBtn->setClickedCallback(onClickTeleport);
142 mTeleportBtn->setCallbackUserData(this);
143
144 mMapBtn = LLViewerUICtrlFactory::getButtonByName(this, "pick_map_btn");
145 mMapBtn->setClickedCallback(onClickMap);
146 mMapBtn->setCallbackUserData(this);
147
148 mSortOrderText = LLViewerUICtrlFactory::getTextBoxByName(this, "sort_order_text");
149
150 mSortOrderEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "sort_order_editor");
151 mSortOrderEditor->setPrevalidate(LLLineEditor::prevalidateInt);
152 mSortOrderEditor->setCommitOnFocusLost(TRUE);
153 mSortOrderEditor->setCommitCallback(onCommitAny);
154 mSortOrderEditor->setCallbackUserData(this);
155
156 mEnabledCheck = LLViewerUICtrlFactory::getCheckBoxByName(this, "enabled_check");
157 mEnabledCheck->setCommitCallback(onCommitAny);
158 mEnabledCheck->setCallbackUserData(this);
159
160 return TRUE;
161}
162
163
164// Fill in some reasonable defaults for a new pick.
165void LLPanelPick::initNewPick()
166{
167 mPickID.generate();
168
169 mCreatorID = gAgent.getID();
170
171 mPosGlobal = gAgent.getPositionGlobal();
172
173 // Try to fill in the current parcel
174 LLParcel* parcel = gParcelMgr->getAgentParcel();
175 if (parcel)
176 {
177 mNameEditor->setText(parcel->getName());
178 mDescEditor->setText(parcel->getDesc());
179 mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
180 }
181
182 // Commit to the database, since we've got "new" values.
183 sendPickInfoUpdate();
184}
185
186
187void LLPanelPick::setPickID(const LLUUID& id)
188{
189 mPickID = id;
190}
191
192
193// Schedules the panel to request data
194// from the server next time it is drawn.
195void LLPanelPick::markForServerRequest()
196{
197 mDataRequested = FALSE;
198 mDataReceived = FALSE;
199}
200
201
202std::string LLPanelPick::getPickName()
203{
204 return mNameEditor->getText();
205}
206
207
208void LLPanelPick::sendPickInfoRequest()
209{
210 LLMessageSystem *msg = gMessageSystem;
211
212 msg->newMessage("PickInfoRequest");
213 msg->nextBlock("AgentData");
214 msg->addUUID("AgentID", gAgent.getID() );
215 msg->addUUID("SessionID", gAgent.getSessionID());
216 msg->nextBlock("Data");
217 msg->addUUID("PickID", mPickID);
218 gAgent.sendReliableMessage();
219
220 mDataRequested = TRUE;
221}
222
223
224void LLPanelPick::sendPickInfoUpdate()
225{
226 // If we don't have a pick id yet, we'll need to generate one,
227 // otherwise we'll keep overwriting pick_id 00000 in the database.
228 if (mPickID.isNull())
229 {
230 mPickID.generate();
231 }
232
233 LLMessageSystem* msg = gMessageSystem;
234
235 msg->newMessage("PickInfoUpdate");
236 msg->nextBlock("AgentData");
237 msg->addUUID("AgentID", gAgent.getID());
238 msg->addUUID("SessionID", gAgent.getSessionID());
239 msg->nextBlock("Data");
240 msg->addUUID("PickID", mPickID);
241 msg->addUUID("CreatorID", mCreatorID);
242 msg->addBOOL("TopPick", mTopPick);
243 // fills in on simulator if null
244 msg->addUUID("ParcelID", mParcelID);
245 msg->addString("Name", mNameEditor->getText());
246 msg->addString("Desc", mDescEditor->getText());
247 msg->addUUID("SnapshotID", mSnapshotCtrl->getImageAssetID());
248 msg->addVector3d("PosGlobal", mPosGlobal);
249
250 // Only top picks have a sort order
251 S32 sort_order;
252 if (mTopPick)
253 {
254 sort_order = atoi(mSortOrderEditor->getText().c_str());
255 }
256 else
257 {
258 sort_order = 0;
259 }
260 msg->addS32("SortOrder", sort_order);
261 msg->addBOOL("Enabled", mEnabledCheck->get());
262 gAgent.sendReliableMessage();
263}
264
265
266//static
267void LLPanelPick::processPickInfoReply(LLMessageSystem *msg, void **)
268{
269 // Extract the agent id and verify the message is for this
270 // client.
271 LLUUID agent_id;
272 msg->getUUID("AgentData", "AgentID", agent_id );
273 if (agent_id != gAgent.getID())
274 {
275 llwarns << "Agent ID mismatch in processPickInfoReply"
276 << llendl;
277 return;
278 }
279
280 LLUUID pick_id;
281 msg->getUUID("Data", "PickID", pick_id);
282
283 LLUUID creator_id;
284 msg->getUUID("Data", "CreatorID", creator_id);
285
286 BOOL top_pick;
287 msg->getBOOL("Data", "TopPick", top_pick);
288
289 LLUUID parcel_id;
290 msg->getUUID("Data", "ParcelID", parcel_id);
291
292 char name[DB_PARCEL_NAME_SIZE];
293 msg->getString("Data", "Name", DB_PARCEL_NAME_SIZE, name);
294
295 char desc[DB_PICK_DESC_SIZE];
296 msg->getString("Data", "Desc", DB_PICK_DESC_SIZE, desc);
297
298 LLUUID snapshot_id;
299 msg->getUUID("Data", "SnapshotID", snapshot_id);
300
301 // "Location text" is actually the owner name, the original
302 // name that owner gave the parcel, and the location.
303 char buffer[256];
304 LLString location_text;
305
306 msg->getString("Data", "User", 256, buffer);
307 location_text.assign(buffer);
308 location_text.append(", ");
309
310 msg->getString("Data", "OriginalName", 256, buffer);
311 if (buffer[0] != '\0')
312 {
313 location_text.append(buffer);
314 location_text.append(", ");
315 }
316
317 char sim_name[256];
318 msg->getString("Data", "SimName", 256, sim_name);
319
320 LLVector3d pos_global;
321 msg->getVector3d("Data", "PosGlobal", pos_global);
322
323 S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
324 S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
325 S32 region_z = llround((F32)pos_global.mdV[VZ]);
326
327 sprintf(buffer, "%s (%d, %d, %d)", sim_name, region_x, region_y, region_z);
328 location_text.append(buffer);
329
330 S32 sort_order;
331 msg->getS32("Data", "SortOrder", sort_order);
332
333 BOOL enabled;
334 msg->getBOOL("Data", "Enabled", enabled);
335
336 // Look up the panel to fill in
337 LLPanelPick *self = NULL;
338 for (self = sAllPanels.getFirstData(); self; self = sAllPanels.getNextData())
339 {
340 // For top picks, must match pick id
341 if (self->mPickID != pick_id)
342 {
343 continue;
344 }
345
346 self->mDataReceived = TRUE;
347
348 // Found the panel, now fill in the information
349 self->mPickID = pick_id;
350 self->mCreatorID = creator_id;
351 self->mParcelID = parcel_id;
352 self->mSimName.assign(sim_name);
353 self->mPosGlobal = pos_global;
354
355 // Update UI controls
356 self->mNameEditor->setText(name);
357 self->mDescEditor->setText(desc);
358 self->mSnapshotCtrl->setImageAssetID(snapshot_id);
359 self->mLocationEditor->setText(location_text);
360 self->mEnabledCheck->set(enabled);
361
362 sprintf(buffer, "%d", sort_order);
363 self->mSortOrderEditor->setText(buffer);
364 }
365}
366
367void LLPanelPick::draw()
368{
369 if (getVisible())
370 {
371 refresh();
372
373 LLPanel::draw();
374 }
375}
376
377
378void LLPanelPick::refresh()
379{
380 if (!mDataRequested)
381 {
382 sendPickInfoRequest();
383 }
384
385 // Check for god mode
386 BOOL godlike = gAgent.isGodlike();
387 BOOL is_self = (gAgent.getID() == mCreatorID);
388
389 // Set button visibility/enablement appropriately
390 if (mTopPick)
391 {
392 mSnapshotCtrl->setEnabled(godlike);
393 mNameEditor->setEnabled(godlike);
394 mDescEditor->setEnabled(godlike);
395
396 mSortOrderText->setVisible(godlike);
397
398 mSortOrderEditor->setVisible(godlike);
399 mSortOrderEditor->setEnabled(godlike);
400
401 mEnabledCheck->setVisible(godlike);
402 mEnabledCheck->setEnabled(godlike);
403
404 mSetBtn->setVisible(godlike);
405 mSetBtn->setEnabled(godlike);
406 }
407 else
408 {
409 mSnapshotCtrl->setEnabled(is_self);
410 mNameEditor->setEnabled(is_self);
411 mDescEditor->setEnabled(is_self);
412
413 mSortOrderText->setVisible(FALSE);
414
415 mSortOrderEditor->setVisible(FALSE);
416 mSortOrderEditor->setEnabled(FALSE);
417
418 mEnabledCheck->setVisible(FALSE);
419 mEnabledCheck->setEnabled(FALSE);
420
421 mSetBtn->setVisible(is_self);
422 mSetBtn->setEnabled(is_self);
423 }
424}
425
426
427// static
428void LLPanelPick::onClickTeleport(void* data)
429{
430 LLPanelPick* self = (LLPanelPick*)data;
431
432 if (!self->mPosGlobal.isExactlyZero())
433 {
434 gAgent.teleportViaLocation(self->mPosGlobal);
435 gFloaterWorldMap->trackLocation(self->mPosGlobal);
436 }
437}
438
439
440// static
441void LLPanelPick::onClickMap(void* data)
442{
443 LLPanelPick* self = (LLPanelPick*)data;
444 gFloaterWorldMap->trackLocation(self->mPosGlobal);
445 LLFloaterWorldMap::show(NULL, TRUE);
446}
447
448// static
449/*
450void LLPanelPick::onClickLandmark(void* data)
451{
452 LLPanelPick* self = (LLPanelPick*)data;
453 create_landmark(self->mNameEditor->getText().c_str(), "", self->mPosGlobal);
454}
455*/
456
457// static
458void LLPanelPick::onClickSet(void* data)
459{
460 LLPanelPick* self = (LLPanelPick*)data;
461
462 // Save location for later.
463 self->mPosGlobal = gAgent.getPositionGlobal();
464
465 LLString location_text;
466 location_text.assign("(will update after save)");
467 location_text.append(", ");
468
469 S32 region_x = llround((F32)self->mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
470 S32 region_y = llround((F32)self->mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
471 S32 region_z = llround((F32)self->mPosGlobal.mdV[VZ]);
472
473 location_text.append(self->mSimName);
474 location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
475
476 // if sim name in pick is different from current sim name
477 // make sure it's clear that all that's being changed
478 // is the location and nothing else
479 if ( gAgent.getRegion ()->getName () != self->mSimName )
480 {
481 gViewerWindow->alertXml("SetPickLocation");
482 };
483
484 self->mLocationEditor->setText(location_text);
485
486 onCommitAny(NULL, data);
487}
488
489
490// static
491void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data)
492{
493 LLPanelPick* self = (LLPanelPick*)data;
494
495 // have we received up to date data for this pick?
496 if (self->mDataReceived)
497 {
498 self->sendPickInfoUpdate();
499
500 // Big hack - assume that top picks are always in a browser,
501 // and non-top-picks are always in a tab container.
502 /*if (self->mTopPick)
503 {
504 LLPanelDirPicks* panel = (LLPanelDirPicks*)self->getParent();
505 panel->renamePick(self->mPickID, self->mNameEditor->getText().c_str());
506 }
507 else
508 {*/
509 LLTabContainerVertical* tab = (LLTabContainerVertical*)self->getParent();
510 tab->setCurrentTabName(self->mNameEditor->getText());
511 //}
512 }
513}