00001 
00032 
00033 
00034 
00035 
00036 #include "llviewerprecompiledheaders.h"
00037 
00038 #include "llpaneldirbrowser.h"
00039 
00040 
00041 #include "lldir.h"
00042 #include "lleventflags.h"
00043 #include "llfontgl.h"
00044 #include "llqueryflags.h"
00045 #include "message.h"
00046 
00047 
00048 #include "llagent.h"
00049 #include "llbutton.h"
00050 #include "llcheckboxctrl.h"
00051 #include "llcombobox.h"
00052 #include "llfloateravatarinfo.h"
00053 #include "llfloaterdirectory.h" 
00054 #include "lllineeditor.h"
00055 #include "llmenucommands.h"
00056 #include "llmenugl.h"
00057 #include "llpanelavatar.h"
00058 #include "llpanelevent.h"
00059 #include "llpanelgroup.h"
00060 #include "llpanelclassified.h"
00061 #include "llpanelpick.h"
00062 #include "llpanelplace.h"
00063 #include "llpaneldirland.h"
00064 #include "llscrolllistctrl.h"
00065 #include "lltextbox.h"
00066 #include "lluiconstants.h"
00067 #include "llviewercontrol.h"
00068 #include "llviewerimagelist.h"
00069 #include "llviewermessage.h"
00070 #include "llvieweruictrlfactory.h"
00071 
00072 
00073 
00074 
00075 
00076 
00077 LLMap< const LLUUID, LLPanelDirBrowser* > gDirBrowserInstances;
00078 
00079 LLPanelDirBrowser::LLPanelDirBrowser(const std::string& name, LLFloaterDirectory* floater)
00080 :       LLPanel(name),
00081         mSearchID(),
00082         mWantSelectID(),
00083         mCurrentSortColumn("name"),
00084         mCurrentSortAscending(TRUE),
00085         mSearchStart(0),
00086         mResultsPerPage(100),
00087         mResultsReceived(0),
00088         mMinSearchChars(1),
00089         mResultsContents(),
00090         mHaveSearchResults(FALSE),
00091         mDidAutoSelect(TRUE),
00092         mLastResultTimer(),
00093         mFloaterDirectory(floater)
00094 {
00095         
00096 }
00097 
00098 BOOL LLPanelDirBrowser::postBuild()
00099 {
00100         childSetCommitCallback("results", onCommitList, this);
00101 
00102         childSetAction("< Prev", onClickPrev, this);
00103         childHide("< Prev");
00104 
00105         childSetAction("Next >", onClickNext, this);
00106         childHide("Next >");
00107 
00108         return TRUE;
00109 }
00110 
00111 LLPanelDirBrowser::~LLPanelDirBrowser()
00112 {
00113         
00114 
00115         gDirBrowserInstances.removeData(mSearchID);
00116 }
00117 
00118 
00119 
00120 void LLPanelDirBrowser::draw()
00121 {
00122         
00123         
00124         
00125         
00126         if (getVisible() && mLastResultTimer.getElapsedTimeF32() > 0.5)
00127         {
00128                 if (!mDidAutoSelect &&
00129                         !childHasFocus("results"))
00130                 {
00131                         LLCtrlListInterface *list = childGetListInterface("results");
00132                         if (list)
00133                         {
00134                                 if (list->getCanSelect())
00135                                 {
00136                                         list->selectFirstItem(); 
00137                                         childSetFocus("results", TRUE);
00138                                 }
00139                                 
00140                                 onCommitList(NULL, this);
00141                         }
00142                 }
00143                 mDidAutoSelect = TRUE;
00144         }
00145         
00146         LLPanel::draw();
00147 }
00148 
00149 
00150 
00151 void LLPanelDirBrowser::nextPage()
00152 {
00153         mSearchStart += mResultsPerPage;
00154         childShow("< Prev");
00155 
00156         performQuery();
00157 }
00158 
00159 
00160 
00161 void LLPanelDirBrowser::prevPage()
00162 {
00163         mSearchStart -= mResultsPerPage;
00164         childSetVisible("< Prev", mSearchStart > 0);
00165 
00166         performQuery();
00167 }
00168 
00169 
00170 void LLPanelDirBrowser::resetSearchStart()
00171 {
00172         mSearchStart = 0;
00173         childHide("Next >");
00174         childHide("< Prev");
00175 }
00176 
00177 
00178 void LLPanelDirBrowser::updateResultCount()
00179 {
00180         LLCtrlListInterface *list = childGetListInterface("results");
00181         if (!list) return;
00182 
00183         S32 result_count = list->getItemCount();
00184         LLString result_text;
00185 
00186         if (!mHaveSearchResults) result_count = 0;
00187 
00188         if (childIsVisible("Next >")) 
00189         {
00190                 
00191                 
00192                 result_text = llformat(">%d found", mResultsPerPage);
00193         }
00194         else 
00195         {
00196                 result_text = llformat("%d found", result_count);
00197         }
00198         
00199         childSetValue("result_text", result_text);
00200         
00201         if (result_count == 0)
00202         {
00203                 
00204                 if (list->getItemCount() == 0)
00205                 {
00206                         list->addSimpleElement("None found.");
00207                         list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
00208                 }
00209         }
00210         else
00211         {
00212                 childEnable("results");
00213         }
00214 }
00215 
00216 
00217 void LLPanelDirBrowser::onClickPrev(void* data)
00218 {
00219         LLPanelDirBrowser* self = (LLPanelDirBrowser*)data;
00220         self->prevPage();
00221 }
00222 
00223 
00224 
00225 void LLPanelDirBrowser::onClickNext(void* data)
00226 {
00227         LLPanelDirBrowser* self = (LLPanelDirBrowser*)data;
00228         self->nextPage();
00229 }
00230 
00231 
00232 void LLPanelDirBrowser::selectByUUID(const LLUUID& id)
00233 {
00234         LLCtrlListInterface *list = childGetListInterface("results");
00235         if (!list) return;
00236         BOOL found = list->setCurrentByID(id);
00237         if (found)
00238         {
00239                 
00240                 
00241                 mWantSelectID.setNull();
00242                 
00243                 onCommitList(NULL, this);
00244         }
00245         else
00246         {
00247                 
00248                 mWantSelectID = id;
00249         }
00250 }
00251 
00252 void LLPanelDirBrowser::selectEventByID(S32 event_id)
00253 {
00254         if (mFloaterDirectory)
00255         {
00256                 if (mFloaterDirectory->mPanelEventp)
00257                 {
00258                         mFloaterDirectory->mPanelEventp->setVisible(TRUE);
00259                         mFloaterDirectory->mPanelEventp->setEventID(event_id);
00260                 }
00261         }
00262 }
00263 
00264 U32 LLPanelDirBrowser::getSelectedEventID() const
00265 {
00266         if (mFloaterDirectory)
00267         {
00268                 if (mFloaterDirectory->mPanelEventp)
00269                 {
00270                         return mFloaterDirectory->mPanelEventp->getEventID();
00271                 }
00272         }
00273         return 0;
00274 }
00275 
00276 void LLPanelDirBrowser::getSelectedInfo(LLUUID* id, S32 *type)
00277 {
00278         LLCtrlListInterface *list = childGetListInterface("results");
00279         if (!list) return;
00280 
00281         LLSD id_sd = childGetValue("results");
00282 
00283         *id = id_sd.asUUID();
00284 
00285         LLString id_str = id_sd.asString();
00286         *type = mResultsContents[id_str]["type"];
00287 }
00288 
00289 
00290 
00291 void LLPanelDirBrowser::onCommitList(LLUICtrl* ctrl, void* data)
00292 {
00293         LLPanelDirBrowser* self = (LLPanelDirBrowser*)data;
00294         LLCtrlListInterface *list = self->childGetListInterface("results");
00295         if (!list) return;
00296 
00297         
00298         if (self->mFloaterDirectory)
00299         {
00300                 self->mFloaterDirectory->hideAllDetailPanels();
00301         }
00302         
00303         if (FALSE == list->getCanSelect())
00304         {
00305                 return;
00306         }
00307 
00308         LLString id_str = self->childGetValue("results").asString();
00309         if (id_str.empty())
00310         {
00311                 return;
00312         }
00313 
00314         LLSD item_id = list->getCurrentID();
00315         S32 type = self->mResultsContents[id_str]["type"];
00316         if (type == EVENT_CODE)
00317         {
00318                 
00319                 item_id = self->mResultsContents[id_str]["event_id"];
00320         }
00321 
00322         
00323         self->showDetailPanel(type, item_id);
00324 }
00325 
00326 void LLPanelDirBrowser::showDetailPanel(S32 type, LLSD id)
00327 {
00328         switch(type)
00329         {
00330         case AVATAR_CODE:
00331                 if (mFloaterDirectory && mFloaterDirectory->mPanelAvatarp)
00332                 {
00333                         mFloaterDirectory->mPanelAvatarp->setVisible(TRUE);
00334                         mFloaterDirectory->mPanelAvatarp->setAvatarID(id.asUUID(), "", ONLINE_STATUS_NO);
00335                 }
00336                 break;
00337         case EVENT_CODE:
00338                 {
00339                         U32 event_id = (U32)id.asInteger();
00340                         showEvent(event_id);
00341                 }
00342                 break;
00343         case GROUP_CODE:
00344                 if (mFloaterDirectory && mFloaterDirectory->mPanelGroupHolderp)
00345                 {
00346                         mFloaterDirectory->mPanelGroupHolderp->setVisible(TRUE);
00347                 }
00348                 if (mFloaterDirectory && mFloaterDirectory->mPanelGroupp)
00349                 {
00350                         mFloaterDirectory->mPanelGroupp->setVisible(TRUE);
00351                         mFloaterDirectory->mPanelGroupp->setGroupID(id.asUUID());
00352                 }
00353                 break;
00354         case CLASSIFIED_CODE:
00355                 if (mFloaterDirectory && mFloaterDirectory->mPanelClassifiedp)
00356                 {
00357                         mFloaterDirectory->mPanelClassifiedp->setVisible(TRUE);
00358                         mFloaterDirectory->mPanelClassifiedp->setClassifiedID(id.asUUID());
00359                         mFloaterDirectory->mPanelClassifiedp->sendClassifiedInfoRequest();
00360                 }
00361                 break;
00362         case FOR_SALE_CODE:
00363         case AUCTION_CODE:
00364                 if (mFloaterDirectory && mFloaterDirectory->mPanelPlaceSmallp)
00365                 {
00366                         mFloaterDirectory->mPanelPlaceSmallp->setVisible(TRUE);
00367                         mFloaterDirectory->mPanelPlaceSmallp->resetLocation();
00368                         mFloaterDirectory->mPanelPlaceSmallp->setParcelID(id.asUUID());
00369                 }
00370                 break;
00371         case PLACE_CODE:
00372         case POPULAR_CODE:
00373                 if (mFloaterDirectory && mFloaterDirectory->mPanelPlacep)
00374                 {
00375                         mFloaterDirectory->mPanelPlacep->setVisible(TRUE);
00376                         mFloaterDirectory->mPanelPlacep->resetLocation();
00377                         mFloaterDirectory->mPanelPlacep->setParcelID(id.asUUID());
00378                 }
00379                 break;
00380         default:
00381                 {
00382                         llwarns << "Unknown event type!" << llendl;
00383                 }
00384                 break;
00385         }
00386 }
00387 
00388 
00389 void LLPanelDirBrowser::showEvent(const U32 event_id)
00390 {
00391         
00392         if (mFloaterDirectory)
00393         {
00394                 mFloaterDirectory->hideAllDetailPanels();
00395                 if (mFloaterDirectory->mPanelEventp)
00396                 {
00397                         mFloaterDirectory->mPanelEventp->setVisible(TRUE);
00398                         mFloaterDirectory->mPanelEventp->setEventID(event_id);
00399                 }
00400         }
00401 }
00402 
00403 void LLPanelDirBrowser::processDirPeopleReply(LLMessageSystem *msg, void**)
00404 {
00405         LLUUID query_id;
00406         char   first_name[DB_FIRST_NAME_BUF_SIZE];      
00407         char   last_name[DB_LAST_NAME_BUF_SIZE];        
00408         LLUUID agent_id;
00409 
00410         msg->getUUIDFast(_PREHASH_QueryData,_PREHASH_QueryID, query_id);
00411 
00412         LLPanelDirBrowser* self;
00413         self = gDirBrowserInstances.getIfThere(query_id);
00414         if (!self) 
00415         {
00416                 
00417                 return;
00418         }
00419 
00420         self->mHaveSearchResults = TRUE;
00421 
00422         LLCtrlListInterface *list = self->childGetListInterface("results");
00423         if (!list) return;
00424 
00425         if (!list->getCanSelect())
00426         {
00427                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00428                 self->mResultsContents = LLSD();
00429         }
00430 
00431         S32 rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
00432         self->mResultsReceived += rows;
00433 
00434         rows = self->showNextButton(rows);
00435 
00436         for (S32 i = 0; i < rows; i++)
00437         {                       
00438                 msg->getStringFast(_PREHASH_QueryReplies,_PREHASH_FirstName, DB_FIRST_NAME_BUF_SIZE, first_name, i);
00439                 msg->getStringFast(_PREHASH_QueryReplies,_PREHASH_LastName,     DB_LAST_NAME_BUF_SIZE, last_name, i);
00440                 msg->getUUIDFast(  _PREHASH_QueryReplies,_PREHASH_AgentID, agent_id, i);
00441                 
00442                 
00443                 
00444                 
00445 
00446                 if (agent_id.isNull())
00447                 {
00448                         continue;
00449                 }
00450 
00451                 LLSD content;
00452 
00453                 LLSD row;
00454                 row["id"] = agent_id;
00455 
00456                 LLUUID image_id;
00457                 
00458                 
00459                 image_id.set( gViewerArt.getString("icon_avatar_offline.tga") );
00460                 row["columns"][0]["column"] = "icon";
00461                 row["columns"][0]["type"] = "icon";
00462                 row["columns"][0]["value"] = image_id;
00463 
00464                 content["type"] = AVATAR_CODE;
00465 
00466                 LLString fullname = LLString(first_name) + " " + LLString(last_name);
00467                 row["columns"][1]["column"] = "name";
00468                 row["columns"][1]["value"] = fullname;
00469                 row["columns"][1]["font"] = "SANSSERIF";
00470 
00471                 content["name"] = fullname;
00472 
00473                 list->addElement(row);
00474                 self->mResultsContents[agent_id.asString()] = content;
00475         }
00476 
00477         list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
00478         self->updateResultCount();
00479 
00480         
00481         self->mLastResultTimer.reset();
00482         self->mDidAutoSelect = FALSE;
00483 }
00484 
00485 
00486 void LLPanelDirBrowser::processDirPlacesReply(LLMessageSystem* msg, void**)
00487 {
00488         LLUUID  agent_id;
00489         LLUUID  query_id;
00490         LLUUID  parcel_id;
00491         char    name[MAX_STRING];               
00492         BOOL    is_for_sale;
00493         BOOL    is_auction;
00494         F32             dwell;
00495 
00496         msg->getUUID("AgentData", "AgentID", agent_id);
00497         msg->getUUID("QueryData", "QueryID", query_id );
00498 
00499         LLPanelDirBrowser* self;
00500         self = gDirBrowserInstances.getIfThere(query_id);
00501         if (!self) 
00502         {
00503                 
00504                 return;
00505         }
00506 
00507         self->mHaveSearchResults = TRUE;
00508 
00509         LLCtrlListInterface *list = self->childGetListInterface("results");
00510         if (!list) return;
00511 
00512         if (!list->getCanSelect())
00513         {
00514                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00515                 self->mResultsContents = LLSD();
00516         }
00517 
00518         S32 i;
00519         S32 count = msg->getNumberOfBlocks("QueryReplies");
00520         self->mResultsReceived += count;
00521 
00522         count = self->showNextButton(count);
00523 
00524         for (i = 0; i < count ; i++)
00525         {
00526                 msg->getUUID("QueryReplies", "ParcelID", parcel_id, i);
00527                 msg->getString("QueryReplies", "Name", MAX_STRING, name, i);
00528                 msg->getBOOL("QueryReplies", "ForSale", is_for_sale, i);
00529                 msg->getBOOL("QueryReplies", "Auction", is_auction, i);
00530                 msg->getF32("QueryReplies", "Dwell", dwell, i);
00531                 
00532                 if (parcel_id.isNull())
00533                 {
00534                         continue;
00535                 }
00536 
00537                 LLSD content;
00538                 S32 type;
00539 
00540                 LLSD row = self->createLandSale(parcel_id, is_auction, is_for_sale,  name, &type);
00541 
00542                 content["type"] = type;
00543                 content["name"] = name;
00544 
00545                 LLString buffer = llformat("%.0f", (F64)dwell);
00546                 row["columns"][3]["column"] = "dwell";
00547                 row["columns"][3]["value"] = buffer;
00548                 row["columns"][3]["font"] = "SANSSERIFSMALL";
00549 
00550                 list->addElement(row);
00551                 self->mResultsContents[parcel_id.asString()] = content;
00552         }
00553 
00554         list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
00555         self->updateResultCount();
00556 
00557         
00558         self->mLastResultTimer.reset();
00559         self->mDidAutoSelect = FALSE;
00560 }
00561 
00562 
00563 
00564 void LLPanelDirBrowser::processDirPopularReply(LLMessageSystem *msg, void**)
00565 {
00566         LLUUID  agent_id;
00567         LLUUID  query_id;
00568         LLUUID  parcel_id;
00569         char    name[MAX_STRING];               
00570         F32             dwell;
00571 
00572         msg->getUUID("AgentData", "AgentID", agent_id);
00573         msg->getUUID("QueryData", "QueryID", query_id );
00574 
00575         LLPanelDirBrowser* self;
00576         self = gDirBrowserInstances.getIfThere(query_id);
00577         if (!self) 
00578         {
00579                 
00580                 return;
00581         }
00582 
00583         self->mHaveSearchResults = TRUE;
00584 
00585         LLCtrlListInterface *list = self->childGetListInterface("results");
00586         if (!list) return;
00587 
00588         if (!list->getCanSelect())
00589         {
00590                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00591                 self->mResultsContents = LLSD();
00592         }
00593 
00594         S32 i;
00595         S32 count = msg->getNumberOfBlocks("QueryReplies");
00596         self->mResultsReceived += count;
00597         for (i = 0; i < count; i++)
00598         {
00599                 msg->getUUID(   "QueryReplies", "ParcelID", parcel_id, i);
00600                 msg->getString( "QueryReplies", "Name", MAX_STRING, name, i);
00601                 msg->getF32(    "QueryReplies", "Dwell", dwell, i);
00602 
00603                 if (parcel_id.isNull())
00604                 {
00605                         continue;
00606                 }
00607 
00608                 LLSD content;
00609                 content["type"] = POPULAR_CODE;
00610                 content["name"] = name;
00611 
00612                 LLSD row;
00613                 row["id"] = parcel_id;
00614 
00615                 LLUUID image_id;
00616                 image_id.set( gViewerArt.getString("icon_popular.tga") );
00617                 row["columns"][0]["column"] = "icon";
00618                 row["columns"][0]["type"] = "icon";
00619                 row["columns"][0]["value"] = image_id;
00620 
00621                 row["columns"][1]["column"] = "name";
00622                 row["columns"][1]["value"] = name;
00623                 row["columns"][1]["font"] = "SANSSERIF";
00624 
00625                 LLString buffer = llformat("%.0f", dwell);
00626                 row["columns"][2]["column"] = "dwell";
00627                 row["columns"][2]["value"] = buffer;
00628                 row["columns"][2]["font"] = "SANSSERIFSMALL";
00629 
00630                 list->addElement(row);
00631                 self->mResultsContents[parcel_id.asString()] = content;
00632         }
00633 
00634         list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
00635         self->updateResultCount();
00636 
00637         
00638         self->mLastResultTimer.reset();
00639         self->mDidAutoSelect = FALSE;
00640 }
00641 
00642 
00643 void LLPanelDirBrowser::processDirEventsReply(LLMessageSystem* msg, void**)
00644 {
00645         LLUUID  agent_id;
00646         LLUUID  query_id;
00647         LLUUID  owner_id;
00648         char    name[MAX_STRING];                       
00649         char    date[MAX_STRING];               
00650         BOOL    show_mature = gSavedSettings.getBOOL("ShowMatureEvents");
00651 
00652         msg->getUUID("AgentData", "AgentID", agent_id);
00653         msg->getUUID("QueryData", "QueryID", query_id );
00654 
00655         LLPanelDirBrowser* self;
00656         self = gDirBrowserInstances.getIfThere(query_id);
00657         if (!self)
00658         {
00659                 return;
00660         }
00661 
00662         self->mHaveSearchResults = TRUE;
00663 
00664         LLCtrlListInterface *list = self->childGetListInterface("results");
00665         if (!list) return;
00666 
00667         if (!list->getCanSelect())
00668         {
00669                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00670                 self->mResultsContents = LLSD();
00671         }
00672 
00673         S32 rows = msg->getNumberOfBlocks("QueryReplies");
00674         self->mResultsReceived += rows;
00675 
00676         rows = self->showNextButton(rows);
00677 
00678         for (S32 i = 0; i < rows; i++)
00679         {
00680                 U32 event_id;
00681                 U32 unix_time;
00682                 U32 event_flags;
00683 
00684                 msg->getUUID("QueryReplies", "OwnerID", owner_id, i);
00685                 msg->getString("QueryReplies", "Name", MAX_STRING, name, i);
00686                 msg->getU32("QueryReplies", "EventID", event_id, i);
00687                 msg->getString("QueryReplies", "Date", MAX_STRING, date, i);
00688                 msg->getU32("QueryReplies", "UnixTime", unix_time, i);
00689                 msg->getU32("QueryReplies", "EventFlags", event_flags, i);
00690         
00691                 
00692                 if (owner_id.isNull())
00693                 {
00694                         
00695                         llwarns << "skipped event due to owner_id null, event_id " << event_id << llendl;
00696                         continue;
00697                 }
00698                 
00699                 if (!show_mature
00700                         && (event_flags & EVENT_FLAG_MATURE))
00701                 {
00702                         llwarns << "Skipped due to maturity, event_id " << event_id << llendl;
00703                         continue;
00704                 }
00705 
00706                 LLSD content;
00707 
00708                 content["type"] = EVENT_CODE;
00709                 content["name"] = name;
00710                 content["event_id"] = (S32)event_id;
00711 
00712                 LLSD row;
00713                 row["id"] = llformat("%u", event_id);
00714 
00715                 
00716                 LLUUID image_id;
00717                 if (event_flags & EVENT_FLAG_MATURE)
00718                 {
00719                         image_id.set( gViewerArt.getString("icon_event_mature.tga") );
00720                         row["columns"][0]["column"] = "icon";
00721                         row["columns"][0]["type"] = "icon";
00722                         row["columns"][0]["value"] = image_id;
00723                 }
00724                 else
00725                 {
00726                         image_id.set( gViewerArt.getString("icon_event.tga") );
00727                         row["columns"][0]["column"] = "icon";
00728                         row["columns"][0]["type"] = "icon";
00729                         row["columns"][0]["value"] = image_id;
00730                 }
00731 
00732                 row["columns"][1]["column"] = "name";
00733                 row["columns"][1]["value"] = name;
00734                 row["columns"][1]["font"] = "SANSSERIF";
00735 
00736                 row["columns"][2]["column"] = "date";
00737                 row["columns"][2]["value"] = date;
00738                 row["columns"][2]["font"] = "SANSSERIFSMALL";
00739 
00740                 row["columns"][3]["column"] = "time";
00741                 row["columns"][3]["value"] = llformat("%u", unix_time);
00742                 row["columns"][3]["font"] = "SANSSERIFSMALL";
00743 
00744                 list->addElement(row, ADD_SORTED);
00745 
00746                 LLString id_str = llformat("%u", event_id);
00747                 self->mResultsContents[id_str] = content;
00748         }
00749 
00750         list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
00751         self->updateResultCount();
00752 
00753         
00754         self->mLastResultTimer.reset();
00755         self->mDidAutoSelect = FALSE;
00756 }
00757 
00758 
00759 
00760 void LLPanelDirBrowser::processDirGroupsReply(LLMessageSystem* msg, void**)
00761 {
00762         S32             i;
00763         
00764         LLUUID  query_id;
00765         LLUUID  group_id;
00766         char    group_name[DB_GROUP_NAME_BUF_SIZE];             
00767         S32     members;
00768         F32     search_order;
00769 
00770         msg->getUUIDFast(_PREHASH_QueryData,_PREHASH_QueryID, query_id );
00771 
00772         LLPanelDirBrowser* self;
00773         self = gDirBrowserInstances.getIfThere(query_id);
00774         if (!self)
00775         {
00776                 return;
00777         }
00778 
00779         self->mHaveSearchResults = TRUE;
00780 
00781         LLCtrlListInterface *list = self->childGetListInterface("results");
00782         if (!list) return;
00783 
00784         if (!list->getCanSelect())
00785         {
00786                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00787                 self->mResultsContents = LLSD();
00788         }
00789 
00790         S32 rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
00791         self->mResultsReceived += rows;
00792 
00793         rows = self->showNextButton(rows);
00794 
00795         for (i = 0; i < rows; i++)
00796         {
00797                 msg->getUUIDFast(_PREHASH_QueryReplies, _PREHASH_GroupID,               group_id, i );
00798                 msg->getStringFast(_PREHASH_QueryReplies, _PREHASH_GroupName,   DB_GROUP_NAME_BUF_SIZE,         group_name,             i);
00799                 msg->getS32Fast(_PREHASH_QueryReplies, _PREHASH_Members,                members, i );
00800                 msg->getF32Fast(_PREHASH_QueryReplies, _PREHASH_SearchOrder,    search_order, i );
00801                 
00802                 if (group_id.isNull())
00803                 {
00804                         continue;
00805                 }
00806 
00807                 LLSD content;
00808                 content["type"] = GROUP_CODE;
00809                 content["name"] = group_name;
00810 
00811                 LLSD row;
00812                 row["id"] = group_id;
00813 
00814                 LLUUID image_id;
00815                 image_id.set( gViewerArt.getString("icon_group.tga") );
00816                 row["columns"][0]["column"] = "icon";
00817                 row["columns"][0]["type"] = "icon";
00818                 row["columns"][0]["value"] = image_id;
00819 
00820                 row["columns"][1]["column"] = "name";
00821                 row["columns"][1]["value"] = group_name;
00822                 row["columns"][1]["font"] = "SANSSERIF";
00823 
00824                 row["columns"][2]["column"] = "members";
00825                 row["columns"][2]["value"] = members;
00826                 row["columns"][2]["font"] = "SANSSERIFSMALL";
00827 
00828                 row["columns"][3]["column"] = "score";
00829                 row["columns"][3]["value"] = search_order;
00830 
00831                 list->addElement(row);
00832                 self->mResultsContents[group_id.asString()] = content;
00833         }
00834         list->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending);
00835         self->updateResultCount();
00836 
00837         
00838         self->mLastResultTimer.reset();
00839         self->mDidAutoSelect = FALSE;
00840 }
00841 
00842 
00843 
00844 void LLPanelDirBrowser::processDirClassifiedReply(LLMessageSystem* msg, void**)
00845 {
00846         S32             i;
00847         S32             num_new_rows;
00848 
00849         LLUUID  agent_id;
00850         LLUUID  query_id;
00851 
00852         msg->getUUID("AgentData", "AgentID", agent_id);
00853         if (agent_id != gAgent.getID())
00854         {
00855                 llwarns << "Message for wrong agent " << agent_id
00856                         << " in processDirClassifiedReply" << llendl;
00857                 return;
00858         }
00859 
00860         msg->getUUID("QueryData", "QueryID", query_id);
00861         LLPanelDirBrowser* self = gDirBrowserInstances.getIfThere(query_id);
00862         if (!self)
00863         {
00864                 return;
00865         }
00866 
00867         self->mHaveSearchResults = TRUE;
00868 
00869         LLCtrlListInterface *list = self->childGetListInterface("results");
00870         if (!list) return;
00871 
00872         if (!list->getCanSelect())
00873         {
00874                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00875                 self->mResultsContents = LLSD();
00876         }
00877 
00878         num_new_rows = msg->getNumberOfBlocksFast(_PREHASH_QueryReplies);
00879         self->mResultsReceived += num_new_rows;
00880 
00881         num_new_rows = self->showNextButton(num_new_rows);
00882         for (i = 0; i < num_new_rows; i++)
00883         {
00884                 LLUUID classified_id;
00885                 char name[DB_PARCEL_NAME_SIZE];         
00886                 U32 creation_date = 0;  
00887                 U32 expiration_date = 0;        
00888                 S32 price_for_listing = 0;
00889                 msg->getUUID("QueryReplies", "ClassifiedID", classified_id, i);
00890                 msg->getString("QueryReplies", "Name", DB_PARCEL_NAME_SIZE, name, i);
00891                 msg->getU32("QueryReplies","CreationDate",creation_date,i);
00892                 msg->getU32("QueryReplies","ExpirationDate",expiration_date,i);
00893                 msg->getS32("QueryReplies","PriceForListing",price_for_listing,i);
00894 
00895                 if ( classified_id.notNull() )
00896                 {
00897                         self->addClassified(list, classified_id, name, creation_date, price_for_listing);
00898 
00899                         LLSD content;
00900                         content["type"] = CLASSIFIED_CODE;
00901                         content["name"] = name;
00902                         self->mResultsContents[classified_id.asString()] = content;
00903                 }
00904         }
00905         
00906         self->updateResultCount();
00907 
00908         
00909         self->mLastResultTimer.reset();
00910         self->mDidAutoSelect = FALSE;
00911 }
00912 
00913 void LLPanelDirBrowser::processDirLandReply(LLMessageSystem *msg, void**)
00914 {
00915         LLUUID  agent_id;
00916         LLUUID  query_id;
00917         LLUUID  parcel_id;
00918         char    name[MAX_STRING];               
00919         BOOL    auction;
00920         BOOL    for_sale;
00921         S32             sale_price;
00922         S32             actual_area;
00923 
00924         msg->getUUID("AgentData", "AgentID", agent_id);
00925         msg->getUUID("QueryData", "QueryID", query_id );
00926 
00927         LLPanelDirBrowser* browser;
00928         browser = gDirBrowserInstances.getIfThere(query_id);
00929         if (!browser) 
00930         {
00931                 
00932                 return;
00933         }
00934 
00935         
00936         LLPanelDirLand* self = (LLPanelDirLand*)browser;
00937 
00938         self->mHaveSearchResults = TRUE;
00939 
00940         LLCtrlListInterface *list = self->childGetListInterface("results");
00941         if (!list) return;
00942 
00943         if (!list->getCanSelect())
00944         {
00945                 list->operateOnAll(LLCtrlListInterface::OP_DELETE);
00946                 self->mResultsContents = LLSD();
00947         }
00948 
00949         BOOL use_price = gSavedSettings.getBOOL("FindLandPrice");
00950         S32 limit_price = self->childGetValue("priceedit").asInteger();
00951 
00952         BOOL use_area = gSavedSettings.getBOOL("FindLandArea");
00953         S32 limit_area = self->childGetValue("areaedit").asInteger();
00954 
00955         S32 i;
00956         S32 count = msg->getNumberOfBlocks("QueryReplies");
00957         self->mResultsReceived += count;
00958         
00959         S32 non_auction_count = 0;
00960         for (i = 0; i < count; i++)
00961         {
00962                 msg->getUUID(   "QueryReplies", "ParcelID", parcel_id, i);
00963                 msg->getString( "QueryReplies", "Name", MAX_STRING, name, i);
00964                 msg->getBOOL(   "QueryReplies", "Auction", auction, i);
00965                 msg->getBOOL(   "QueryReplies", "ForSale", for_sale, i);
00966                 msg->getS32(    "QueryReplies", "SalePrice", sale_price, i);
00967                 msg->getS32(    "QueryReplies", "ActualArea", actual_area, i);
00968                 
00969                 if (parcel_id.isNull()) continue;
00970 
00971                 if (use_price && (sale_price > limit_price)) continue;
00972 
00973                 if (use_area && (actual_area < limit_area)) continue;
00974 
00975                 LLSD content;
00976                 S32 type;
00977 
00978                 LLSD row = self->createLandSale(parcel_id, auction, for_sale,  name, &type);
00979 
00980                 content["type"] = type;
00981                 content["name"] = name;
00982 
00983                 LLString buffer = "Auction";
00984                 if (!auction)
00985                 {
00986                         buffer = llformat("%d", sale_price);
00987                         non_auction_count++;
00988                 }
00989                 row["columns"][3]["column"] = "price";
00990                 row["columns"][3]["value"] = buffer;
00991                 row["columns"][3]["font"] = "SANSSERIFSMALL";
00992 
00993                 buffer = llformat("%d", actual_area);
00994                 row["columns"][4]["column"] = "area";
00995                 row["columns"][4]["value"] = buffer;
00996                 row["columns"][4]["font"] = "SANSSERIFSMALL";
00997 
00998                 if (!auction)
00999                 {
01000                         F32 price_per_meter;
01001                         if (actual_area > 0)
01002                         {
01003                                 price_per_meter = (F32)sale_price / (F32)actual_area;
01004                         }
01005                         else
01006                         {
01007                                 price_per_meter = 0.f;
01008                         }
01009                         
01010                         buffer = llformat("%.1f", price_per_meter);
01011                         row["columns"][5]["column"] = "per_meter";
01012                         row["columns"][5]["value"] = buffer;
01013                         row["columns"][5]["font"] = "SANSSERIFSMALL";
01014                 }
01015                 else
01016                 {
01017                         
01018                         row["columns"][5]["column"] = "per_meter";
01019                         row["columns"][5]["value"] = "1.0";
01020                         row["columns"][5]["font"] = "SANSSERIFSMALL";
01021                 }
01022 
01023                 list->addElement(row);
01024                 self->mResultsContents[parcel_id.asString()] = content;
01025         }
01026 
01027         
01028         
01029         
01030         count = self->showNextButton(non_auction_count);
01031 
01032         
01033         list->sortByColumn("",FALSE);
01034         self->updateResultCount();
01035 
01036         
01037         self->mLastResultTimer.reset();
01038         self->mDidAutoSelect = FALSE;
01039 }
01040 
01041 void LLPanelDirBrowser::addClassified(LLCtrlListInterface *list, const LLUUID& pick_id, const char* name, const U32 creation_date, const S32 price_for_listing)
01042 {
01043         LLString type = llformat("%d", CLASSIFIED_CODE);
01044 
01045         LLSD row;
01046         row["id"] = pick_id;
01047 
01048         LLUUID image_id;
01049         image_id.set( gViewerArt.getString("icon_top_pick.tga") );
01050         row["columns"][0]["column"] = "icon";
01051         row["columns"][0]["type"] = "icon";
01052         row["columns"][0]["value"] = image_id;
01053 
01054         row["columns"][1]["column"] = "name";
01055         row["columns"][1]["value"] = name;
01056         row["columns"][1]["font"] = "SANSSERIF";
01057 
01058         row["columns"][2]["column"] = "price";
01059         row["columns"][2]["value"] = price_for_listing;
01060         row["columns"][2]["font"] = "SANSSERIFSMALL";
01061 
01062         list->addElement(row);
01063 }
01064 
01065 LLSD LLPanelDirBrowser::createLandSale(const LLUUID& parcel_id, BOOL is_auction, BOOL is_for_sale,  const LLString& name, S32 *type)
01066 {
01067         LLSD row;
01068         row["id"] = parcel_id;
01069         LLUUID image_id;
01070 
01071         
01072         if(is_auction)
01073         {
01074                 image_id.set( gViewerArt.getString("icon_auction.tga") );
01075                 row["columns"][0]["column"] = "icon";
01076                 row["columns"][0]["type"] = "icon";
01077                 row["columns"][0]["value"] = image_id;
01078 
01079                 *type = AUCTION_CODE;
01080         }
01081         else if (is_for_sale)
01082         {
01083                 image_id.set( gViewerArt.getString("icon_for_sale.tga") );
01084                 row["columns"][0]["column"] = "icon";
01085                 row["columns"][0]["type"] = "icon";
01086                 row["columns"][0]["value"] = image_id;
01087 
01088                 *type = FOR_SALE_CODE;
01089         }
01090         else
01091         {
01092                 image_id.set( gViewerArt.getString("icon_place.tga") );
01093                 row["columns"][0]["column"] = "icon";
01094                 row["columns"][0]["type"] = "icon";
01095                 row["columns"][0]["value"] = image_id;
01096 
01097                 *type = PLACE_CODE;
01098         }
01099 
01100         row["columns"][2]["column"] = "name";
01101         row["columns"][2]["value"] = name;
01102         row["columns"][2]["font"] = "SANSSERIF";
01103 
01104         return row;
01105 }
01106 
01107 void LLPanelDirBrowser::newClassified()
01108 {
01109         LLCtrlListInterface *list = childGetListInterface("results");
01110         if (!list) return;
01111 
01112         if (mFloaterDirectory->mPanelClassifiedp)
01113         {
01114                 
01115                 mFloaterDirectory->mPanelClassifiedp->reset();
01116 
01117                 
01118                 
01119                 mFloaterDirectory->mPanelClassifiedp->initNewClassified();
01120 
01121                 
01122                 LLUUID classified_id = mFloaterDirectory->mPanelClassifiedp->getClassifiedID();
01123 
01124                 
01125                 addClassified(list, classified_id, mFloaterDirectory->mPanelClassifiedp->getClassifiedName().c_str(),0,0);
01126 
01127                 
01128                 list->setCurrentByID(classified_id);
01129 
01130                 
01131                 mFloaterDirectory->mPanelClassifiedp->setVisible(TRUE);
01132         }
01133 }
01134 
01135 void LLPanelDirBrowser::renameClassified(const LLUUID& classified_id, const char* name)
01136 {
01137         
01138         
01139 
01140 
01141 
01142 
01143 
01144 
01145 
01146 
01147 
01148 
01149 
01150 
01151 
01152 
01153 
01154 
01155 
01156 
01157 }
01158 
01159 
01160 void LLPanelDirBrowser::setupNewSearch()
01161 {
01162         LLCtrlListInterface *list = childGetListInterface("results");
01163         if (!list) return;
01164 
01165         gDirBrowserInstances.removeData(mSearchID);
01166         
01167         mSearchID.generate();
01168 
01169         gDirBrowserInstances.addData(mSearchID, this);
01170 
01171         
01172         list->operateOnAll(LLCtrlListInterface::OP_DELETE);
01173         list->addSimpleElement("Searching...");
01174         childDisable("results");
01175 
01176         mResultsReceived = 0;
01177         mHaveSearchResults = FALSE;
01178 
01179         
01180         mFloaterDirectory->hideAllDetailPanels();
01181 
01182         updateResultCount();
01183 }
01184 
01185 
01186 
01187 void LLPanelDirBrowser::onClickSearchCore(void* userdata)
01188 {
01189         LLPanelDirBrowser* self = (LLPanelDirBrowser*)userdata;
01190         if (!self) return;
01191 
01192         self->resetSearchStart();
01193         self->performQuery();
01194 }
01195 
01196 
01197 
01198 void LLPanelDirBrowser::sendDirFindQuery(
01199         LLMessageSystem* msg,
01200         const LLUUID& query_id,
01201         const LLString& text,
01202         U32 flags,
01203         S32 query_start)
01204 {
01205         msg->newMessage("DirFindQuery");
01206         msg->nextBlock("AgentData");
01207         msg->addUUID("AgentID", gAgent.getID());
01208         msg->addUUID("SessionID", gAgent.getSessionID());
01209         msg->nextBlock("QueryData");
01210         msg->addUUID("QueryID", query_id);
01211         msg->addString("QueryText", text);
01212         msg->addU32("QueryFlags", flags);
01213         msg->addS32("QueryStart", query_start);
01214         gAgent.sendReliableMessage();
01215 }
01216 
01217 
01218 void LLPanelDirBrowser::addHelpText(const char* text)
01219 {
01220         LLCtrlListInterface *list = childGetListInterface("results");
01221         if (!list) return;
01222 
01223         list->addSimpleElement(text);
01224         childDisable("results");
01225 }
01226 
01227 
01228 void LLPanelDirBrowser::onKeystrokeName(LLLineEditor* line, void* data)
01229 {
01230         LLPanelDirBrowser *self = (LLPanelDirBrowser*)data;
01231         if (line->getLength() >= (S32)self->mMinSearchChars)
01232         {
01233                 self->setDefaultBtn( "Search" );
01234                 self->childEnable("Search");
01235         }
01236         else
01237         {
01238                 self->setDefaultBtn();
01239                 self->childDisable("Search");
01240         }
01241 }
01242 
01243 
01244 void LLPanelDirBrowser::onVisibilityChange(BOOL new_visibility)
01245 {
01246         if (new_visibility)
01247         {
01248                 onCommitList(NULL, this);
01249         }
01250         LLPanel::onVisibilityChange(new_visibility);
01251 }
01252 
01253 S32 LLPanelDirBrowser::showNextButton(S32 rows)
01254 {
01255         
01256         
01257         if ( getName() != "find_all_old_panel")
01258         {
01259                 
01260                 bool show_next = (mResultsReceived > mResultsPerPage);
01261                 childSetVisible("Next >", show_next);
01262                 if (show_next)
01263                 {
01264                         rows -= (mResultsReceived - mResultsPerPage);
01265                 }
01266         }
01267         else
01268         {
01269                 
01270                 childHide("Next >");
01271                 childHide("< Prev");
01272         }
01273         return rows;
01274 }