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 "lluictrlfactory.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                 LLUICtrlFactory::getInstance()->buildPanel(this, "panel_top_pick.xml");
00092         }
00093         else
00094         {
00095                 LLUICtrlFactory::getInstance()->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 = getChild<LLTextureCtrl>("snapshot_ctrl");
00125         mSnapshotCtrl->setCommitCallback(onCommitAny);
00126         mSnapshotCtrl->setCallbackUserData(this);
00127 
00128     mNameEditor = getChild<LLLineEditor>("given_name_editor");
00129         mNameEditor->setCommitOnFocusLost(TRUE);
00130         mNameEditor->setCommitCallback(onCommitAny);
00131         mNameEditor->setCallbackUserData(this);
00132 
00133     mDescEditor = getChild<LLTextEditor>("desc_editor");
00134         mDescEditor->setCommitOnFocusLost(TRUE);
00135         mDescEditor->setCommitCallback(onCommitAny);
00136         mDescEditor->setCallbackUserData(this);
00137         mDescEditor->setTabsToNextField(TRUE);
00138 
00139     mLocationEditor = getChild<LLLineEditor>("location_editor");
00140 
00141     mSetBtn = getChild<LLButton>( "set_location_btn");
00142     mSetBtn->setClickedCallback(onClickSet);
00143     mSetBtn->setCallbackUserData(this);
00144 
00145     mTeleportBtn = getChild<LLButton>( "pick_teleport_btn");
00146     mTeleportBtn->setClickedCallback(onClickTeleport);
00147     mTeleportBtn->setCallbackUserData(this);
00148 
00149     mMapBtn = getChild<LLButton>( "pick_map_btn");
00150     mMapBtn->setClickedCallback(onClickMap);
00151     mMapBtn->setCallbackUserData(this);
00152 
00153         mSortOrderText = getChild<LLTextBox>("sort_order_text");
00154 
00155         mSortOrderEditor = getChild<LLLineEditor>("sort_order_editor");
00156         mSortOrderEditor->setPrevalidate(LLLineEditor::prevalidateInt);
00157         mSortOrderEditor->setCommitOnFocusLost(TRUE);
00158         mSortOrderEditor->setCommitCallback(onCommitAny);
00159         mSortOrderEditor->setCallbackUserData(this);
00160 
00161         mEnabledCheck = getChild<LLCheckBoxCtrl>( "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 = LLViewerParcelMgr::getInstance()->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         refresh();
00371 
00372         LLPanel::draw();
00373 }
00374 
00375 
00376 void LLPanelPick::refresh()
00377 {
00378         if (!mDataRequested)
00379         {
00380                 sendPickInfoRequest();
00381         }
00382 
00383     // Check for god mode
00384     BOOL godlike = gAgent.isGodlike();
00385         BOOL is_self = (gAgent.getID() == mCreatorID);
00386 
00387     // Set button visibility/enablement appropriately
00388         if (mTopPick)
00389         {
00390                 mSnapshotCtrl->setEnabled(godlike);
00391                 mNameEditor->setEnabled(godlike);
00392                 mDescEditor->setEnabled(godlike);
00393 
00394                 mSortOrderText->setVisible(godlike);
00395 
00396                 mSortOrderEditor->setVisible(godlike);
00397                 mSortOrderEditor->setEnabled(godlike);
00398 
00399                 mEnabledCheck->setVisible(godlike);
00400                 mEnabledCheck->setEnabled(godlike);
00401 
00402                 mSetBtn->setVisible(godlike);
00403                 mSetBtn->setEnabled(godlike);
00404         }
00405         else
00406         {
00407                 mSnapshotCtrl->setEnabled(is_self);
00408                 mNameEditor->setEnabled(is_self);
00409                 mDescEditor->setEnabled(is_self);
00410 
00411                 mSortOrderText->setVisible(FALSE);
00412 
00413                 mSortOrderEditor->setVisible(FALSE);
00414                 mSortOrderEditor->setEnabled(FALSE);
00415 
00416                 mEnabledCheck->setVisible(FALSE);
00417                 mEnabledCheck->setEnabled(FALSE);
00418 
00419                 mSetBtn->setVisible(is_self);
00420                 mSetBtn->setEnabled(is_self);
00421         }
00422 }
00423 
00424 
00425 // static
00426 void LLPanelPick::onClickTeleport(void* data)
00427 {
00428     LLPanelPick* self = (LLPanelPick*)data;
00429 
00430     if (!self->mPosGlobal.isExactlyZero())
00431     {
00432         gAgent.teleportViaLocation(self->mPosGlobal);
00433         gFloaterWorldMap->trackLocation(self->mPosGlobal);
00434     }
00435 }
00436 
00437 
00438 // static
00439 void LLPanelPick::onClickMap(void* data)
00440 {
00441         LLPanelPick* self = (LLPanelPick*)data;
00442         gFloaterWorldMap->trackLocation(self->mPosGlobal);
00443         LLFloaterWorldMap::show(NULL, TRUE);
00444 }
00445 
00446 // static
00447 /*
00448 void LLPanelPick::onClickLandmark(void* data)
00449 {
00450     LLPanelPick* self = (LLPanelPick*)data;
00451         create_landmark(self->mNameEditor->getText().c_str(), "", self->mPosGlobal);
00452 }
00453 */
00454 
00455 // static
00456 void LLPanelPick::onClickSet(void* data)
00457 {
00458     LLPanelPick* self = (LLPanelPick*)data;
00459 
00460         // Save location for later.
00461         self->mPosGlobal = gAgent.getPositionGlobal();
00462 
00463         LLString location_text;
00464         location_text.assign("(will update after save)");
00465         location_text.append(", ");
00466 
00467     S32 region_x = llround((F32)self->mPosGlobal.mdV[VX]) % REGION_WIDTH_UNITS;
00468     S32 region_y = llround((F32)self->mPosGlobal.mdV[VY]) % REGION_WIDTH_UNITS;
00469         S32 region_z = llround((F32)self->mPosGlobal.mdV[VZ]);
00470 
00471         location_text.append(self->mSimName);
00472     location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
00473 
00474         // if sim name in pick is different from current sim name
00475         // make sure it's clear that all that's being changed
00476         // is the location and nothing else
00477         if ( gAgent.getRegion ()->getName () != self->mSimName )
00478         {
00479                 gViewerWindow->alertXml("SetPickLocation");
00480         };
00481 
00482         self->mLocationEditor->setText(location_text);
00483 
00484         onCommitAny(NULL, data);
00485 }
00486 
00487 
00488 // static
00489 void LLPanelPick::onCommitAny(LLUICtrl* ctrl, void* data)
00490 {
00491         LLPanelPick* self = (LLPanelPick*)data;
00492 
00493         // have we received up to date data for this pick?
00494         if (self->mDataReceived)
00495         {
00496                 self->sendPickInfoUpdate();
00497 
00498                 // Big hack - assume that top picks are always in a browser,
00499                 // and non-top-picks are always in a tab container.
00500                 /*if (self->mTopPick)
00501                 {
00502                         LLPanelDirPicks* panel = (LLPanelDirPicks*)self->getParent();
00503                         panel->renamePick(self->mPickID, self->mNameEditor->getText().c_str());
00504                 }
00505                 else
00506                 {*/
00507                 LLTabContainer* tab = (LLTabContainer*)self->getParent();
00508                 if (tab)
00509                 {
00510                         if(tab) tab->setCurrentTabName(self->mNameEditor->getText());
00511                 }
00512                 //}
00513         }
00514 }

Generated on Fri May 16 08:33:55 2008 for SecondLife by  doxygen 1.5.5