PageRenderTime 65ms CodeModel.GetById 9ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llselectmgr.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 866 lines | 599 code | 140 blank | 127 comment | 27 complexity | 09e7fd96c5cdde594cbd6b688e6ea8ef MD5 | raw file
  1/** 
  2 * @file llselectmgr.h
  3 * @brief A manager for selected objects and TEs.
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLSELECTMGR_H
 28#define LL_LLSELECTMGR_H
 29
 30#include "llcharacter.h"
 31#include "lleditmenuhandler.h"
 32#include "llundo.h"
 33#include "lluuid.h"
 34#include "llpointer.h"
 35#include "llsafehandle.h"
 36#include "llsaleinfo.h"
 37#include "llcategory.h"
 38#include "v3dmath.h"
 39#include "llquaternion.h"
 40#include "llcoord.h"
 41#include "llframetimer.h"
 42#include "llbbox.h"
 43#include "llpermissions.h"
 44#include "llcontrol.h"
 45#include "llviewerobject.h"	// LLObjectSelection::getSelectedTEValue template
 46
 47#include <deque>
 48#include <boost/iterator/filter_iterator.hpp>
 49#include <boost/signals2.hpp>
 50
 51class LLMessageSystem;
 52class LLViewerTexture;
 53class LLColor4;
 54class LLVector3;
 55class LLSelectNode;
 56
 57const S32 SELECT_ALL_TES = -1;
 58const S32 SELECT_MAX_TES = 32;
 59
 60// Do something to all objects in the selection manager.
 61// The BOOL return value can be used to indicate if all
 62// objects are identical (gathering information) or if
 63// the operation was successful.
 64struct LLSelectedObjectFunctor
 65{
 66	virtual ~LLSelectedObjectFunctor() {};
 67	virtual bool apply(LLViewerObject* object) = 0;
 68};
 69
 70// Do something to all select nodes in the selection manager.
 71// The BOOL return value can be used to indicate if all
 72// objects are identical (gathering information) or if
 73// the operation was successful.
 74struct LLSelectedNodeFunctor
 75{
 76	virtual ~LLSelectedNodeFunctor() {};
 77	virtual bool apply(LLSelectNode* node) = 0;
 78};
 79
 80struct LLSelectedTEFunctor
 81{
 82	virtual ~LLSelectedTEFunctor() {};
 83	virtual bool apply(LLViewerObject* object, S32 face) = 0;
 84};
 85
 86template <typename T> struct LLSelectedTEGetFunctor
 87{
 88	virtual ~LLSelectedTEGetFunctor() {};
 89	virtual T get(LLViewerObject* object, S32 te) = 0;
 90};
 91
 92typedef enum e_send_type
 93{
 94	SEND_ONLY_ROOTS,
 95	SEND_INDIVIDUALS,
 96	SEND_ROOTS_FIRST, // useful for serial undos on linked sets
 97	SEND_CHILDREN_FIRST // useful for serial transforms of linked sets
 98} ESendType;
 99
100typedef enum e_grid_mode
101{
102	GRID_MODE_WORLD,
103	GRID_MODE_LOCAL,
104	GRID_MODE_REF_OBJECT
105} EGridMode;
106
107typedef enum e_action_type
108{
109	SELECT_ACTION_TYPE_BEGIN,
110	SELECT_ACTION_TYPE_PICK,
111	SELECT_ACTION_TYPE_MOVE,
112	SELECT_ACTION_TYPE_ROTATE,
113	SELECT_ACTION_TYPE_SCALE,
114	NUM_ACTION_TYPES
115}EActionType;
116
117typedef enum e_selection_type
118{
119	SELECT_TYPE_WORLD,
120	SELECT_TYPE_ATTACHMENT,
121	SELECT_TYPE_HUD
122}ESelectType;
123
124// Contains information about a selected object, particularly which TEs are selected.
125class LLSelectNode
126{
127public:
128	LLSelectNode(LLViewerObject* object, BOOL do_glow);
129	LLSelectNode(const LLSelectNode& nodep);
130	~LLSelectNode();
131
132	void selectAllTEs(BOOL b);
133	void selectTE(S32 te_index, BOOL selected);
134	BOOL isTESelected(S32 te_index);
135	S32 getLastSelectedTE();
136	S32 getTESelectMask() { return mTESelectMask; }
137	void renderOneWireframe(const LLColor4& color);
138	void renderOneSilhouette(const LLColor4 &color);
139	void setTransient(BOOL transient) { mTransient = transient; }
140	BOOL isTransient() { return mTransient; }
141	LLViewerObject* getObject();
142	void setObject(LLViewerObject* object);
143	// *NOTE: invalidate stored textures and colors when # faces change
144	void saveColors();
145	void saveTextures(const uuid_vec_t& textures);
146	void saveTextureScaleRatios();
147
148	BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
149
150public:
151	BOOL			mIndividualSelection;		// For root objects and objects individually selected
152
153	BOOL			mTransient;
154	BOOL			mValid;				// is extra information valid?
155	LLPermissions*	mPermissions;
156	LLSaleInfo		mSaleInfo;
157	LLAggregatePermissions mAggregatePerm;
158	LLAggregatePermissions mAggregateTexturePerm;
159	LLAggregatePermissions mAggregateTexturePermOwner;
160	std::string		mName;
161	std::string		mDescription;
162	LLCategory		mCategory;
163	S16				mInventorySerial;
164	LLVector3		mSavedPositionLocal;	// for interactively modifying object position
165	LLVector3		mLastPositionLocal;
166	LLVector3d		mSavedPositionGlobal;	// for interactively modifying object position
167	LLVector3		mSavedScale;			// for interactively modifying object scale
168	LLVector3		mLastScale;
169	LLQuaternion	mSavedRotation;			// for interactively modifying object rotation
170	LLQuaternion	mLastRotation;
171	BOOL			mDuplicated;
172	LLVector3d		mDuplicatePos;
173	LLQuaternion	mDuplicateRot;
174	LLUUID			mItemID;
175	LLUUID			mFolderID;
176	LLUUID			mFromTaskID;
177	std::string		mTouchName;
178	std::string		mSitName;
179	U64				mCreationDate;
180	std::vector<LLColor4>	mSavedColors;
181	uuid_vec_t		mSavedTextures;
182	std::vector<LLVector3>  mTextureScaleRatios;
183	std::vector<LLVector3>	mSilhouetteVertices;	// array of vertices to render silhouette of object
184	std::vector<LLVector3>	mSilhouetteNormals;	// array of normals to render silhouette of object
185	BOOL					mSilhouetteExists;	// need to generate silhouette?
186
187protected:
188	LLPointer<LLViewerObject>	mObject;
189	S32				mTESelectMask;
190	S32				mLastTESelected;
191};
192
193class LLObjectSelection : public LLRefCount
194{
195	friend class LLSelectMgr;
196
197protected:
198	~LLObjectSelection();
199
200public:
201	typedef std::list<LLSelectNode*> list_t;
202
203	// Iterators
204	struct is_non_null
205	{
206		bool operator()(LLSelectNode* node)
207		{
208			return (node->getObject() != NULL);
209		}
210	};
211	typedef boost::filter_iterator<is_non_null, list_t::iterator > iterator;
212	iterator begin() { return iterator(mList.begin(), mList.end()); }
213	iterator end() { return iterator(mList.end(), mList.end()); }
214
215	struct is_valid
216	{
217		bool operator()(LLSelectNode* node)
218		{
219			return (node->getObject() != NULL) && node->mValid;
220		}
221	};
222	typedef boost::filter_iterator<is_valid, list_t::iterator > valid_iterator;
223	valid_iterator valid_begin() { return valid_iterator(mList.begin(), mList.end()); }
224	valid_iterator valid_end() { return valid_iterator(mList.end(), mList.end()); }
225
226	struct is_root
227	{
228		bool operator()(LLSelectNode* node);
229	};
230	typedef boost::filter_iterator<is_root, list_t::iterator > root_iterator;
231	root_iterator root_begin() { return root_iterator(mList.begin(), mList.end()); }
232	root_iterator root_end() { return root_iterator(mList.end(), mList.end()); }
233	
234	struct is_valid_root
235	{
236		bool operator()(LLSelectNode* node);
237	};
238	typedef boost::filter_iterator<is_valid_root, list_t::iterator > valid_root_iterator;
239	valid_root_iterator valid_root_begin() { return valid_root_iterator(mList.begin(), mList.end()); }
240	valid_root_iterator valid_root_end() { return valid_root_iterator(mList.end(), mList.end()); }
241	
242	struct is_root_object
243	{
244		bool operator()(LLSelectNode* node);
245	};
246	typedef boost::filter_iterator<is_root_object, list_t::iterator > root_object_iterator;
247	root_object_iterator root_object_begin() { return root_object_iterator(mList.begin(), mList.end()); }
248	root_object_iterator root_object_end() { return root_object_iterator(mList.end(), mList.end()); }
249	
250public:
251	LLObjectSelection();
252
253	void updateEffects();
254
255	BOOL isEmpty() const;
256
257	LLSelectNode*	getFirstNode(LLSelectedNodeFunctor* func = NULL);
258	LLSelectNode*	getFirstRootNode(LLSelectedNodeFunctor* func = NULL, BOOL non_root_ok = FALSE);
259	LLViewerObject* getFirstSelectedObject(LLSelectedNodeFunctor* func, BOOL get_parent = FALSE);
260	LLViewerObject*	getFirstObject();
261	LLViewerObject*	getFirstRootObject(BOOL non_root_ok = FALSE);
262	
263	LLSelectNode*	getFirstMoveableNode(BOOL get_root_first = FALSE);
264
265	LLViewerObject*	getFirstEditableObject(BOOL get_parent = FALSE);
266	LLViewerObject*	getFirstCopyableObject(BOOL get_parent = FALSE);
267	LLViewerObject* getFirstDeleteableObject();
268	LLViewerObject*	getFirstMoveableObject(BOOL get_parent = FALSE);
269
270	/// Return the object that lead to this selection, possible a child
271	LLViewerObject* getPrimaryObject() { return mPrimaryObject; }
272
273	// iterate through texture entries
274	template <typename T> bool getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res);
275	template <typename T> bool isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value);
276	
277	S32 getNumNodes();
278	LLSelectNode* findNode(LLViewerObject* objectp);
279
280	// count members
281	S32 getObjectCount();
282	F32 getSelectedObjectCost();
283	F32 getSelectedLinksetCost();
284	F32 getSelectedPhysicsCost();
285	F32 getSelectedLinksetPhysicsCost();
286	S32 getSelectedObjectRenderCost();
287	
288	F32 getSelectedObjectStreamingCost(S32* total_bytes = NULL, S32* visible_bytes = NULL);
289	U32 getSelectedObjectTriangleCount(S32* vcount = NULL);
290
291	S32 getTECount();
292	S32 getRootObjectCount();
293
294	BOOL isMultipleTESelected();
295	BOOL contains(LLViewerObject* object);
296	BOOL contains(LLViewerObject* object, S32 te);
297
298	// returns TRUE is any node is currenly worn as an attachment
299	BOOL isAttachment();
300
301	// Apply functors to various subsets of the selected objects
302	// If firstonly is FALSE, returns the AND of all apply() calls.
303	// Else returns TRUE immediately if any apply() call succeeds (i.e. OR with early exit)
304	bool applyToRootObjects(LLSelectedObjectFunctor* func, bool firstonly = false);
305	bool applyToObjects(LLSelectedObjectFunctor* func);
306	bool applyToTEs(LLSelectedTEFunctor* func, bool firstonly = false);
307	bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
308	bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
309
310	ESelectType getSelectType() const { return mSelectType; }
311
312private:
313	void addNode(LLSelectNode *nodep);
314	void addNodeAtEnd(LLSelectNode *nodep);
315	void moveNodeToFront(LLSelectNode *nodep);
316	void removeNode(LLSelectNode *nodep);
317	void deleteAllNodes();
318	void cleanupNodes();
319
320
321private:
322	list_t mList;
323	const LLObjectSelection &operator=(const LLObjectSelection &);
324
325	LLPointer<LLViewerObject> mPrimaryObject;
326	std::map<LLPointer<LLViewerObject>, LLSelectNode*> mSelectNodeMap;
327	ESelectType mSelectType;
328};
329
330typedef LLSafeHandle<LLObjectSelection> LLObjectSelectionHandle;
331
332// Build time optimization, generate this once in .cpp file
333#ifndef LLSELECTMGR_CPP
334extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance();
335#endif
336
337class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
338{
339public:
340	static BOOL					sRectSelectInclusive;	// do we need to surround an object to pick it?
341	static BOOL					sRenderHiddenSelections;	// do we show selection silhouettes that are occluded?
342	static BOOL					sRenderLightRadius;	// do we show the radius of selected lights?
343
344	static F32					sHighlightThickness;
345	static F32					sHighlightUScale;
346	static F32					sHighlightVScale;
347	static F32					sHighlightAlpha;
348	static F32					sHighlightAlphaTest;
349	static F32					sHighlightUAnim;
350	static F32					sHighlightVAnim;
351	static LLColor4				sSilhouetteParentColor;
352	static LLColor4				sSilhouetteChildColor;
353	static LLColor4				sHighlightParentColor;
354	static LLColor4				sHighlightChildColor;
355	static LLColor4				sHighlightInspectColor;
356	static LLColor4				sContextSilhouetteColor;
357
358	LLCachedControl<bool>					mHideSelectedObjects;
359	LLCachedControl<bool>					mRenderHighlightSelections;
360	LLCachedControl<bool>					mAllowSelectAvatar;
361	LLCachedControl<bool>					mDebugSelectMgr;
362
363public:
364	LLSelectMgr();
365	~LLSelectMgr();
366
367	static void cleanupGlobals();
368
369	// LLEditMenuHandler interface
370	virtual BOOL canUndo() const;
371	virtual void undo();
372
373	virtual BOOL canRedo() const;
374	virtual void redo();
375
376	virtual BOOL canDoDelete() const;
377	virtual void doDelete();
378
379	virtual void deselect();
380	virtual BOOL canDeselect() const;
381
382	virtual void duplicate();
383	virtual BOOL canDuplicate() const;
384
385	void clearSelections();
386	void update();
387	void updateEffects(); // Update HUD effects
388	void overrideObjectUpdates();
389
390	// Returns the previous value of mForceSelection
391	BOOL setForceSelection(BOOL force);
392
393	////////////////////////////////////////////////////////////////
394	// Selection methods
395	////////////////////////////////////////////////////////////////
396
397	////////////////////////////////////////////////////////////////
398	// Add
399	////////////////////////////////////////////////////////////////
400
401	// This method is meant to select an object, and then select all
402	// of the ancestors and descendants. This should be the normal behavior.
403	//
404	// *NOTE: You must hold on to the object selection handle, otherwise
405	// the objects will be automatically deselected in 1 frame.
406	LLObjectSelectionHandle selectObjectAndFamily(LLViewerObject* object, BOOL add_to_end = FALSE);
407
408	// For when you want just a child object.
409	LLObjectSelectionHandle selectObjectOnly(LLViewerObject* object, S32 face = SELECT_ALL_TES);
410
411	// Same as above, but takes a list of objects.  Used by rectangle select.
412	LLObjectSelectionHandle selectObjectAndFamily(const std::vector<LLViewerObject*>& object_list, BOOL send_to_sim = TRUE);
413
414	// converts all objects currently highlighted to a selection, and returns it
415	LLObjectSelectionHandle selectHighlightedObjects();
416
417	LLObjectSelectionHandle setHoverObject(LLViewerObject *objectp, S32 face = -1);
418	LLSelectNode *getHoverNode();
419	LLSelectNode *getPrimaryHoverNode();
420
421	void highlightObjectOnly(LLViewerObject *objectp);
422	void highlightObjectAndFamily(LLViewerObject *objectp);
423	void highlightObjectAndFamily(const std::vector<LLViewerObject*>& list);
424
425	////////////////////////////////////////////////////////////////
426	// Remove
427	////////////////////////////////////////////////////////////////
428
429	void deselectObjectOnly(LLViewerObject* object, BOOL send_to_sim = TRUE);
430	void deselectObjectAndFamily(LLViewerObject* object, BOOL send_to_sim = TRUE, BOOL include_entire_object = FALSE);
431
432	// Send deselect messages to simulator, then clear the list
433	void deselectAll();
434	void deselectAllForStandingUp();
435
436	// deselect only if nothing else currently referencing the selection
437	void deselectUnused();
438
439	// Deselect if the selection center is too far away from the agent.
440	void deselectAllIfTooFar();
441
442	// Removes all highlighted objects from current selection
443	void deselectHighlightedObjects();
444
445	void unhighlightObjectOnly(LLViewerObject *objectp);
446	void unhighlightObjectAndFamily(LLViewerObject *objectp);
447	void unhighlightAll();
448
449	BOOL removeObjectFromSelections(const LLUUID &id);
450
451	////////////////////////////////////////////////////////////////
452	// Selection editing
453	////////////////////////////////////////////////////////////////
454	bool linkObjects();
455
456	bool unlinkObjects();
457
458	bool enableLinkObjects();
459
460	bool enableUnlinkObjects();
461
462	////////////////////////////////////////////////////////////////
463	// Selection accessors
464	////////////////////////////////////////////////////////////////
465	LLObjectSelectionHandle	getSelection() { return mSelectedObjects; }
466	// right now this just renders the selection with root/child colors instead of a single color
467	LLObjectSelectionHandle	getEditSelection() { convertTransient(); return mSelectedObjects; }
468	LLObjectSelectionHandle	getHighlightedObjects() { return mHighlightedObjects; }
469
470	////////////////////////////////////////////////////////////////
471	// Grid manipulation
472	////////////////////////////////////////////////////////////////
473	void			addGridObject(LLViewerObject* objectp);
474	void			clearGridObjects();
475	void			setGridMode(EGridMode mode);
476	EGridMode		getGridMode() { return mGridMode; }
477	void			getGrid(LLVector3& origin, LLQuaternion& rotation, LLVector3 &scale);
478
479	BOOL getTEMode()		{ return mTEMode; }
480	void setTEMode(BOOL b)	{ mTEMode = b; }
481
482	BOOL shouldShowSelection()	{ return mShowSelection; }
483
484	LLBBox getBBoxOfSelection() const;
485	LLBBox getSavedBBoxOfSelection() const { return mSavedSelectionBBox; }
486
487	void dump();
488	void cleanup();
489
490	void updateSilhouettes();
491	void renderSilhouettes(BOOL for_hud);
492	void enableSilhouette(BOOL enable) { mRenderSilhouettes = enable; }
493	
494	////////////////////////////////////////////////////////////////
495	// Utility functions that operate on the current selection
496	////////////////////////////////////////////////////////////////
497	void saveSelectedObjectTransform(EActionType action_type);
498	void saveSelectedObjectColors();
499	void saveSelectedObjectTextures();
500
501	void selectionUpdatePhysics(BOOL use_physics);
502	void selectionUpdateTemporary(BOOL is_temporary);
503	void selectionUpdatePhantom(BOOL is_ghost);
504	void selectionUpdateCastShadows(BOOL cast_shadows);
505	void selectionDump();
506
507	BOOL selectionAllPCode(LLPCode code);		// all objects have this PCode
508	BOOL selectionGetClickAction(U8 *out_action);
509	bool selectionGetIncludeInSearch(bool* include_in_search_out); // true if all selected objects have same
510	BOOL selectionGetGlow(F32 *glow);
511
512	void selectionSetPhysicsType(U8 type);
513	void selectionSetGravity(F32 gravity);
514	void selectionSetFriction(F32 friction);
515	void selectionSetDensity(F32 density);
516	void selectionSetRestitution(F32 restitution);
517	void selectionSetMaterial(U8 material);
518	void selectionSetImage(const LLUUID& imageid); // could be item or asset id
519	void selectionSetColor(const LLColor4 &color);
520	void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
521	void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
522	void selectionRevertColors();
523	BOOL selectionRevertTextures();
524	void selectionSetBumpmap( U8 bumpmap );
525	void selectionSetTexGen( U8 texgen );
526	void selectionSetShiny( U8 shiny );
527	void selectionSetFullbright( U8 fullbright );
528	void selectionSetMedia( U8 media_type, const LLSD &media_data );
529	void selectionSetClickAction(U8 action);
530	void selectionSetIncludeInSearch(bool include_in_search);
531	void selectionSetGlow(const F32 glow);
532
533	void selectionSetObjectPermissions(U8 perm_field, BOOL set, U32 perm_mask, BOOL override = FALSE);
534	void selectionSetObjectName(const std::string& name);
535	void selectionSetObjectDescription(const std::string& desc);
536	void selectionSetObjectCategory(const LLCategory& category);
537	void selectionSetObjectSaleInfo(const LLSaleInfo& sale_info);
538
539	void selectionTexScaleAutofit(F32 repeats_per_meter);
540	void adjustTexturesByScale(BOOL send_to_sim, BOOL stretch);
541
542	void selectionResetRotation();				// sets rotation quat to identity
543	void selectionRotateAroundZ(F32 degrees);
544	bool selectionMove(const LLVector3& displ, F32 rx, F32 ry, F32 rz,
545					   U32 update_type);
546	void sendSelectionMove();
547
548	void sendGodlikeRequest(const std::string& request, const std::string& parameter);
549
550
551	// will make sure all selected object meet current criteria, or deselect them otherwise
552	void validateSelection();
553
554	// returns TRUE if it is possible to select this object
555	BOOL canSelectObject(LLViewerObject* object);
556
557	// Returns TRUE if the viewer has information on all selected objects
558	BOOL selectGetAllRootsValid();
559	BOOL selectGetAllValid();
560	BOOL selectGetAllValidAndObjectsFound();
561
562	// returns TRUE if you can modify all selected objects. 
563	BOOL selectGetRootsModify();
564	BOOL selectGetModify();
565
566	// returns TRUE if selected objects can be transferred.
567	BOOL selectGetRootsTransfer();
568
569	// returns TRUE if selected objects can be copied.
570	BOOL selectGetRootsCopy();
571	
572	BOOL selectGetCreator(LLUUID& id, std::string& name);					// TRUE if all have same creator, returns id
573	BOOL selectGetOwner(LLUUID& id, std::string& name);					// TRUE if all objects have same owner, returns id
574	BOOL selectGetLastOwner(LLUUID& id, std::string& name);				// TRUE if all objects have same owner, returns id
575
576	// returns TRUE if all are the same. id is stuffed with
577	// the value found if available.
578	BOOL selectGetGroup(LLUUID& id); 
579	BOOL selectGetPerm(	U8 which_perm, U32* mask_on, U32* mask_off);	// TRUE if all have data, returns two masks, each indicating which bits are all on and all off
580
581	BOOL selectIsGroupOwned();											// TRUE if all root objects have valid data and are group owned.
582
583	// returns TRUE if all the nodes are valid. Accumulates
584	// permissions in the parameter.
585	BOOL selectGetPermissions(LLPermissions& perm);
586	
587	// Get a bunch of useful sale information for the object(s) selected.
588	// "_mixed" is true if not all objects have the same setting.
589	void selectGetAggregateSaleInfo(U32 &num_for_sale,
590									BOOL &is_for_sale_mixed, 
591									BOOL &is_sale_price_mixed,
592									S32 &total_sale_price,
593									S32 &individual_sale_price);
594
595	// returns TRUE if all nodes are valid. 
596	BOOL selectGetCategory(LLCategory& category);
597	
598	// returns TRUE if all nodes are valid. method also stores an
599	// accumulated sale info.
600	BOOL selectGetSaleInfo(LLSaleInfo& sale_info);
601
602	// returns TRUE if all nodes are valid. fills passed in object
603	// with the aggregate permissions of the selection.
604	BOOL selectGetAggregatePermissions(LLAggregatePermissions& ag_perm);
605
606	// returns TRUE if all nodes are valid. fills passed in object
607	// with the aggregate permissions for texture inventory items of the selection.
608	BOOL selectGetAggregateTexturePermissions(LLAggregatePermissions& ag_perm);
609
610	LLPermissions* findObjectPermissions(const LLViewerObject* object);
611
612	void selectDelete();							// Delete on simulator
613	void selectForceDelete();			// just delete, no into trash
614	void selectDuplicate(const LLVector3& offset, BOOL select_copy);	// Duplicate on simulator
615	void repeatDuplicate();
616	void selectDuplicateOnRay(const LLVector3 &ray_start_region,
617								const LLVector3 &ray_end_region,
618								BOOL bypass_raycast,
619								BOOL ray_end_is_intersection,
620								const LLUUID &ray_target_id,
621								BOOL copy_centers,
622								BOOL copy_rotates,
623								BOOL select_copy);
624
625	void sendMultipleUpdate(U32 type);	// Position, rotation, scale all in one
626	void sendOwner(const LLUUID& owner_id, const LLUUID& group_id, BOOL override = FALSE);
627	void sendGroup(const LLUUID& group_id);
628
629	// Category ID is the UUID of the folder you want to contain the purchase.
630	// *NOTE: sale_info check doesn't work for multiple object buy,
631	// which UI does not currently support sale info is used for
632	// verification only, if it doesn't match region info then sale is
633	// canceled
634	void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
635	void sendAttach(U8 attachment_point, bool replace);
636	void sendDetach();
637	void sendDropAttachment();
638	void sendLink();
639	void sendDelink();
640	//void sendHinge(U8 type);
641	//void sendDehinge();
642	void sendSelect();
643
644	void requestObjectPropertiesFamily(LLViewerObject* object);	// asks sim for creator, permissions, resources, etc.
645	static void processObjectProperties(LLMessageSystem *mesgsys, void **user_data);
646	static void processObjectPropertiesFamily(LLMessageSystem *mesgsys, void **user_data);
647	static void processForceObjectSelect(LLMessageSystem* msg, void**);
648
649	void requestGodInfo();
650
651	LLVector3d		getSelectionCenterGlobal() const	{ return mSelectionCenterGlobal; }
652	void			updateSelectionCenter();
653
654	void resetAgentHUDZoom();
655	void setAgentHUDZoom(F32 target_zoom, F32 current_zoom);
656	void getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const;
657
658	void updatePointAt();
659
660	// Internal list maintenance functions. TODO: Make these private!
661	void remove(std::vector<LLViewerObject*>& objects);
662	void remove(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE);
663	void removeAll();
664	void addAsIndividual(LLViewerObject* object, S32 te = SELECT_ALL_TES, BOOL undoable = TRUE);
665	void promoteSelectionToRoot();
666	void demoteSelectionToIndividuals();
667
668private:
669	void convertTransient(); // converts temporarily selected objects to full-fledged selections
670	ESelectType getSelectTypeForObject(LLViewerObject* object);
671	void addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to_end = FALSE);
672	void generateSilhouette(LLSelectNode *nodep, const LLVector3& view_point);
673	void updateSelectionSilhouette(LLObjectSelectionHandle object_handle, S32& num_sils_genned, std::vector<LLViewerObject*>& changed_objects);
674	// Send one message to each region containing an object on selection list.
675	void sendListToRegions(	const std::string& message_name,
676							void (*pack_header)(void *user_data), 
677							void (*pack_body)(LLSelectNode* node, void *user_data), 
678							void *user_data,
679							ESendType send_type);
680
681
682	static void packAgentID(	void *);
683	static void packAgentAndSessionID(void* user_data);
684	static void packAgentAndGroupID(void* user_data);
685	static void packAgentAndSessionAndGroupID(void* user_data);
686	static void packAgentIDAndSessionAndAttachment(void*);
687	static void packAgentGroupAndCatID(void*);
688	static void packDeleteHeader(void* userdata);
689	static void packDeRezHeader(void* user_data);
690	static void packObjectID(	LLSelectNode* node, void *);
691	static void packObjectIDAsParam(LLSelectNode* node, void *);
692	static void packObjectIDAndRotation(LLSelectNode* node, void *);
693	static void packObjectLocalID(LLSelectNode* node, void *);
694	static void packObjectClickAction(LLSelectNode* node, void* data);
695	static void packObjectIncludeInSearch(LLSelectNode* node, void* data);
696	static void packObjectName(LLSelectNode* node, void* user_data);
697	static void packObjectDescription(LLSelectNode* node, void* user_data);
698	static void packObjectCategory(LLSelectNode* node, void* user_data);
699	static void packObjectSaleInfo(LLSelectNode* node, void* user_data);
700	static void packBuyObjectIDs(LLSelectNode* node, void* user_data);
701	static void packDuplicate(	LLSelectNode* node, void *duplicate_data);
702	static void packDuplicateHeader(void*);
703	static void packDuplicateOnRayHead(void *user_data);
704	static void packPermissions(LLSelectNode* node, void *user_data);
705	static void packDeselect(	LLSelectNode* node, void *user_data);
706	static void packMultipleUpdate(LLSelectNode* node, void *user_data);
707	static void packPhysics(LLSelectNode* node, void *user_data);
708	static void packShape(LLSelectNode* node, void *user_data);
709	static void packOwnerHead(void *user_data);
710	static void packHingeHead(void *user_data);
711	static void packPermissionsHead(void* user_data);
712	static void packGodlikeHead(void* user_data);
713	static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
714
715public:
716	// Observer/callback support for when object selection changes or
717	// properties are received/updated
718	typedef boost::signals2::signal< void ()> update_signal_t;
719	update_signal_t mUpdateSignal;
720
721private:
722	LLPointer<LLViewerTexture>				mSilhouetteImagep;
723	LLObjectSelectionHandle					mSelectedObjects;
724	LLObjectSelectionHandle					mHoverObjects;
725	LLObjectSelectionHandle					mHighlightedObjects;
726	std::set<LLPointer<LLViewerObject> >	mRectSelectedObjects;
727	
728	LLObjectSelection		mGridObjects;
729	LLQuaternion			mGridRotation;
730	LLVector3				mGridOrigin;
731	LLVector3				mGridScale;
732	EGridMode				mGridMode;
733	BOOL					mGridValid;
734
735
736	BOOL					mTEMode;			// render te
737	LLVector3d				mSelectionCenterGlobal;
738	LLBBox					mSelectionBBox;
739
740	LLVector3d				mLastSentSelectionCenterGlobal;
741	BOOL					mShowSelection; // do we send the selection center name value and do we animate this selection?
742	LLVector3d				mLastCameraPos;		// camera position from last generation of selection silhouette
743	BOOL					mRenderSilhouettes;	// do we render the silhouette
744	LLBBox					mSavedSelectionBBox;
745
746	LLFrameTimer			mEffectsTimer;
747	BOOL					mForceSelection;
748
749	LLAnimPauseRequest		mPauseRequest;
750};
751
752// *DEPRECATED: For callbacks or observers, use
753// LLSelectMgr::getInstance()->mUpdateSignal.connect( callback )
754// Update subscribers to the selection list
755void dialog_refresh_all();		
756
757// Templates
758//-----------------------------------------------------------------------------
759// getSelectedTEValue
760//-----------------------------------------------------------------------------
761template <typename T> bool LLObjectSelection::getSelectedTEValue(LLSelectedTEGetFunctor<T>* func, T& res)
762{
763	bool have_first = false;
764	bool have_selected = false;
765	T selected_value = T();
766
767	// Now iterate through all TEs to test for sameness
768	bool identical = TRUE;
769	for (iterator iter = begin(); iter != end(); iter++)
770	{
771		LLSelectNode* node = *iter;
772		LLViewerObject* object = node->getObject();
773		S32 selected_te = -1;
774		if (object == getPrimaryObject())
775		{
776			selected_te = node->getLastSelectedTE();
777		}
778		for (S32 te = 0; te < object->getNumTEs(); ++te)
779		{
780			if (!node->isTESelected(te))
781			{
782				continue;
783			}
784			T value = func->get(object, te);
785			if (!have_first)
786			{
787				have_first = true;
788				if (!have_selected)
789				{
790					selected_value = value;
791				}
792			}
793			else
794			{
795				if ( value != selected_value )
796				{
797					identical = false;
798				}
799				if (te == selected_te)
800				{
801					selected_value = value;
802					have_selected = true;
803				}
804			}
805		}
806		if (!identical && have_selected)
807		{
808			break;
809		}
810	}
811	if (have_first || have_selected)
812	{
813		res = selected_value;
814	}
815	return identical;
816}
817
818// Templates
819//-----------------------------------------------------------------------------
820// isMultipleTEValue iterate through all TEs and test for uniqueness 
821// with certain return value ignored when performing the test. 
822// e.g. when testing if the selection has a unique non-empty homeurl :
823// you can set ignore_value = "" and it will only compare among the non-empty  
824// homeUrls and ignore the empty ones.
825//-----------------------------------------------------------------------------
826template <typename T> bool LLObjectSelection::isMultipleTEValue(LLSelectedTEGetFunctor<T>* func, const T& ignore_value)
827{
828	bool have_first = false;
829	T selected_value = T();
830	
831	// Now iterate through all TEs to test for sameness
832	bool unique = TRUE;
833	for (iterator iter = begin(); iter != end(); iter++)
834	{
835		LLSelectNode* node = *iter;
836		LLViewerObject* object = node->getObject();
837		for (S32 te = 0; te < object->getNumTEs(); ++te)
838		{
839			if (!node->isTESelected(te))
840			{
841				continue;
842			}
843			T value = func->get(object, te);
844			if(value == ignore_value)
845			{
846				continue;
847			}
848			if (!have_first)
849			{
850				have_first = true;
851			}
852			else
853			{
854				if (value !=selected_value  )
855				{
856					unique = false;
857					return !unique;
858				}
859			}
860		}
861	}
862	return !unique;
863}
864
865
866#endif