diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llfloaterland.cpp |
Print done when done.
Diffstat (limited to 'indra/newview/llfloaterland.cpp')
-rw-r--r-- | indra/newview/llfloaterland.cpp | 3208 |
1 files changed, 3208 insertions, 0 deletions
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp new file mode 100644 index 0000000000..6897e49dd9 --- /dev/null +++ b/indra/newview/llfloaterland.cpp @@ -0,0 +1,3208 @@ +/** + * @file llfloaterland.cpp + * @brief "About Land" floater, allowing display and editing of land parcel properties. + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include <sstream> +#include <time.h> + +#include "llfloaterland.h" + +#include "llcachename.h" +#include "llfocusmgr.h" +#include "llparcel.h" +#include "message.h" + +#include "llagent.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloaterauction.h" +#include "llfloateravatarinfo.h" +#include "llfloatergroups.h" +#include "llfloatergroupinfo.h" +#include "lllineeditor.h" +#include "llnamelistctrl.h" +#include "llnotify.h" +#include "llradiogroup.h" +#include "llscrolllistctrl.h" +#include "llselectmgr.h" +#include "llspinctrl.h" +#include "lltabcontainer.h" +#include "lltextbox.h" +#include "lltexturectrl.h" +#include "lluiconstants.h" +#include "llvieweruictrlfactory.h" +#include "llviewermessage.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewertexteditor.h" +#include "llviewerwindow.h" +#include "llmediaengine.h" +#include "llviewercontrol.h" +#include "roles_constants.h" + +static const S32 EDIT_HEIGHT = 16; +static const S32 LEFT = HPAD; +static const S32 BOTTOM = VPAD; +static const S32 RULER0 = LEFT; +static const S32 RULER05 = RULER0 + 24; +static const S32 RULER1 = RULER05 + 16; +static const S32 RULER15 = RULER1 + 20; +static const S32 RULER2 = RULER1 + 32; +static const S32 RULER205= RULER2 + 32; +static const S32 RULER20 = RULER2 + 64; +static const S32 RULER21 = RULER20 + 16; +static const S32 RULER22 = RULER21 + 32; +static const S32 RULER225 = RULER20 + 64; +static const S32 RULER23 = RULER22 + 64; +static const S32 RULER24 = RULER23 + 26; +static const S32 RULER3 = RULER2 + 102; +static const S32 RULER4 = RULER3 + 8; +static const S32 RULER5 = RULER4 + 50; +static const S32 RULER6 = RULER5 + 52; +static const S32 RULER7 = RULER6 + 24; +static const S32 RIGHT = LEFT + 278; +static const S32 FAR_RIGHT = LEFT + 324 + 40; + +static const char PRICE[] = "Price:"; +static const char NO_PRICE[] = ""; +static const char AREA[] = "Area:"; + +static const char OWNER_ONLINE[] = "0"; +static const char OWNER_OFFLINE[] = "1"; +static const char OWNER_GROUP[] = "2"; + +static const char NEED_TIER_TO_MODIFY_STRING[] = "You must approve your purchase to modify this land."; + +static const char WEB_PAGE[] = "Web page"; +static const char QUICKTIME_MOVIE[] = "QuickTime movie"; +static const char RAW_HTML[] = "Raw HTML"; + +// constants used in callbacks below - syntactic sugar. +static const BOOL BUY_GROUP_LAND = TRUE; +static const BOOL BUY_PERSONAL_LAND = FALSE; + +// Statics +LLFloaterLand* LLFloaterLand::sInstance = NULL; +LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL; +S32 LLFloaterLand::sLastTab = 0; +BOOL LLFloaterLand::sRequestReplyOnUpdate = TRUE; + +// Local classes +class LLParcelSelectionObserver : public LLParcelObserver +{ +public: + virtual void changed() { LLFloaterLand::refreshAll(); } +}; + +//--------------------------------------------------------------------------- +// LLFloaterLand +//--------------------------------------------------------------------------- + +void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, + uuid_list_t* return_ids = NULL) +{ + LLMessageSystem *msg = gMessageSystem; + + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if (!region) return; + + // Since new highlight will be coming in, drop any highlights + // that exist right now. + gSelectMgr->unhighlightAll(); + + msg->newMessageFast(_PREHASH_ParcelSelectObjects); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel_local_id); + msg->addS32Fast(_PREHASH_ReturnType, return_type); + + // Throw all return ids into the packet. + // TODO: Check for too many ids. + if (return_ids) + { + uuid_list_t::iterator end = return_ids->end(); + for (uuid_list_t::iterator it = return_ids->begin(); + it != end; + ++it) + { + msg->nextBlockFast(_PREHASH_ReturnIDs); + msg->addUUIDFast(_PREHASH_ReturnID, (*it)); + } + } + else + { + // Put in a null key so that the message is complete. + msg->nextBlockFast(_PREHASH_ReturnIDs); + msg->addUUIDFast(_PREHASH_ReturnID, LLUUID::null); + } + + msg->sendReliable(region->getHost()); +} + + +// static +void LLFloaterLand::show() +{ + if (!sInstance) + { + sInstance = new LLFloaterLand(); + + // Select tab from last view + sInstance->mTabLand->selectTab(sLastTab); + + sObserver = new LLParcelSelectionObserver(); + gParcelMgr->addObserver( sObserver ); + } + + sInstance->open(); + + // Done automatically when the selected parcel's properties arrive + // (and hence we have the local id). + // gParcelMgr->sendParcelAccessListRequest(AL_ACCESS | AL_BAN | AL_RENTER); + + // If we've already got the parcel data, fill the + // floater with it. + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (parcel) + { + sInstance->refresh(); + } + + sRequestReplyOnUpdate = TRUE; +} + +//static +LLPanelLandObjects* LLFloaterLand::getCurrentPanelLandObjects() +{ + if (!sInstance) + { + return NULL; + } + + return sInstance->mPanelObjects; +} + +//static +LLPanelLandCovenant* LLFloaterLand::getCurrentPanelLandCovenant() +{ + if (!sInstance) + { + return NULL; + } + + return sInstance->mPanelCovenant; +} + +// static +void LLFloaterLand::refreshAll() +{ + if (sInstance) + { + sInstance->refresh(); + } +} + + +// virtual +BOOL LLFloaterLand::canClose() +{ + // canClose is checked as the first step of attempting to close + // the window, before focus is released from controls. Since we're + // closing the window and deselecting the land, we + // don't want replies to the upstream messages that get sent + // (because the reply will cause the land to be selected again). + sRequestReplyOnUpdate = FALSE; + return TRUE; +} + +// virtual +void LLFloaterLand::onClose(bool app_quitting) +{ + gParcelMgr->removeObserver( sObserver ); + delete sObserver; + sObserver = NULL; + + // Must do this after removing observer, otherwise + // infinite loops notifying and closing. + gParcelMgr->deselectLand(); + + // Might have been showing owned objects + gSelectMgr->unhighlightAll(); + + // Save which panel we had open + sLastTab = mTabLand->getCurrentPanelIndex(); + + destroy(); +} + + +LLFloaterLand::LLFloaterLand() +: LLFloater("floaterland", "FloaterLandRect5", "About Land") +{ + + + std::map<LLString, LLCallbackMap> factory_map; + factory_map["land_general_panel"] = LLCallbackMap(createPanelLandGeneral, this); + + + factory_map["land_covenant_panel"] = LLCallbackMap(createPanelLandCovenant, this); + factory_map["land_objects_panel"] = LLCallbackMap(createPanelLandObjects, this); + factory_map["land_options_panel"] = LLCallbackMap(createPanelLandOptions, this); + factory_map["land_media_panel"] = LLCallbackMap(createPanelLandMedia, this); + factory_map["land_access_panel"] = LLCallbackMap(createPanelLandAccess, this); + factory_map["land_ban_panel"] = LLCallbackMap(createPanelLandBan, this); + + gUICtrlFactory->buildFloater(this, "floater_about_land.xml", &factory_map); + + + LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(this, "landtab"); + + mTabLand = (LLTabContainer*) tab; + + + if (tab) + { + tab->selectTab(sLastTab); + } +} + + +// virtual +LLFloaterLand::~LLFloaterLand() +{ + sInstance = NULL; +} + + +// public +void LLFloaterLand::refresh() +{ + mPanelGeneral->refresh(); + mPanelObjects->refresh(); + mPanelOptions->refresh(); + mPanelMedia->refresh(); + mPanelAccess->refresh(); + mPanelBan->refresh(); +} + + + +void* LLFloaterLand::createPanelLandGeneral(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelGeneral = new LLPanelLandGeneral(); + return self->mPanelGeneral; +} + +// static + + +void* LLFloaterLand::createPanelLandCovenant(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelCovenant = new LLPanelLandCovenant(); + return self->mPanelCovenant; +} + + +// static +void* LLFloaterLand::createPanelLandObjects(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelObjects = new LLPanelLandObjects(); + return self->mPanelObjects; +} + +// static +void* LLFloaterLand::createPanelLandOptions(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelOptions = new LLPanelLandOptions(); + return self->mPanelOptions; +} + +// static +void* LLFloaterLand::createPanelLandMedia(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelMedia = new LLPanelLandMedia(); + return self->mPanelMedia; +} + +// static +void* LLFloaterLand::createPanelLandAccess(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelAccess = new LLPanelLandAccess(); + return self->mPanelAccess; +} + +// static +void* LLFloaterLand::createPanelLandBan(void* data) +{ + LLFloaterLand* self = (LLFloaterLand*)data; + self->mPanelBan = new LLPanelLandBan(); + return self->mPanelBan; +} + + +//--------------------------------------------------------------------------- +// LLPanelLandGeneral +//--------------------------------------------------------------------------- + + +LLPanelLandGeneral::LLPanelLandGeneral() +: LLPanel("land_general_panel"), + mUncheckedSell(FALSE) +{ +} + +BOOL LLPanelLandGeneral::postBuild() +{ + + mEditName = LLUICtrlFactory::getLineEditorByName(this, "Name"); + mEditName->setCommitCallback(onCommitAny); + childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe); + childSetUserData("Name", this); + + + mEditDesc = LLUICtrlFactory::getLineEditorByName(this, "Description"); + mEditDesc->setCommitCallback(onCommitAny); + childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe); + childSetUserData("Description", this); + + + mTextSalePending = LLUICtrlFactory::getTextBoxByName(this, "SalePending"); + mTextOwnerLabel = LLUICtrlFactory::getTextBoxByName(this, "Owner:"); + mTextOwner = LLUICtrlFactory::getTextBoxByName(this, "OwnerText"); + + + mBtnProfile = LLUICtrlFactory::getButtonByName(this, "Profile..."); + mBtnProfile->setClickedCallback(onClickProfile, this); + + + mTextGroupLabel = LLUICtrlFactory::getTextBoxByName(this, "Group:"); + mTextGroup = LLUICtrlFactory::getTextBoxByName(this, "GroupText"); + + + mBtnSetGroup = LLUICtrlFactory::getButtonByName(this, "Set..."); + mBtnSetGroup->setClickedCallback(onClickSetGroup, this); + + + + mCheckDeedToGroup = LLUICtrlFactory::getCheckBoxByName(this, "check deed"); + childSetCommitCallback("check deed", onCommitAny, this); + + + mBtnDeedToGroup = LLUICtrlFactory::getButtonByName(this, "Deed..."); + mBtnDeedToGroup->setClickedCallback(onClickDeed, this); + + + mCheckContributeWithDeed = LLUICtrlFactory::getCheckBoxByName(this, "check contib"); + childSetCommitCallback("check contib", onCommitAny, this); + + + + mSaleInfoNotForSale = LLUICtrlFactory::getTextBoxByName(this, "Not for sale."); + + mSaleInfoForSale1 = LLUICtrlFactory::getTextBoxByName(this, "For Sale: Price L$[PRICE]."); + + + mBtnSellLand = LLUICtrlFactory::getButtonByName(this, "Sell Land..."); + mBtnSellLand->setClickedCallback(onClickSellLand, this); + + mSaleInfoForSale2 = LLUICtrlFactory::getTextBoxByName(this, "For sale to"); + + mSaleInfoForSaleObjects = LLUICtrlFactory::getTextBoxByName(this, "Sell with landowners objects in parcel."); + + mSaleInfoForSaleNoObjects = LLUICtrlFactory::getTextBoxByName(this, "Selling with no objects in parcel."); + + + mBtnStopSellLand = LLUICtrlFactory::getButtonByName(this, "Cancel Land Sale"); + mBtnStopSellLand->setClickedCallback(onClickStopSellLand, this); + + + mTextClaimDateLabel = LLUICtrlFactory::getTextBoxByName(this, "Claimed:"); + mTextClaimDate = LLUICtrlFactory::getTextBoxByName(this, "DateClaimText"); + + + mTextPriceLabel = LLUICtrlFactory::getTextBoxByName(this, "PriceLabel"); + mTextPrice = LLUICtrlFactory::getTextBoxByName(this, "PriceText"); + + + mTextDwell = LLUICtrlFactory::getTextBoxByName(this, "DwellText"); + + + mBtnBuyLand = LLUICtrlFactory::getButtonByName(this, "Buy Land..."); + mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND); + + mBtnBuyGroupLand = LLUICtrlFactory::getButtonByName(this, "Buy For Group..."); + mBtnBuyGroupLand->setClickedCallback(onClickBuyLand, (void*)&BUY_GROUP_LAND); + + + static BOOL deselect_when_done = FALSE; + mBtnBuyPass = LLUICtrlFactory::getButtonByName(this, "Buy Pass..."); + mBtnBuyPass->setClickedCallback(onClickBuyPass, &deselect_when_done); + + mBtnReleaseLand = LLUICtrlFactory::getButtonByName(this, "Abandon Land..."); + mBtnReleaseLand->setClickedCallback(onClickRelease, NULL); + + mBtnReclaimLand = LLUICtrlFactory::getButtonByName(this, "Reclaim Land..."); + mBtnReclaimLand->setClickedCallback(onClickReclaim, NULL); + + mBtnStartAuction = LLUICtrlFactory::getButtonByName(this, "Linden Sale..."); + mBtnStartAuction->setClickedCallback(onClickStartAuction, NULL); + + return TRUE; +} + + +// virtual +LLPanelLandGeneral::~LLPanelLandGeneral() +{ } + + +// public +void LLPanelLandGeneral::refresh() +{ + mBtnStartAuction->setVisible(gAgent.isGodlike()); + + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + bool region_owner = false; + LLViewerRegion* regionp = gParcelMgr->getSelectionRegion(); + if(regionp && (regionp->getOwner() == gAgent.getID())) + { + region_owner = true; + mBtnReleaseLand->setVisible(FALSE); + mBtnReclaimLand->setVisible(TRUE); + } + else + { + mBtnReleaseLand->setVisible(TRUE); + mBtnReclaimLand->setVisible(FALSE); + } + if (!parcel) + { + // nothing selected, disable panel + mEditName->setEnabled(FALSE); + mEditName->setText(""); + + mEditDesc->setEnabled(FALSE); + mEditDesc->setText(""); + + mTextSalePending->setText(""); + mTextSalePending->setEnabled(FALSE); + + mBtnDeedToGroup->setEnabled(FALSE); + mBtnSetGroup->setEnabled(FALSE); + mBtnStartAuction->setEnabled(FALSE); + + mCheckDeedToGroup ->set(FALSE); + mCheckDeedToGroup ->setEnabled(FALSE); + mCheckContributeWithDeed->set(FALSE); + mCheckContributeWithDeed->setEnabled(FALSE); + + mTextOwner->setText(""); + mBtnProfile->setLabelSelected("Profile..."); + mBtnProfile->setLabelUnselected("Profile..."); + mBtnProfile->setEnabled(FALSE); + + mTextClaimDate->setText(""); + mTextGroup->setText(""); + mTextPrice->setText(""); + + mSaleInfoForSale1->setVisible(FALSE); + mSaleInfoForSale2->setVisible(FALSE); + mSaleInfoForSaleObjects->setVisible(FALSE); + mSaleInfoForSaleNoObjects->setVisible(FALSE); + mSaleInfoNotForSale->setVisible(FALSE); + mBtnSellLand->setVisible(FALSE); + mBtnStopSellLand->setVisible(FALSE); + + mTextPriceLabel->setText(NO_PRICE); + mTextDwell->setText(""); + + mBtnBuyLand->setEnabled(FALSE); + mBtnBuyGroupLand->setEnabled(FALSE); + mBtnReleaseLand->setEnabled(FALSE); + mBtnReclaimLand->setEnabled(FALSE); + mBtnBuyPass->setEnabled(FALSE); + } + else + { + // something selected, hooray! + BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus()); + BOOL region_xfer = FALSE; + if(regionp + && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)) + { + region_xfer = TRUE; + } + + // estate owner/manager cannot edit other parts of the parcel + BOOL estate_manager_sellable = !parcel->getAuctionID() + && gAgent.canManageEstate() + // estate manager/owner can only sell parcels owned by estate owner + && regionp + && (parcel->getOwnerID() == regionp->getOwner()); + BOOL owner_sellable = region_xfer && !parcel->getAuctionID() + && LLViewerParcelMgr::isParcelModifiableByAgent( + parcel, GP_LAND_SET_SALE_INFO); + BOOL can_be_sold = owner_sellable || estate_manager_sellable; + + const LLUUID &owner_id = parcel->getOwnerID(); + BOOL is_public = parcel->isPublic(); + + // Is it owned? + if (is_public) + { + mTextSalePending->setText(""); + mTextSalePending->setEnabled(FALSE); + mTextOwner->setText("(public)"); + mTextOwner->setEnabled(FALSE); + mBtnProfile->setEnabled(FALSE); + mTextClaimDate->setText(""); + mTextClaimDate->setEnabled(FALSE); + mTextGroup->setText("(none)"); + mTextGroup->setEnabled(FALSE); + mBtnStartAuction->setEnabled(FALSE); + } + else + { + if(!is_leased && (owner_id == gAgent.getID())) + { + mTextSalePending->setText(NEED_TIER_TO_MODIFY_STRING); + mTextSalePending->setEnabled(TRUE); + } + else if(parcel->getAuctionID()) + { + char auction_str[MAX_STRING]; + sprintf(auction_str, "Auction ID: %u", parcel->getAuctionID()); + mTextSalePending->setText(auction_str); + mTextSalePending->setEnabled(TRUE); + } + else + { + // not the owner, or it is leased + mTextSalePending->setText(""); + mTextSalePending->setEnabled(FALSE); + } + //refreshNames(); + mTextOwner->setEnabled(TRUE); + + // We support both group and personal profiles + mBtnProfile->setEnabled(TRUE); + + if (parcel->getGroupID().isNull()) + { + // Not group owned, so "Profile" + mBtnProfile->setLabelSelected("Profile..."); + mBtnProfile->setLabelUnselected("Profile..."); + + mTextGroup->setText("(none)"); + mTextGroup->setEnabled(FALSE); + } + else + { + // Group owned, so "Info" + mBtnProfile->setLabelSelected("Info..."); + mBtnProfile->setLabelUnselected("Info..."); + + //mTextGroup->setText("HIPPOS!");//parcel->getGroupName()); + mTextGroup->setEnabled(TRUE); + } + + // Display claim date + time_t claim_date = parcel->getClaimDate(); + char time_buf[TIME_STR_LENGTH]; + mTextClaimDate->setText(formatted_time(claim_date, time_buf)); + mTextClaimDate->setEnabled(is_leased); + + BOOL enable_auction = (gAgent.getGodLevel() >= GOD_LIAISON) + && (owner_id == GOVERNOR_LINDEN_ID) + && (parcel->getAuctionID() == 0); + mBtnStartAuction->setEnabled(enable_auction); + } + + // Display options + BOOL can_edit_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_IDENTITY); + mEditName->setEnabled(can_edit_identity); + mEditDesc->setEnabled(can_edit_identity); + + BOOL can_edit_agent_only = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_NO_POWERS); + mBtnSetGroup->setEnabled(can_edit_agent_only && !parcel->getIsGroupOwned()); + + const LLUUID& group_id = parcel->getGroupID(); + + // Can only allow deeding if you own it and it's got a group. + BOOL enable_deed = (owner_id == gAgent.getID() + && group_id.notNull() + && gAgent.isInGroup(group_id)); + // You don't need special powers to allow your object to + // be deeded to the group. + mCheckDeedToGroup->setEnabled(enable_deed); + mCheckDeedToGroup->set( parcel->getAllowDeedToGroup() ); + mCheckContributeWithDeed->setEnabled(enable_deed && parcel->getAllowDeedToGroup()); + mCheckContributeWithDeed->set(parcel->getContributeWithDeed()); + + // Actually doing the deeding requires you to have GP_LAND_DEED + // powers in the group. + BOOL can_deed = gAgent.hasPowerInGroup(group_id, GP_LAND_DEED); + mBtnDeedToGroup->setEnabled( parcel->getAllowDeedToGroup() + && group_id.notNull() + && can_deed + && !parcel->getIsGroupOwned() + ); + + mEditName->setText( parcel->getName() ); + mEditDesc->setText( parcel->getDesc() ); + + BOOL for_sale = parcel->getForSale(); + + mBtnSellLand->setVisible(FALSE); + mBtnStopSellLand->setVisible(FALSE); + + if (for_sale) + { + mSaleInfoForSale1->setVisible(TRUE); + mSaleInfoForSale2->setVisible(TRUE); + if (parcel->getSellWithObjects()) + { + mSaleInfoForSaleObjects->setVisible(TRUE); + mSaleInfoForSaleNoObjects->setVisible(FALSE); + } + else + { + mSaleInfoForSaleObjects->setVisible(FALSE); + mSaleInfoForSaleNoObjects->setVisible(TRUE); + } + mSaleInfoNotForSale->setVisible(FALSE); + mSaleInfoForSale1->setTextArg("[PRICE]", llformat("%d", parcel->getSalePrice())); + if (can_be_sold) + { + mBtnStopSellLand->setVisible(TRUE); + } + } + else + { + mSaleInfoForSale1->setVisible(FALSE); + mSaleInfoForSale2->setVisible(FALSE); + mSaleInfoForSaleObjects->setVisible(FALSE); + mSaleInfoForSaleNoObjects->setVisible(FALSE); + mSaleInfoNotForSale->setVisible(TRUE); + if (can_be_sold) + { + mBtnSellLand->setVisible(TRUE); + } + } + + refreshNames(); + + mBtnBuyLand->setEnabled( + gParcelMgr->canAgentBuyParcel(parcel, false)); + mBtnBuyGroupLand->setEnabled( + gParcelMgr->canAgentBuyParcel(parcel, true)); + + // show pricing information + char price[64]; + const char* label = NULL; + S32 area; + S32 claim_price; + S32 rent_price; + F32 dwell; + gParcelMgr->getDisplayInfo(&area, + &claim_price, + &rent_price, + &for_sale, + &dwell); + + // Area + sprintf(price, "%d sq. m.", area); + label = AREA; + + mTextPriceLabel->setText(label); + mTextPrice->setText(price); + + sprintf(price, "%.0f", dwell); + mTextDwell->setText(price); + + if(region_owner) + { + mBtnReclaimLand->setEnabled( + !is_public && (parcel->getOwnerID() != gAgent.getID())); + } + else + { + BOOL is_owner_release = LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_RELEASE); + BOOL is_manager_release = (gAgent.canManageEstate() && + regionp && + (parcel->getOwnerID() != regionp->getOwner())); + BOOL can_release = is_owner_release || is_manager_release; + mBtnReleaseLand->setEnabled( can_release ); + } + + BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !gParcelMgr->isCollisionBanned();; + mBtnBuyPass->setEnabled(use_pass); + } +} + +// public +void LLPanelLandGeneral::refreshNames() +{ + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + mTextOwner->setText(""); + return; + } + + char buffer[MAX_STRING]; + if (parcel->getIsGroupOwned()) + { + buffer[0] = '\0'; + strcat(buffer, "(Group Owned)"); + } + else + { + // Figure out the owner's name + char owner_first[MAX_STRING]; + char owner_last[MAX_STRING]; + gCacheName->getName(parcel->getOwnerID(), owner_first, owner_last); + sprintf(buffer, "%s %s", owner_first, owner_last); + } + + if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) + { + strcat(buffer, " (Sale Pending)"); + } + mTextOwner->setText(buffer); + + if(!parcel->getGroupID().isNull()) + { + gCacheName->getGroupName(parcel->getGroupID(), buffer); + } + else + { + buffer[0] = '\0'; + } + mTextGroup->setText(buffer); + + const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); + if(auth_buyer_id.notNull()) + { + LLString name; + char firstname[MAX_STRING]; + char lastname[MAX_STRING]; + gCacheName->getName(auth_buyer_id, firstname, lastname); + name.assign(firstname); + name.append(" "); + name.append(lastname); + + mSaleInfoForSale2->setTextArg("[BUYER]", name); + } + else if(parcel->getReservedForNewbie()) + { + mSaleInfoForSale2->setTextArg("[BUYER]", childGetText("new users only")); + } + else + { + mSaleInfoForSale2->setTextArg("[BUYER]", childGetText("anyone")); + } +} + + +// virtual +void LLPanelLandGeneral::draw() +{ + refreshNames(); + LLPanel::draw(); +} + +// static +void LLPanelLandGeneral::onClickSetGroup(void* userdata) +{ + LLFloaterGroups* fg; + fg = LLFloaterGroups::show(gAgent.getID(), LLFloaterGroups::CHOOSE_ONE); + fg->setOkCallback( cbGroupID, userdata ); +} + +// static +void LLPanelLandGeneral::onClickProfile(void* data) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + if (parcel->getIsGroupOwned()) + { + const LLUUID& group_id = parcel->getGroupID(); + LLFloaterGroupInfo::showFromUUID(group_id); + } + else + { + const LLUUID& avatar_id = parcel->getOwnerID(); + LLFloaterAvatarInfo::showFromObject(avatar_id); + } +} + +// static +void LLPanelLandGeneral::cbGroupID(LLUUID group_id, void* userdata) +{ + LLPanelLandGeneral* self = (LLPanelLandGeneral*)userdata; + self->setGroup(group_id); +} + +// public +void LLPanelLandGeneral::setGroup(const LLUUID& group_id) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + // Set parcel properties and send message + parcel->setGroupID(group_id); + //parcel->setGroupName(group_name); + //mTextGroup->setText(group_name); + + // Send update + gParcelMgr->sendParcelPropertiesUpdate(parcel, LLFloaterLand::sRequestReplyOnUpdate); + + // Update UI + refresh(); +} + +// static +void LLPanelLandGeneral::onClickBuyLand(void* data) +{ + BOOL* for_group = (BOOL*)data; + gParcelMgr->startBuyLand(*for_group); +} + +BOOL LLPanelLandGeneral::enableDeedToGroup(void*) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + return (parcel != NULL) && (parcel->getParcelFlag(PF_ALLOW_DEED_TO_GROUP)); +} + +// static +void LLPanelLandGeneral::onClickDeed(void*) +{ + //LLParcel* parcel = gParcelMgr->getSelectedParcel(); + //if (parcel) + //{ + gParcelMgr->startDeedLandToGroup(); + //} +} + +// static +void LLPanelLandGeneral::onClickRelease(void*) +{ + gParcelMgr->startReleaseLand(); +} + +// static +void LLPanelLandGeneral::onClickReclaim(void*) +{ + lldebugs << "LLPanelLandGeneral::onClickReclaim()" << llendl; + gParcelMgr->reclaimParcel(); +} + +// static +BOOL LLPanelLandGeneral::enableBuyPass(void*) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + return (parcel != NULL) && (parcel->getParcelFlag(PF_USE_PASS_LIST) && !gParcelMgr->isCollisionBanned()); +} + + +// static +void LLPanelLandGeneral::onClickBuyPass(void* deselect_when_done) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + S32 pass_price = parcel->getPassPrice(); + const char* parcel_name = parcel->getName(); + F32 pass_hours = parcel->getPassHours(); + + char cost[256], time[256]; + sprintf(cost, "%d", pass_price); + sprintf(time, "%.2f", pass_hours); + + LLStringBase<char>::format_map_t args; + args["[COST]"] = cost; + args["[PARCEL_NAME]"] = parcel_name; + args["[TIME]"] = time; + + gViewerWindow->alertXml("LandBuyPass", args, cbBuyPass, deselect_when_done); +} + +// static +void LLPanelLandGeneral::onClickStartAuction(void*) +{ + LLParcel* parcelp = gParcelMgr->getSelectedParcel(); + if(parcelp) + { + if(parcelp->getForSale()) + { + gViewerWindow->alertXml("CannotStartAuctionAlreadForSale"); + } + else + { + LLFloaterAuction::show(); + } + } +} + +// static +void LLPanelLandGeneral::cbBuyPass(S32 option, void* data) +{ + BOOL deselect_when_done = (BOOL)(intptr_t)data; + + if (0 == option) + { + // User clicked OK + gParcelMgr->buyPass(); + } + + if (deselect_when_done) + { + gParcelMgr->deselectLand(); + } +} + + +// static +void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)userdata; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + std::string name = panelp->mEditName->getText(); + std::string desc = panelp->mEditDesc->getText(); + + // Valid data from UI + + // Stuff data into selected parcel + parcel->setName(name.c_str()); + parcel->setDesc(desc.c_str()); + + BOOL allow_deed_to_group= panelp->mCheckDeedToGroup->get(); + BOOL contribute_with_deed = panelp->mCheckContributeWithDeed->get(); + + parcel->setParcelFlag(PF_ALLOW_DEED_TO_GROUP, allow_deed_to_group); + parcel->setContributeWithDeed(contribute_with_deed); + + // Send update to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + + // Might have changed properties, so let's redraw! + panelp->refresh(); +} + +// static +void LLPanelLandGeneral::onClickSellLand(void* data) +{ + gParcelMgr->startSellLand(); +} + +// static +void LLPanelLandGeneral::onClickStopSellLand(void* data) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + + parcel->setParcelFlag(PF_FOR_SALE, FALSE); + parcel->setSalePrice(0); + parcel->setAuthorizedBuyerID(LLUUID::null); + + gParcelMgr->sendParcelPropertiesUpdate(parcel, LLFloaterLand::sRequestReplyOnUpdate); +} + +//--------------------------------------------------------------------------- +// LLPanelLandObjects +//--------------------------------------------------------------------------- +LLPanelLandObjects::LLPanelLandObjects() +: LLPanel("land_objects_panel") +{ +} + + + +BOOL LLPanelLandObjects::postBuild() +{ + + mFirstReply = TRUE; + mParcelObjectBonus = LLUICtrlFactory::getTextBoxByName(this, "Simulator Primitive Bonus Factor: 1.00"); + + mSWTotalObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Simulator primitive usage:"); + mSWTotalObjects = LLUICtrlFactory::getTextBoxByName(this, "0 out of 0 available"); + + mObjectContributionLabel = LLUICtrlFactory::getTextBoxByName(this, "Primitives parcel supports:"); + mObjectContribution = LLUICtrlFactory::getTextBoxByName(this, "object_contrib_text"); + + + mTotalObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Primitives on parcel:"); + mTotalObjects = LLUICtrlFactory::getTextBoxByName(this, "total_objects_text"); + + + mOwnerObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Owned by parcel owner:"); + mOwnerObjects = LLUICtrlFactory::getTextBoxByName(this, "owner_objects_text"); + + + mBtnShowOwnerObjects = LLUICtrlFactory::getButtonByName(this, "ShowOwner"); + mBtnShowOwnerObjects->setClickedCallback(onClickShowOwnerObjects, this); + + mBtnReturnOwnerObjects = LLUICtrlFactory::getButtonByName(this, "ReturnOwner..."); + mBtnReturnOwnerObjects->setClickedCallback(onClickReturnOwnerObjects, this); + + + mGroupObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Set to group:"); + mGroupObjects = LLUICtrlFactory::getTextBoxByName(this, "group_objects_text"); + + + mBtnShowGroupObjects = LLUICtrlFactory::getButtonByName(this, "ShowGroup"); + mBtnShowGroupObjects->setClickedCallback(onClickShowGroupObjects, this); + + mBtnReturnGroupObjects = LLUICtrlFactory::getButtonByName(this, "ReturnGroup..."); + mBtnReturnGroupObjects->setClickedCallback(onClickReturnGroupObjects, this); + + + mOtherObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Owned by others:"); + mOtherObjects = LLUICtrlFactory::getTextBoxByName(this, "other_objects_text"); + + mBtnShowOtherObjects = LLUICtrlFactory::getButtonByName(this, "ShowOther"); + mBtnShowOtherObjects->setClickedCallback(onClickShowOtherObjects, this); + + mBtnReturnOtherObjects = LLUICtrlFactory::getButtonByName(this, "ReturnOther..."); + mBtnReturnOtherObjects->setClickedCallback(onClickReturnOtherObjects, this); + + mSelectedObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Selected / sat upon:"); + mSelectedObjects = LLUICtrlFactory::getTextBoxByName(this, "selected_objects_text"); + + mCleanOtherObjectsLabel = LLUICtrlFactory::getTextBoxByName(this, "Autoreturn other resident's objects (minutes, 0 for off):"); + + mCleanOtherObjectsTime = LLUICtrlFactory::getLineEditorByName(this, "clean other time"); + mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus); + childSetPrevalidate("clean other time", LLLineEditor::prevalidatePrintableNotPipe); + childSetUserData("clean other time", this); + + mOwnerListText = LLUICtrlFactory::getTextBoxByName(this, "Object Owners:"); + + + mBtnRefresh = LLUICtrlFactory::getButtonByName(this, "Refresh List"); + mBtnRefresh->setClickedCallback(onClickRefresh, this); + + + mBtnReturnOwnerList = LLUICtrlFactory::getButtonByName(this, "Return objects..."); + mBtnReturnOwnerList->setClickedCallback(onClickReturnOwnerList, this); + + LLUUID image_id; + + image_id.set( gViewerArt.getString("icon_avatar_online.tga") ); + mIconAvatarOnline = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); + + image_id.set( gViewerArt.getString("icon_avatar_offline.tga") ); + mIconAvatarOffline = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); + + image_id.set( gViewerArt.getString("icon_group.tga") ); + mIconGroup = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE); + + mCurrentSortColumn = 3; // sort by number of objects by default. + mCurrentSortAscending = FALSE; + + // Column widths for various columns + const S32 SORTER_WIDTH = 308; + const S32 DESC_BTN_WIDTH = 64; + const S32 ICON_WIDTH = 24; + mColWidth[0] = ICON_WIDTH; // type icon + mColWidth[1] = -1; // hidden type code + mColWidth[2] = SORTER_WIDTH - mColWidth[0] - DESC_BTN_WIDTH; + mColWidth[3] = DESC_BTN_WIDTH; // info + mColWidth[4] = -1; // type data 1 + mColWidth[5] = -1; + mColWidth[6] = -1; // type data 3 + mColWidth[7] = -1; // type data 4 + mColWidth[8] = -1; // type data 5 + + // Adjust description for other widths + S32 sum = 0; + for (S32 i = 0; i < 8; i++) + { + if (mColWidth[i] > 0) + { + sum += mColWidth[i]; + } + } + mColWidth[8] = mRect.getWidth() - HPAD - sum - HPAD - HPAD; + + mBtnType = LLUICtrlFactory::getButtonByName(this, "Type"); + mBtnType->setClickedCallback(onClickType, this); + + mBtnName = LLUICtrlFactory::getButtonByName(this, "Name"); + mBtnName->setClickedCallback(onClickName, this); + + mBtnDescription = LLUICtrlFactory::getButtonByName(this, "Count"); + mBtnDescription->setClickedCallback(onClickDesc, this); + + mOwnerList = LLUICtrlFactory::getNameListByName(this, "owner list"); + childSetCommitCallback("owner list", onCommitList, this); + mOwnerList->setDoubleClickCallback(onDoubleClickOwner); + + return TRUE; +} + + + + +// virtual +LLPanelLandObjects::~LLPanelLandObjects() +{ } + +// static +void LLPanelLandObjects::onDoubleClickOwner(void *userdata) +{ + LLPanelLandObjects *self = (LLPanelLandObjects *)userdata; + + LLScrollListItem* item = self->mOwnerList->getFirstSelected(); + if (item) + { + LLUUID owner_id = item->getUUID(); + // Look up the selected name, for future dialog box use. + const LLScrollListCell* cell; + cell = item->getColumn(1); + if (!cell) + { + return; + } + // Is this a group? + BOOL is_group = cell->getText() == OWNER_GROUP; + if (is_group) + { + LLFloaterGroupInfo::showFromUUID(owner_id); + } + else + { + LLFloaterAvatarInfo::showFromDirectory(owner_id); + } + } +} + +// public +void LLPanelLandObjects::refresh() +{ + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + + mBtnShowOwnerObjects->setEnabled(FALSE); + mBtnShowGroupObjects->setEnabled(FALSE); + mBtnShowOtherObjects->setEnabled(FALSE); + mBtnReturnOwnerObjects->setEnabled(FALSE); + mBtnReturnGroupObjects->setEnabled(FALSE); + mBtnReturnOtherObjects->setEnabled(FALSE); + mCleanOtherObjectsTime->setEnabled(FALSE); + mBtnRefresh-> setEnabled(FALSE); + mBtnReturnOwnerList-> setEnabled(FALSE); + + mSelectedOwners.clear(); + mOwnerList->deleteAllItems(); + mOwnerList->setEnabled(FALSE); + + if (!parcel) + { + mSWTotalObjects->setText("0 out of 0 available"); + mObjectContribution->setText("0"); + mTotalObjects->setText("0"); + mOwnerObjects->setText("0"); + mGroupObjects->setText("0"); + mOtherObjects->setText("0"); + mSelectedObjects->setText("0"); + } + else + { + char count[MAX_STRING]; + S32 sw_max; + S32 sw_total; + S32 max; + S32 total; + S32 owned; + S32 group; + S32 other; + S32 selected; + F32 parcel_object_bonus; + + gParcelMgr->getPrimInfo(sw_max, sw_total, + max, total, owned, group, other, selected, + parcel_object_bonus, mOtherTime); + + // Can't have more than region max tasks, regardless of parcel + // object bonus factor. + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if (region) + { + S32 max_tasks_per_region = (S32)region->getMaxTasks(); + sw_max = llmin(sw_max, max_tasks_per_region); + max = llmin(max, max_tasks_per_region); + } + + if (parcel_object_bonus != 1.0f) + { + sprintf(count, "Region Object Bonus Factor: %.2f", + parcel_object_bonus); + mParcelObjectBonus->setText(count); + } + else + { + mParcelObjectBonus->setText(""); + } + + if (sw_total > sw_max) + { + sprintf(count, "%d out of %d (%d will be deleted)", + sw_total, sw_max, sw_total - sw_max); + } + else + { + sprintf(count, "%d out of %d (%d available)", + sw_total, sw_max, sw_max - sw_total); + } + mSWTotalObjects->setText(count); + + sprintf(count, "%d", max); + mObjectContribution->setText(count); + + sprintf(count, "%d", total); + mTotalObjects->setText(count); + + sprintf(count, "%d", owned); + mOwnerObjects->setText(count); + + sprintf(count, "%d", group); + mGroupObjects->setText(count); + + sprintf(count, "%d", other); + mOtherObjects->setText(count); + + sprintf(count, "%d", selected); + mSelectedObjects->setText(count); + + sprintf(count, "%d", mOtherTime); + mCleanOtherObjectsTime->setText(count); + + BOOL can_return_owned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_OWNED); + BOOL can_return_group_set = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_GROUP_SET); + BOOL can_return_other = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_RETURN_NON_GROUP); + + if (can_return_owned || can_return_group_set || can_return_other) + { + if (owned && can_return_owned) + { + mBtnShowOwnerObjects->setEnabled(TRUE); + mBtnReturnOwnerObjects->setEnabled(TRUE); + } + if (group && can_return_group_set) + { + mBtnShowGroupObjects->setEnabled(TRUE); + mBtnReturnGroupObjects->setEnabled(TRUE); + } + if (other && can_return_other) + { + mBtnShowOtherObjects->setEnabled(TRUE); + mBtnReturnOtherObjects->setEnabled(TRUE); + } + + mCleanOtherObjectsTime->setEnabled(TRUE); + mBtnRefresh->setEnabled(TRUE); + } + } +} + +// virtual +void LLPanelLandObjects::draw() +{ + LLPanel::draw(); +} + +void send_other_clean_time_message(S32 parcel_local_id, S32 other_clean_time) +{ + LLMessageSystem *msg = gMessageSystem; + + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if (!region) return; + + msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel_local_id); + msg->addS32Fast(_PREHASH_OtherCleanTime, other_clean_time); + + msg->sendReliable(region->getHost()); +} + +void send_return_objects_message(S32 parcel_local_id, S32 return_type, + uuid_list_t* owner_ids = NULL) +{ + LLMessageSystem *msg = gMessageSystem; + + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if (!region) return; + + msg->newMessageFast(_PREHASH_ParcelReturnObjects); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel_local_id); + msg->addU32Fast(_PREHASH_ReturnType, (U32) return_type); + + // Dummy task id, not used + msg->nextBlock("TaskIDs"); + msg->addUUID("TaskID", LLUUID::null); + + // Throw all return ids into the packet. + // TODO: Check for too many ids. + if (owner_ids) + { + uuid_list_t::iterator end = owner_ids->end(); + for (uuid_list_t::iterator it = owner_ids->begin(); + it != end; + ++it) + { + msg->nextBlockFast(_PREHASH_OwnerIDs); + msg->addUUIDFast(_PREHASH_OwnerID, (*it)); + } + } + else + { + msg->nextBlockFast(_PREHASH_OwnerIDs); + msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null); + } + + msg->sendReliable(region->getHost()); +} + +// static +void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata) +{ + LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata; + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (0 == option) + { + if (parcel) + { + LLUUID owner_id = parcel->getOwnerID(); + LLString::format_map_t args; + if (owner_id == gAgentID) + { + LLNotifyBox::showXml("OwnedObjectsReturned"); + } + else + { + char first[DB_FIRST_NAME_BUF_SIZE]; + char last[DB_LAST_NAME_BUF_SIZE]; + gCacheName->getName(owner_id, first, last); + args["[FIRST]"] = first; + args["[LAST]"] = last; + LLNotifyBox::showXml("OtherObjectsReturned", args); + } + send_return_objects_message(parcel->getLocalID(), RT_OWNER); + } + } + + gSelectMgr->unhighlightAll(); + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + lop->refresh(); +} + +// static +void LLPanelLandObjects::callbackReturnGroupObjects(S32 option, void* userdata) +{ + LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata; + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (0 == option) + { + if (parcel) + { + char group_name[MAX_STRING]; + gCacheName->getGroupName(parcel->getGroupID(), group_name); + LLString::format_map_t args; + args["[GROUPNAME]"] = group_name; + LLNotifyBox::showXml("GroupObjectsReturned", args); + send_return_objects_message(parcel->getLocalID(), RT_GROUP); + } + } + gSelectMgr->unhighlightAll(); + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + lop->refresh(); +} + +// static +void LLPanelLandObjects::callbackReturnOtherObjects(S32 option, void* userdata) +{ + LLPanelLandObjects *lop = (LLPanelLandObjects *)userdata; + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (0 == option) + { + if (parcel) + { + LLNotifyBox::showXml("UnOwnedObjectsReturned"); + send_return_objects_message(parcel->getLocalID(), RT_OTHER); + } + } + gSelectMgr->unhighlightAll(); + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + lop->refresh(); +} + +// static +void LLPanelLandObjects::callbackReturnOwnerList(S32 option, void* userdata) +{ + LLPanelLandObjects *self = (LLPanelLandObjects *)userdata; + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (0 == option) + { + if (parcel) + { + // Make sure we have something selected. + uuid_list_t::iterator selected = self->mSelectedOwners.begin(); + if (selected != self->mSelectedOwners.end()) + { + LLString::format_map_t args; + if (self->mSelectedIsGroup) + { + args["[GROUPNAME]"] = self->mSelectedName; + LLNotifyBox::showXml("GroupObjectsReturned", args); + } + else + { + // XUI:translate NAME -> FIRST LAST + args["[NAME]"] = self->mSelectedName; + LLNotifyBox::showXml("OtherObjectsReturned2", args); + } + + send_return_objects_message(parcel->getLocalID(), RT_LIST, &(self->mSelectedOwners)); + } + } + } + gSelectMgr->unhighlightAll(); + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + self->refresh(); +} + + +// static +void LLPanelLandObjects::onClickReturnOwnerList(void* userdata) +{ + LLPanelLandObjects *self = (LLPanelLandObjects *)userdata; + + S32 sw_max, sw_total; + S32 max, total; + S32 owned, group, other, selected; + F32 parcel_object_bonus; + S32 other_time; + + gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time); + + LLParcel* parcelp = gParcelMgr->getSelectedParcel(); + if (!parcelp) return; + + // Make sure we have something selected. + if (self->mSelectedOwners.empty()) + { + return; + } + //uuid_list_t::iterator selected_itr = self->mSelectedOwners.begin(); + //if (selected_itr == self->mSelectedOwners.end()) return; + + send_parcel_select_objects(parcelp->getLocalID(), RT_LIST, &(self->mSelectedOwners)); + + LLStringBase<char>::format_map_t args; + args["[NAME]"] = self->mSelectedName; + args["[N]"] = llformat("%d",self->mSelectedCount); + if (self->mSelectedIsGroup) + { + gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnOwnerList, userdata); + } + else + { + gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerList, userdata); + } +} + + +// static +void LLPanelLandObjects::onClickRefresh(void* userdata) +{ + LLPanelLandObjects *self = (LLPanelLandObjects*)userdata; + + LLMessageSystem *msg = gMessageSystem; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if (!region) return; + + // ready the list for results + self->mOwnerList->deleteAllItems(); + self->mOwnerList->addSimpleItem("Searching..."); + self->mOwnerList->setEnabled(FALSE); + self->mFirstReply = TRUE; + + // send the message + msg->newMessageFast(_PREHASH_ParcelObjectOwnersRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID()); + + msg->sendReliable(region->getHost()); +} + +// static +void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, void **) +{ + LLPanelLandObjects* self = LLFloaterLand::getCurrentPanelLandObjects(); + + const LLFontGL* FONT = LLFontGL::sSansSerif; + + // Extract all of the owners. + S32 rows = msg->getNumberOfBlocksFast(_PREHASH_Data); + //uuid_list_t return_ids; + LLUUID owner_id; + BOOL is_group_owned; + S32 object_count; + BOOL is_online; + char object_count_str[MAX_STRING]; + //BOOL b_need_refresh = FALSE; + + // If we were waiting for the first reply, clear the "Searching..." text. + if (self->mFirstReply) + { + self->mOwnerList->deleteAllItems(); + self->mFirstReply = FALSE; + } + + for(S32 i = 0; i < rows; ++i) + { + msg->getUUIDFast(_PREHASH_Data, _PREHASH_OwnerID, owner_id, i); + msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned, is_group_owned, i); + msg->getS32Fast (_PREHASH_Data, _PREHASH_Count, object_count, i); + msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus, is_online, i); + + if (owner_id.isNull()) + { + continue; + } + + LLScrollListItem *row = new LLScrollListItem( TRUE, NULL, owner_id); + if (is_group_owned) + { + row->addColumn(self->mIconGroup, self->mColWidth[0]); + row->addColumn(OWNER_GROUP, FONT, self->mColWidth[1]); + } + else if (is_online) + { + row->addColumn(self->mIconAvatarOnline, self->mColWidth[0]); + row->addColumn(OWNER_ONLINE, FONT, self->mColWidth[1]); + } + else // offline + { + row->addColumn(self->mIconAvatarOffline, self->mColWidth[0]); + row->addColumn(OWNER_OFFLINE, FONT, self->mColWidth[1]); + } + // Placeholder for name. + row->addColumn("", FONT, self->mColWidth[2]); + + sprintf(object_count_str, "%d", object_count); + row->addColumn(object_count_str, FONT, self->mColWidth[3]); + + if (is_group_owned) + { + self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM); + } + else + { + self->mOwnerList->addNameItem(row, ADD_BOTTOM); + } + + lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") + << ") owns " << object_count << " objects." << llendl; + } + self->mOwnerList->sortByColumn(self->mCurrentSortColumn, self->mCurrentSortAscending); + + // check for no results + if (0 == self->mOwnerList->getItemCount()) + { + self->mOwnerList->addSimpleItem("None found."); + } + else + { + self->mOwnerList->setEnabled(TRUE); + } +} + +void LLPanelLandObjects::sortBtnCore(S32 column) +{ + if (column == (S32)mCurrentSortColumn) // is this already our sorted column? + { + mCurrentSortAscending = !mCurrentSortAscending; + } + else // default to ascending first time a column is clicked + { + mCurrentSortColumn = column; + mCurrentSortAscending = TRUE; + } + + mOwnerList->sortByColumn(column, mCurrentSortAscending); +} + +// static +void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data) +{ + LLPanelLandObjects* self = (LLPanelLandObjects*)data; + + if (FALSE == self->mOwnerList->getCanSelect()) + { + return; + } + LLScrollListItem *item = self->mOwnerList->getFirstSelected(); + if (item) + { + // Look up the selected name, for future dialog box use. + const LLScrollListCell* cell; + cell = item->getColumn(1); + if (!cell) + { + return; + } + // Is this a group? + self->mSelectedIsGroup = cell->getText() == OWNER_GROUP; + cell = item->getColumn(2); + self->mSelectedName = cell->getText(); + cell = item->getColumn(3); + self->mSelectedCount = atoi(cell->getText().c_str()); + + // Set the selection, and enable the return button. + self->mSelectedOwners.clear(); + self->mSelectedOwners.insert(item->getUUID()); + self->mBtnReturnOwnerList->setEnabled(TRUE); + + // Highlight this user's objects + clickShowCore(RT_LIST, &(self->mSelectedOwners)); + } +} + +// static +void LLPanelLandObjects::onClickType(void* userdata) +{ + // Sort on hidden type column + LLPanelLandObjects* self = (LLPanelLandObjects*)userdata; + self->sortBtnCore(1); +} + +// static +void LLPanelLandObjects::onClickDesc(void* userdata) +{ + LLPanelLandObjects* self = (LLPanelLandObjects*)userdata; + self->sortBtnCore(3); +} + +// static +void LLPanelLandObjects::onClickName(void* userdata) +{ + LLPanelLandObjects* self = (LLPanelLandObjects*)userdata; + self->sortBtnCore(2); +} + +// static +void LLPanelLandObjects::clickShowCore(S32 return_type, uuid_list_t* list) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + send_parcel_select_objects(parcel->getLocalID(), return_type, list); +} + +// static +void LLPanelLandObjects::onClickShowOwnerObjects(void*) +{ + clickShowCore(RT_OWNER); +} + +// static +void LLPanelLandObjects::onClickShowGroupObjects(void*) +{ + clickShowCore(RT_GROUP); +} + +// static +void LLPanelLandObjects::onClickShowOtherObjects(void*) +{ + clickShowCore(RT_OTHER); +} + +// static +void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata) +{ + S32 sw_max=0, sw_total=0; + S32 max=0, total=0; + S32 owned=0, group=0, other=0, selected=0; + F32 parcel_object_bonus=0; + S32 other_time=0; + + gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time); + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + send_parcel_select_objects(parcel->getLocalID(), RT_OWNER); + + LLUUID owner_id = parcel->getOwnerID(); + + LLStringBase<char>::format_map_t args; + args["[N]"] = llformat("%d",owned); + + if (owner_id == gAgent.getID()) + { + gViewerWindow->alertXml("ReturnObjectsOwnedBySelf", args, callbackReturnOwnerObjects, userdata); + } + else + { + char first[DB_FIRST_NAME_BUF_SIZE]; + char last[DB_LAST_NAME_BUF_SIZE]; + gCacheName->getName(owner_id, first, last); + std::string name = first; + name += " "; + name += last; + args["[NAME]"] = name; + gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerObjects, userdata); + } +} + +// static +void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata) +{ + S32 sw_max=0, sw_total=0; + S32 max=0, total=0; + S32 owned=0, group=0, other=0, selected=0; + F32 parcel_object_bonus=0; + S32 other_time=0; + + gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time); + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + send_parcel_select_objects(parcel->getLocalID(), RT_GROUP); + + char group_name[MAX_STRING]; + gCacheName->getGroupName(parcel->getGroupID(), group_name); + + LLStringBase<char>::format_map_t args; + args["[NAME]"] = group_name; + args["[N]"] = llformat("%d",group); + + // create and show confirmation textbox + gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnGroupObjects, userdata); +} + +// static +void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata) +{ + S32 sw_max=0, sw_total=0; + S32 max=0, total=0; + S32 owned=0, group=0, other=0, selected=0; + F32 parcel_object_bonus=0; + S32 other_time=0; + + gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time); + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + send_parcel_select_objects(parcel->getLocalID(), RT_OTHER); + + LLStringBase<char>::format_map_t args; + args["[N]"] = llformat("%d", other); + + if (parcel->getIsGroupOwned()) + { + char group_name[MAX_STRING]; + gCacheName->getGroupName(parcel->getGroupID(), group_name); + args["[NAME]"] = group_name; + + gViewerWindow->alertXml("ReturnObjectsNotOwnedByGroup", args, callbackReturnOtherObjects, userdata); + } + else + { + LLUUID owner_id = parcel->getOwnerID(); + + if (owner_id == gAgent.getID()) + { + gViewerWindow->alertXml("ReturnObjectsNotOwnedBySelf", args, callbackReturnOtherObjects, userdata); + } + else + { + char first[DB_FIRST_NAME_BUF_SIZE]; + char last[DB_LAST_NAME_BUF_SIZE]; + gCacheName->getName(owner_id, first, last); + std::string name; + name += first; + name += " "; + name += last; + args["[NAME]"] = name; + + gViewerWindow->alertXml("ReturnObjectsNotOwnedByUser", args, callbackReturnOtherObjects, userdata); + } + } +} + +// static +void LLPanelLandObjects::onLostFocus(LLLineEditor *caller, void* user_data) +{ + LLPanelLandObjects *lop = (LLPanelLandObjects *)user_data; + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + if (parcel) + { + lop->mOtherTime = atoi(lop->mCleanOtherObjectsTime->getText().c_str()); + + parcel->setCleanOtherTime(lop->mOtherTime); + send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime); + } +} + + +//--------------------------------------------------------------------------- +// LLPanelLandOptions +//--------------------------------------------------------------------------- + +LLPanelLandOptions::LLPanelLandOptions() +: LLPanel("land_options_panel"), + mCheckEditObjects(NULL), + mCheckEditGroupObjects(NULL), + mCheckAllObjectEntry(NULL), + mCheckGroupObjectEntry(NULL), + mCheckEditLand(NULL), + mCheckSafe(NULL), + mCheckFly(NULL), + mCheckGroupScripts(NULL), + mCheckOtherScripts(NULL), + mCheckLandmark(NULL), + mCheckShowDirectory(NULL), + mCategoryCombo(NULL), + mLandingTypeCombo(NULL), + mSnapshotCtrl(NULL), + mLocationText(NULL), + mSetBtn(NULL), + mClearBtn(NULL), + mAllowPublishCtrl(NULL), + mMatureCtrl(NULL), + mPushRestrictionCtrl(NULL), + mPublishHelpButton(NULL) +{ + +} + + +BOOL LLPanelLandOptions::postBuild() +{ + + + mCheckEditObjects = LLUICtrlFactory::getCheckBoxByName(this, "edit objects check"); + childSetCommitCallback("edit objects check", onCommitAny, this); + + mCheckEditGroupObjects = LLUICtrlFactory::getCheckBoxByName(this, "edit group objects check"); + childSetCommitCallback("edit group objects check", onCommitAny, this); + + mCheckAllObjectEntry = LLUICtrlFactory::getCheckBoxByName(this, "all object entry check"); + childSetCommitCallback("all object entry check", onCommitAny, this); + + mCheckGroupObjectEntry = LLUICtrlFactory::getCheckBoxByName(this, "group object entry check"); + childSetCommitCallback("group object entry check", onCommitAny, this); + + mCheckEditLand = LLUICtrlFactory::getCheckBoxByName(this, "edit land check"); + childSetCommitCallback("edit land check", onCommitAny, this); + + + mCheckLandmark = LLUICtrlFactory::getCheckBoxByName(this, "check landmark"); + childSetCommitCallback("check landmark", onCommitAny, this); + + + mCheckGroupScripts = LLUICtrlFactory::getCheckBoxByName(this, "check group scripts"); + childSetCommitCallback("check group scripts", onCommitAny, this); + + + mCheckFly = LLUICtrlFactory::getCheckBoxByName(this, "check fly"); + childSetCommitCallback("check fly", onCommitAny, this); + + + mCheckOtherScripts = LLUICtrlFactory::getCheckBoxByName(this, "check other scripts"); + childSetCommitCallback("check other scripts", onCommitAny, this); + + + mCheckSafe = LLUICtrlFactory::getCheckBoxByName(this, "check safe"); + childSetCommitCallback("check safe", onCommitAny, this); + + + mPushRestrictionCtrl = LLUICtrlFactory::getCheckBoxByName(this, "PushRestrictCheck"); + childSetCommitCallback("PushRestrictCheck", onCommitAny, this); + + mCheckShowDirectory = LLUICtrlFactory::getCheckBoxByName(this, "ShowDirectoryCheck"); + childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this); + + + mCategoryCombo = LLUICtrlFactory::getComboBoxByName(this, "land category"); + childSetCommitCallback("land category", onCommitAny, this); + + mAllowPublishCtrl = LLUICtrlFactory::getCheckBoxByName(this, "PublishCheck"); + childSetCommitCallback("PublishCheck", onCommitAny, this); + + + mMatureCtrl = LLUICtrlFactory::getCheckBoxByName(this, "MatureCheck"); + childSetCommitCallback("MatureCheck", onCommitAny, this); + + mPublishHelpButton = LLUICtrlFactory::getButtonByName(this, "?"); + mPublishHelpButton->setClickedCallback(onClickPublishHelp, this); + + + if (gAgent.mAccess < SIM_ACCESS_MATURE) + { + // Disable these buttons if they are PG (Teen) users + mAllowPublishCtrl->setVisible(FALSE); + mAllowPublishCtrl->setEnabled(FALSE); + mPublishHelpButton->setVisible(FALSE); + mPublishHelpButton->setEnabled(FALSE); + mMatureCtrl->setVisible(FALSE); + mMatureCtrl->setEnabled(FALSE); + } + + // Load up the category list + //now in xml file + /* + S32 i; + for (i = 0; i < LLParcel::C_COUNT; i++) + { + LLParcel::ECategory cat = (LLParcel::ECategory)i; + + // Selecting Linden Location when you're not a god + // is also blocked on the server. + BOOL enabled = TRUE; + if (!gAgent.isGodlike() + && i == LLParcel::C_LINDEN) + { + enabled = FALSE; + } + + mCategoryCombo->add( LLParcel::getCategoryUIString(cat), ADD_BOTTOM, enabled ); + }*/ + + + mSnapshotCtrl = LLUICtrlFactory::getTexturePickerByName(this, "snapshot_ctrl"); + mSnapshotCtrl->setCommitCallback( onCommitAny ); + mSnapshotCtrl->setCallbackUserData( this ); + mSnapshotCtrl->setAllowNoTexture ( TRUE ); + mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + + + + mLocationText = LLUICtrlFactory::getTextBoxByName(this, "Landing Point: (none)"); + + mSetBtn = LLUICtrlFactory::getButtonByName(this, "Set"); + mSetBtn->setClickedCallback(onClickSet, this); + + + mClearBtn = LLUICtrlFactory::getButtonByName(this, "Clear"); + mClearBtn->setClickedCallback(onClickClear, this); + + + mLandingTypeCombo = LLUICtrlFactory::getComboBoxByName(this, "landing type"); + childSetCommitCallback("landing type", onCommitAny, this); + + return TRUE; +} + + +// virtual +LLPanelLandOptions::~LLPanelLandOptions() +{ } + + +// public +void LLPanelLandOptions::refresh() +{ + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + + if (!parcel) + { + mCheckEditObjects ->set(FALSE); + mCheckEditObjects ->setEnabled(FALSE); + + mCheckEditGroupObjects ->set(FALSE); + mCheckEditGroupObjects ->setEnabled(FALSE); + + mCheckAllObjectEntry ->set(FALSE); + mCheckAllObjectEntry ->setEnabled(FALSE); + + mCheckGroupObjectEntry ->set(FALSE); + mCheckGroupObjectEntry ->setEnabled(FALSE); + + mCheckEditLand ->set(FALSE); + mCheckEditLand ->setEnabled(FALSE); + + mCheckSafe ->set(FALSE); + mCheckSafe ->setEnabled(FALSE); + + mCheckFly ->set(FALSE); + mCheckFly ->setEnabled(FALSE); + + mCheckLandmark ->set(FALSE); + mCheckLandmark ->setEnabled(FALSE); + + mCheckGroupScripts ->set(FALSE); + mCheckGroupScripts ->setEnabled(FALSE); + + mCheckOtherScripts ->set(FALSE); + mCheckOtherScripts ->setEnabled(FALSE); + + mCheckShowDirectory ->set(FALSE); + mCheckShowDirectory ->setEnabled(FALSE); + + mPushRestrictionCtrl->set(FALSE); + mPushRestrictionCtrl->setEnabled(FALSE); + + const char* none_string = LLParcel::getCategoryUIString(LLParcel::C_NONE); + mCategoryCombo->setSimple(none_string); + mCategoryCombo->setEnabled(FALSE); + + mLandingTypeCombo->setCurrentByIndex(0); + mLandingTypeCombo->setEnabled(FALSE); + + mSnapshotCtrl->setImageAssetID(LLUUID::null); + mSnapshotCtrl->setEnabled(FALSE); + + mLocationText->setText("Landing Point: (none)"); + mSetBtn->setEnabled(FALSE); + mClearBtn->setEnabled(FALSE); + + mAllowPublishCtrl->setEnabled(FALSE); + mMatureCtrl->setEnabled(FALSE); + mPublishHelpButton->setEnabled(FALSE); + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_options = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_OPTIONS); + mCheckEditObjects ->set( parcel->getAllowModify() ); + mCheckEditObjects ->setEnabled( can_change_options ); + + mCheckEditGroupObjects ->set( parcel->getAllowGroupModify() || parcel->getAllowModify()); + mCheckEditGroupObjects ->setEnabled( can_change_options && !parcel->getAllowModify() ); // If others edit is enabled, then this is explicitly enabled. + + mCheckAllObjectEntry ->set( parcel->getAllowAllObjectEntry() ); + mCheckAllObjectEntry ->setEnabled( can_change_options ); + + mCheckGroupObjectEntry ->set( parcel->getAllowGroupObjectEntry() || parcel->getAllowAllObjectEntry()); + mCheckGroupObjectEntry ->setEnabled( can_change_options && !parcel->getAllowAllObjectEntry() ); + + BOOL can_change_terraform = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_EDIT); + mCheckEditLand ->set( parcel->getAllowTerraform() ); + mCheckEditLand ->setEnabled( can_change_terraform ); + + mCheckSafe ->set( !parcel->getAllowDamage() ); + mCheckSafe ->setEnabled( can_change_options ); + + mCheckFly ->set( parcel->getAllowFly() ); + mCheckFly ->setEnabled( can_change_options ); + + mCheckLandmark ->set( parcel->getAllowLandmark() ); + mCheckLandmark ->setEnabled( can_change_options ); + + mCheckGroupScripts ->set( parcel->getAllowGroupScripts() || parcel->getAllowOtherScripts()); + mCheckGroupScripts ->setEnabled( can_change_options && !parcel->getAllowOtherScripts()); + + mCheckOtherScripts ->set( parcel->getAllowOtherScripts() ); + mCheckOtherScripts ->setEnabled( can_change_options ); + + BOOL can_change_identity = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, + GP_LAND_CHANGE_IDENTITY); + mCheckShowDirectory ->set( parcel->getParcelFlag(PF_SHOW_DIRECTORY)); + mCheckShowDirectory ->setEnabled( can_change_identity ); + + mPushRestrictionCtrl->set( parcel->getRestrictPushObject() ); + if(parcel->getRegionPushOverride()) + { + mPushRestrictionCtrl->setLabel("Restrict Pushing (Region Override)"); + mPushRestrictionCtrl->setEnabled(false); + mPushRestrictionCtrl->set(TRUE); + } + else + { + mPushRestrictionCtrl->setLabel("Restrict Pushing"); + mPushRestrictionCtrl->setEnabled(can_change_options); + } + + // Set by string in case the order in UI doesn't match the order + // by index. + LLParcel::ECategory cat = parcel->getCategory(); + const char* category_string = LLParcel::getCategoryUIString(cat); + mCategoryCombo->setSimple(category_string); + mCategoryCombo->setEnabled( can_change_identity ); + + BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, + GP_LAND_SET_LANDING_POINT); + mLandingTypeCombo->setCurrentByIndex((S32)parcel->getLandingType()); + mLandingTypeCombo->setEnabled( can_change_landing_point ); + + mSnapshotCtrl->setImageAssetID(parcel->getSnapshotID()); + mSnapshotCtrl->setEnabled( can_change_identity ); + + LLVector3 pos = parcel->getUserLocation(); + if (pos.isExactlyZero()) + { + mLocationText->setText("Landing Point: (none)"); + } + else + { + char buffer[256]; + sprintf(buffer, "Landing Point: %d, %d, %d", + llround(pos.mV[VX]), + llround(pos.mV[VY]), + llround(pos.mV[VZ])); + mLocationText->setText(buffer); + } + + mSetBtn->setEnabled( can_change_landing_point ); + mClearBtn->setEnabled( can_change_landing_point ); + + mAllowPublishCtrl->set(parcel->getAllowPublish()); + mAllowPublishCtrl->setEnabled( can_change_identity ); + mMatureCtrl->set(parcel->getMaturePublish()); + mMatureCtrl->setEnabled( can_change_identity ); + mPublishHelpButton->setEnabled( can_change_identity ); + + if (gAgent.mAccess < SIM_ACCESS_MATURE) + { + // Disable these buttons if they are PG (Teen) users + mAllowPublishCtrl->setVisible(FALSE); + mAllowPublishCtrl->setEnabled(FALSE); + mPublishHelpButton->setVisible(FALSE); + mPublishHelpButton->setEnabled(FALSE); + mMatureCtrl->setVisible(FALSE); + mMatureCtrl->setEnabled(FALSE); + } + } +} + + +// static +void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandOptions *self = (LLPanelLandOptions *)userdata; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL create_objects = self->mCheckEditObjects->get(); + BOOL create_group_objects = self->mCheckEditGroupObjects->get() || self->mCheckEditObjects->get(); + BOOL all_object_entry = self->mCheckAllObjectEntry->get(); + BOOL group_object_entry = self->mCheckGroupObjectEntry->get() || self->mCheckAllObjectEntry->get(); + BOOL allow_terraform = self->mCheckEditLand->get(); + BOOL allow_damage = !self->mCheckSafe->get(); + BOOL allow_fly = self->mCheckFly->get(); + BOOL allow_landmark = self->mCheckLandmark->get(); + BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get(); + BOOL allow_other_scripts = self->mCheckOtherScripts->get(); + BOOL allow_publish = self->mAllowPublishCtrl->get(); + BOOL mature_publish = self->mMatureCtrl->get(); + BOOL push_restriction = self->mPushRestrictionCtrl->get(); + BOOL show_directory = self->mCheckShowDirectory->get(); + S32 category_index = self->mCategoryCombo->getCurrentIndex(); + S32 landing_type_index = self->mLandingTypeCombo->getCurrentIndex(); + LLUUID snapshot_id = self->mSnapshotCtrl->getImageAssetID(); + LLViewerRegion* region; + region = gParcelMgr->getSelectionRegion(); + + if (!allow_other_scripts && region && region->getAllowDamage()) + { + + gViewerWindow->alertXml("UnableToDisableOutsideScripts"); + return; + } + + // Push data into current parcel + parcel->setParcelFlag(PF_CREATE_OBJECTS, create_objects); + parcel->setParcelFlag(PF_CREATE_GROUP_OBJECTS, create_group_objects); + parcel->setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, all_object_entry); + parcel->setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, group_object_entry); + parcel->setParcelFlag(PF_ALLOW_TERRAFORM, allow_terraform); + parcel->setParcelFlag(PF_ALLOW_DAMAGE, allow_damage); + parcel->setParcelFlag(PF_ALLOW_FLY, allow_fly); + parcel->setParcelFlag(PF_ALLOW_LANDMARK, allow_landmark); + parcel->setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, allow_group_scripts); + parcel->setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, allow_other_scripts); + parcel->setParcelFlag(PF_SHOW_DIRECTORY, show_directory); + parcel->setParcelFlag(PF_ALLOW_PUBLISH, allow_publish); + parcel->setParcelFlag(PF_MATURE_PUBLISH, mature_publish); + parcel->setParcelFlag(PF_RESTRICT_PUSHOBJECT, push_restriction); + parcel->setCategory((LLParcel::ECategory)category_index); + parcel->setLandingType((LLParcel::ELandingType)landing_type_index); + parcel->setSnapshotID(snapshot_id); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} + + +// static +void LLPanelLandOptions::onClickSet(void* userdata) +{ + LLPanelLandOptions* self = (LLPanelLandOptions*)userdata; + + LLParcel* selected_parcel = gParcelMgr->getSelectedParcel(); + if (!selected_parcel) return; + + LLParcel* agent_parcel = gParcelMgr->getAgentParcel(); + if (!agent_parcel) return; + + if (agent_parcel->getLocalID() != selected_parcel->getLocalID()) + { + gViewerWindow->alertXml("MustBeInParcel"); + return; + } + + LLVector3 pos_region = gAgent.getPositionAgent(); + selected_parcel->setUserLocation(pos_region); + selected_parcel->setUserLookAt(gAgent.getFrameAgent().getAtAxis()); + + gParcelMgr->sendParcelPropertiesUpdate(selected_parcel, LLFloaterLand::sRequestReplyOnUpdate); + + self->refresh(); +} + +void LLPanelLandOptions::onClickClear(void* userdata) +{ + LLPanelLandOptions* self = (LLPanelLandOptions*)userdata; + + LLParcel* selected_parcel = gParcelMgr->getSelectedParcel(); + if (!selected_parcel) return; + + // yes, this magic number of 0,0,0 means that it is clear + LLVector3 zero_vec(0.f, 0.f, 0.f); + selected_parcel->setUserLocation(zero_vec); + selected_parcel->setUserLookAt(zero_vec); + + gParcelMgr->sendParcelPropertiesUpdate(selected_parcel, LLFloaterLand::sRequestReplyOnUpdate); + + self->refresh(); +} + +// static +void LLPanelLandOptions::onClickPublishHelp(void*) +{ + gViewerWindow->alertXml("ClickPublishHelpLand"); +} + +//--------------------------------------------------------------------------- +// LLPanelLandMedia +//--------------------------------------------------------------------------- + +LLPanelLandMedia::LLPanelLandMedia() +: LLPanel("land_media_panel") +{ +} + + + + +BOOL LLPanelLandMedia::postBuild() +{ + + mCheckSoundLocal = LLUICtrlFactory::getCheckBoxByName(this, "check sound local"); + childSetCommitCallback("check sound local", onCommitAny, this); + + mMusicURLEdit = LLUICtrlFactory::getLineEditorByName(this, "music_url"); + childSetCommitCallback("music_url", onCommitAny, this); + + + mMediaTextureCtrl = LLUICtrlFactory::getTexturePickerByName(this, "media texture"); + mMediaTextureCtrl->setCommitCallback( onCommitAny ); + mMediaTextureCtrl->setCallbackUserData( this ); + mMediaTextureCtrl->setAllowNoTexture ( TRUE ); + mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + + mMediaAutoScaleCheck = LLUICtrlFactory::getCheckBoxByName(this, "media_auto_scale"); + childSetCommitCallback("media_auto_scale", onCommitAny, this); + + mMediaURLEdit = LLUICtrlFactory::getLineEditorByName(this, "media_url"); + childSetCommitCallback("media_url", onCommitAny, this); + + return TRUE; +} + + +// virtual +LLPanelLandMedia::~LLPanelLandMedia() +{ } + + +// public +void LLPanelLandMedia::refresh() +{ + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + + if (!parcel) + { + mCheckSoundLocal->set(FALSE); + mCheckSoundLocal->setEnabled(FALSE); + + mMusicURLEdit->setText(""); + mMusicURLEdit->setEnabled(FALSE); + + mMediaURLEdit->setText(""); + mMediaURLEdit->setEnabled(FALSE); + + mMediaAutoScaleCheck->set ( FALSE ); + mMediaAutoScaleCheck->setEnabled(FALSE); + + mMediaTextureCtrl->clear(); + mMediaTextureCtrl->setEnabled(FALSE); + + #if 0 + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + #endif + } + else + { + // something selected, hooray! + + // Display options + BOOL can_change_media = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_CHANGE_MEDIA); + + mCheckSoundLocal->set( parcel->getSoundLocal() ); + mCheckSoundLocal->setEnabled( can_change_media ); + + // don't display urls if you're not able to change it + // much requested change in forums so people can't 'steal' urls + // NOTE: bug#2009 means this is still vunerable - however, bug + // should be closed since this bug opens up major security issues elsewhere. + if ( can_change_media ) + { + mMusicURLEdit->setDrawAsterixes ( FALSE ); + mMediaURLEdit->setDrawAsterixes ( FALSE ); + } + else + { + mMusicURLEdit->setDrawAsterixes ( TRUE ); + mMediaURLEdit->setDrawAsterixes ( TRUE ); + } + + mMusicURLEdit->setText(parcel->getMusicURL()); + mMusicURLEdit->setEnabled( can_change_media ); + + mMediaURLEdit->setText(parcel->getMediaURL()); + mMediaURLEdit->setEnabled( can_change_media ); + + mMediaAutoScaleCheck->set ( parcel->getMediaAutoScale () ); + mMediaAutoScaleCheck->setEnabled ( can_change_media ); + + LLUUID tmp = parcel->getMediaID(); + mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); + mMediaTextureCtrl->setEnabled( can_change_media ); + + #if 0 + // there is a media url and a media texture selected + if ( ( ! ( std::string ( parcel->getMediaURL() ).empty () ) ) && ( ! ( parcel->getMediaID ().isNull () ) ) ) + { + // turn on transport controls if allowed for this parcel + mMediaStopButton->setEnabled ( editable ); + mMediaStartButton->setEnabled ( editable ); + } + else + { + // no media url or no media texture + mMediaStopButton->setEnabled ( FALSE ); + mMediaStartButton->setEnabled ( FALSE ); + }; + #endif + } +} + +// static +void LLPanelLandMedia::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandMedia *self = (LLPanelLandMedia *)userdata; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL sound_local = self->mCheckSoundLocal->get(); + std::string music_url = self->mMusicURLEdit->getText(); + std::string media_url = self->mMediaURLEdit->getText(); + U8 media_auto_scale = self->mMediaAutoScaleCheck->get(); + LLUUID media_id = self->mMediaTextureCtrl->getImageAssetID(); + + // Push data into current parcel + parcel->setParcelFlag(PF_SOUND_LOCAL, sound_local); + parcel->setMusicURL(music_url.c_str()); + parcel->setMediaURL(media_url.c_str()); + parcel->setMediaID(media_id); + parcel->setMediaAutoScale ( media_auto_scale ); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} + +void LLPanelLandMedia::onClickStopMedia ( void* data ) +{ + LLMediaEngine::getInstance ()->stop (); +} + +void LLPanelLandMedia::onClickStartMedia ( void* data ) +{ + // force a commit + gFocusMgr.setKeyboardFocus ( NULL, NULL ); + + // force a reload + LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, std::string()); +} + +//--------------------------------------------------------------------------- +// LLPanelLandAccess +//--------------------------------------------------------------------------- + +LLPanelLandAccess::LLPanelLandAccess() +: LLPanel("land_access_panel") +{ +} + + + +BOOL LLPanelLandAccess::postBuild() +{ + + + mCheckGroup = LLUICtrlFactory::getCheckBoxByName(this, "GroupCheck"); + childSetCommitCallback("GroupCheck", onCommitAny, this); + + mCheckAccess = LLUICtrlFactory::getCheckBoxByName(this, "AccessCheck"); + childSetCommitCallback("AccessCheck", onCommitAny, this); + + mListAccess = LLUICtrlFactory::getNameListByName(this, "AccessList"); + + mBtnAddAccess = LLUICtrlFactory::getButtonByName(this, "Add..."); + + mBtnAddAccess->setClickedCallback(onClickAdd, this); + + mBtnRemoveAccess = LLUICtrlFactory::getButtonByName(this, "Remove"); + + mBtnRemoveAccess->setClickedCallback(onClickRemove, this); + + mCheckPass = LLUICtrlFactory::getCheckBoxByName(this, "PassCheck"); + childSetCommitCallback("PassCheck", onCommitAny, this); + + + mSpinPrice = LLUICtrlFactory::getSpinnerByName(this, "PriceSpin"); + childSetCommitCallback("PriceSpin", onCommitAny, this); + + mSpinHours = LLUICtrlFactory::getSpinnerByName(this, "HoursSpin"); + childSetCommitCallback("HoursSpin", onCommitAny, this); + + + return TRUE; +} + + +LLPanelLandAccess::~LLPanelLandAccess() +{ } + +void LLPanelLandAccess::refresh() +{ + mListAccess->deleteAllItems(); + + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + + if (parcel) + { + char label[256]; + + // Display options + BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP); + mCheckGroup->set( use_group ); + + char group_name[MAX_STRING]; + gCacheName->getGroupName(parcel->getGroupID(), group_name); + sprintf(label, "Group: %s", group_name); + mCheckGroup->setLabel( label ); + + S32 count = parcel->mAccessList.size(); + + BOOL use_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST); + mCheckAccess->set( use_list ); + sprintf(label, "Avatars: (%d listed, %d max)", + count, PARCEL_MAX_ACCESS_LIST); + mCheckAccess->setLabel( label ); + + access_map_const_iterator cit = parcel->mAccessList.begin(); + access_map_const_iterator end = parcel->mAccessList.end(); + + for (; cit != end; ++cit) + { + const LLAccessEntry& entry = (*cit).second; + LLString suffix; + if (entry.mTime != 0) + { + S32 now = time(NULL); + S32 seconds = entry.mTime - now; + if (seconds < 0) seconds = 0; + suffix.assign(" ("); + if (seconds >= 120) + { + char buf[30]; + sprintf(buf, "%d minutes", (seconds/60)); + suffix.append(buf); + } + else if (seconds >= 60) + { + suffix.append("1 minute"); + } + else + { + char buf[30]; + sprintf(buf, "%d seconds", seconds); + suffix.append(buf); + } + suffix.append(" remaining)"); + } + mListAccess->addNameItem(entry.mID, ADD_BOTTOM, TRUE, suffix); + } + + BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED); + + BOOL enable_add = can_manage_allowed && (count < PARCEL_MAX_ACCESS_LIST); + mBtnAddAccess->setEnabled(enable_add); + + BOOL enable_remove = can_manage_allowed && (count > 0); + mBtnRemoveAccess->setEnabled(enable_remove); + + // Can only sell passes when limiting the access. + BOOL can_manage_passes = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_PASSES); + mCheckPass->setEnabled( (use_group || use_list) && can_manage_passes ); + + BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST); + mCheckPass->set( use_pass ); + + BOOL enable_pass = can_manage_passes && use_pass; + mSpinPrice->setEnabled( enable_pass ); + mSpinHours->setEnabled( enable_pass ); + + S32 pass_price = parcel->getPassPrice(); + mSpinPrice->set( F32(pass_price) ); + + F32 pass_hours = parcel->getPassHours(); + mSpinHours->set( pass_hours ); + + mCheckGroup->setEnabled( can_manage_allowed ); + mCheckAccess->setEnabled( can_manage_allowed ); + + } + else + { + mCheckGroup->set(FALSE); + mCheckGroup->setLabel("Group:"); + mCheckAccess->set(FALSE); + mCheckAccess->setLabel("Avatars:"); + mBtnAddAccess->setEnabled(FALSE); + mBtnRemoveAccess->setEnabled(FALSE); + mSpinPrice->set((F32)PARCEL_PASS_PRICE_DEFAULT); + mSpinPrice->setEnabled(FALSE); + mSpinHours->set( PARCEL_PASS_HOURS_DEFAULT ); + mSpinHours->setEnabled(FALSE); + mCheckGroup->setEnabled(FALSE); + mCheckAccess->setEnabled(FALSE); + } +} + +// public +void LLPanelLandAccess::refreshNames() +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + char group_name[DB_GROUP_NAME_BUF_SIZE]; + group_name[0] = '\0'; + if(parcel) + { + gCacheName->getGroupName(parcel->getGroupID(), group_name); + } + char label[MAX_STRING]; + snprintf(label, MAX_STRING, "Group: %s", group_name); + mCheckGroup->setLabel(label); +} + + +// virtual +void LLPanelLandAccess::draw() +{ + refreshNames(); + LLPanel::draw(); +} + + +void LLPanelLandAccess::onAccessLevelChange(LLUICtrl*, void *userdata) +{ + LLPanelLandAccess::onCommitAny(NULL, userdata); +} + +// static +void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandAccess *self = (LLPanelLandAccess *)userdata; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL use_access_group = self->mCheckGroup->get(); + BOOL use_access_list = self->mCheckAccess->get(); + BOOL use_pass_list = self->mCheckPass->get(); + + + + // Must be limiting access to sell passes + if (!use_access_group && !use_access_list) + { + use_pass_list = FALSE; + } + + S32 pass_price = llfloor(self->mSpinPrice->get()); + F32 pass_hours = self->mSpinHours->get(); + + // Validate extracted data + + // Push data into current parcel + parcel->setParcelFlag(PF_USE_ACCESS_GROUP, use_access_group); + parcel->setParcelFlag(PF_USE_ACCESS_LIST, use_access_list); + parcel->setParcelFlag(PF_USE_PASS_LIST, use_pass_list); + + parcel->setPassPrice( pass_price ); + parcel->setPassHours( pass_hours ); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} + +// static +void LLPanelLandAccess::onClickAdd(void* data) +{ + LLPanelLandAccess* panelp = (LLPanelLandAccess*)data; + gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data) ); +} + +// static +void LLPanelLandAccess::callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) +{ + LLPanelLandAccess* self = (LLPanelLandAccess*)userdata; + if (names.empty() || ids.empty()) return; + self->addAvatar(ids[0]); +} + + +void LLPanelLandAccess::addAvatar(LLUUID id) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + parcel->addToAccessList(id, 0); + + gParcelMgr->sendParcelAccessListUpdate(AL_ACCESS); + + refresh(); +} + + +// static +void LLPanelLandAccess::onClickRemove(void* data) +{ + LLPanelLandAccess* self = (LLPanelLandAccess*)data; + if (!self) return; + + LLScrollListItem* item = self->mListAccess->getFirstSelected(); + if (!item) return; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + const LLUUID& agent_id = item->getUUID(); + + parcel->removeFromAccessList(agent_id); + + gParcelMgr->sendParcelAccessListUpdate(AL_ACCESS); + + self->refresh(); +} + + + +//--------------------------------------------------------------------------- +// LLPanelLandBan +//--------------------------------------------------------------------------- +LLPanelLandBan::LLPanelLandBan() +: LLPanel("land_ban_panel") +{ + +} + + + +BOOL LLPanelLandBan::postBuild() +{ + + mCheck = LLUICtrlFactory::getCheckBoxByName(this, "LandBanCheck"); + childSetCommitCallback("LandBanCheck", onCommitAny, this); + + mList = LLUICtrlFactory::getNameListByName(this, "LandBanList"); + + mBtnAdd = LLUICtrlFactory::getButtonByName(this, "Add..."); + + mBtnAdd->setClickedCallback(onClickAdd, this); + + mBtnRemove = LLUICtrlFactory::getButtonByName(this, "Remove"); + + mBtnRemove->setClickedCallback(onClickRemove, this); + + mCheckDenyAnonymous = LLUICtrlFactory::getCheckBoxByName(this, "DenyAnonymousCheck"); + childSetCommitCallback("DenyAnonymousCheck", onCommitAny, this); + + mCheckDenyIdentified = LLUICtrlFactory::getCheckBoxByName(this, "DenyIdentifiedCheck"); + childSetCommitCallback("DenyIdentifiedCheck", onCommitAny, this); + + mCheckDenyTransacted = LLUICtrlFactory::getCheckBoxByName(this, "DenyTransactedCheck"); + childSetCommitCallback("DenyTransactedCheck", onCommitAny, this); + + return TRUE; + +} + + +LLPanelLandBan::~LLPanelLandBan() +{ } + +void LLPanelLandBan::refresh() +{ + mList->deleteAllItems(); + + LLParcel *parcel = gParcelMgr->getSelectedParcel(); + + if (parcel) + { + char label[256]; + + // Display options + + S32 count = parcel->mBanList.size(); + + BOOL use_ban = parcel->getParcelFlag(PF_USE_BAN_LIST); + mCheck->set( use_ban ); + + sprintf(label, "Ban these avatars: (%d listed, %d max)", + count, PARCEL_MAX_ACCESS_LIST); + mCheck->setLabel( label ); + + access_map_const_iterator cit = parcel->mBanList.begin(); + access_map_const_iterator end = parcel->mBanList.end(); + for ( ; cit != end; ++cit) + { + const LLAccessEntry& entry = (*cit).second; + LLString suffix; + if (entry.mTime != 0) + { + S32 now = time(NULL); + S32 seconds = entry.mTime - now; + if (seconds < 0) seconds = 0; + suffix.assign(" ("); + if (seconds >= 120) + { + char buf[30]; + sprintf(buf, "%d minutes", (seconds/60)); + suffix.append(buf); + } + else if (seconds >= 60) + { + suffix.append("1 minute"); + } + else + { + char buf[30]; + sprintf(buf, "%d seconds", seconds); + suffix.append(buf); + } + suffix.append(" remaining)"); + } + mList->addNameItem(entry.mID, ADD_BOTTOM, TRUE, suffix); + } + + BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED); + mCheck->setEnabled( can_manage_banned ); + mCheckDenyAnonymous->setEnabled( FALSE ); + mCheckDenyIdentified->setEnabled( FALSE ); + mCheckDenyTransacted->setEnabled( FALSE ); + + if(parcel->getRegionDenyAnonymousOverride()) + { + mCheckDenyAnonymous->set(TRUE); + } + else if(can_manage_banned) + { + mCheckDenyAnonymous->setEnabled(TRUE); + mCheckDenyAnonymous->set(parcel->getParcelFlag(PF_DENY_ANONYMOUS)); + } + if(parcel->getRegionDenyIdentifiedOverride()) + { + mCheckDenyIdentified->set(TRUE); + } + else if(can_manage_banned) + { + mCheckDenyIdentified->setEnabled(TRUE); + mCheckDenyIdentified->set(parcel->getParcelFlag(PF_DENY_IDENTIFIED)); + } + if(parcel->getRegionDenyTransactedOverride()) + { + mCheckDenyTransacted->set(TRUE); + } + else if(can_manage_banned) + { + mCheckDenyTransacted->setEnabled(TRUE); + mCheckDenyTransacted->set(parcel->getParcelFlag(PF_DENY_TRANSACTED)); + } + + + BOOL enable_add = can_manage_banned && (count < PARCEL_MAX_ACCESS_LIST); + mBtnAdd->setEnabled(enable_add); + + BOOL enable_remove = can_manage_banned && (count > 0); + mBtnRemove->setEnabled(enable_remove); + } + else + { + mCheck->set(FALSE); + mCheck->setLabel("Ban these avatars:"); + mCheck->setEnabled(FALSE); + mBtnAdd->setEnabled(FALSE); + mBtnRemove->setEnabled(FALSE); + mCheckDenyAnonymous->set(FALSE); + mCheckDenyAnonymous->setEnabled(FALSE); + mCheckDenyIdentified->set(FALSE); + mCheckDenyIdentified->setEnabled(FALSE); + mCheckDenyTransacted->set(FALSE); + mCheckDenyTransacted->setEnabled(FALSE); + } +} + +// static +void LLPanelLandBan::onCommitAny(LLUICtrl *ctrl, void *userdata) +{ + LLPanelLandBan *self = (LLPanelLandBan*)userdata; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) + { + return; + } + + // Extract data from UI + BOOL use_ban_list = self->mCheck->get(); + BOOL deny_access_anonymous = self->mCheckDenyAnonymous->get(); + BOOL deny_access_identified = self->mCheckDenyIdentified->get(); + BOOL deny_access_transacted = self->mCheckDenyTransacted->get(); + + // Push data into current parcel + parcel->setParcelFlag(PF_USE_BAN_LIST, use_ban_list); + parcel->setParcelFlag(PF_DENY_ANONYMOUS, deny_access_anonymous); + parcel->setParcelFlag(PF_DENY_IDENTIFIED, deny_access_identified); + parcel->setParcelFlag(PF_DENY_TRANSACTED, deny_access_transacted); + + // Send current parcel data upstream to server + gParcelMgr->sendParcelPropertiesUpdate( parcel, LLFloaterLand::sRequestReplyOnUpdate ); + + // Might have changed properties, so let's redraw! + self->refresh(); +} + +// static +void LLPanelLandBan::onClickAdd(void* data) +{ + LLPanelLandBan* panelp = (LLPanelLandBan*)data; + gFloaterView->getParentFloater(panelp)->addDependentFloater(LLFloaterAvatarPicker::show(callbackAvatarID, data) ); +} + +// static +void LLPanelLandBan::callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata) +{ + LLPanelLandBan* self = (LLPanelLandBan*)userdata; + if (names.empty() || ids.empty()) return; + self->addAvatar(ids[0]); +} + + +void LLPanelLandBan::addAvatar(LLUUID id) +{ + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + parcel->addToBanList(id, 0); + + gParcelMgr->sendParcelAccessListUpdate(AL_BAN); + + refresh(); +} + + +// static +void LLPanelLandBan::onClickRemove(void* data) +{ + LLPanelLandBan* self = (LLPanelLandBan*)data; + if (!self) return; + + LLScrollListItem* item = self->mList->getFirstSelected(); + if (!item) return; + + LLParcel* parcel = gParcelMgr->getSelectedParcel(); + if (!parcel) return; + + const LLUUID& agent_id = item->getUUID(); + + parcel->removeFromBanList(agent_id); + + gParcelMgr->sendParcelAccessListUpdate(AL_BAN); + + self->refresh(); +} + +//--------------------------------------------------------------------------- +// LLPanelLandRenters +//--------------------------------------------------------------------------- +LLPanelLandRenters::LLPanelLandRenters() +: LLPanel("landrenters", LLRect(0,500,500,0)) +{ + const S32 BTN_WIDTH = 64; + + S32 x = LEFT; + S32 y = mRect.getHeight() - VPAD; + + LLCheckBoxCtrl* check = NULL; + LLButton* btn = NULL; + LLNameListCtrl* list = NULL; + + check = new LLCheckBoxCtrl("RentersCheck", + LLRect(RULER0, y, RIGHT, y-LINE), + "Rent space to these avatars:"); + addChild(check); + mCheckRenters = check; + + y -= VPAD + LINE; + + const S32 ITEMS = 5; + const BOOL NO_MULTIPLE_SELECT = FALSE; + + list = new LLNameListCtrl("RentersList", + LLRect(RULER05, y, RIGHT, y-LINE*ITEMS), + NULL, NULL, + NO_MULTIPLE_SELECT); + list->addSimpleItem("foo tester"); + list->addSimpleItem("bar tester"); + list->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + addChild(list); + mListRenters = list; + + y -= VPAD + LINE*ITEMS; + + x = RULER05; + btn = new LLButton("Add...", + LLRect(x, y, x+BTN_WIDTH, y-LINE), + "", + onClickAdd, this); + btn->setFont( LLFontGL::sSansSerifSmall ); + btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + addChild(btn); + mBtnAddRenter = btn; + + x += HPAD + BTN_WIDTH; + + btn = new LLButton("Remove", + LLRect(x, y, x+BTN_WIDTH, y-LINE), + "", + onClickRemove, this); + btn->setFont( LLFontGL::sSansSerifSmall ); + btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); + addChild(btn); + mBtnRemoveRenter = btn; +} + +LLPanelLandRenters::~LLPanelLandRenters() +{ } + +void LLPanelLandRenters::refresh() +{ } + +// static +void LLPanelLandRenters::onClickAdd(void*) +{ +} + +// static +void LLPanelLandRenters::onClickRemove(void*) +{ +} + +//--------------------------------------------------------------------------- +// LLPanelLandCovenant +//--------------------------------------------------------------------------- +LLPanelLandCovenant::LLPanelLandCovenant() +: LLPanel("land_covenant_panel") +{ +} + +LLPanelLandCovenant::~LLPanelLandCovenant() +{ +} + +BOOL LLPanelLandCovenant::postBuild() +{ + refresh(); + return TRUE; +} + +// virtual +void LLPanelLandCovenant::refresh() +{ + LLViewerRegion* region = gParcelMgr->getSelectionRegion(); + if(!region) return; + + LLTextBox* region_name = (LLTextBox*)getChildByName("region_name_text"); + if (region_name) + { + region_name->setText(region->getName()); + } + + LLTextBox* resellable_clause = (LLTextBox*)getChildByName("resellable_clause"); + if (resellable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL) + { + resellable_clause->setText(childGetText("can_not_resell")); + } + else + { + resellable_clause->setText(childGetText("can_resell")); + } + } + + LLTextBox* changeable_clause = (LLTextBox*)getChildByName("changeable_clause"); + if (changeable_clause) + { + if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES) + { + changeable_clause->setText(childGetText("can_change")); + } + else + { + changeable_clause->setText(childGetText("can_not_change")); + } + } + + // send EstateCovenantInfo message + LLMessageSystem *msg = gMessageSystem; + msg->newMessage("EstateCovenantRequest"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); + msg->sendReliable(region->getHost()); +} + +// static +void LLPanelLandCovenant::updateCovenantText(const std::string &string) +{ + LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); + if (self) + { + LLViewerTextEditor* editor = (LLViewerTextEditor*)self->getChildByName("covenant_editor"); + if (editor) + { + editor->setHandleEditKeysDirectly(TRUE); + editor->setText(string); + } + } +} + +// static +void LLPanelLandCovenant::updateEstateName(const std::string& name) +{ + LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); + if (self) + { + LLTextBox* editor = (LLTextBox*)self->getChildByName("estate_name_text"); + if (editor) editor->setText(name); + } +} + +// static +void LLPanelLandCovenant::updateLastModified(const std::string& text) +{ + LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); + if (self) + { + LLTextBox* editor = (LLTextBox*)self->getChildByName("covenant_timestamp_text"); + if (editor) editor->setText(text); + } +} + +// static +void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) +{ + LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); + if (self) + { + LLTextBox* editor = (LLTextBox*)self->getChildByName("estate_owner_text"); + if (editor) editor->setText(name); + } +} |