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 "llvieweruictrlfactory.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                 gUICtrlFactory->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                 gParcelMgr->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 (gParcelMgr->selectionEmpty())
00160                 {
00161                         ui->close();
00162                 }
00163                 else {
00164                         ui->setParcel(
00165                                 gParcelMgr->getSelectionRegion(),
00166                                 gParcelMgr->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                 char firstname[MAX_STRING];             /* Flawfinder: ignore */
00248                 char lastname[MAX_STRING];              /* Flawfinder: ignore */
00249                 gCacheName->getName(mAuthorizedBuyer, firstname, lastname);
00250                 name.assign(firstname);
00251                 name.append(" ");
00252                 name.append(lastname);
00253 
00254                 childSetText("sell_to_agent", name);
00255         }
00256 }
00257 
00258 void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
00259 {
00260         static LLUUID badgeOK(gViewerArt.getString("badge_ok.tga"));
00261         static LLUUID badgeNote(gViewerArt.getString("badge_note.tga"));
00262         static LLUUID badgeWarn(gViewerArt.getString("badge_warn.tga"));
00263         static LLUUID badgeError(gViewerArt.getString("badge_error.tga"));
00264         
00265         LLUUID badgeUUID;
00266         switch (badge)
00267         {
00268                 default:
00269                 case BADGE_OK:          badgeUUID = badgeOK;    break;
00270                 case BADGE_NOTE:        badgeUUID = badgeNote;  break;
00271                 case BADGE_WARN:        badgeUUID = badgeWarn;  break;
00272                 case BADGE_ERROR:       badgeUUID = badgeError; break;
00273         }
00274         
00275         childSetValue(id, badgeUUID);
00276 }
00277 
00278 void LLFloaterSellLandUI::refreshUI()
00279 {
00280         LLParcel* parcelp = mParcelSelection->getParcel();
00281         if (!parcelp) return;
00282 
00283         LLTextureCtrl* snapshot = LLViewerUICtrlFactory::getTexturePickerByName(this, "info_image");
00284         if (snapshot)
00285         {
00286                 snapshot->setImageAssetID(mParcelSnapshot);
00287         }
00288 
00289         childSetText("info_parcel", parcelp->getName());
00290         childSetTextArg("info_size", "[AREA]", llformat("%d", mParcelActualArea));
00291 
00292         LLString price_str = childGetValue("price").asString();
00293         bool valid_price = false;
00294         valid_price = (price_str != "") && LLLineEditor::prevalidateNonNegativeS32(utf8str_to_wstring(price_str));
00295 
00296         if (valid_price && mParcelActualArea > 0)
00297         {
00298                 F32 per_meter_price = 0;
00299                 per_meter_price = F32(mParcelPrice) / F32(mParcelActualArea);
00300                 childSetTextArg("price_per_m", "[PER_METER]", llformat("%0.2f", per_meter_price));
00301                 childShow("price_per_m");
00302 
00303                 setBadge("step_price", BADGE_OK);
00304         }
00305         else
00306         {
00307                 childHide("price_per_m");
00308 
00309                 if ("" == price_str)
00310                 {
00311                         setBadge("step_price", BADGE_NOTE);
00312                 }
00313                 else
00314                 {
00315                         setBadge("step_price", BADGE_ERROR);
00316                 }
00317         }
00318 
00319         if (mSellToBuyer)
00320         {
00321                 childSetValue("sell_to", "user");
00322                 childShow("sell_to_agent");
00323                 childShow("sell_to_select_agent");
00324         }
00325         else
00326         {
00327                 if (mChoseSellTo)
00328                 {
00329                         childSetValue("sell_to", "anyone");
00330                 }
00331                 else
00332                 {
00333                         childSetValue("sell_to", "select");
00334                 }
00335                 childHide("sell_to_agent");
00336                 childHide("sell_to_select_agent");
00337         }
00338 
00339         // Must select Sell To: Anybody, or User (with a specified username)
00340         LLString sell_to = childGetValue("sell_to").asString();
00341         bool valid_sell_to = "select" != sell_to &&
00342                 ("user" != sell_to || mAuthorizedBuyer.notNull());
00343 
00344         if (!valid_sell_to)
00345         {
00346                 setBadge("step_sell_to", BADGE_NOTE);
00347         }
00348         else
00349         {
00350                 setBadge("step_sell_to", BADGE_OK);
00351         }
00352 
00353         bool valid_sell_objects = ("none" != childGetValue("sell_objects").asString());
00354 
00355         if (!valid_sell_objects)
00356         {
00357                 setBadge("step_sell_objects", BADGE_NOTE);
00358         }
00359         else
00360         {
00361                 setBadge("step_sell_objects", BADGE_OK);
00362         }
00363 
00364         if (valid_sell_to && valid_price && valid_sell_objects)
00365         {
00366                 childEnable("sell_btn");
00367         }
00368         else
00369         {
00370                 childDisable("sell_btn");
00371         }
00372 }
00373 
00374 // static
00375 void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
00376 {
00377         LLFloaterSellLandUI *self = (LLFloaterSellLandUI *)userdata;
00378 
00379         LLString sell_to = self->childGetValue("sell_to").asString();
00380 
00381         if (sell_to == "user")
00382         {
00383                 self->mChoseSellTo = true;
00384                 self->mSellToBuyer = true;
00385                 if (self->mAuthorizedBuyer.isNull())
00386                 {
00387                         doSelectAgent(self);
00388                 }
00389         }
00390         else if (sell_to == "anyone")
00391         {
00392                 self->mChoseSellTo = true;
00393                 self->mSellToBuyer = false;
00394         }
00395 
00396         self->mParcelPrice = self->childGetValue("price");
00397 
00398         if ("yes" == self->childGetValue("sell_objects").asString())
00399         {
00400                 self->mParcelSoldWithObjects = true;
00401         }
00402         else
00403         {
00404                 self->mParcelSoldWithObjects = false;
00405         }
00406 
00407         self->refreshUI();
00408 }
00409 
00410 // static
00411 void LLFloaterSellLandUI::doSelectAgent(void *userdata)
00412 {
00413         LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)userdata;
00414         // grandparent is a floater, in order to set up dependency
00415         floaterp->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarPick, floaterp, FALSE, TRUE));
00416 }
00417 
00418 // static
00419 void LLFloaterSellLandUI::callbackAvatarPick(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data)
00420 {       
00421         LLFloaterSellLandUI* floaterp = (LLFloaterSellLandUI*)data;
00422         LLParcel* parcel = floaterp->mParcelSelection->getParcel();
00423 
00424         if (names.empty() || ids.empty()) return;
00425         
00426         LLUUID id = ids[0];
00427         parcel->setAuthorizedBuyerID(id);
00428 
00429         floaterp->mAuthorizedBuyer = ids[0];
00430 
00431         floaterp->childSetText("sell_to_agent", names[0]);
00432 
00433         floaterp->refreshUI();
00434 }
00435 
00436 // static
00437 void LLFloaterSellLandUI::doCancel(void *userdata)
00438 {
00439         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00440         self->close();
00441 }
00442 
00443 // static
00444 void LLFloaterSellLandUI::doShowObjects(void *userdata)
00445 {
00446         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00447         LLParcel* parcel = self->mParcelSelection->getParcel();
00448         if (!parcel) return;
00449 
00450         send_parcel_select_objects(parcel->getLocalID(), RT_SELL);
00451 
00452         LLNotifyBox::showXml("TransferObjectsHighlighted",
00453                                                  callbackHighlightTransferable,
00454                                                  userdata);
00455 }
00456 
00457 // static
00458 void LLFloaterSellLandUI::callbackHighlightTransferable(S32 option, void* userdata)
00459 {
00460         gSelectMgr->unhighlightAll();
00461 }
00462 
00463 // static
00464 void LLFloaterSellLandUI::doSellLand(void *userdata)
00465 {
00466         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00467 
00468         LLParcel* parcel = self->mParcelSelection->getParcel();
00469 
00470         // Do a confirmation
00471         if (!parcel->getForSale())
00472         {
00473                 S32 sale_price = self->childGetValue("price");
00474                 S32 area = parcel->getArea();
00475                 std::string authorizedBuyerName = "Anyone";
00476                 bool sell_to_anyone = true;
00477                 if ("user" == self->childGetValue("sell_to").asString())
00478                 {
00479                         authorizedBuyerName = self->childGetText("sell_to_agent");
00480                         sell_to_anyone = false;
00481                 }
00482 
00483                 // must sell to someone if indicating sale to anyone
00484                 if ((sale_price == 0) && sell_to_anyone)
00485                 {
00486                         gViewerWindow->alertXml("SalePriceRestriction");
00487                         return;
00488                 }
00489 
00490                 LLStringBase<char>::format_map_t args;
00491                 args["[LAND_SIZE]"] = llformat("%d",area);
00492                 args["[SALE_PRICE]"] = llformat("%d",sale_price);
00493                 args["[NAME]"] = authorizedBuyerName;
00494 
00495                 gViewerWindow->alertXml("ConfirmLandSaleChange", args, onConfirmSale, self);
00496         }
00497         else
00498         {
00499                 onConfirmSale(-1, self);
00500         }
00501 }
00502 
00503 // static
00504 void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
00505 {
00506         if (option != 0)
00507         {
00508                 return;
00509         }
00510         LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
00511         S32  sale_price = self->childGetValue("price");
00512 
00513         // Valid extracted data
00514         if (sale_price < 0)
00515         {
00516                 // TomY TODO: Throw an error
00517                 return;
00518         }
00519 
00520         LLParcel* parcel = self->mParcelSelection->getParcel();
00521         if (!parcel) return;
00522 
00523         // can_agent_modify_parcel deprecated by GROUPS
00524 //      if (!can_agent_modify_parcel(parcel))
00525 //      {
00526 //              self->close();
00527 //              return;
00528 //      }
00529 
00530         parcel->setParcelFlag(PF_FOR_SALE, TRUE);
00531         parcel->setSalePrice(sale_price);
00532         bool sell_with_objects = false;
00533         if ("yes" == self->childGetValue("sell_objects").asString())
00534         {
00535                 sell_with_objects = true;
00536         }
00537         parcel->setSellWithObjects(sell_with_objects);
00538         if ("user" == self->childGetValue("sell_to").asString())
00539         {
00540                 parcel->setAuthorizedBuyerID(self->mAuthorizedBuyer);
00541         }
00542         else
00543         {
00544                 parcel->setAuthorizedBuyerID(LLUUID::null);
00545         }
00546 
00547         // Send update to server
00548         gParcelMgr->sendParcelPropertiesUpdate( parcel );
00549 
00550         self->close();
00551 }

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