llfloatersellland.cpp

Go to the documentation of this file.
00001 
00031 #include "llviewerprecompiledheaders.h"
00032 
00033 #include "llfloatersellland.h"
00034 
00035 #include "llfloateravatarpicker.h"
00036 #include "llfloater.h"
00037 #include "llfloaterland.h"
00038 #include "lllineeditor.h"
00039 #include "llnotify.h"
00040 #include "llparcel.h"
00041 #include "llselectmgr.h"
00042 #include "lltexturectrl.h"
00043 #include "llviewercontrol.h"
00044 #include "llviewerparcelmgr.h"
00045 #include "lluictrlfactory.h"
00046 #include "llviewerwindow.h"
00047 
00048 // defined in llfloaterland.cpp
00049 void send_parcel_select_objects(S32 parcel_local_id, S32 return_type,
00050                                                                 uuid_list_t* return_ids = NULL);
00051 
00052 enum Badge { BADGE_OK, BADGE_NOTE, BADGE_WARN, BADGE_ERROR };
00053 
00054 class LLFloaterSellLandUI
00055 :       public LLFloater
00056 {
00057 private:
00058         LLFloaterSellLandUI();
00059         virtual ~LLFloaterSellLandUI();
00060 
00061         LLViewerRegion* mRegion;
00062         LLParcelSelectionHandle mParcelSelection;
00063         bool                                    mParcelIsForSale;
00064         bool                                    mSellToBuyer;
00065         bool                                    mChoseSellTo;
00066         S32                                             mParcelPrice;
00067         S32                                             mParcelActualArea;
00068         LLUUID                                  mParcelSnapshot;
00069         LLUUID                                  mAuthorizedBuyer;
00070         bool                                    mParcelSoldWithObjects;
00071         
00072         void updateParcelInfo();
00073         void refreshUI();
00074         void setBadge(const char* id, Badge badge);
00075 
00076         static LLFloaterSellLandUI* sInstance;
00077 
00078         static void onChangeValue(LLUICtrl *ctrl, void *userdata);
00079         static void doSelectAgent(void *userdata);
00080         static void doCancel(void *userdata);
00081         static void doSellLand(void *userdata);
00082         static void onConfirmSale(S32 option, void *userdata);
00083         static void doShowObjects(void *userdata);
00084         static void callbackHighlightTransferable(S32 option, void* userdata);
00085 
00086         static void callbackAvatarPick(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
00087 
00088 public:
00089         virtual BOOL postBuild();
00090         virtual void onClose(bool app_quitting);
00091         
00092         static LLFloaterSellLandUI* soleInstance(bool createIfNeeded);
00093 
00094         bool setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel);
00095 
00096 private:
00097         class SelectionObserver : public LLParcelObserver
00098         {
00099         public:
00100                 virtual void changed();
00101         };
00102 };
00103 
00104 // static
00105 void LLFloaterSellLand::sellLand(
00106         LLViewerRegion* region, LLParcelSelectionHandle parcel)
00107 {
00108         LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(true);
00109         if (ui->setParcel(region, parcel))
00110         {
00111                 ui->open();             /* Flawfinder: ignore */
00112         }
00113 }
00114 
00115 // static
00116 LLFloaterSellLandUI* LLFloaterSellLandUI::sInstance = NULL;
00117 
00118 // static
00119 LLFloaterSellLandUI* LLFloaterSellLandUI::soleInstance(bool createIfNeeded)
00120 {
00121         if (!sInstance  &&  createIfNeeded)
00122         {
00123                 sInstance = new LLFloaterSellLandUI();
00124 
00125                 LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_sell_land.xml");
00126                 sInstance->center();
00127         }
00128         
00129 
00130         static SelectionObserver* parcelSelectionObserver = NULL;
00131         if (!parcelSelectionObserver)
00132         {
00133                 parcelSelectionObserver = new SelectionObserver;
00134                 LLViewerParcelMgr::getInstance()->addObserver(parcelSelectionObserver);
00135         }
00136 
00137         return sInstance;
00138 }
00139 
00140 LLFloaterSellLandUI::LLFloaterSellLandUI()
00141 :       LLFloater("Sell Land"),
00142         mRegion(0)
00143 {
00144 }
00145 
00146 LLFloaterSellLandUI::~LLFloaterSellLandUI()
00147 {
00148         if (sInstance == this)
00149         {
00150                 sInstance = NULL;
00151         }
00152 }
00153 
00154 void LLFloaterSellLandUI::SelectionObserver::changed()
00155 {
00156         LLFloaterSellLandUI* ui = LLFloaterSellLandUI::soleInstance(false);
00157         if (ui)
00158         {
00159                 if (LLViewerParcelMgr::getInstance()->selectionEmpty())
00160                 {
00161                         ui->close();
00162                 }
00163                 else {
00164                         ui->setParcel(
00165                                 LLViewerParcelMgr::getInstance()->getSelectionRegion(),
00166                                 LLViewerParcelMgr::getInstance()->getParcelSelection());
00167                 }
00168         }
00169 }
00170 
00171 void LLFloaterSellLandUI::onClose(bool app_quitting)
00172 {
00173         LLFloater::onClose(app_quitting);
00174         destroy();
00175 }
00176 
00177 BOOL LLFloaterSellLandUI::postBuild()
00178 {
00179         childSetCommitCallback("sell_to", onChangeValue, this);
00180         childSetCommitCallback("price", onChangeValue, this);
00181         childSetPrevalidate("price", LLLineEditor::prevalidateNonNegativeS32);
00182         childSetCommitCallback("sell_objects", onChangeValue, this);
00183         childSetAction("sell_to_select_agent", doSelectAgent, this);
00184         childSetAction("cancel_btn", doCancel, this);
00185         childSetAction("sell_btn", doSellLand, this);
00186         childSetAction("show_objects", doShowObjects, this);
00187         return TRUE;
00188 }
00189 
00190 bool LLFloaterSellLandUI::setParcel(LLViewerRegion* region, LLParcelSelectionHandle parcel)
00191 {
00192         if (!parcel->getParcel()) // || !can_agent_modify_parcel(parcel)) // can_agent_modify_parcel was deprecated by GROUPS
00193         {
00194                 return false;
00195         }
00196 
00197         mRegion = region;
00198         mParcelSelection = parcel;
00199         mChoseSellTo = false;
00200 
00201 
00202         updateParcelInfo();
00203         refreshUI();
00204 
00205         return true;
00206 }
00207 
00208 void LLFloaterSellLandUI::updateParcelInfo()
00209 {
00210         LLParcel* parcelp = mParcelSelection->getParcel();
00211         if (!parcelp) return;
00212 
00213         mParcelActualArea = parcelp->getArea();
00214         mParcelIsForSale = parcelp->getForSale();
00215         if (mParcelIsForSale)
00216         {
00217                 mChoseSellTo = true;
00218         }
00219         mParcelPrice = mParcelIsForSale ? parcelp->getSalePrice() : 0;
00220         mParcelSoldWithObjects = parcelp->getSellWithObjects();
00221         if (mParcelIsForSale)
00222         {
00223                 childSetValue("price", mParcelPrice);
00224                 if (mParcelSoldWithObjects)
00225                 {
00226                         childSetValue("sell_objects", "yes");
00227                 }
00228                 else
00229                 {
00230                         childSetValue("sell_objects", "no");
00231                 }
00232         }
00233         else
00234         {
00235                 childSetValue("price", "");
00236                 childSetValue("sell_objects", "none");
00237         }
00238 
00239         mParcelSnapshot = parcelp->getSnapshotID();
00240 
00241         mAuthorizedBuyer = parcelp->getAuthorizedBuyerID();
00242         mSellToBuyer = mAuthorizedBuyer.notNull();
00243 
00244         if(mSellToBuyer)
00245         {
00246                 LLString name;
00247                 gCacheName->getFullName(mAuthorizedBuyer, name);
00248                 childSetText("sell_to_agent", name);
00249         }
00250 }
00251 
00252 void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
00253 {
00254         static LLString badgeOK("badge_ok.j2c");
00255         static LLString badgeNote("badge_note.j2c");
00256         static LLString badgeWarn("badge_warn.j2c");
00257         static LLString badgeError("badge_error.j2c");
00258         
00259         LLString badgeName;
00260         switch (badge)
00261         {
00262                 default:
00263                 case BADGE_OK:          badgeName = badgeOK;    break;
00264                 case BADGE_NOTE:        badgeName = badgeNote;  break;
00265                 case BADGE_WARN:        badgeName = badgeWarn;  break;
00266                 case BADGE_ERROR:       badgeName = badgeError; break;
00267         }
00268         
00269         childSetValue(id, badgeName);
00270 }
00271 
00272 void LLFloaterSellLandUI::refreshUI()
00273 {
00274         LLParcel* parcelp = mParcelSelection->getParcel();
00275         if (!parcelp) return;
00276 
00277         LLTextureCtrl* snapshot = getChild<LLTextureCtrl>("info_image");
00278         if (snapshot)
00279         {
00280                 snapshot->setImageAssetID(mParcelSnapshot);
00281         }
00282 
00283         childSetText("info_parcel", parcelp->getName());
00284         childSetTextArg("info_size", "[AREA]", llformat("%d", mParcelActualArea));
00285 
00286         LLString price_str = childGetValue("price").asString();
00287         bool valid_price = false;
00288         valid_price = (price_str != "") && LLLineEditor::prevalidateNonNegativeS32(utf8str_to_wstring(price_str));
00289 
00290         if (valid_price && mParcelActualArea > 0)
00291         {
00292                 F32 per_meter_price = 0;
00293                 per_meter_price = F32(mParcelPrice) / F32(mParcelActualArea);
00294                 childSetTextArg("price_per_m", "[PER_METER]", llformat("%0.2f", per_meter_price));
00295                 childShow("price_per_m");
00296 
00297                 setBadge("step_price", BADGE_OK);
00298         }
00299         else
00300         {
00301                 childHide("price_per_m");
00302 
00303                 if ("" == price_str)
00304                 {
00305                         setBadge("step_price", BADGE_NOTE);
00306                 }
00307                 else
00308                 {
00309                         setBadge("step_price", BADGE_ERROR);
00310                 }
00311         }
00312 
00313         if (mSellToBuyer)
00314         {
00315                 childSetValue("sell_to", "user");
00316                 childShow("sell_to_agent");
00317                 childShow("sell_to_select_agent");
00318         }
00319         else
00320         {
00321                 if (mChoseSellTo)
00322                 {
00323                         childSetValue("sell_to", "anyone");
00324                 }
00325                 else
00326                 {
00327                         childSetValue("sell_to", "select");
00328                 }
00329                 childHide("sell_to_agent");
00330                 childHide("sell_to_select_agent");
00331         }
00332 
00333         // Must select Sell To: Anybody, or User (with a specified username)
00334         LLString sell_to = childGetValue("sell_to").asString();
00335         bool valid_sell_to = "select" != sell_to &&
00336                 ("user" != sell_to || mAuthorizedBuyer.notNull());
00337 
00338         if (!valid_sell_to)
00339         {
00340                 setBadge("step_sell_to", BADGE_NOTE);
00341         }
00342         else
00343         {
00344                 setBadge("step_sell_to", BADGE_OK);
00345         }
00346 
00347         bool valid_sell_objects = ("none" != childGetValue("sell_objects").asString());
00348 
00349         if (!valid_sell_objects)
00350         {
00351                 setBadge("step_sell_objects", BADGE_NOTE);
00352         }
00353         else
00354         {
00355                 setBadge("step_sell_objects", BADGE_OK);
00356         }
00357 
00358         if (valid_sell_to && valid_price && valid_sell_objects)
00359         {
00360                 childEnable("sell_btn");
00361         }
00362         else
00363         {
00364                 childDisable("sell_btn");
00365         }
00366 }
00367 
00368 // static
00369 void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
00370 {
00371         LLFloaterSellLandUI *self = (LLFloaterSellLandUI *)userdata;
00372 
00373         LLString sell_to = self->childGetValue("sell_to").asString();
00374 
00375         if (sell_to == "user")
00376         {
00377                 self->mChoseSellTo = true;
00378                 self->mSellToBuyer = true;
00379                 if (self->mAuthorizedBuyer.isNull())
00380                 {
00381                         doSelectAgent(self);
00382                 }
00383         }
00384         else if (sell_to == "anyone")
00385         {
00386                 self->mChoseSellTo = true;
00387                 self->mSellToBuyer = false;
00388         }
00389 
00390         self->mParcelPrice = self->childGetValue("price");
00391 
00392         if ("yes" == self->childGetValue("sell_objects").asString())
00393         {
00394                 self->mParcelSoldWithObjects = true;
00395         }
00396         else
00397         {
00398                 self->mParcelSoldWithObjects = false;
00399         }
00400 
00401         self->refreshUI();
00402 }
00403 
00404 // static
00405 void LLFloaterSellLandUI::doSelectAgent(void *userdata)
00406 {
00407         LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)userdata;
00408         // grandparent is a floater, in order to set up dependency
00409         floaterp->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarPick, floaterp, FALSE, TRUE));
00410 }
00411 
00412 // static
00413 void LLFloaterSellLandUI::callbackAvatarPick(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data)
00414 {       
00415         LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)data;
00416         LLParcel* parcel = floaterp->mParcelSelection->getParcel();
00417 
00418         if (names.empty() || ids.empty()) return;
00419         
00420         LLUUID id = ids[0];
00421         parcel->setAuthorizedBuyerID(id);
00422 
00423         floaterp->mAuthorizedBuyer = ids[0];
00424 
00425         floaterp->childSetText("sell_to_agent", names[0]);
00426 
00427         floaterp->refreshUI();
00428 }
00429 
00430 // static
00431 void LLFloaterSellLandUI::doCancel(void *userdata)
00432 {
00433         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00434         self->close();
00435 }
00436 
00437 // static
00438 void LLFloaterSellLandUI::doShowObjects(void *userdata)
00439 {
00440         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00441         LLParcel* parcel = self->mParcelSelection->getParcel();
00442         if (!parcel) return;
00443 
00444         send_parcel_select_objects(parcel->getLocalID(), RT_SELL);
00445 
00446         LLNotifyBox::showXml("TransferObjectsHighlighted",
00447                                                  callbackHighlightTransferable,
00448                                                  userdata);
00449 }
00450 
00451 // static
00452 void LLFloaterSellLandUI::callbackHighlightTransferable(S32 option, void* userdata)
00453 {
00454         LLSelectMgr::getInstance()->unhighlightAll();
00455 }
00456 
00457 // static
00458 void LLFloaterSellLandUI::doSellLand(void *userdata)
00459 {
00460         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00461 
00462         LLParcel* parcel = self->mParcelSelection->getParcel();
00463 
00464         // Do a confirmation
00465         if (!parcel->getForSale())
00466         {
00467                 S32 sale_price = self->childGetValue("price");
00468                 S32 area = parcel->getArea();
00469                 std::string authorizedBuyerName = "Anyone";
00470                 bool sell_to_anyone = true;
00471                 if ("user" == self->childGetValue("sell_to").asString())
00472                 {
00473                         authorizedBuyerName = self->childGetText("sell_to_agent");
00474                         sell_to_anyone = false;
00475                 }
00476 
00477                 // must sell to someone if indicating sale to anyone
00478                 if ((sale_price == 0) && sell_to_anyone)
00479                 {
00480                         gViewerWindow->alertXml("SalePriceRestriction");
00481                         return;
00482                 }
00483 
00484                 LLStringBase<char>::format_map_t args;
00485                 args["[LAND_SIZE]"] = llformat("%d",area);
00486                 args["[SALE_PRICE]"] = llformat("%d",sale_price);
00487                 args["[NAME]"] = authorizedBuyerName;
00488 
00489                 if (sell_to_anyone)
00490                 {
00491                         gViewerWindow->alertXml("ConfirmLandSaleToAnyoneChange", args, onConfirmSale, self);
00492                 }
00493                 else
00494                 {
00495                         gViewerWindow->alertXml("ConfirmLandSaleChange", args, onConfirmSale, self);
00496                 }
00497         }
00498         else
00499         {
00500                 onConfirmSale(-1, self);
00501         }
00502 }
00503 
00504 // static
00505 void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
00506 {
00507         if (option != 0)
00508         {
00509                 return;
00510         }
00511         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00512         S32  sale_price = self->childGetValue("price");
00513 
00514         // Valid extracted data
00515         if (sale_price < 0)
00516         {
00517                 // TomY TODO: Throw an error
00518                 return;
00519         }
00520 
00521         LLParcel* parcel = self->mParcelSelection->getParcel();
00522         if (!parcel) return;
00523 
00524         // can_agent_modify_parcel deprecated by GROUPS
00525 //      if (!can_agent_modify_parcel(parcel))
00526 //      {
00527 //              self->close();
00528 //              return;
00529 //      }
00530 
00531         parcel->setParcelFlag(PF_FOR_SALE, TRUE);
00532         parcel->setSalePrice(sale_price);
00533         bool sell_with_objects = false;
00534         if ("yes" == self->childGetValue("sell_objects").asString())
00535         {
00536                 sell_with_objects = true;
00537         }
00538         parcel->setSellWithObjects(sell_with_objects);
00539         if ("user" == self->childGetValue("sell_to").asString())
00540         {
00541                 parcel->setAuthorizedBuyerID(self->mAuthorizedBuyer);
00542         }
00543         else
00544         {
00545                 parcel->setAuthorizedBuyerID(LLUUID::null);
00546         }
00547 
00548         // Send update to server
00549         LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
00550 
00551         self->close();
00552 }

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