PageRenderTime 442ms CodeModel.GetById 40ms app.highlight 149ms RepoModel.GetById 12ms app.codeStats 1ms

/indra/newview/llpanelpermissions.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1094 lines | 838 code | 138 blank | 118 comment | 172 complexity | da356b4a2dc214506d0aa540e922b761 MD5 | raw file
   1/** 
   2 * @file llpanelpermissions.cpp
   3 * @brief LLPanelPermissions class implementation
   4 * This class represents the panel in the build view for
   5 * viewing/editing object names, owners, permissions, etc.
   6 *
   7 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
   8 * Second Life Viewer Source Code
   9 * Copyright (C) 2010, Linden Research, Inc.
  10 * 
  11 * This library is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU Lesser General Public
  13 * License as published by the Free Software Foundation;
  14 * version 2.1 of the License only.
  15 * 
  16 * This library is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 * Lesser General Public License for more details.
  20 * 
  21 * You should have received a copy of the GNU Lesser General Public
  22 * License along with this library; if not, write to the Free Software
  23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  24 * 
  25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  26 * $/LicenseInfo$
  27 */
  28
  29#include "llviewerprecompiledheaders.h"
  30
  31#include "llpanelpermissions.h"
  32
  33// library includes
  34#include "lluuid.h"
  35#include "llpermissions.h"
  36#include "llcategory.h"
  37#include "llclickaction.h"
  38#include "llfocusmgr.h"
  39#include "llnotificationsutil.h"
  40#include "llstring.h"
  41
  42// project includes
  43#include "llviewerwindow.h"
  44#include "llresmgr.h"
  45#include "lltextbox.h"
  46#include "llbutton.h"
  47#include "llcheckboxctrl.h"
  48#include "llviewerobject.h"
  49#include "llselectmgr.h"
  50#include "llagent.h"
  51#include "llstatusbar.h"		// for getBalance()
  52#include "lllineeditor.h"
  53#include "llcombobox.h"
  54#include "lluiconstants.h"
  55#include "lldbstrings.h"
  56#include "llfloatergroups.h"
  57#include "llfloaterreg.h"
  58#include "llavataractions.h"
  59#include "llnamebox.h"
  60#include "llviewercontrol.h"
  61#include "lluictrlfactory.h"
  62#include "llspinctrl.h"
  63#include "roles_constants.h"
  64#include "llgroupactions.h"
  65
  66
  67U8 string_value_to_click_action(std::string p_value);
  68std::string click_action_to_string_value( U8 action);
  69
  70U8 string_value_to_click_action(std::string p_value)
  71{
  72	if(p_value == "Touch")
  73	{
  74		return CLICK_ACTION_TOUCH;
  75	}
  76	if(p_value == "Sit")
  77	{
  78		return CLICK_ACTION_SIT;
  79	}
  80	if(p_value == "Buy")
  81	{
  82		return CLICK_ACTION_BUY;
  83	}
  84	if(p_value == "Pay")
  85	{
  86		return CLICK_ACTION_PAY;
  87	}
  88	if(p_value == "Open")
  89	{
  90		return CLICK_ACTION_OPEN;
  91	}
  92	if(p_value == "Zoom")
  93	{
  94		return CLICK_ACTION_ZOOM;
  95	}
  96	return CLICK_ACTION_TOUCH;
  97}
  98
  99std::string click_action_to_string_value( U8 action)
 100{
 101	switch (action) 
 102	{
 103		case CLICK_ACTION_TOUCH:
 104		default:	
 105			return "Touch";
 106			break;
 107		case CLICK_ACTION_SIT:
 108			return "Sit";
 109			break;
 110		case CLICK_ACTION_BUY:
 111			return "Buy";
 112			break;
 113		case CLICK_ACTION_PAY:
 114			return "Pay";
 115			break;
 116		case CLICK_ACTION_OPEN:
 117			return "Open";
 118			break;
 119		case CLICK_ACTION_ZOOM:
 120			return "Zoom";
 121			break;
 122	}
 123}
 124
 125///----------------------------------------------------------------------------
 126/// Class llpanelpermissions
 127///----------------------------------------------------------------------------
 128
 129// Default constructor
 130LLPanelPermissions::LLPanelPermissions() :
 131	LLPanel()
 132{
 133	setMouseOpaque(FALSE);
 134}
 135
 136BOOL LLPanelPermissions::postBuild()
 137{
 138	childSetCommitCallback("Object Name",LLPanelPermissions::onCommitName,this);
 139	getChild<LLLineEditor>("Object Name")->setPrevalidate(LLTextValidate::validateASCIIPrintableNoPipe);
 140	childSetCommitCallback("Object Description",LLPanelPermissions::onCommitDesc,this);
 141	getChild<LLLineEditor>("Object Description")->setPrevalidate(LLTextValidate::validateASCIIPrintableNoPipe);
 142
 143	
 144	getChild<LLUICtrl>("button set group")->setCommitCallback(boost::bind(&LLPanelPermissions::onClickGroup,this));
 145
 146	childSetCommitCallback("checkbox share with group",LLPanelPermissions::onCommitGroupShare,this);
 147
 148	childSetAction("button deed",LLPanelPermissions::onClickDeedToGroup,this);
 149
 150	childSetCommitCallback("checkbox allow everyone move",LLPanelPermissions::onCommitEveryoneMove,this);
 151
 152	childSetCommitCallback("checkbox allow everyone copy",LLPanelPermissions::onCommitEveryoneCopy,this);
 153	
 154	childSetCommitCallback("checkbox for sale",LLPanelPermissions::onCommitSaleInfo,this);
 155
 156	childSetCommitCallback("sale type",LLPanelPermissions::onCommitSaleType,this);
 157
 158	childSetCommitCallback("Edit Cost", LLPanelPermissions::onCommitSaleInfo, this);
 159	
 160	childSetCommitCallback("checkbox next owner can modify",LLPanelPermissions::onCommitNextOwnerModify,this);
 161	childSetCommitCallback("checkbox next owner can copy",LLPanelPermissions::onCommitNextOwnerCopy,this);
 162	childSetCommitCallback("checkbox next owner can transfer",LLPanelPermissions::onCommitNextOwnerTransfer,this);
 163	childSetCommitCallback("clickaction",LLPanelPermissions::onCommitClickAction,this);
 164	childSetCommitCallback("search_check",LLPanelPermissions::onCommitIncludeInSearch,this);
 165	
 166	mLabelGroupName = getChild<LLNameBox>("Group Name Proxy");
 167
 168	return TRUE;
 169}
 170
 171
 172LLPanelPermissions::~LLPanelPermissions()
 173{
 174	// base class will take care of everything
 175}
 176
 177
 178void LLPanelPermissions::disableAll()
 179{
 180	getChildView("perm_modify")->setEnabled(FALSE);
 181	getChild<LLUICtrl>("perm_modify")->setValue(LLStringUtil::null);
 182
 183	getChildView("Creator:")->setEnabled(FALSE);
 184	getChild<LLUICtrl>("Creator Name")->setValue(LLStringUtil::null);
 185	getChildView("Creator Name")->setEnabled(FALSE);
 186
 187	getChildView("Owner:")->setEnabled(FALSE);
 188	getChild<LLUICtrl>("Owner Name")->setValue(LLStringUtil::null);
 189	getChildView("Owner Name")->setEnabled(FALSE);
 190
 191	getChildView("Group:")->setEnabled(FALSE);
 192	getChild<LLUICtrl>("Group Name Proxy")->setValue(LLStringUtil::null);
 193	getChildView("Group Name Proxy")->setEnabled(FALSE);
 194	getChildView("button set group")->setEnabled(FALSE);
 195
 196	getChild<LLUICtrl>("Object Name")->setValue(LLStringUtil::null);
 197	getChildView("Object Name")->setEnabled(FALSE);
 198	getChildView("Name:")->setEnabled(FALSE);
 199	getChild<LLUICtrl>("Group Name")->setValue(LLStringUtil::null);
 200	getChildView("Group Name")->setEnabled(FALSE);
 201	getChildView("Description:")->setEnabled(FALSE);
 202	getChild<LLUICtrl>("Object Description")->setValue(LLStringUtil::null);
 203	getChildView("Object Description")->setEnabled(FALSE);
 204
 205	getChildView("Permissions:")->setEnabled(FALSE);
 206		
 207	getChild<LLUICtrl>("checkbox share with group")->setValue(FALSE);
 208	getChildView("checkbox share with group")->setEnabled(FALSE);
 209	getChildView("button deed")->setEnabled(FALSE);
 210
 211	getChild<LLUICtrl>("checkbox allow everyone move")->setValue(FALSE);
 212	getChildView("checkbox allow everyone move")->setEnabled(FALSE);
 213	getChild<LLUICtrl>("checkbox allow everyone copy")->setValue(FALSE);
 214	getChildView("checkbox allow everyone copy")->setEnabled(FALSE);
 215
 216	//Next owner can:
 217	getChildView("Next owner can:")->setEnabled(FALSE);
 218	getChild<LLUICtrl>("checkbox next owner can modify")->setValue(FALSE);
 219	getChildView("checkbox next owner can modify")->setEnabled(FALSE);
 220	getChild<LLUICtrl>("checkbox next owner can copy")->setValue(FALSE);
 221	getChildView("checkbox next owner can copy")->setEnabled(FALSE);
 222	getChild<LLUICtrl>("checkbox next owner can transfer")->setValue(FALSE);
 223	getChildView("checkbox next owner can transfer")->setEnabled(FALSE);
 224
 225	//checkbox for sale
 226	getChild<LLUICtrl>("checkbox for sale")->setValue(FALSE);
 227	getChildView("checkbox for sale")->setEnabled(FALSE);
 228
 229	//checkbox include in search
 230	getChild<LLUICtrl>("search_check")->setValue(FALSE);
 231	getChildView("search_check")->setEnabled(FALSE);
 232		
 233	LLComboBox*	combo_sale_type = getChild<LLComboBox>("sale type");
 234	combo_sale_type->setValue(LLSaleInfo::FS_COPY);
 235	combo_sale_type->setEnabled(FALSE);
 236		
 237	getChildView("Cost")->setEnabled(FALSE);
 238	getChild<LLUICtrl>("Cost")->setValue(getString("Cost Default"));
 239	getChild<LLUICtrl>("Edit Cost")->setValue(LLStringUtil::null);
 240	getChildView("Edit Cost")->setEnabled(FALSE);
 241		
 242	getChildView("label click action")->setEnabled(FALSE);
 243	LLComboBox*	combo_click_action = getChild<LLComboBox>("clickaction");
 244	if (combo_click_action)
 245	{
 246		combo_click_action->setEnabled(FALSE);
 247		combo_click_action->clear();
 248	}
 249	getChildView("B:")->setVisible(								FALSE);
 250	getChildView("O:")->setVisible(								FALSE);
 251	getChildView("G:")->setVisible(								FALSE);
 252	getChildView("E:")->setVisible(								FALSE);
 253	getChildView("N:")->setVisible(								FALSE);
 254	getChildView("F:")->setVisible(								FALSE);
 255}
 256
 257void LLPanelPermissions::refresh()
 258{
 259	LLButton*	BtnDeedToGroup = getChild<LLButton>("button deed");
 260	if(BtnDeedToGroup)
 261	{	
 262		std::string deedText;
 263		if (gWarningSettings.getBOOL("DeedObject"))
 264		{
 265			deedText = getString("text deed continued");
 266		}
 267		else
 268		{
 269			deedText = getString("text deed");
 270		}
 271		BtnDeedToGroup->setLabelSelected(deedText);
 272		BtnDeedToGroup->setLabelUnselected(deedText);
 273	}
 274	BOOL root_selected = TRUE;
 275	LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
 276	S32 object_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
 277	if(!nodep || 0 == object_count)
 278	{
 279		nodep = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
 280		object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
 281		root_selected = FALSE;
 282	}
 283
 284	//BOOL attachment_selected = LLSelectMgr::getInstance()->getSelection()->isAttachment();
 285	//attachment_selected = false;
 286	LLViewerObject* objectp = NULL;
 287	if(nodep) objectp = nodep->getObject();
 288	if(!nodep || !objectp)// || attachment_selected)
 289	{
 290		// ...nothing selected
 291		disableAll();
 292		return;
 293	}
 294
 295	// figure out a few variables
 296	const BOOL is_one_object = (object_count == 1);
 297	
 298	// BUG: fails if a root and non-root are both single-selected.
 299	BOOL is_perm_modify = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() 
 300						   && LLSelectMgr::getInstance()->selectGetRootsModify())
 301		|| LLSelectMgr::getInstance()->selectGetModify();
 302	const LLFocusableElement* keyboard_focus_view = gFocusMgr.getKeyboardFocus();
 303
 304	S32 string_index = 0;
 305	std::string MODIFY_INFO_STRINGS[] =
 306		{
 307			getString("text modify info 1"),
 308			getString("text modify info 2"),
 309			getString("text modify info 3"),
 310			getString("text modify info 4")
 311		};
 312	if (!is_perm_modify)
 313	{
 314		string_index += 2;
 315	}
 316	if (!is_one_object)
 317	{
 318		++string_index;
 319	}
 320	getChildView("perm_modify")->setEnabled(TRUE);
 321	getChild<LLUICtrl>("perm_modify")->setValue(MODIFY_INFO_STRINGS[string_index]);
 322
 323	getChildView("Permissions:")->setEnabled(TRUE);
 324	
 325	// Update creator text field
 326	getChildView("Creator:")->setEnabled(TRUE);
 327	BOOL creators_identical;
 328	std::string creator_name;
 329	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
 330																	  creator_name);
 331
 332	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
 333	getChildView("Creator Name")->setEnabled(TRUE);
 334
 335	// Update owner text field
 336	getChildView("Owner:")->setEnabled(TRUE);
 337
 338	std::string owner_name;
 339	const BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(mOwnerID, owner_name);
 340	if (mOwnerID.isNull())
 341	{
 342		if (LLSelectMgr::getInstance()->selectIsGroupOwned())
 343		{
 344			// Group owned already displayed by selectGetOwner
 345		}
 346		else
 347		{
 348			// Display last owner if public
 349			std::string last_owner_name;
 350			LLSelectMgr::getInstance()->selectGetLastOwner(mLastOwnerID, last_owner_name);
 351
 352			// It should never happen that the last owner is null and the owner
 353			// is null, but it seems to be a bug in the simulator right now. JC
 354			if (!mLastOwnerID.isNull() && !last_owner_name.empty())
 355			{
 356				owner_name.append(", last ");
 357				owner_name.append(last_owner_name);
 358			}
 359		}
 360	}
 361	getChild<LLUICtrl>("Owner Name")->setValue(owner_name);
 362	getChildView("Owner Name")->setEnabled(TRUE);
 363
 364	// update group text field
 365	getChildView("Group:")->setEnabled(TRUE);
 366	getChild<LLUICtrl>("Group Name")->setValue(LLStringUtil::null);
 367	LLUUID group_id;
 368	BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
 369	if (groups_identical)
 370	{
 371		if (mLabelGroupName)
 372		{
 373			mLabelGroupName->setNameID(group_id,TRUE);
 374			mLabelGroupName->setEnabled(TRUE);
 375		}
 376	}
 377	else
 378	{
 379		if (mLabelGroupName)
 380		{
 381			mLabelGroupName->setNameID(LLUUID::null, TRUE);
 382			mLabelGroupName->refresh(LLUUID::null, std::string(), true);
 383			mLabelGroupName->setEnabled(FALSE);
 384		}
 385	}
 386	
 387	getChildView("button set group")->setEnabled(owners_identical && (mOwnerID == gAgent.getID()));
 388
 389	getChildView("Name:")->setEnabled(TRUE);
 390	LLLineEditor* LineEditorObjectName = getChild<LLLineEditor>("Object Name");
 391	getChildView("Description:")->setEnabled(TRUE);
 392	LLLineEditor* LineEditorObjectDesc = getChild<LLLineEditor>("Object Description");
 393
 394	if (is_one_object)
 395	{
 396		if (keyboard_focus_view != LineEditorObjectName)
 397		{
 398			getChild<LLUICtrl>("Object Name")->setValue(nodep->mName);
 399		}
 400
 401		if (LineEditorObjectDesc)
 402		{
 403			if (keyboard_focus_view != LineEditorObjectDesc)
 404			{
 405				LineEditorObjectDesc->setText(nodep->mDescription);
 406			}
 407		}
 408	}
 409	else
 410	{
 411		getChild<LLUICtrl>("Object Name")->setValue(LLStringUtil::null);
 412		LineEditorObjectDesc->setText(LLStringUtil::null);
 413	}
 414
 415	// figure out the contents of the name, description, & category
 416	BOOL edit_name_desc = FALSE;
 417	if (is_one_object && objectp->permModify())
 418	{
 419		edit_name_desc = TRUE;
 420	}
 421	if (edit_name_desc)
 422	{
 423		getChildView("Object Name")->setEnabled(TRUE);
 424		getChildView("Object Description")->setEnabled(TRUE);
 425	}
 426	else
 427	{
 428		getChildView("Object Name")->setEnabled(FALSE);
 429		getChildView("Object Description")->setEnabled(FALSE);
 430	}
 431
 432	S32 total_sale_price = 0;
 433	S32 individual_sale_price = 0;
 434	BOOL is_for_sale_mixed = FALSE;
 435	BOOL is_sale_price_mixed = FALSE;
 436	U32 num_for_sale = FALSE;
 437    LLSelectMgr::getInstance()->selectGetAggregateSaleInfo(num_for_sale,
 438														   is_for_sale_mixed,
 439														   is_sale_price_mixed,
 440														   total_sale_price,
 441														   individual_sale_price);
 442
 443	const BOOL self_owned = (gAgent.getID() == mOwnerID);
 444	const BOOL group_owned = LLSelectMgr::getInstance()->selectIsGroupOwned() ;
 445	const BOOL public_owned = (mOwnerID.isNull() && !LLSelectMgr::getInstance()->selectIsGroupOwned());
 446	const BOOL can_transfer = LLSelectMgr::getInstance()->selectGetRootsTransfer();
 447	const BOOL can_copy = LLSelectMgr::getInstance()->selectGetRootsCopy();
 448
 449	if (!owners_identical)
 450	{
 451		getChildView("Cost")->setEnabled(FALSE);
 452		getChild<LLUICtrl>("Edit Cost")->setValue(LLStringUtil::null);
 453		getChildView("Edit Cost")->setEnabled(FALSE);
 454	}
 455	// You own these objects.
 456	else if (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id,GP_OBJECT_SET_SALE)))
 457	{
 458		// If there are multiple items for sale then set text to PRICE PER UNIT.
 459		if (num_for_sale > 1)
 460		{
 461			getChild<LLUICtrl>("Cost")->setValue(getString("Cost Per Unit"));
 462		}
 463		else
 464		{
 465			getChild<LLUICtrl>("Cost")->setValue(getString("Cost Default"));
 466		}
 467		
 468		LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
 469		if (!edit_price->hasFocus())
 470		{
 471			// If the sale price is mixed then set the cost to MIXED, otherwise
 472			// set to the actual cost.
 473			if ((num_for_sale > 0) && is_for_sale_mixed)
 474			{
 475				edit_price->setTentative(TRUE);
 476			}
 477			else if ((num_for_sale > 0) && is_sale_price_mixed)
 478			{
 479				edit_price->setTentative(TRUE);
 480			}
 481			else 
 482			{
 483				edit_price->setValue(individual_sale_price);
 484			}
 485		}
 486		// The edit fields are only enabled if you can sell this object
 487		// and the sale price is not mixed.
 488		BOOL enable_edit = (num_for_sale && can_transfer) ? !is_for_sale_mixed : FALSE;
 489		getChildView("Cost")->setEnabled(enable_edit);
 490		getChildView("Edit Cost")->setEnabled(enable_edit);
 491	}
 492	// Someone, not you, owns these objects.
 493	else if (!public_owned)
 494	{
 495		getChildView("Cost")->setEnabled(FALSE);
 496		getChildView("Edit Cost")->setEnabled(FALSE);
 497		
 498		// Don't show a price if none of the items are for sale.
 499		if (num_for_sale)
 500			getChild<LLUICtrl>("Edit Cost")->setValue(llformat("%d",total_sale_price));
 501		else
 502			getChild<LLUICtrl>("Edit Cost")->setValue(LLStringUtil::null);
 503
 504		// If multiple items are for sale, set text to TOTAL PRICE.
 505		if (num_for_sale > 1)
 506			getChild<LLUICtrl>("Cost")->setValue(getString("Cost Total"));
 507		else
 508			getChild<LLUICtrl>("Cost")->setValue(getString("Cost Default"));
 509	}
 510	// This is a public object.
 511	else
 512	{
 513		getChildView("Cost")->setEnabled(FALSE);
 514		getChild<LLUICtrl>("Cost")->setValue(getString("Cost Default"));
 515		
 516		getChild<LLUICtrl>("Edit Cost")->setValue(LLStringUtil::null);
 517		getChildView("Edit Cost")->setEnabled(FALSE);
 518	}
 519
 520	// Enable and disable the permissions checkboxes
 521	// based on who owns the object.
 522	// TODO: Creator permissions
 523
 524	U32 base_mask_on 			= 0;
 525	U32 base_mask_off		 	= 0;
 526	U32 owner_mask_off			= 0;
 527	U32 owner_mask_on 			= 0;
 528	U32 group_mask_on 			= 0;
 529	U32 group_mask_off 			= 0;
 530	U32 everyone_mask_on 		= 0;
 531	U32 everyone_mask_off 		= 0;
 532	U32 next_owner_mask_on 		= 0;
 533	U32 next_owner_mask_off		= 0;
 534
 535	BOOL valid_base_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_BASE,
 536																			&base_mask_on,
 537																			&base_mask_off);
 538	//BOOL valid_owner_perms =//
 539	LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
 540											  &owner_mask_on,
 541											  &owner_mask_off);
 542	BOOL valid_group_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
 543																			&group_mask_on,
 544																			&group_mask_off);
 545	
 546	BOOL valid_everyone_perms 	= LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
 547																			&everyone_mask_on,
 548																			&everyone_mask_off);
 549	
 550	BOOL valid_next_perms 		= LLSelectMgr::getInstance()->selectGetPerm(PERM_NEXT_OWNER,
 551																			&next_owner_mask_on,
 552																			&next_owner_mask_off);
 553
 554	
 555	if (gSavedSettings.getBOOL("DebugPermissions") )
 556	{
 557		if (valid_base_perms)
 558		{
 559			getChild<LLUICtrl>("B:")->setValue("B: " + mask_to_string(base_mask_on));
 560			getChildView("B:")->setVisible(							TRUE);
 561			
 562			getChild<LLUICtrl>("O:")->setValue("O: " + mask_to_string(owner_mask_on));
 563			getChildView("O:")->setVisible(							TRUE);
 564			
 565			getChild<LLUICtrl>("G:")->setValue("G: " + mask_to_string(group_mask_on));
 566			getChildView("G:")->setVisible(							TRUE);
 567			
 568			getChild<LLUICtrl>("E:")->setValue("E: " + mask_to_string(everyone_mask_on));
 569			getChildView("E:")->setVisible(							TRUE);
 570			
 571			getChild<LLUICtrl>("N:")->setValue("N: " + mask_to_string(next_owner_mask_on));
 572			getChildView("N:")->setVisible(							TRUE);
 573		}
 574
 575		U32 flag_mask = 0x0;
 576		if (objectp->permMove()) 		flag_mask |= PERM_MOVE;
 577		if (objectp->permModify()) 		flag_mask |= PERM_MODIFY;
 578		if (objectp->permCopy()) 		flag_mask |= PERM_COPY;
 579		if (objectp->permTransfer()) 	flag_mask |= PERM_TRANSFER;
 580
 581		getChild<LLUICtrl>("F:")->setValue("F:" + mask_to_string(flag_mask));
 582		getChildView("F:")->setVisible(								TRUE);
 583	}
 584	else
 585	{
 586		getChildView("B:")->setVisible(								FALSE);
 587		getChildView("O:")->setVisible(								FALSE);
 588		getChildView("G:")->setVisible(								FALSE);
 589		getChildView("E:")->setVisible(								FALSE);
 590		getChildView("N:")->setVisible(								FALSE);
 591		getChildView("F:")->setVisible(								FALSE);
 592	}
 593
 594	BOOL has_change_perm_ability = FALSE;
 595	BOOL has_change_sale_ability = FALSE;
 596
 597	if (valid_base_perms &&
 598		(self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_MANIPULATE))))
 599	{
 600		has_change_perm_ability = TRUE;
 601	}
 602	if (valid_base_perms &&
 603	   (self_owned || (group_owned && gAgent.hasPowerInGroup(group_id, GP_OBJECT_SET_SALE))))
 604	{
 605		has_change_sale_ability = TRUE;
 606	}
 607
 608	if (!has_change_perm_ability && !has_change_sale_ability && !root_selected)
 609	{
 610		// ...must select root to choose permissions
 611		getChild<LLUICtrl>("perm_modify")->setValue(getString("text modify warning"));
 612	}
 613
 614	if (has_change_perm_ability)
 615	{
 616		getChildView("checkbox share with group")->setEnabled(TRUE);
 617		getChildView("checkbox allow everyone move")->setEnabled(owner_mask_on & PERM_MOVE);
 618		getChildView("checkbox allow everyone copy")->setEnabled(owner_mask_on & PERM_COPY && owner_mask_on & PERM_TRANSFER);
 619	}
 620	else
 621	{
 622		getChildView("checkbox share with group")->setEnabled(FALSE);
 623		getChildView("checkbox allow everyone move")->setEnabled(FALSE);
 624		getChildView("checkbox allow everyone copy")->setEnabled(FALSE);
 625	}
 626
 627	if (has_change_sale_ability && (owner_mask_on & PERM_TRANSFER))
 628	{
 629		getChildView("checkbox for sale")->setEnabled(can_transfer || (!can_transfer && num_for_sale));
 630		// Set the checkbox to tentative if the prices of each object selected
 631		// are not the same.
 632		getChild<LLUICtrl>("checkbox for sale")->setTentative( 				is_for_sale_mixed);
 633		getChildView("sale type")->setEnabled(num_for_sale && can_transfer && !is_sale_price_mixed);
 634
 635		getChildView("Next owner can:")->setEnabled(TRUE);
 636		getChildView("checkbox next owner can modify")->setEnabled(base_mask_on & PERM_MODIFY);
 637		getChildView("checkbox next owner can copy")->setEnabled(base_mask_on & PERM_COPY);
 638		getChildView("checkbox next owner can transfer")->setEnabled(next_owner_mask_on & PERM_COPY);
 639	}
 640	else 
 641	{
 642		getChildView("checkbox for sale")->setEnabled(FALSE);
 643		getChildView("sale type")->setEnabled(FALSE);
 644
 645		getChildView("Next owner can:")->setEnabled(FALSE);
 646		getChildView("checkbox next owner can modify")->setEnabled(FALSE);
 647		getChildView("checkbox next owner can copy")->setEnabled(FALSE);
 648		getChildView("checkbox next owner can transfer")->setEnabled(FALSE);
 649	}
 650
 651	if (valid_group_perms)
 652	{
 653		if ((group_mask_on & PERM_COPY) && (group_mask_on & PERM_MODIFY) && (group_mask_on & PERM_MOVE))
 654		{
 655			getChild<LLUICtrl>("checkbox share with group")->setValue(TRUE);
 656			getChild<LLUICtrl>("checkbox share with group")->setTentative(	FALSE);
 657			getChildView("button deed")->setEnabled(gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
 658		}
 659		else if ((group_mask_off & PERM_COPY) && (group_mask_off & PERM_MODIFY) && (group_mask_off & PERM_MOVE))
 660		{
 661			getChild<LLUICtrl>("checkbox share with group")->setValue(FALSE);
 662			getChild<LLUICtrl>("checkbox share with group")->setTentative(	FALSE);
 663			getChildView("button deed")->setEnabled(FALSE);
 664		}
 665		else
 666		{
 667			getChild<LLUICtrl>("checkbox share with group")->setValue(TRUE);
 668			getChild<LLUICtrl>("checkbox share with group")->setTentative(	TRUE);
 669			getChildView("button deed")->setEnabled(gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && (group_mask_on & PERM_MOVE) && (owner_mask_on & PERM_TRANSFER) && !group_owned && can_transfer);
 670		}
 671	}			
 672
 673	if (valid_everyone_perms)
 674	{
 675		// Move
 676		if (everyone_mask_on & PERM_MOVE)
 677		{
 678			getChild<LLUICtrl>("checkbox allow everyone move")->setValue(TRUE);
 679			getChild<LLUICtrl>("checkbox allow everyone move")->setTentative( 	FALSE);
 680		}
 681		else if (everyone_mask_off & PERM_MOVE)
 682		{
 683			getChild<LLUICtrl>("checkbox allow everyone move")->setValue(FALSE);
 684			getChild<LLUICtrl>("checkbox allow everyone move")->setTentative( 	FALSE);
 685		}
 686		else
 687		{
 688			getChild<LLUICtrl>("checkbox allow everyone move")->setValue(TRUE);
 689			getChild<LLUICtrl>("checkbox allow everyone move")->setTentative( 	TRUE);
 690		}
 691
 692		// Copy == everyone can't copy
 693		if (everyone_mask_on & PERM_COPY)
 694		{
 695			getChild<LLUICtrl>("checkbox allow everyone copy")->setValue(TRUE);
 696			getChild<LLUICtrl>("checkbox allow everyone copy")->setTentative( 	!can_copy || !can_transfer);
 697		}
 698		else if (everyone_mask_off & PERM_COPY)
 699		{
 700			getChild<LLUICtrl>("checkbox allow everyone copy")->setValue(FALSE);
 701			getChild<LLUICtrl>("checkbox allow everyone copy")->setTentative(	FALSE);
 702		}
 703		else
 704		{
 705			getChild<LLUICtrl>("checkbox allow everyone copy")->setValue(TRUE);
 706			getChild<LLUICtrl>("checkbox allow everyone copy")->setTentative(	TRUE);
 707		}
 708	}
 709
 710	if (valid_next_perms)
 711	{
 712		// Modify == next owner canot modify
 713		if (next_owner_mask_on & PERM_MODIFY)
 714		{
 715			getChild<LLUICtrl>("checkbox next owner can modify")->setValue(TRUE);
 716			getChild<LLUICtrl>("checkbox next owner can modify")->setTentative(	FALSE);
 717		}
 718		else if (next_owner_mask_off & PERM_MODIFY)
 719		{
 720			getChild<LLUICtrl>("checkbox next owner can modify")->setValue(FALSE);
 721			getChild<LLUICtrl>("checkbox next owner can modify")->setTentative(	FALSE);
 722		}
 723		else
 724		{
 725			getChild<LLUICtrl>("checkbox next owner can modify")->setValue(TRUE);
 726			getChild<LLUICtrl>("checkbox next owner can modify")->setTentative(	TRUE);
 727		}
 728
 729		// Copy == next owner cannot copy
 730		if (next_owner_mask_on & PERM_COPY)
 731		{			
 732			getChild<LLUICtrl>("checkbox next owner can copy")->setValue(TRUE);
 733			getChild<LLUICtrl>("checkbox next owner can copy")->setTentative(	!can_copy);
 734		}
 735		else if (next_owner_mask_off & PERM_COPY)
 736		{
 737			getChild<LLUICtrl>("checkbox next owner can copy")->setValue(FALSE);
 738			getChild<LLUICtrl>("checkbox next owner can copy")->setTentative(	FALSE);
 739		}
 740		else
 741		{
 742			getChild<LLUICtrl>("checkbox next owner can copy")->setValue(TRUE);
 743			getChild<LLUICtrl>("checkbox next owner can copy")->setTentative(	TRUE);
 744		}
 745
 746		// Transfer == next owner cannot transfer
 747		if (next_owner_mask_on & PERM_TRANSFER)
 748		{
 749			getChild<LLUICtrl>("checkbox next owner can transfer")->setValue(TRUE);
 750			getChild<LLUICtrl>("checkbox next owner can transfer")->setTentative( !can_transfer);
 751		}
 752		else if (next_owner_mask_off & PERM_TRANSFER)
 753		{
 754			getChild<LLUICtrl>("checkbox next owner can transfer")->setValue(FALSE);
 755			getChild<LLUICtrl>("checkbox next owner can transfer")->setTentative( FALSE);
 756		}
 757		else
 758		{
 759			getChild<LLUICtrl>("checkbox next owner can transfer")->setValue(TRUE);
 760			getChild<LLUICtrl>("checkbox next owner can transfer")->setTentative( TRUE);
 761		}
 762	}
 763
 764	// reflect sale information
 765	LLSaleInfo sale_info;
 766	BOOL valid_sale_info = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
 767	LLSaleInfo::EForSale sale_type = sale_info.getSaleType();
 768
 769	LLComboBox* combo_sale_type = getChild<LLComboBox>("sale type");
 770	if (valid_sale_info)
 771	{
 772		combo_sale_type->setValue(					sale_type == LLSaleInfo::FS_NOT ? LLSaleInfo::FS_COPY : sale_type);
 773		combo_sale_type->setTentative(				FALSE); // unfortunately this doesn't do anything at the moment.
 774	}
 775	else
 776	{
 777		// default option is sell copy, determined to be safest
 778		combo_sale_type->setValue(					LLSaleInfo::FS_COPY);
 779		combo_sale_type->setTentative(				TRUE); // unfortunately this doesn't do anything at the moment.
 780	}
 781
 782	getChild<LLUICtrl>("checkbox for sale")->setValue((num_for_sale != 0));
 783
 784	// HACK: There are some old objects in world that are set for sale,
 785	// but are no-transfer.  We need to let users turn for-sale off, but only
 786	// if for-sale is set.
 787	bool cannot_actually_sell = !can_transfer || (!can_copy && sale_type == LLSaleInfo::FS_COPY);
 788	if (cannot_actually_sell)
 789	{
 790		if (num_for_sale && has_change_sale_ability)
 791		{
 792			getChildView("checkbox for sale")->setEnabled(true);
 793		}
 794	}
 795	
 796	// Check search status of objects
 797	const BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
 798	bool include_in_search;
 799	const BOOL all_include_in_search = LLSelectMgr::getInstance()->selectionGetIncludeInSearch(&include_in_search);
 800	getChildView("search_check")->setEnabled(has_change_sale_ability && all_volume);
 801	getChild<LLUICtrl>("search_check")->setValue(include_in_search);
 802	getChild<LLUICtrl>("search_check")->setTentative( 				!all_include_in_search);
 803
 804	// Click action (touch, sit, buy)
 805	U8 click_action = 0;
 806	if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action))
 807	{
 808		LLComboBox*	combo_click_action = getChild<LLComboBox>("clickaction");
 809		if(combo_click_action)
 810		{
 811			const std::string combo_value = click_action_to_string_value(click_action);
 812			combo_click_action->setValue(LLSD(combo_value));
 813		}
 814	}
 815	getChildView("label click action")->setEnabled(is_perm_modify && all_volume);
 816	getChildView("clickaction")->setEnabled(is_perm_modify && all_volume);
 817}
 818
 819
 820// static
 821void LLPanelPermissions::onClickClaim(void*)
 822{
 823	// try to claim ownership
 824	LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID());
 825}
 826
 827// static
 828void LLPanelPermissions::onClickRelease(void*)
 829{
 830	// try to release ownership
 831	LLSelectMgr::getInstance()->sendOwner(LLUUID::null, LLUUID::null);
 832}
 833
 834void LLPanelPermissions::onClickGroup()
 835{
 836	LLUUID owner_id;
 837	std::string name;
 838	BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, name);
 839	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
 840
 841	if(owners_identical && (owner_id == gAgent.getID()))
 842	{
 843		LLFloaterGroupPicker* fg = 	LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID()));
 844		if (fg)
 845		{
 846			fg->setSelectGroupCallback( boost::bind(&LLPanelPermissions::cbGroupID, this, _1) );
 847
 848			if (parent_floater)
 849			{
 850				LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, fg);
 851				fg->setOrigin(new_rect.mLeft, new_rect.mBottom);
 852				parent_floater->addDependentFloater(fg);
 853			}
 854		}
 855	}
 856}
 857
 858void LLPanelPermissions::cbGroupID(LLUUID group_id)
 859{
 860	if(mLabelGroupName)
 861	{
 862		mLabelGroupName->setNameID(group_id, TRUE);
 863	}
 864	LLSelectMgr::getInstance()->sendGroup(group_id);
 865}
 866
 867bool callback_deed_to_group(const LLSD& notification, const LLSD& response)
 868{
 869	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 870	if (0 == option)
 871	{
 872		LLUUID group_id;
 873		BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
 874		if(group_id.notNull() && groups_identical && (gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED)))
 875		{
 876			LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE);
 877//			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
 878		}
 879	}
 880	return false;
 881}
 882
 883void LLPanelPermissions::onClickDeedToGroup(void* data)
 884{
 885	LLNotificationsUtil::add( "DeedObjectToGroup", LLSD(), LLSD(), callback_deed_to_group);
 886}
 887
 888///----------------------------------------------------------------------------
 889/// Permissions checkboxes
 890///----------------------------------------------------------------------------
 891
 892// static
 893void LLPanelPermissions::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32 perm)
 894{
 895	LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
 896	if(!object) return;
 897
 898	// Checkbox will have toggled itself
 899	// LLPanelPermissions* self = (LLPanelPermissions*)data;
 900	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 901	BOOL new_state = check->get();
 902	
 903	LLSelectMgr::getInstance()->selectionSetObjectPermissions(field, new_state, perm);
 904}
 905
 906// static
 907void LLPanelPermissions::onCommitGroupShare(LLUICtrl *ctrl, void *data)
 908{
 909	onCommitPerm(ctrl, data, PERM_GROUP, PERM_MODIFY | PERM_MOVE | PERM_COPY);
 910}
 911
 912// static
 913void LLPanelPermissions::onCommitEveryoneMove(LLUICtrl *ctrl, void *data)
 914{
 915	onCommitPerm(ctrl, data, PERM_EVERYONE, PERM_MOVE);
 916}
 917
 918
 919// static
 920void LLPanelPermissions::onCommitEveryoneCopy(LLUICtrl *ctrl, void *data)
 921{
 922	onCommitPerm(ctrl, data, PERM_EVERYONE, PERM_COPY);
 923}
 924
 925// static
 926void LLPanelPermissions::onCommitNextOwnerModify(LLUICtrl* ctrl, void* data)
 927{
 928	//llinfos << "LLPanelPermissions::onCommitNextOwnerModify" << llendl;
 929	onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_MODIFY);
 930}
 931
 932// static
 933void LLPanelPermissions::onCommitNextOwnerCopy(LLUICtrl* ctrl, void* data)
 934{
 935	//llinfos << "LLPanelPermissions::onCommitNextOwnerCopy" << llendl;
 936	onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_COPY);
 937}
 938
 939// static
 940void LLPanelPermissions::onCommitNextOwnerTransfer(LLUICtrl* ctrl, void* data)
 941{
 942	//llinfos << "LLPanelPermissions::onCommitNextOwnerTransfer" << llendl;
 943	onCommitPerm(ctrl, data, PERM_NEXT_OWNER, PERM_TRANSFER);
 944}
 945
 946// static
 947void LLPanelPermissions::onCommitName(LLUICtrl*, void* data)
 948{
 949	//llinfos << "LLPanelPermissions::onCommitName()" << llendl;
 950	LLPanelPermissions* self = (LLPanelPermissions*)data;
 951	LLLineEditor*	tb = self->getChild<LLLineEditor>("Object Name");
 952	if(tb)
 953	{
 954		LLSelectMgr::getInstance()->selectionSetObjectName(tb->getText());
 955//		LLSelectMgr::getInstance()->selectionSetObjectName(self->mLabelObjectName->getText());
 956	}
 957}
 958
 959
 960// static
 961void LLPanelPermissions::onCommitDesc(LLUICtrl*, void* data)
 962{
 963	//llinfos << "LLPanelPermissions::onCommitDesc()" << llendl;
 964	LLPanelPermissions* self = (LLPanelPermissions*)data;
 965	LLLineEditor*	le = self->getChild<LLLineEditor>("Object Description");
 966	if(le)
 967	{
 968		LLSelectMgr::getInstance()->selectionSetObjectDescription(le->getText());
 969	}
 970}
 971
 972// static
 973void LLPanelPermissions::onCommitSaleInfo(LLUICtrl*, void* data)
 974{
 975	LLPanelPermissions* self = (LLPanelPermissions*)data;
 976	self->setAllSaleInfo();
 977}
 978
 979// static
 980void LLPanelPermissions::onCommitSaleType(LLUICtrl*, void* data)
 981{
 982	LLPanelPermissions* self = (LLPanelPermissions*)data;
 983	self->setAllSaleInfo();
 984}
 985
 986void LLPanelPermissions::setAllSaleInfo()
 987{
 988	llinfos << "LLPanelPermissions::setAllSaleInfo()" << llendl;
 989	LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_NOT;
 990
 991	LLCheckBoxCtrl *checkPurchase = getChild<LLCheckBoxCtrl>("checkbox for sale");
 992	
 993	// Set the sale type if the object(s) are for sale.
 994	if(checkPurchase && checkPurchase->get())
 995	{
 996		sale_type = static_cast<LLSaleInfo::EForSale>(getChild<LLComboBox>("sale type")->getValue().asInteger());
 997	}
 998
 999	S32 price = -1;
1000	
1001	LLSpinCtrl *edit_price = getChild<LLSpinCtrl>("Edit Cost");
1002	price = (edit_price->getTentative()) ? DEFAULT_PRICE : edit_price->getValue().asInteger();
1003
1004	// If somehow an invalid price, turn the sale off.
1005	if (price < 0)
1006		sale_type = LLSaleInfo::FS_NOT;
1007
1008	LLSaleInfo old_sale_info;
1009	LLSelectMgr::getInstance()->selectGetSaleInfo(old_sale_info);
1010
1011	LLSaleInfo new_sale_info(sale_type, price);
1012	LLSelectMgr::getInstance()->selectionSetObjectSaleInfo(new_sale_info);
1013	
1014	U8 old_click_action = 0;
1015	LLSelectMgr::getInstance()->selectionGetClickAction(&old_click_action);
1016
1017	if (old_sale_info.isForSale()
1018		&& !new_sale_info.isForSale()
1019		&& old_click_action == CLICK_ACTION_BUY)
1020	{
1021		// If turned off for-sale, make sure click-action buy is turned
1022		// off as well
1023		LLSelectMgr::getInstance()->
1024			selectionSetClickAction(CLICK_ACTION_TOUCH);
1025	}
1026	else if (new_sale_info.isForSale()
1027		&& !old_sale_info.isForSale()
1028		&& old_click_action == CLICK_ACTION_TOUCH)
1029	{
1030		// If just turning on for-sale, preemptively turn on one-click buy
1031		// unless user have a different click action set
1032		LLSelectMgr::getInstance()->
1033			selectionSetClickAction(CLICK_ACTION_BUY);
1034	}
1035}
1036
1037struct LLSelectionPayable : public LLSelectedObjectFunctor
1038{
1039	virtual bool apply(LLViewerObject* obj)
1040	{
1041		// can pay if you or your parent has money() event in script
1042		LLViewerObject* parent = (LLViewerObject*)obj->getParent();
1043		return (obj->flagTakesMoney() 
1044			   || (parent && parent->flagTakesMoney()));
1045	}
1046};
1047
1048// static
1049void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*)
1050{
1051	LLComboBox* box = (LLComboBox*)ctrl;
1052	if (!box) return;
1053	std::string value = box->getValue().asString();
1054	U8 click_action = string_value_to_click_action(value);
1055	
1056	if (click_action == CLICK_ACTION_BUY)
1057	{
1058		LLSaleInfo sale_info;
1059		LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
1060		if (!sale_info.isForSale())
1061		{
1062			LLNotificationsUtil::add("CantSetBuyObject");
1063
1064			// Set click action back to its old value
1065			U8 click_action = 0;
1066			LLSelectMgr::getInstance()->selectionGetClickAction(&click_action);
1067			std::string item_value = click_action_to_string_value(click_action);
1068			box->setValue(LLSD(item_value));
1069			return;
1070		}
1071	}
1072	else if (click_action == CLICK_ACTION_PAY)
1073	{
1074		// Verify object has script with money() handler
1075		LLSelectionPayable payable;
1076		bool can_pay = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&payable);
1077		if (!can_pay)
1078		{
1079			// Warn, but do it anyway.
1080			LLNotificationsUtil::add("ClickActionNotPayable");
1081		}
1082	}
1083	LLSelectMgr::getInstance()->selectionSetClickAction(click_action);
1084}
1085
1086// static
1087void LLPanelPermissions::onCommitIncludeInSearch(LLUICtrl* ctrl, void*)
1088{
1089	LLCheckBoxCtrl* box = (LLCheckBoxCtrl*)ctrl;
1090	llassert(box);
1091
1092	LLSelectMgr::getInstance()->selectionSetIncludeInSearch(box->get());
1093}
1094