void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
	if (user_action && (items.size() > 0))
	{
		deselectOtherThan(inventory_list);
		mCurrentSelectedList = inventory_list;
	}
	updateVerbs();
}
void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
    updateVerbs();
    if (getRootFolder()->needsAutoRename() && items.size())
    {
        getRootFolder()->startRenamingSelectedItem();
        getRootFolder()->setNeedsAutoRename(FALSE);
    }
}
void LLPanelOutfitsInventory::onTabChange()
{
    mActivePanel = (LLInventoryPanel*)childGetVisibleTab("appearance_tabs");
    if (!mActivePanel)
    {
        return;
    }
    mActivePanel->setFilterSubString(mFilterSubString);
    updateVerbs();
}
예제 #4
0
void LLPanelOutfitsInventory::onTabChange()
{
	mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
	if (!mActivePanel) return;

	mActivePanel->setFilterSubString(mFilterSubString);
	mActivePanel->onOpen(LLSD());

	updateVerbs();
}
예제 #5
0
void LLPanelPlaces::onBackButtonClicked()
{
	togglePlaceInfoPanel(FALSE);

	// Resetting mPlaceInfoType when Place Info panel is closed.
	mPlaceInfoType = LLStringUtil::null;

	isLandmarkEditModeOn = false;

	updateVerbs();
}
예제 #6
0
void LLPanelPlaces::onEditButtonClicked()
{
	if (!mLandmarkInfo || isLandmarkEditModeOn)
		return;

	isLandmarkEditModeOn = true;

	mLandmarkInfo->toggleLandmarkEditMode(TRUE);

	updateVerbs();
}
void LLSidepanelInventorySubpanel::draw()
{
	if (mIsDirty)
	{
		refresh();
		updateVerbs();
		mIsDirty = FALSE;
	}

	LLPanel::draw();
}
예제 #8
0
void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
{
	if (!mLandmarkInfo)
		return;

	LLUUID region_id;
	landmark->getRegionID(region_id);
	landmark->getGlobalPos(mPosGlobal);
	mLandmarkInfo->displayParcelInfo(region_id, mPosGlobal);

	updateVerbs();
}
예제 #9
0
void LLTeleportHistoryPanel::onTeleportHistoryChange(S32 removed_index)
{
	mLastSelectedItemIndex = -1;

	if (-1 == removed_index)
		showTeleportHistory(); // recreate all items
	else
	{
		replaceItem(removed_index); // replace removed item by most recent
		updateVerbs();
	}
}
예제 #10
0
S32 LLPanelPlaces::notifyParent(const LLSD& info)
{
	if(info.has("update_verbs"))
	{
		if(mPosGlobal.isExactlyZero())
		{
			mPosGlobal.setVec(info["global_x"], info["global_y"], info["global_z"]);
		}

		updateVerbs();
		
		return 1;
	}
	return LLPanel::notifyParent(info);
}
예제 #11
0
void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
{
	if (clearMain)
	{
		LLInventoryPanel * inv_panel = getActivePanel();
		
		if (inv_panel)
		{
			inv_panel->clearSelection();
		}
	}
	
	if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
	{
		mInventoryPanelInbox->clearSelection();
	}
	
	updateVerbs();
}
예제 #12
0
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
	*accept = ACCEPT_NO;

	switch (cargo_type)
	{

	case DAD_LANDMARK:
	case DAD_CATEGORY:
		{
			bool is_enabled = isActionEnabled("delete");

			if (is_enabled) *accept = ACCEPT_YES_MULTI;

			if (is_enabled && drop)
			{
				// don't call onClipboardAction("delete")
				// this lead to removing (N * 2 - 1) items if drag N>1 items into trash. EXT-6757
				// So, let remove items one by one.
				LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);
				if (item)
				{
					LLFolderViewItem* fv_item = mCurrentSelectedList
						? mCurrentSelectedList->getItemByID(item->getUUID())
						: NULL;

					if (fv_item)
					{
						// is Item Removable checked inside of remove()
						fv_item->remove();
					}
				}
			}
		}
		break;
	default:
		break;
	}

	updateVerbs();
	return true;
}
void LLPanelOutfitsInventory::onCustomAction(const LLSD& userdata)
{
    if (!isActionEnabled(userdata))
        return;

    const std::string command_name = userdata.asString();
    if (command_name == "new")
    {
        onSave();
    }
    if (command_name == "edit")
    {
        onEdit();
    }
    if (command_name == "wear")
    {
        onWearButtonClick();
    }
    // Note: This option has been removed from the gear menu.
    if (command_name == "add")
    {
        onAdd();
    }
    if (command_name == "remove")
    {
        onRemove();
    }
    if (command_name == "rename")
    {
        onClipboardAction("rename");
    }
    if (command_name == "remove_link")
    {
        onClipboardAction("delete");
    }
    if (command_name == "delete")
    {
        onClipboardAction("delete");
    }
    updateListCommands();
    updateVerbs();
}
예제 #14
0
void LLPanelPlaces::changedParcelSelection()
{
	if (!mPlaceProfile)
		return;

	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
	mParcel = parcel_mgr->getFloatingParcelSelection();
	LLParcel* parcel = mParcel->getParcel();
	LLViewerRegion* region = parcel_mgr->getSelectionRegion();
	if (!region || !parcel)
		return;

	LLVector3d prev_pos_global = mPosGlobal;

	// If agent is inside the selected parcel show agent's region<X, Y, Z>,
	// otherwise show region<X, Y, Z> of agent's selection point.
	bool is_current_parcel = is_agent_in_selected_parcel(parcel);
	if (is_current_parcel)
	{
		mPosGlobal = gAgent.getPositionGlobal();
	}
	else
	{
		LLVector3d pos_global = gViewerWindow->getLastPick().mPosGlobal;
		if (!pos_global.isExactlyZero())
		{
			mPosGlobal = pos_global;
		}
	}

	// Reset location info only if global position has changed
	// and update timer has expired to reduce unnecessary text and icons updates.
	if (prev_pos_global != mPosGlobal && mResetInfoTimer.hasExpired())
	{
		mPlaceProfile->resetLocation();
		mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
	}

	mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);

	updateVerbs();
}
예제 #15
0
void LLPanelPlaces::onCancelButtonClicked()
{
	if (!mLandmarkInfo)
		return;

	if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
	{
		onBackButtonClicked();
	}
	else
	{
		mLandmarkInfo->toggleLandmarkEditMode(FALSE);
		isLandmarkEditModeOn = false;

		updateVerbs();

		// Reload the landmark properties.
		mLandmarkInfo->displayItemInfo(mItem);
	}
}
void LLSidepanelInventorySubpanel::onEditButtonClicked()
{
	setIsEditing(TRUE);
	refresh();
	updateVerbs();
}
예제 #17
0
// Called to add items, no more, than ADD_LIMIT at time
void LLTeleportHistoryPanel::refresh()
{
	if (!mHistoryAccordion)
	{
		mDirty = false;
		return;
	}

	const LLTeleportHistoryStorage::slurl_list_t& items = mTeleportHistory->getItems();

	// Setting tab_boundary_date to "now", so date from any item would be earlier, than boundary.
	// That leads to call to getNextTab to get right tab_idx in first pass
	LLDate tab_boundary_date =  LLDate::now();

	LLFlatListView* curr_flat_view = NULL;
	std::string filter_string = sFilterSubString;
	LLStringUtil::toUpper(filter_string);

	U32 added_items = 0;
	while (mCurrentItem >= 0)
	{
		// Filtering
		if (!filter_string.empty())
		{
			std::string landmark_title(items[mCurrentItem].mTitle);
			LLStringUtil::toUpper(landmark_title);
			if( std::string::npos == landmark_title.find(filter_string) )
			{
				mCurrentItem--;
				continue;
			}
		}

		// Checking whether date of item is earlier, than tab_boundary_date.
		// In that case, item should be added to another tab
		const LLDate &date = items[mCurrentItem].mDate;

		if (date < tab_boundary_date)
		{
			// Getting apropriate tab_idx for this and subsequent items,
			// tab_boundary_date would be earliest possible date for this tab
			S32 tab_idx = 0;
			getNextTab(date, tab_idx, tab_boundary_date);
			tab_idx = mItemContainers.size() - 1 - tab_idx;
			if (tab_idx >= 0)
			{
				LLAccordionCtrlTab* tab = mItemContainers.get(tab_idx);
				tab->setVisible(true);

				// Expand all accordion tabs when filtering
				if(!sFilterSubString.empty())
				{
					//store accordion tab state when filter is not empty
					tab->notifyChildren(LLSD().with("action","store_state"));
				
					tab->setDisplayChildren(true);
				}
				// Restore each tab's expand state when not filtering
				else
				{
					bool collapsed = isAccordionCollapsedByUser(tab);
					tab->setDisplayChildren(!collapsed);
			
					//restore accordion state after all those accodrion tabmanipulations
					tab->notifyChildren(LLSD().with("action","restore_state"));
				}

				curr_flat_view = getFlatListViewFromTab(tab);
			}
		}

		if (curr_flat_view)
		{
			LLTeleportHistoryFlatItem* item =
				LLTeleportHistoryFlatItemStorage::instance()
				.getFlatItemForPersistentItem(&mContextMenu,
											  items[mCurrentItem],
											  mCurrentItem,
											  filter_string);
			if ( !curr_flat_view->addItem(item, LLUUID::null, ADD_BOTTOM, false) )
				llerrs << "Couldn't add flat item to teleport history." << llendl;
			if (mLastSelectedItemIndex == mCurrentItem)
				curr_flat_view->selectItem(item, true);
		}

		mCurrentItem--;

		if (++added_items >= ADD_LIMIT)
			break;
	}

	for (S32 n = mItemContainers.size() - 1; n >= 0; --n)
	{
		LLAccordionCtrlTab* tab = mItemContainers.get(n);
		LLFlatListView* fv = getFlatListViewFromTab(tab);
		if (fv)
		{
			fv->notify(LLSD().with("rearrange", LLSD()));
		}
	}

	mHistoryAccordion->setFilterSubString(sFilterSubString);

	mHistoryAccordion->arrange();

	updateVerbs();

	if (mCurrentItem < 0)
		mDirty = false;
}
예제 #18
0
void LLSidepanelInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
	updateVerbs();
}
예제 #19
0
BOOL LLSidepanelInventory::postBuild()
{
	// UI elements from inventory panel
	{
		mInventoryPanel = getChild<LLPanel>("sidepanel__inventory_panel");

		mInfoBtn = mInventoryPanel->getChild<LLButton>("info_btn");
		mInfoBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onInfoButtonClicked, this));
		
		mShareBtn = mInventoryPanel->getChild<LLButton>("share_btn");
		mShareBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShareButtonClicked, this));
		
		mShopBtn = mInventoryPanel->getChild<LLButton>("shop_btn");
		mShopBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onShopButtonClicked, this));

		mWearBtn = mInventoryPanel->getChild<LLButton>("wear_btn");
		mWearBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onWearButtonClicked, this));
		
		mPlayBtn = mInventoryPanel->getChild<LLButton>("play_btn");
		mPlayBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onPlayButtonClicked, this));
		
		mTeleportBtn = mInventoryPanel->getChild<LLButton>("teleport_btn");
		mTeleportBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onTeleportButtonClicked, this));
		
		mOverflowBtn = mInventoryPanel->getChild<LLButton>("overflow_btn");
		mOverflowBtn->setClickedCallback(boost::bind(&LLSidepanelInventory::onOverflowButtonClicked, this));
		
		mPanelMainInventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
		mPanelMainInventory->setSelectCallback(boost::bind(&LLSidepanelInventory::onSelectionChange, this, _1, _2));
		LLTabContainer* tabs = mPanelMainInventory->getChild<LLTabContainer>("inventory filter tabs");
		tabs->setCommitCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));

		/* 
		   EXT-4846 : "Can we suppress the "Landmarks" and "My Favorites" folder since they have their own Task Panel?"
		   Deferring this until 2.1.
		LLInventoryPanel *my_inventory_panel = mPanelMainInventory->getChild<LLInventoryPanel>("All Items");
		my_inventory_panel->addHideFolderType(LLFolderType::FT_LANDMARK);
		my_inventory_panel->addHideFolderType(LLFolderType::FT_FAVORITE);
		*/

		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLSidepanelInventory::updateVerbs, this));
	}

	// UI elements from item panel
	{
		mItemPanel = getChild<LLSidepanelItemInfo>("sidepanel__item_panel");
		
		LLButton* back_btn = mItemPanel->getChild<LLButton>("back_btn");
		back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
	}

	// UI elements from task panel
	{
		mTaskPanel = findChild<LLSidepanelTaskInfo>("sidepanel__task_panel");
		if (mTaskPanel)
		{
			LLButton* back_btn = mTaskPanel->getChild<LLButton>("back_btn");
			back_btn->setClickedCallback(boost::bind(&LLSidepanelInventory::onBackButtonClicked, this));
		}
	}
	
	// Received items inbox setup
	{
		LLLayoutStack* inv_stack = getChild<LLLayoutStack>(INVENTORY_LAYOUT_STACK_NAME);

		// Collapse inbox panel
		inv_stack->collapsePanel(getChild<LLLayoutPanel>(INBOX_LAYOUT_PANEL_NAME), true);
		
		// Set up button states and callbacks
		LLButton * inbox_button = getChild<LLButton>(INBOX_BUTTON_NAME);

		inbox_button->setToggleState(false);
		inbox_button->setCommitCallback(boost::bind(&LLSidepanelInventory::onToggleInboxBtn, this));

		// Set the inbox visible based on debug settings (final setting comes from http request below)
		enableInbox(gSavedSettings.getBOOL("InventoryDisplayInbox"));

		// Trigger callback for after login so we can setup to track inbox changes after initial inventory load
		LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSidepanelInventory::updateInbox, this));
	}

	gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));

	// Update the verbs buttons state.
	updateVerbs();

	return TRUE;
}
void LLPanelOutfitEdit::update()
{
	mCOFWearables->refresh();

	updateVerbs();
}
void LLSidepanelItemInfo::refresh()
{
	LLViewerInventoryItem* item = findItem();
	if(item)
	{
		refreshFromItem(item);
		updateVerbs();
		return;
	}
	else
	{
		if (getIsEditing())
		{
			setIsEditing(FALSE);
		}
	}

	if (!getIsEditing())
	{
		const std::string no_item_names[]={
			"LabelItemName",
			"LabelItemDesc",
			"LabelCreatorName",
			"LabelOwnerName",
			"CheckOwnerModify",
			"CheckOwnerCopy",
			"CheckOwnerTransfer",
			"CheckShareWithGroup",
			"CheckEveryoneCopy",
			"CheckNextOwnerModify",
			"CheckNextOwnerCopy",
			"CheckNextOwnerTransfer",
			"CheckPurchase",
			"RadioSaleType",
			"Edit Cost"
		};

		for(size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t)
		{
			childSetEnabled(no_item_names[t],false);
		}
		
		const std::string hide_names[]={
			"BaseMaskDebug",
			"OwnerMaskDebug",
			"GroupMaskDebug",
			"EveryoneMaskDebug",
			"NextMaskDebug"
		};
		for(size_t t=0; t<LL_ARRAY_SIZE(hide_names); ++t)
		{
			childSetVisible(hide_names[t],false);
		}
	}

	if (!item)
	{
		const std::string no_edit_mode_names[]={
			"BtnCreator",
			"BtnOwner",
		};
		for(size_t t=0; t<LL_ARRAY_SIZE(no_edit_mode_names); ++t)
		{
			childSetEnabled(no_edit_mode_names[t],false);
		}
	}

	updateVerbs();
}
예제 #22
0
void LLPanelPlaces::onOpen(const LLSD& key)
{
	if (!mPlaceProfile || !mLandmarkInfo)
		return;

	if (key.size() != 0)
	{
		mFilterEditor->clear();
		onFilterEdit("", false);

		mPlaceInfoType = key["type"].asString();
		mPosGlobal.setZero();
		mItem = NULL;
		isLandmarkEditModeOn = false;
		togglePlaceInfoPanel(TRUE);

		if (mPlaceInfoType == AGENT_INFO_TYPE)
		{
			mPlaceProfile->setInfoType(LLPanelPlaceInfo::AGENT);
		}
		else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
		{
			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);

			if (key.has("x") && key.has("y") && key.has("z"))
			{
				mPosGlobal = LLVector3d(key["x"].asReal(),
										key["y"].asReal(),
										key["z"].asReal());
			}
			else
			{
				mPosGlobal = gAgent.getPositionGlobal();
			}

			mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);

			// Disabling "Save", "Close" and "Back" buttons to prevent closing "Create Landmark"
			// panel before created landmark is loaded.
			// These buttons will be enabled when created landmark is added to inventory.
			mSaveBtn->setEnabled(FALSE);
			mCloseBtn->setEnabled(FALSE);
			mLandmarkInfoBackBtn->setEnabled(FALSE);
		}
		else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
		{
			mLandmarkInfo->setInfoType(LLPanelPlaceInfo::LANDMARK);

			LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
			if (!item)
				return;

			setItem(item);
		}
		else if (mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
		{
			if (key.has("id"))
			{
				LLUUID parcel_id = key["id"].asUUID();
				mPlaceProfile->setParcelID(parcel_id);

				// query the server to get the global 3D position of this
				// parcel - we need this for teleport/mapping functions.
				mRemoteParcelObserver->setParcelID(parcel_id);
			}
			else
			{
				mPosGlobal = LLVector3d(key["x"].asReal(),
										key["y"].asReal(),
										key["z"].asReal());
				mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
			}

			mPlaceProfile->setInfoType(LLPanelPlaceInfo::PLACE);
		}
		else if (mPlaceInfoType == TELEPORT_HISTORY_INFO_TYPE)
		{
			S32 index = key["id"].asInteger();

			const LLTeleportHistoryStorage::slurl_list_t& hist_items =
						LLTeleportHistoryStorage::getInstance()->getItems();

			mPosGlobal = hist_items[index].mGlobalPos;

			mPlaceProfile->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
			mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
		}

		updateVerbs();
	}

	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
	if (!parcel_mgr)
		return;

	// Start using LLViewerParcelMgr for land selection if
	// information about nearby land is requested.
	// Otherwise stop using land selection and deselect land.
	if (mPlaceInfoType == AGENT_INFO_TYPE)
	{
		// We don't know if we are already added to LLViewerParcelMgr observers list
		// so try to remove observer not to add an extra one.
		parcel_mgr->removeObserver(mParcelObserver);

		parcel_mgr->addObserver(mParcelObserver);
		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
	}
	else
	{
		parcel_mgr->removeObserver(mParcelObserver);

		// Clear the reference to selection to allow its removal in deselectUnused().
		mParcel.clear();

		if (!parcel_mgr->selectionEmpty())
		{
			parcel_mgr->deselectUnused();
		}
	}
}
void LLSidepanelInventorySubpanel::onCancelButtonClicked()
{
	setIsEditing(FALSE);
	refresh();
	updateVerbs();
}
예제 #24
0
void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos)
{
	mPosGlobal = global_pos;
	updateVerbs();
}
예제 #25
0
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
	updateVerbs();
}
예제 #26
0
void LLSidepanelTaskInfo::refresh()
{
	LLButton* btn_deed_to_group = getChild<LLButton>("button deed");
	if (btn_deed_to_group)
	{	
		std::string deedText;
		if (gWarningSettings.getBOOL("DeedObject"))
		{
			deedText = getString("text deed continued");
		}
		else
		{
			deedText = getString("text deed");
		}
		btn_deed_to_group->setLabelSelected(deedText);
		btn_deed_to_group->setLabelUnselected(deedText);
	}

	BOOL root_selected = TRUE;
	LLSelectNode* nodep = mObjectSelection->getFirstRootNode();
	S32 object_count = mObjectSelection->getRootObjectCount();
	if (!nodep || (object_count == 0))
	{
		nodep = mObjectSelection->getFirstNode();
		object_count = mObjectSelection->getObjectCount();
		root_selected = FALSE;
	}

	LLViewerObject* objectp = NULL;
	if (nodep)
	{
		objectp = nodep->getObject();
	}

	// ...nothing selected
	if (!nodep || !objectp)
	{
		disableAll();
		return;
	}

	// figure out a few variables
	const BOOL is_one_object = (object_count == 1);
	
	// BUG: fails if a root and non-root are both single-selected.
	const BOOL is_perm_modify = (mObjectSelection->getFirstRootNode() && LLSelectMgr::getInstance()->selectGetRootsModify()) ||
		LLSelectMgr::getInstance()->selectGetModify();

	S32 string_index = 0;
	std::string MODIFY_INFO_STRINGS[] =
		{
			getString("text modify info 1"),
			getString("text modify info 2"),
			getString("text modify info 3"),
			getString("text modify info 4")
		};
	if (!is_perm_modify)
	{
		string_index += 2;
	}
	if (!is_one_object)
	{
		++string_index;
	}
	childSetEnabled("perm_modify", 			   			TRUE);
	childSetText("perm_modify",							MODIFY_INFO_STRINGS[string_index]);

	childSetEnabled("Permissions:", 					TRUE);
	
	// Update creator text field
	childSetEnabled("Creator:", 						TRUE);
	BOOL creators_identical;
	std::string creator_name;
	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
																	  creator_name);

	childSetText("Creator Name",						creator_name);
	childSetEnabled("Creator Name", 					TRUE);

	// Update owner text field
	childSetEnabled("Owner:", 							TRUE);

	std::string owner_name;
	const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name);
	if (mOwnerID.isNull())
	{
		if (LLSelectMgr::getInstance()->selectIsGroupOwned())
		{
			// Group owned already displayed by selectGetOwner
		}
		else
		{
			// Display last owner if public
			std::string last_owner_name;
			LLSelectMgr::getInstance()->selectGetLastOwner(mLastOwnerID, last_owner_name);

			// It should never happen that the last owner is null and the owner
			// is null, but it seems to be a bug in the simulator right now. JC
			if (!mLastOwnerID.isNull() && !last_owner_name.empty())
			{
				owner_name.append(", last ");
				owner_name.append(last_owner_name);
			}
		}
	}
	childSetText("Owner Name",						owner_name);
	childSetEnabled("Owner Name", 					TRUE);

	// update group text field
	childSetEnabled("Group:", 						TRUE);
	childSetText("Group Name", 						LLStringUtil::null);
	LLUUID group_id;
	BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
	if (groups_identical)
	{
		if (mLabelGroupName)
		{
			mLabelGroupName->setNameID(group_id,TRUE);
			mLabelGroupName->setEnabled(TRUE);
		}
	}
	else
	{
		if (mLabelGroupName)
		{
			mLabelGroupName->setNameID(LLUUID::null, TRUE);
			mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE);
			mLabelGroupName->setEnabled(FALSE);
		}
	}
	
	childSetEnabled("button set group", owners_identical && (mOwnerID == gAgent.getID()));

	childSetEnabled("Name:", 						TRUE);
	LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");
	childSetEnabled("Description:", 				TRUE);
	LLLineEditor* LineEditorObjectDesc = getChild<LLLineEditor>("Object Description");

	if (is_one_object)
	{
		if (!LineEditorObjectName->hasFocus())
		{
			childSetText("Object Name",nodep->mName);
		}

		if (LineEditorObjectDesc)
		{
			if (!LineEditorObjectDesc->hasFocus())
			{
				LineEditorObjectDesc->setText(nodep->mDescription);
			}
		}
	}
	else
	{
		childSetText("Object Name",					LLStringUtil::null);
		LineEditorObjectDesc->setText(LLStringUtil::null);
	}

	// figure out the contents of the name, description, & category
	BOOL edit_name_desc = FALSE;
	if (is_one_object && objectp->permModify())
	{
		edit_name_desc = TRUE;
	}
	if (edit_name_desc)
	{
		childSetEnabled("Object Name", 				TRUE);
		childSetEnabled("Object Description", 		TRUE);
	}
	else
	{
		childSetEnabled("Object Name", 				FALSE);
		childSetEnabled("Object Description", 		FALSE);
	}

	S32 total_sale_price = 0;
	S32 individual_sale_price = 0;
	BOOL is_for_sale_mixed = FALSE;
	BOOL is_sale_price_mixed = FALSE;
	U32 num_for_sale = FALSE;
    LLSelectMgr::getInstance()->selectGetAggregateSaleInfo(num_for_sale,
														   is_for_sale_mixed,
														   is_sale_price_mixed,
														   total_sale_price,
														   individual_sale_price);

	const BOOL self_owned = (gAgent.getID() == mOwnerID);
	const BOOL group_owned = LLSelectMgr::getInstance()->selectIsGroupOwned() ;
	const BOOL public_owned = (mOwnerID.isNull() && !LLSelectMgr::getInstance()->selectIsGroupOwned());
	const BOOL can_transfer = LLSelectMgr::getInstance()->selectGetRootsTransfer();
	const BOOL can_copy = LLSelectMgr::getInstance()->selectGetRootsCopy();

	if (!owners_identical)
	{
		childSetEnabled("Cost", 					FALSE);
		childSetText("Edit Cost",					LLStringUtil::null);
		childSetEnabled("Edit Cost", 				FALSE);
	}
	// You own these objects.
	else if (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id,GP_OBJECT_SET_SALE)))
	{
		// If there are multiple items for sale then set text to PRICE PER UNIT.
		if (num_for_sale > 1)
		{
			childSetText("Cost",					getString("Cost Per Unit"));
		}
		else
		{
			childSetText("Cost",					getString("Cost Default"));
		}
		
		LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
		if (!edit_price->hasFocus())
		{
			// If the sale price is mixed then set the cost to MIXED, otherwise
			// set to the actual cost.
			if ((num_for_sale > 0) && is_for_sale_mixed)
			{
				edit_price->setTentative(TRUE);
			}
			else if ((num_for_sale > 0) && is_sale_price_mixed)
			{
				edit_price->setTentative(TRUE);
			}
			else 
			{
				edit_price->setValue(individual_sale_price);
			}
		}
		// The edit fields are only enabled if you can sell this object
		// and the sale price is not mixed.
		BOOL enable_edit = (num_for_sale && can_transfer) ? !is_for_sale_mixed : FALSE;
		childSetEnabled("Cost",					enable_edit);
		childSetEnabled("Edit Cost",			enable_edit);
	}
	// Someone, not you, owns these objects.
	else if (!public_owned)
	{
		childSetEnabled("Cost",					FALSE);
		childSetEnabled("Edit Cost",			FALSE);
		
		// Don't show a price if none of the items are for sale.
		if (num_for_sale)
			childSetText("Edit Cost",			llformat("%d",total_sale_price));
		else
			childSetText("Edit Cost",			LLStringUtil::null);

		// If multiple items are for sale, set text to TOTAL PRICE.
		if (num_for_sale > 1)
			childSetText("Cost",				getString("Cost Total"));
		else
			childSetText("Cost",				getString("Cost Default"));
	}
	// This is a public object.
	else
	{
		childSetEnabled("Cost",					FALSE);
		childSetText("Cost",					getString("Cost Default"));
		
		childSetText("Edit Cost",				LLStringUtil::null);
		childSetEnabled("Edit Cost",			FALSE);
	}

	// Enable and disable the permissions checkboxes
	// based on who owns the object.
	// TODO: Creator permissions

	U32 base_mask_on 			= 0;
	U32 base_mask_off		 	= 0;
	U32 owner_mask_off			= 0;
	U32 owner_mask_on 			= 0;
	U32 group_mask_on 			= 0;
	U32 group_mask_off 			= 0;
	U32 everyone_mask_on 		= 0;
	U32 everyone_mask_off 		= 0;
	U32 next_owner_mask_on 		= 0;
	U32 next_owner_mask_off		= 0;

	BOOL valid_base_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE,
																			&base_mask_on,
																			&base_mask_off);
	//BOOL valid_owner_perms =//
	LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
											  &owner_mask_on,
											  &owner_mask_off);
	BOOL valid_group_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
																			&group_mask_on,
																			&group_mask_off);
	
	BOOL valid_everyone_perms 	= LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
																			&everyone_mask_on,
																			&everyone_mask_off);
	
	BOOL valid_next_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_NEXT_OWNER,
																			&next_owner_mask_on,
																			&next_owner_mask_off);

	
	if (gSavedSettings.getBOOL("DebugPermissions") )
	{
		if (valid_base_perms)
		{
			childSetText("B:",								"B: " + mask_to_string(base_mask_on));
			childSetVisible("B:",							TRUE);
			
			childSetText("O:",								"O: " + mask_to_string(owner_mask_on));
			childSetVisible("O:",							TRUE);
			
			childSetText("G:",								"G: " + mask_to_string(group_mask_on));
			childSetVisible("G:",							TRUE);
			
			childSetText("E:",								"E: " + mask_to_string(everyone_mask_on));
			childSetVisible("E:",							TRUE);
			
			childSetText("N:",								"N: " + mask_to_string(next_owner_mask_on));
			childSetVisible("N:",							TRUE);
		}

		U32 flag_mask = 0x0;
		if (objectp->permMove()) 		flag_mask |= PERM_MOVE;
		if (objectp->permModify()) 		flag_mask |= PERM_MODIFY;
		if (objectp->permCopy()) 		flag_mask |= PERM_COPY;
		if (objectp->permTransfer()) 	flag_mask |= PERM_TRANSFER;

		childSetText("F:",									"F:" + mask_to_string(flag_mask));
		childSetVisible("F:",								TRUE);
	}
	else
	{
		childSetVisible("B:",								FALSE);
		childSetVisible("O:",								FALSE);
		childSetVisible("G:",								FALSE);
		childSetVisible("E:",								FALSE);
		childSetVisible("N:",								FALSE);
		childSetVisible("F:",								FALSE);
	}

	BOOL has_change_perm_ability = FALSE;
	BOOL has_change_sale_ability = FALSE;

	if (valid_base_perms &&
		(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
	{
		has_change_perm_ability = TRUE;
	}
	if (valid_base_perms &&
	   (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
	{
		has_change_sale_ability = TRUE;
	}

	if (!has_change_perm_ability && !has_change_sale_ability && !root_selected)
	{
		// ...must select root to choose permissions
		childSetValue("perm_modify", 						getString("text modify warning"));
	}

	if (has_change_perm_ability)
	{
		childSetEnabled("checkbox share with group",		TRUE);
		childSetEnabled("checkbox allow everyone move",		owner_mask_on & PERM_MOVE);
		childSetEnabled("checkbox allow everyone copy",		owner_mask_on & PERM_COPY && owner_mask_on & PERM_TRANSFER);
	}
	else
	{
		childSetEnabled("checkbox share with group", 		FALSE);
		childSetEnabled("checkbox allow everyone move", 	FALSE);
		childSetEnabled("checkbox allow everyone copy", 	FALSE);
	}

	if (has_change_sale_ability && (owner_mask_on & PERM_TRANSFER))
	{
		childSetEnabled("checkbox for sale", 				can_transfer || (!can_transfer && num_for_sale));
		// Set the checkbox to tentative if the prices of each object selected
		// are not the same.
		childSetTentative("checkbox for sale", 				is_for_sale_mixed);
		childSetEnabled("sale type", 						num_for_sale && can_transfer && !is_sale_price_mixed);

		childSetEnabled("Next owner can:", 					TRUE);
		childSetEnabled("checkbox next owner can modify", 	base_mask_on & PERM_MODIFY);
		childSetEnabled("checkbox next owner can copy", 	base_mask_on & PERM_COPY);
		childSetEnabled("checkbox next owner can transfer", next_owner_mask_on & PERM_COPY);
	}
	else 
	{
		childSetEnabled("checkbox for sale",				FALSE);
		childSetEnabled("sale type",						FALSE);

		childSetEnabled("Next owner can:",					FALSE);
		childSetEnabled("checkbox next owner can modify",	FALSE);
		childSetEnabled("checkbox next owner can copy",		FALSE);
		childSetEnabled("checkbox next owner can transfer",	FALSE);
	}

	if (valid_group_perms)
	{
		if ((group_mask_on & PERM_COPY) && (group_mask_on & PERM_MODIFY) && (group_mask_on & PERM_MOVE))
		{
			childSetValue("checkbox share with group",		TRUE);
			childSetTentative("checkbox share with group",	FALSE);
			childSetEnabled("button deed",					gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
		}
		else if ((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE))
		{
			childSetValue("checkbox share with group",		FALSE);
			childSetTentative("checkbox share with group",	FALSE);
			childSetEnabled("button deed",					FALSE);
		}
		else
		{
			childSetValue("checkbox share with group",		TRUE);
			childSetTentative("checkbox share with group",	TRUE);
			childSetEnabled("button deed",					gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
		}
	}			

	if (valid_everyone_perms)
	{
		// Move
		if (everyone_mask_on & PERM_MOVE)
		{
			childSetValue("checkbox allow everyone move",		TRUE);
			childSetTentative("checkbox allow everyone move", 	FALSE);
		}
		else if (everyone_mask_off & PERM_MOVE)
		{
			childSetValue("checkbox allow everyone move",		FALSE);
			childSetTentative("checkbox allow everyone move", 	FALSE);
		}
		else
		{
			childSetValue("checkbox allow everyone move",		TRUE);
			childSetTentative("checkbox allow everyone move", 	TRUE);
		}

		// Copy == everyone can't copy
		if (everyone_mask_on & PERM_COPY)
		{
			childSetValue("checkbox allow everyone copy",		TRUE);
			childSetTentative("checkbox allow everyone copy", 	!can_copy || !can_transfer);
		}
		else if (everyone_mask_off & PERM_COPY)
		{
			childSetValue("checkbox allow everyone copy",		FALSE);
			childSetTentative("checkbox allow everyone copy",	FALSE);
		}
		else
		{
			childSetValue("checkbox allow everyone copy",		TRUE);
			childSetTentative("checkbox allow everyone copy",	TRUE);
		}
	}

	if (valid_next_perms)
	{
		// Modify == next owner canot modify
		if (next_owner_mask_on & PERM_MODIFY)
		{
			childSetValue("checkbox next owner can modify",		TRUE);
			childSetTentative("checkbox next owner can modify",	FALSE);
		}
		else if (next_owner_mask_off & PERM_MODIFY)
		{
			childSetValue("checkbox next owner can modify",		FALSE);
			childSetTentative("checkbox next owner can modify",	FALSE);
		}
		else
		{
			childSetValue("checkbox next owner can modify",		TRUE);
			childSetTentative("checkbox next owner can modify",	TRUE);
		}

		// Copy == next owner cannot copy
		if (next_owner_mask_on & PERM_COPY)
		{			
			childSetValue("checkbox next owner can copy",		TRUE);
			childSetTentative("checkbox next owner can copy",	!can_copy);
		}
		else if (next_owner_mask_off & PERM_COPY)
		{
			childSetValue("checkbox next owner can copy",		FALSE);
			childSetTentative("checkbox next owner can copy",	FALSE);
		}
		else
		{
			childSetValue("checkbox next owner can copy",		TRUE);
			childSetTentative("checkbox next owner can copy",	TRUE);
		}

		// Transfer == next owner cannot transfer
		if (next_owner_mask_on & PERM_TRANSFER)
		{
			childSetValue("checkbox next owner can transfer",	TRUE);
			childSetTentative("checkbox next owner can transfer", !can_transfer);
		}
		else if (next_owner_mask_off & PERM_TRANSFER)
		{
			childSetValue("checkbox next owner can transfer",	FALSE);
			childSetTentative("checkbox next owner can transfer", FALSE);
		}
		else
		{
			childSetValue("checkbox next owner can transfer",	TRUE);
			childSetTentative("checkbox next owner can transfer", TRUE);
		}
	}

	// reflect sale information
	LLSaleInfo sale_info;
	BOOL valid_sale_info = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
	LLSaleInfo::EForSale sale_type = sale_info.getSaleType();

	LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
	if (valid_sale_info)
	{
		combo_sale_type->setValue(					sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type);
		combo_sale_type->setTentative(				FALSE); // unfortunately this doesn't do anything at the moment.
	}
	else
	{
		// default option is sell copy, determined to be safest
		combo_sale_type->setValue(					LLSaleInfo::FS_COPY);
		combo_sale_type->setTentative(				TRUE); // unfortunately this doesn't do anything at the moment.
	}

	childSetValue("checkbox for sale", (num_for_sale != 0));

	// HACK: There are some old objects in world that are set for sale,
	// but are no-transfer.  We need to let users turn for-sale off, but only
	// if for-sale is set.
	bool cannot_actually_sell = !can_transfer || (!can_copy && sale_type == LLSaleInfo::FS_COPY);
	if (cannot_actually_sell)
	{
		if (num_for_sale && has_change_sale_ability)
		{
			childSetEnabled("checkbox for sale", true);
		}
	}
	
	// Check search status of objects
	const BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
	bool include_in_search;
	const BOOL all_include_in_search = LLSelectMgr::getInstance()->selectionGetIncludeInSearch(&include_in_search);
	childSetEnabled("search_check", 				has_change_sale_ability && all_volume);
	childSetValue("search_check", 					include_in_search);
	childSetTentative("search_check", 				!all_include_in_search);

	// Click action (touch, sit, buy)
	U8 click_action = 0;
	if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action))
	{
		LLComboBox*	ComboClickAction = getChild<LLComboBox>("clickaction");
		if (ComboClickAction)
		{
			ComboClickAction->setCurrentByIndex((S32)click_action);
		}
	}
	childSetEnabled("label click action",			is_perm_modify && all_volume);
	childSetEnabled("clickaction",					is_perm_modify && all_volume);

	if (!getIsEditing())
	{
		const std::string no_item_names[] = 
			{
				"Object Name",
				"Object Description",
				"button set group",
				"checkbox share with group",
				"button deed",
				"checkbox allow everyone move",
				"checkbox allow everyone copy",
				"checkbox for sale",
				"sale type",
				"Edit Cost",
				"checkbox next owner can modify",
				"checkbox next owner can copy",
				"checkbox next owner can transfer",
				"clickaction",
				"search_check",
				"perm_modify",
				"Group Name",
			};
		for (size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t)
		{
			childSetEnabled(no_item_names[t],		FALSE);
		}
	}
	updateVerbs();
}