llpanelpick.cpp

Go to the documentation of this file.
00001 
00032 // Display of a "Top Pick" used both for the global top picks in the 
00033 // Find directory, and also for each individual user's picks in their
00034 // profile.
00035 
00036 #include "llviewerprecompiledheaders.h"
00037 
00038 #include "llpanelpick.h"
00039 
00040 #include "lldir.h"
00041 #include "llparcel.h"
00042 #include "message.h"
00043 
00044 #include "llagent.h"
00045 #include "llbutton.h"
00046 #include "llcheckboxctrl.h"
00047 #include "llviewercontrol.h"
00048 #include "lllineeditor.h"
00049 #include "lltabcontainervertical.h"
00050 #include "lltextbox.h"
00051 #include "llviewertexteditor.h"
00052 #include "lltexturectrl.h"
00053 #include "lluiconstants.h"
00054 #include "llviewergenericmessage.h"
00055 #include "llvieweruictrlfactory.h"
00056 #include "llviewerparcelmgr.h"
00057 #include "llworldmap.h"
00058 #include "llfloaterworldmap.h"
00059 #include "llviewerregion.h"
00060 #include "llviewerwindow.h"
00061 
00062 //static
00063 std::list<LLPanelPick*> LLPanelPick::sAllPanels;
00064 
00065 LLPanelPick::LLPanelPick(BOOL top_pick)
00066 :       LLPanel("Top Picks Panel"),
00067         mTopPick(top_pick),
00068         mPickID(),
00069         mCreatorID(),
00070         mParcelID(),
00071         mDataRequested(FALSE),
00072         mDataReceived(FALSE),
00073     mPosGlobal(),
00074     mSnapshotCtrl(NULL),
00075     mNameEditor(NULL),
00076     mDescEditor(NULL),
00077     mLocationEditor(NULL),
00078     mTeleportBtn(NULL),
00079     mMapBtn(NULL),
00080     //mLandmarkBtn(NULL),
00081     mSortOrderText(NULL),
00082     mSortOrderEditor(NULL),
00083     mEnabledCheck(NULL),
00084     mSetBtn(NULL)
00085 {
00086     sAllPanels.push_back(this);
00087 
00088         std::string pick_def_file;
00089         if (top_pick)
00090         {
00091                 gUICtrlFactory->buildPanel(this, "panel_top_pick.xml");
00092         }
00093         else
00094         {
00095                 gUICtrlFactory->buildPanel(this, "panel_avatar_pick.xml");
00096         }       
00097 }
00098 
00099 
00100 LLPanelPick::~LLPanelPick()
00101 {
00102     sAllPanels.remove(this);
00103 }
00104 
00105 
00106 void LLPanelPick::reset()
00107 {
00108         mPickID.setNull();
00109         mCreatorID.setNull();
00110         mParcelID.setNull();
00111 
00112         // Don't request data, this isn't valid
00113         mDataRequested = TRUE;
00114         mDataReceived = FALSE;
00115 
00116         mPosGlobal.clearVec();
00117 
00118         clearCtrls();
00119 }
00120 
00121 
00122 BOOL LLPanelPick::postBuild()
00123 {
00124     mSnapshotCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl");
00125         mSnapshotCtrl->setCommitCallback(onCommitAny);
00126         mSnapshotCtrl->setCallbackUserData(this);
00127 
00128     mNameEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "given_name_editor");
00129         mNameEditor->setCommitOnFocusLost(TRUE);
00130         mNameEditor->setCommitCallback(onCommitAny);
00131         mNameEditor->setCallbackUserData(this);
00132 
00133     mDescEditor = LLUICtrlFactory::getTextEditorByName(this, "desc_editor");
00134         mDescEditor->setCommitOnFocusLost(TRUE);
00135         mDescEditor->setCommitCallback(onCommitAny);
00136         mDescEditor->setCallbackUserData(this);
00137         mDescEditor->setTabToNextField(TRUE);
00138 
00139     mLocationEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "location_editor");
00140 
00141     mSetBtn = LLViewerUICtrlFactory::getButtonByName(this, "set_location_btn");
00142     mSetBtn->setClickedCallback(onClickSet);
00143     mSetBtn->setCallbackUserData(this);
00144 
00145     mTeleportBtn = LLViewerUICtrlFactory::getButtonByName(this, "pick_teleport_btn");
00146     mTeleportBtn->setClickedCallback(onClickTeleport);
00147     mTeleportBtn->setCallbackUserData(this);
00148 
00149     mMapBtn = LLViewerUICtrlFactory::getButtonByName(this, "pick_map_btn");
00150     mMapBtn->setClickedCallback(onClickMap);
00151     mMapBtn->setCallbackUserData(this);
00152 
00153         mSortOrderText = LLViewerUICtrlFactory::getTextBoxByName(this, "sort_order_text");
00154 
00155         mSortOrderEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "sort_order_editor");
00156         mSortOrderEditor->setPrevalidate(LLLineEditor::prevalidateInt);
00157         mSortOrderEditor->setCommitOnFocusLost(TRUE);
00158         mSortOrderEditor->setCommitCallback(onCommitAny);
00159         mSortOrderEditor->setCallbackUserData(this);
00160 
00161         mEnabledCheck = LLViewerUICtrlFactory::getCheckBoxByName(this, "enabled_check");
00162         mEnabledCheck->setCommitCallback(onCommitAny);
00163         mEnabledCheck->setCallbackUserData(this);
00164 
00165     return TRUE;
00166 }
00167 
00168 
00169 // Fill in some reasonable defaults for a new pick.
00170 void LLPanelPick::initNewPick()
00171 {
00172         mPickID.generate();
00173 
00174         mCreatorID = gAgent.getID();
00175 
00176         mPosGlobal = gAgent.getPositionGlobal();
00177 
00178         // Try to fill in the current parcel
00179         LLParcel* parcel = gParcelMgr->getAgentParcel();
00180         if (parcel)
00181         {
00182                 mNameEditor->setText(parcel->getName());
00183                 mDescEditor->setText(parcel->getDesc());
00184                 mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID());
00185         }
00186 
00187         // Commit to the database, since we've got "new" values.
00188         sendPickInfoUpdate();
00189 }
00190 
00191 
00192 void LLPanelPick::setPickID(const LLUUID& pick_id, const LLUUID& creator_id)
00193 {
00194         mPickID = pick_id;
00195         mCreatorID = creator_id;
00196 }
00197 
00198 
00199 // Schedules the panel to request data
00200 // from the server next time it is drawn.
00201 void LLPanelPick::markForServerRequest()
00202 {
00203         mDataRequested = FALSE;
00204         mDataReceived = FALSE;
00205 }
00206 
00207 
00208 std::string LLPanelPick::getPickName()
00209 {
00210         return mNameEditor->getText();
00211 }
00212 
00213 
00214 void LLPanelPick::sendPickInfoRequest()
00215 {
00216         // Must ask for a pick based on the creator id because
00217         // the pick database is distributed to the inventory cluster. JC
00218         std::vector<std::string> strings;
00219         strings.push_back( mCreatorID.asString() );
00220         strings.push_back( mPickID.asString() );
00221         send_generic_message("pickinforequest", strings);
00222 
00223         mDataRequested = TRUE;
00224 }
00225 
00226 
00227 void LLPanelPick::sendPickInfoUpdate()
00228 {
00229         // If we don't have a pick id yet, we'll need to generate one,
00230         // otherwise we'll keep overwriting pick_id 00000 in the database.
00231         if (mPickID.isNull())
00232         {
00233                 mPickID.generate();
00234         }
00235 
00236         LLMessageSystem* msg = gMessageSystem;
00237 
00238         msg->newMessage("PickInfoUpdate");
00239         msg->nextBlock("AgentData");
00240         msg->addUUID("AgentID", gAgent.getID());
00241         msg->addUUID("SessionID", gAgent.getSessionID());
00242         msg->nextBlock("Data");
00243         msg->addUUID("PickID", mPickID);
00244         msg->addUUID("CreatorID", mCreatorID);
00245         msg->addBOOL("TopPick", mTopPick);
00246         // fills in on simulator if null
00247         msg->addUUID("ParcelID", mParcelID);
00248         msg->addString("Name", mNameEditor->getText());
00249         msg->addString("Desc", mDescEditor->getText());
00250         msg->addUUID("SnapshotID", mSnapshotCtrl->getImageAssetID());
00251         msg->addVector3d("PosGlobal", mPosGlobal);
00252         
00253         // Only top picks have a sort order
00254         S32 sort_order;
00255         if (mTopPick)
00256         {
00257                 sort_order = atoi(mSortOrderEditor->getText().c_str());
00258         }
00259         else
00260         {
00261                 sort_order = 0;
00262         }
00263         msg->addS32("SortOrder", sort_order);
00264         msg->addBOOL("Enabled", mEnabledCheck->get());
00265         gAgent.sendReliableMessage();
00266 }
00267 
00268 
00269 //static
00270 void LLPanelPick::processPickInfoReply(LLMessageSystem *msg, void **)
00271 {
00272     // Extract the agent id and verify the message is for this
00273     // client.
00274     LLUUID agent_id;
00275     msg->getUUID("AgentData", "AgentID", agent_id );
00276     if (agent_id != gAgent.getID())
00277     {
00278         llwarns << "Agent ID mismatch in processPickInfoReply"
00279             << llendl;
00280                 return;
00281     }
00282 
00283     LLUUID pick_id;
00284     msg->getUUID("Data", "PickID", pick_id);
00285 
00286     LLUUID creator_id;
00287     msg->getUUID("Data", "CreatorID", creator_id);
00288 
00289         BOOL top_pick;
00290         msg->getBOOL("Data", "TopPick", top_pick);
00291 
00292     LLUUID parcel_id;
00293     msg->getUUID("Data", "ParcelID", parcel_id);
00294 
00295         char name[DB_PARCEL_NAME_SIZE];         /*Flawfinder: ignore*/
00296         msg->getString("Data", "Name", DB_PARCEL_NAME_SIZE, name);
00297 
00298         char desc[DB_PICK_DESC_SIZE];           /*Flawfinder: ignore*/
00299         msg->getString("Data", "Desc", DB_PICK_DESC_SIZE, desc);
00300 
00301         LLUUID snapshot_id;
00302         msg->getUUID("Data", "SnapshotID", snapshot_id);
00303 
00304     // "Location text" is actually the owner name, the original
00305     // name that owner gave the parcel, and the location.
00306         char buffer[256];               /*Flawfinder: ignore*/
00307     LLString location_text;
00308 
00309     msg->getString("Data", "User", 256, buffer);
00310     location_text.assign(buffer);
00311     location_text.append(", ");
00312 
00313     msg->getString("Data", "OriginalName", 256, buffer);
00314         if (buffer[0] != '\0')
00315         {
00316                 location_text.append(buffer);
00317                 location_text.append(", ");
00318         }
00319 
00320         char sim_name[256];             /*Flawfinder: ignore*/
00321         msg->getString("Data", "SimName", 256, sim_name);
00322 
00323         LLVector3d pos_global;
00324         msg->getVector3d("Data", "PosGlobal", pos_global);
00325 
00326     S32 region_x = llround((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
00327     S32 region_y = llround((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
00328         S32 region_z = llround((F32)pos_global.mdV[VZ]);
00329    
00330     location_text.append(llformat("%s (%d, %d, %d)", sim_name, region_x, region_y, region_z));
00331 
00332         S32 sort_order;
00333     msg->getS32("Data", "SortOrder", sort_order);
00334 
00335         BOOL enabled;
00336         msg->getBOOL("Data", "Enabled", enabled);
00337 
00338     // Look up the panel to fill in
00339         for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
00340         {
00341                 LLPanelPick* self = *iter;
00342                 // For top picks, must match pick id
00343                 if (self->mPickID != pick_id)
00344                 {
00345                         continue;
00346                 }
00347 
00348                 self->mDataReceived = TRUE;
00349 
00350         // Found the panel, now fill in the information
00351                 self->mPickID = pick_id;
00352                 self->mCreatorID = creator_id;
00353                 self->mParcelID = parcel_id;
00354                 self->mSimName.assign(sim_name);
00355                 self->mPosGlobal = pos_global;
00356 
00357                 // Update UI controls
00358         self->mNameEditor->setText(LLString(name));
00359         self->mDescEditor->setText(LLString(desc));
00360         self->mSnapshotCtrl->setImageAssetID(snapshot_id);
00361         self->mLocationEditor->setText(location_text);
00362         self->mEnabledCheck->set(enabled);
00363 
00364                 self->mSortOrderEditor->setText(llformat("%d", sort_order));
00365     }
00366 }
00367 
00368 void LLPanelPick::draw()
00369 {
00370         if (getVisible())
00371         {
00372                 refresh();
00373 
00374                 LLPanel::draw();
00375         }
00376 }
00377 
00378 
00379 void LLPanelPick::refresh()
00380 {
00381         if (!mDataRequested)
00382         {
00383                 sendPickInfoRequest();
00384         }
00385 
00386     // Check for god mode
00387     BOOL godlike = gAgent.isGodlike();
00388         BOOL is_self = (gAgent.getID() == mCreatorID);
00389 
00390     // Set button visibility/enablement appropriately
00391         if (mTopPick)
00392         {
00393                 mSnapshotCtrl->setEnabled(godlike);
00394                 mNameEditor->setEnabled(godlike);
00395                 mDescEditor->setEnabled(godlike);
00396 
00397                 mSortOrderText->setVisible(godlike);
00398 
00399                 mSortOrderEditor->setVisible(godlike);
00400                 mSortOrderEditor->setEnabled(godlike);
00401 
00402                 mEnabledCheck->setVisible(godlike);
00403                 mEnabledCheck->setEnabled(godlike);
00404 
00405                 mSetBtn->setVisible(godlike);
00406                 mSetBtn->setEnabled(godlike);
00407         }
00408         else
00409         {
00410                 mSnapshotCtrl->setEnabled(is_self);
00411                 mNameEditor->setEnabled(is_self);
00412                 mDescEditor->setEnabled(is_self);
00413 
00414                 mSortOrderText->setVisible(FALSE);
00415 
00416                 mSortOrderEditor->setVisible(FALSE);
00417                 mSortOrderEditor->setEnabled(FALSE);
00418 
00419                 mEnabledCheck->setVisible(FALSE);
00420                 mEnabledCheck->setEnabled(FALSE);
00421 
00422                 mSetBtn->setVisible(is_self);
00423                 mSetBtn->setEnabled(is_self);
00424         }
00425 }
00426 
00427 
00428 // static
00429 void LLPanelPick::onClickTeleport(void* data)
00430 {
00431     LLPanelPick* self = (LLPanelPick*)data;
00432 
00433     if (!self->mPosGlobal.isExactlyZero())
00434     {
00435         gAgent.teleportViaLocation(self->mPosGlobal);
00436         gFloaterWorldMap->trackLocation(self->mPosGlobal);
00437     }
00438 }
00439 
00440 
00441 // static
00442 void LLPanelPick::onClickMap(void* data)
00443 {
00444         LLPanelPick* self = (LLPanelPick*)data;
00445         gFloaterWorldMap->trackLocation(self->mPosGlobal);
00446         LLFloaterWorldMap::show(NULL, TRUE);
00447 }
00448 
00449 // static
00450 /*
00451 void LLPanelPick::onClickLandmark(void* data)
00452 {
00453     LLPanelPick* self = (LLPanelPick*)data;
00454         create_landmark(self->mNameEditor->getText().c_str(), "", self->mPosGlobal);
00455 }
00456 */
00457 
00458 // static
00459 void LLPanelPick::onClickSet(void* data)
00460 {
00461     LLPanelPick* self = (LLPanelPick*)data;
00462 
00463         // Save location for later.
00464         self->mPosGlobal = gAgent.getPositionGlobal();
00465 
00466         LLString location_text;
00467         location_text.assign("(will update after save)");
00468         location_text.append(", ");
00469 
00470     S32 region_x = llround((F32)self->mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
00471     S32 region_y = llround((F32)self->mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
00472         S32 region_z = llround((F32)self->mPosGlobal.mdV[VZ]);
00473 
00474         location_text.append(self->mSimName);
00475     location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
00476 
00477         // if sim name in pick is different from current sim name
00478         // make sure it's clear that all that's being changed
00479         // is the location and nothing else
00480         if ( gAgent.getRegion ()->getName () != self->mSimName )
00481         {
00482                 gViewerWindow->alertXml("SetPickLocation");
00483         };
00484 
00485         self->mLocationEditor->setText(location_text);
00486 
00487         onCommitAny(NULL, data);
00488 }
00489 
00490 
00491 // static
00492 void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data)
00493 {
00494         LLPanelPick* self = (LLPanelPick*)data;
00495 
00496         // have we received up to date data for this pick?
00497         if (self->mDataReceived)
00498         {
00499                 self->sendPickInfoUpdate();
00500 
00501                 // Big hack - assume that top picks are always in a browser,
00502                 // and non-top-picks are always in a tab container.
00503                 /*if (self->mTopPick)
00504                 {
00505                         LLPanelDirPicks* panel = (LLPanelDirPicks*)self->getParent();
00506                         panel->renamePick(self->mPickID, self->mNameEditor->getText().c_str());
00507                 }
00508                 else
00509                 {*/
00510                 LLTabContainerVertical* tab = (LLTabContainerVertical*)self->getParent();
00511                 if (tab)
00512                 {
00513                         if(tab) tab->setCurrentTabName(self->mNameEditor->getText());
00514                 }
00515                 //}
00516         }
00517 }

Generated on Thu Jul 1 06:08:59 2010 for Second Life Viewer by  doxygen 1.4.7