aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterproperties.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterproperties.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloaterproperties.cpp946
1 files changed, 946 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterproperties.cpp b/linden/indra/newview/llfloaterproperties.cpp
new file mode 100644
index 0000000..abae955
--- /dev/null
+++ b/linden/indra/newview/llfloaterproperties.cpp
@@ -0,0 +1,946 @@
1/**
2 * @file llfloaterproperties.cpp
3 * @brief A floater which shows an inventory item's properties.
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29#include "llfloaterproperties.h"
30
31#include <algorithm>
32#include <functional>
33#include "llcachename.h"
34#include "lldbstrings.h"
35#include "llinventory.h"
36
37#include "llagent.h"
38#include "llbutton.h"
39#include "llcheckboxctrl.h"
40#include "llfloateravatarinfo.h"
41#include "llfloatergroupinfo.h"
42#include "llinventorymodel.h"
43#include "lllineeditor.h"
44#include "llradiogroup.h"
45#include "llresmgr.h"
46#include "roles_constants.h"
47#include "llselectmgr.h"
48#include "lltextbox.h"
49#include "lluiconstants.h"
50#include "llviewerinventory.h"
51#include "llviewerobjectlist.h"
52#include "llviewerregion.h"
53#include "llviewercontrol.h"
54
55#include "llvieweruictrlfactory.h"
56
57
58///----------------------------------------------------------------------------
59/// Local function declarations, constants, enums, and typedefs
60///----------------------------------------------------------------------------
61
62const char* YOU_CAN = "You can:";
63const char* OWNER_CAN = "Owner can: ";
64
65
66//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67// Class LLPropertiesObserver
68//
69// helper class to watch the inventory.
70//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71
72class LLPropertiesObserver : public LLInventoryObserver
73{
74public:
75 LLPropertiesObserver() {}
76 virtual ~LLPropertiesObserver() {}
77 virtual void changed(U32 mask);
78};
79
80LLPropertiesObserver* gPropertiesObserver = NULL;
81void LLPropertiesObserver::changed(U32 mask)
82{
83 // if there's a change we're interested in.
84 if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
85 {
86 LLFloaterProperties::dirtyAll();
87 }
88}
89
90
91
92///----------------------------------------------------------------------------
93/// Class LLFloaterProperties
94///----------------------------------------------------------------------------
95
96LLFloaterProperties::instance_map LLFloaterProperties::sInstances;
97
98// static
99LLFloaterProperties* LLFloaterProperties::find(const LLUUID& item_id,
100 const LLUUID& object_id)
101{
102 // for simplicity's sake, we key the properties window with a
103 // single uuid. However, the items are keyed by item and object
104 // (obj == null -> agent inventory). So, we xor the two ids, and
105 // use that as a lookup key
106 instance_map::iterator it = sInstances.find(item_id ^ object_id);
107 if(it != sInstances.end())
108 {
109 return (*it).second;
110 }
111 return NULL;
112}
113
114// static
115LLFloaterProperties* LLFloaterProperties::show(const LLUUID& item_id,
116 const LLUUID& object_id)
117{
118 LLFloaterProperties* instance = find(item_id, object_id);
119 if(instance)
120 {
121 if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost())
122 {
123 // this properties window is being opened in a new context
124 // needs to be rehosted
125 LLFloater::getFloaterHost()->addFloater(instance, TRUE);
126 }
127
128 instance->refresh();
129 instance->open();
130 }
131 return instance;
132}
133
134void LLFloaterProperties::dirtyAll()
135{
136 // ...this is more clear. Possibly more correct, because the
137 // refresh method may delete the object.
138 for(instance_map::iterator it = sInstances.begin(); it!=sInstances.end(); )
139 {
140 (*it++).second->dirty();
141 }
142}
143
144// Default constructor
145LLFloaterProperties::LLFloaterProperties(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id, const LLUUID& object_id) :
146 LLFloater(name, rect, title),
147 mItemID(item_id),
148 mObjectID(object_id),
149 mDirty(TRUE)
150{
151 gUICtrlFactory->buildFloater(this,"floater_inventory_item_properties.xml");
152
153 // hack to make sure these floaters are observing the inventory.
154 if(!gPropertiesObserver)
155 {
156 gPropertiesObserver = new LLPropertiesObserver;
157 gInventory.addObserver(gPropertiesObserver);
158 }
159 // add the object to the static structure
160 LLUUID key = mItemID ^ mObjectID;
161 sInstances.insert(instance_map::value_type(key, this));
162 // build the UI
163 // item name & description
164 childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidatePrintableNotPipe);
165 childSetCommitCallback("LabelItemName",onCommitName,this);
166 childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidatePrintableNotPipe);
167 // Creator information
168 childSetAction("BtnCreator",onClickCreator,this);
169 // owner information
170 childSetAction("BtnOwner",onClickOwner,this);
171 // acquired date
172 // owner permissions
173 // Permissions debug text
174 // group permissions
175 childSetCommitCallback("CheckShareWithGroup",&onCommitPermissions, this);
176 // everyone permissions
177 childSetCommitCallback("CheckEveryoneCopy",&onCommitPermissions, this);
178 // next owner permissions
179 childSetCommitCallback("CheckNextOwnerModify",&onCommitPermissions, this);
180 childSetCommitCallback("CheckNextOwnerCopy",&onCommitPermissions, this);
181 childSetCommitCallback("CheckNextOwnerTransfer",&onCommitPermissions, this);
182 // Mark for sale or not, and sale info
183 childSetCommitCallback("CheckPurchase",&onCommitSaleInfo, this);
184 childSetCommitCallback("RadioSaleType",&onCommitSaleType, this);
185 // "Price" label for edit
186 childSetCommitCallback("EditPrice",&onCommitSaleInfo, this);
187 // The UI has been built, now fill in all the values
188 refresh();
189}
190
191// Destroys the object
192LLFloaterProperties::~LLFloaterProperties()
193{
194 // clean up the static data.
195 instance_map::iterator it = sInstances.find(mItemID ^ mObjectID);
196 if(it != sInstances.end())
197 {
198 sInstances.erase(it);
199 }
200}
201
202void LLFloaterProperties::refresh()
203{
204 LLInventoryItem* item = findItem();
205 if(item)
206 {
207 refreshFromItem(item);
208 }
209 else
210 {
211 //RN: it is possible that the container object is in the middle of an inventory refresh
212 // causing findItem() to fail, so just temporarily disable everything
213
214 mDirty = TRUE;
215
216 const char* enableNames[]={
217 "LabelItemName",
218 "LabelItemDesc",
219 "LabelCreatorName",
220 "BtnCreator",
221 "LabelOwnerName",
222 "BtnOwner",
223 "CheckOwnerModify",
224 "CheckOwnerCopy",
225 "CheckOwnerTransfer",
226 "CheckShareWithGroup",
227 "CheckEveryoneCopy",
228 "CheckNextOwnerModify",
229 "CheckNextOwnerCopy",
230 "CheckNextOwnerTransfer",
231 "CheckPurchase",
232 "RadioSaleType",
233 "EditPrice"
234 };
235 for(int t=0;t<sizeof(enableNames)/sizeof(char*);t++)
236 {
237 childSetEnabled(enableNames[t],false);
238 }
239 const char* hideNames[]={
240 "BaseMaskDebug",
241 "OwnerMaskDebug",
242 "GroupMaskDebug",
243 "EveryoneMaskDebug",
244 "NextMaskDebug"
245 };
246 for(int t=0;t<sizeof(hideNames)/sizeof(char*);t++)
247 {
248 childSetVisible(hideNames[t],false);
249 }
250 }
251}
252
253void LLFloaterProperties::draw()
254{
255 if (mDirty)
256 {
257 // RN: clear dirty first because refresh can set dirty to TRUE
258 mDirty = FALSE;
259 refresh();
260 }
261
262 LLFloater::draw();
263}
264
265void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
266{
267 ////////////////////////
268 // PERMISSIONS LOOKUP //
269 ////////////////////////
270
271 // do not enable the UI for incomplete items.
272 LLViewerInventoryItem* i = (LLViewerInventoryItem*)item;
273 BOOL is_complete = i->isComplete();
274
275 const LLPermissions& perm = item->getPermissions();
276 BOOL can_agent_manipulate = gAgent.allowOperation(PERM_OWNER, perm,
277 GP_OBJECT_MANIPULATE);
278 BOOL can_agent_sell = gAgent.allowOperation(PERM_OWNER, perm,
279 GP_OBJECT_SET_SALE);
280
281 // You need permission to modify the object to modify an inventory
282 // item in it.
283 LLViewerObject* object = NULL;
284 if(!mObjectID.isNull()) object = gObjectList.findObject(mObjectID);
285 BOOL is_obj_modify = TRUE;
286 if(object)
287 {
288 is_obj_modify = object->permOwnerModify();
289 }
290
291 //////////////////////
292 // ITEM NAME & DESC //
293 //////////////////////
294 BOOL is_modifiable = gAgent.allowOperation(PERM_MODIFY, perm,
295 GP_OBJECT_MANIPULATE)
296 && is_obj_modify && is_complete;
297
298 childSetEnabled("LabelItemNameTitle",TRUE);
299 childSetEnabled("LabelItemName",is_modifiable);
300 const char EMPTY_STRING[1] = "";
301 const char* txt = EMPTY_STRING;
302 if(!item->getName().empty())
303 {
304 txt = item->getName().c_str();
305 }
306 childSetText("LabelItemName",txt);
307 childSetEnabled("LabelItemDescTitle",TRUE);
308 childSetEnabled("LabelItemDesc",is_modifiable);
309 childSetVisible("IconLocked",!is_modifiable);
310 txt = EMPTY_STRING;
311 if(!item->getDescription().empty())
312 {
313 txt = item->getDescription().c_str();
314 }
315 childSetText("LabelItemDesc",txt);
316
317 //////////////////
318 // CREATOR NAME //
319 //////////////////
320 char first_name[DB_FIRST_NAME_BUF_SIZE];
321 char last_name[DB_LAST_NAME_BUF_SIZE];
322 if(!gCacheName) return;
323 if(!gAgent.getRegion()) return;
324
325 if (item->getCreatorUUID().notNull())
326 {
327 gCacheName->getName(item->getCreatorUUID(), first_name, last_name);
328 LLString name(first_name);
329 name.append(1, ' ');
330 name.append(last_name);
331
332 childSetEnabled("BtnCreator",TRUE);
333 childSetEnabled("LabelCreatorTitle",TRUE);
334 childSetEnabled("LabelCreatorName",TRUE);
335 childSetText("LabelCreatorName",name);
336 }
337 else
338 {
339 childSetEnabled("BtnCreator",FALSE);
340 childSetEnabled("LabelCreatorTitle",FALSE);
341 childSetEnabled("LabelCreatorName",FALSE);
342 childSetText("LabelCreatorName","(unknown)"); // XUI:translate
343 }
344
345 ////////////////
346 // OWNER NAME //
347 ////////////////
348 if(perm.isOwned())
349 {
350 LLString name;
351 if (perm.isGroupOwned())
352 {
353 char group_name[DB_GROUP_NAME_BUF_SIZE];
354 gCacheName->getGroupName(perm.getGroup(), group_name);
355 name.assign(group_name);
356 }
357 else
358 {
359 gCacheName->getName(perm.getOwner(), first_name, last_name);
360 name.assign(first_name);
361 name.append(1, ' ');
362 name.append(last_name);
363 }
364 childSetEnabled("BtnOwner",TRUE);
365 childSetEnabled("LabelOwnerTitle",TRUE);
366 childSetEnabled("LabelOwnerName",TRUE);
367 childSetText("LabelOwnerName",name);
368 }
369 else
370 {
371 childSetEnabled("BtnOwner",FALSE);
372 childSetEnabled("LabelOwnerTitle",FALSE);
373 childSetEnabled("LabelOwnerName",FALSE);
374 childSetText("LabelOwnerName","(public)"); // XUI:translate
375 }
376
377 //////////////////
378 // ACQUIRE DATE //
379 //////////////////
380 time_t time_utc = (time_t)item->getCreationDate();
381 if (0 == time_utc)
382 {
383 childSetText("LabelAcquiredDate","(unknown)");
384 }
385 else
386 {
387 childSetText("LabelAcquiredDate", ctime(&time_utc) );
388 }
389
390 ///////////////////////
391 // OWNER PERMISSIONS //
392 ///////////////////////
393 if(can_agent_manipulate)
394 {
395 childSetText("OwnerLabel",YOU_CAN);
396 }
397 else
398 {
399 childSetText("OwnerLabel",OWNER_CAN);
400 }
401
402 U32 base_mask = perm.getMaskBase();
403 U32 owner_mask = perm.getMaskOwner();
404 U32 group_mask = perm.getMaskGroup();
405 U32 everyone_mask = perm.getMaskEveryone();
406 U32 next_owner_mask = perm.getMaskNextOwner();
407
408 childSetEnabled("OwnerLabel",TRUE);
409 childSetEnabled("CheckOwnerModify",FALSE);
410 childSetValue("CheckOwnerModify",LLSD((BOOL)(owner_mask & PERM_MODIFY)));
411 childSetEnabled("CheckOwnerCopy",FALSE);
412 childSetValue("CheckOwnerCopy",LLSD((BOOL)(owner_mask & PERM_COPY)));
413 childSetEnabled("CheckOwnerTransfer",FALSE);
414 childSetValue("CheckOwnerTransfer",LLSD((BOOL)(owner_mask & PERM_TRANSFER)));
415
416 ///////////////////////
417 // DEBUG PERMISSIONS //
418 ///////////////////////
419
420 if( gSavedSettings.getBOOL("DebugPermissions") )
421 {
422 BOOL slam_perm = FALSE;
423 BOOL overwrite_group = FALSE;
424 BOOL overwrite_everyone = FALSE;
425
426 if (item->getType() == LLAssetType::AT_OBJECT)
427 {
428 U32 flags = item->getFlags();
429 slam_perm = flags & LLInventoryItem::II_FLAGS_OBJECT_SLAM_PERM;
430 overwrite_everyone = flags & LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
431 overwrite_group = flags & LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
432 }
433
434 char perm_string[11];
435
436 sprintf(perm_string, "B: ");
437 mask_to_string(base_mask, perm_string+3);
438 childSetText("BaseMaskDebug",perm_string);
439 childSetVisible("BaseMaskDebug",TRUE);
440
441 sprintf(perm_string, "O: ");
442 mask_to_string(owner_mask, perm_string+3);
443 childSetText("OwnerMaskDebug",perm_string);
444 childSetVisible("OwnerMaskDebug",TRUE);
445
446 sprintf(perm_string, "G%s: ", overwrite_group ? "*" : "");
447 mask_to_string(group_mask, perm_string + (overwrite_group ? 4 : 3));
448 childSetText("GroupMaskDebug",perm_string);
449 childSetVisible("GroupMaskDebug",TRUE);
450
451 sprintf(perm_string, "E%s: ", overwrite_everyone ? "*" : "");
452 mask_to_string(everyone_mask, perm_string + (overwrite_everyone ? 4 : 3));
453 childSetText("EveryoneMaskDebug",perm_string);
454 childSetVisible("EveryoneMaskDebug",TRUE);
455
456 sprintf(perm_string, "N%s: ", slam_perm ? "*" : "");
457 mask_to_string(next_owner_mask, perm_string + (slam_perm ? 4 : 3));
458 childSetText("NextMaskDebug",perm_string);
459 childSetVisible("NextMaskDebug",TRUE);
460 }
461 else
462 {
463 childSetVisible("BaseMaskDebug",FALSE);
464 childSetVisible("OwnerMaskDebug",FALSE);
465 childSetVisible("GroupMaskDebug",FALSE);
466 childSetVisible("EveryoneMaskDebug",FALSE);
467 childSetVisible("NextMaskDebug",FALSE);
468 }
469
470 /////////////
471 // SHARING //
472 /////////////
473
474 // Check for ability to change values.
475 if (is_obj_modify && can_agent_manipulate)
476 {
477 childSetEnabled("CheckShareWithGroup",TRUE);
478 childSetEnabled("CheckEveryoneCopy",(owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER));
479 }
480 else
481 {
482 childSetEnabled("CheckShareWithGroup",FALSE);
483 childSetEnabled("CheckEveryoneCopy",FALSE);
484 }
485
486 // Set values.
487 BOOL is_group_copy = (group_mask & PERM_COPY) ? TRUE : FALSE;
488 BOOL is_group_modify = (group_mask & PERM_MODIFY) ? TRUE : FALSE;
489 BOOL is_group_move = (group_mask & PERM_MOVE) ? TRUE : FALSE;
490
491 if (is_group_copy && is_group_modify && is_group_move)
492 {
493 childSetValue("CheckShareWithGroup",LLSD((BOOL)TRUE));
494
495 LLCheckBoxCtrl* ctl = LLUICtrlFactory::getCheckBoxByName(this,"CheckShareWithGroup");
496 if(ctl)
497 {
498 ctl->setTentative(FALSE);
499 }
500 }
501 else if (!is_group_copy && !is_group_modify && !is_group_move)
502 {
503 childSetValue("CheckShareWithGroup",LLSD((BOOL)FALSE));
504 LLCheckBoxCtrl* ctl = LLUICtrlFactory::getCheckBoxByName(this,"CheckShareWithGroup");
505 if(ctl)
506 {
507 ctl->setTentative(FALSE);
508 }
509 }
510 else
511 {
512 LLCheckBoxCtrl* ctl = LLUICtrlFactory::getCheckBoxByName(this,"CheckShareWithGroup");
513 if(ctl)
514 {
515 ctl->setTentative(TRUE);
516 ctl->set(TRUE);
517 }
518 }
519
520 childSetValue("CheckEveryoneCopy",LLSD((BOOL)(everyone_mask & PERM_COPY)));
521
522 ///////////////
523 // SALE INFO //
524 ///////////////
525
526 const LLSaleInfo& sale_info = item->getSaleInfo();
527 BOOL is_for_sale = sale_info.isForSale();
528 // Check for ability to change values.
529 if (is_obj_modify && can_agent_sell
530 && gAgent.allowOperation(PERM_TRANSFER, perm, GP_OBJECT_MANIPULATE))
531 {
532 childSetEnabled("SaleLabel",is_complete);
533 childSetEnabled("CheckPurchase",is_complete);
534
535 childSetEnabled("NextOwnerLabel",TRUE);
536 childSetEnabled("CheckNextOwnerModify",base_mask & PERM_MODIFY);
537 childSetEnabled("CheckNextOwnerCopy",base_mask & PERM_COPY);
538 childSetEnabled("CheckNextOwnerTransfer",next_owner_mask & PERM_COPY);
539
540 childSetEnabled("RadioSaleType",is_complete && is_for_sale);
541 childSetEnabled("TextPrice",is_complete && is_for_sale);
542 childSetEnabled("EditPrice",is_complete && is_for_sale);
543 }
544 else
545 {
546 childSetEnabled("SaleLabel",FALSE);
547 childSetEnabled("CheckPurchase",FALSE);
548
549 childSetEnabled("NextOwnerLabel",FALSE);
550 childSetEnabled("CheckNextOwnerModify",FALSE);
551 childSetEnabled("CheckNextOwnerCopy",FALSE);
552 childSetEnabled("CheckNextOwnerTransfer",FALSE);
553
554 childSetEnabled("RadioSaleType",FALSE);
555 childSetEnabled("TextPrice",FALSE);
556 childSetEnabled("EditPrice",FALSE);
557 }
558
559 // Set values.
560 childSetValue("CheckPurchase", is_for_sale);
561 childSetValue("CheckNextOwnerModify",LLSD(BOOL(next_owner_mask & PERM_MODIFY)));
562 childSetValue("CheckNextOwnerCopy",LLSD(BOOL(next_owner_mask & PERM_COPY)));
563 childSetValue("CheckNextOwnerTransfer",LLSD(BOOL(next_owner_mask & PERM_TRANSFER)));
564
565 LLRadioGroup* radioSaleType = LLUICtrlFactory::getRadioGroupByName(this,"RadioSaleType");
566 if (is_for_sale)
567 {
568 radioSaleType->setSelectedIndex((S32)sale_info.getSaleType() - 1);
569 char numerical_price[MAX_STRING];
570 sprintf(numerical_price, "%d", sale_info.getSalePrice());
571 childSetText("EditPrice",numerical_price);
572 }
573 else
574 {
575 radioSaleType->setSelectedIndex(-1);
576 childSetText("EditPrice","");
577 }
578}
579
580// static
581void LLFloaterProperties::onClickCreator(void* data)
582{
583 LLFloaterProperties* self = (LLFloaterProperties*)data;
584 if(!self) return;
585 LLInventoryItem* item = self->findItem();
586 if(!item) return;
587 if(!item->getCreatorUUID().isNull())
588 {
589 LLFloaterAvatarInfo::showFromObject(item->getCreatorUUID());
590 }
591}
592
593// static
594void LLFloaterProperties::onClickOwner(void* data)
595{
596 LLFloaterProperties* self = (LLFloaterProperties*)data;
597 if(!self) return;
598 LLInventoryItem* item = self->findItem();
599 if(!item) return;
600 if(item->getPermissions().isGroupOwned())
601 {
602 LLFloaterGroupInfo::showFromUUID(item->getPermissions().getGroup());
603 }
604 else
605 {
606 if(!item->getPermissions().getOwner().isNull())
607 {
608 LLFloaterAvatarInfo::showFromObject(item->getPermissions().getOwner());
609 }
610 }
611}
612
613// static
614void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data)
615{
616 //llinfos << "LLFloaterProperties::onCommitName()" << llendl;
617 LLFloaterProperties* self = (LLFloaterProperties*)data;
618 if(!self)
619 {
620 return;
621 }
622 LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
623 if(!item)
624 {
625 return;
626 }
627 LLLineEditor* labelItemName = LLUICtrlFactory::getLineEditorByName(self,"LabelItemName");
628
629 if(labelItemName&&
630 (item->getName() != labelItemName->getText()) &&
631 (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) )
632 {
633 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
634 new_item->rename(labelItemName->getText());
635 if(self->mObjectID.isNull())
636 {
637 new_item->updateServer(FALSE);
638 gInventory.updateItem(new_item);
639 gInventory.notifyObservers();
640 }
641 else
642 {
643 LLViewerObject* object = gObjectList.findObject(self->mObjectID);
644 if(object)
645 {
646 object->updateInventory(
647 new_item,
648 TASK_INVENTORY_ITEM_KEY,
649 false);
650 }
651 }
652 }
653}
654
655// static
656void LLFloaterProperties::onCommitDescription(LLUICtrl* ctrl, void* data)
657{
658 //llinfos << "LLFloaterProperties::onCommitDescription()" << llendl;
659 LLFloaterProperties* self = (LLFloaterProperties*)data;
660 if(!self) return;
661 LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
662 if(!item) return;
663
664 LLLineEditor* labelItemDesc = LLUICtrlFactory::getLineEditorByName(self,"LabelItemDesc");
665 if(!labelItemDesc)
666 {
667 return;
668 }
669 if((item->getDescription() != labelItemDesc->getText()) &&
670 (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)))
671 {
672 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
673
674 new_item->setDescription(labelItemDesc->getText());
675 if(self->mObjectID.isNull())
676 {
677 new_item->updateServer(FALSE);
678 gInventory.updateItem(new_item);
679 gInventory.notifyObservers();
680 }
681 else
682 {
683 LLViewerObject* object = gObjectList.findObject(self->mObjectID);
684 if(object)
685 {
686 object->updateInventory(
687 new_item,
688 TASK_INVENTORY_ITEM_KEY,
689 false);
690 }
691 }
692 }
693}
694
695// static
696void LLFloaterProperties::onCommitPermissions(LLUICtrl* ctrl, void* data)
697{
698 //llinfos << "LLFloaterProperties::onCommitPermissions()" << llendl;
699 LLFloaterProperties* self = (LLFloaterProperties*)data;
700 if(!self) return;
701 LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->findItem();
702 if(!item) return;
703 LLPermissions perm(item->getPermissions());
704
705
706 LLCheckBoxCtrl* CheckShareWithGroup = LLUICtrlFactory::getCheckBoxByName(self,"CheckShareWithGroup");
707
708 if(CheckShareWithGroup)
709 {
710 perm.setGroupBits(gAgent.getID(), gAgent.getGroupID(),
711 CheckShareWithGroup->get(),
712 PERM_MODIFY | PERM_MOVE | PERM_COPY);
713 }
714 LLCheckBoxCtrl* CheckEveryoneCopy = LLUICtrlFactory::getCheckBoxByName(self,"CheckEveryoneCopy");
715 if(CheckEveryoneCopy)
716 {
717 perm.setEveryoneBits(gAgent.getID(), gAgent.getGroupID(),
718 CheckEveryoneCopy->get(), PERM_COPY);
719 }
720
721 LLCheckBoxCtrl* CheckNextOwnerModify = LLUICtrlFactory::getCheckBoxByName(self,"CheckNextOwnerModify");
722 if(CheckNextOwnerModify)
723 {
724 perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
725 CheckNextOwnerModify->get(), PERM_MODIFY);
726 }
727 LLCheckBoxCtrl* CheckNextOwnerCopy = LLUICtrlFactory::getCheckBoxByName(self,"CheckNextOwnerCopy");
728 if(CheckNextOwnerCopy)
729 {
730 perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
731 CheckNextOwnerCopy->get(), PERM_COPY);
732 }
733 LLCheckBoxCtrl* CheckNextOwnerTransfer = LLUICtrlFactory::getCheckBoxByName(self,"CheckNextOwnerTransfer");
734 if(CheckNextOwnerTransfer)
735 {
736 perm.setNextOwnerBits(gAgent.getID(), gAgent.getGroupID(),
737 CheckNextOwnerTransfer->get(), PERM_TRANSFER);
738 }
739 if(perm != item->getPermissions()
740 && item->isComplete())
741 {
742 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
743 new_item->setPermissions(perm);
744 U32 flags = new_item->getFlags();
745 // If next owner permissions have changed (and this is an object)
746 // then set the slam permissions flag so that they are applied on rez.
747 if((perm.getMaskNextOwner()!=item->getPermissions().getMaskNextOwner())
748 && (item->getType() == LLAssetType::AT_OBJECT))
749 {
750 flags |= LLInventoryItem::II_FLAGS_OBJECT_SLAM_PERM;
751 }
752 // If everyone permissions have changed (and this is an object)
753 // then set the overwrite everyone permissions flag so they
754 // are applied on rez.
755 if ((perm.getMaskEveryone()!=item->getPermissions().getMaskEveryone())
756 && (item->getType() == LLAssetType::AT_OBJECT))
757 {
758 flags |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_EVERYONE;
759 }
760 // If group permissions have changed (and this is an object)
761 // then set the overwrite group permissions flag so they
762 // are applied on rez.
763 if ((perm.getMaskGroup()!=item->getPermissions().getMaskGroup())
764 && (item->getType() == LLAssetType::AT_OBJECT))
765 {
766 flags |= LLInventoryItem::II_FLAGS_OBJECT_PERM_OVERWRITE_GROUP;
767 }
768 new_item->setFlags(flags);
769 if(self->mObjectID.isNull())
770 {
771 new_item->updateServer(FALSE);
772 gInventory.updateItem(new_item);
773 gInventory.notifyObservers();
774 }
775 else
776 {
777 LLViewerObject* object = gObjectList.findObject(self->mObjectID);
778 if(object)
779 {
780 object->updateInventory(
781 new_item,
782 TASK_INVENTORY_ITEM_KEY,
783 false);
784 }
785 }
786 }
787 else
788 {
789 // need to make sure we don't just follow the click
790 self->refresh();
791 }
792}
793
794// static
795void LLFloaterProperties::onCommitSaleInfo(LLUICtrl* ctrl, void* data)
796{
797 //llinfos << "LLFloaterProperties::onCommitSaleInfo()" << llendl;
798 LLFloaterProperties* self = (LLFloaterProperties*)data;
799 if(!self) return;
800 self->updateSaleInfo();
801}
802
803// static
804void LLFloaterProperties::onCommitSaleType(LLUICtrl* ctrl, void* data)
805{
806 //llinfos << "LLFloaterProperties::onCommitSaleType()" << llendl;
807 LLFloaterProperties* self = (LLFloaterProperties*)data;
808 if(!self) return;
809 self->updateSaleInfo();
810}
811
812void LLFloaterProperties::updateSaleInfo()
813{
814 LLViewerInventoryItem* item = (LLViewerInventoryItem*)findItem();
815 if(!item) return;
816 LLSaleInfo sale_info(item->getSaleInfo());
817 if(!gAgent.allowOperation(PERM_TRANSFER, item->getPermissions(), GP_OBJECT_SET_SALE))
818 {
819 childSetValue("CheckPurchase",LLSD((BOOL)FALSE));
820 }
821
822 if((BOOL)childGetValue("CheckPurchase"))
823 {
824 // turn on sale info
825 LLSaleInfo::EForSale sale_type = LLSaleInfo::FS_COPY;
826
827 LLRadioGroup* RadioSaleType = LLUICtrlFactory::getRadioGroupByName(this,"RadioSaleType");
828 if(RadioSaleType)
829 {
830 switch (RadioSaleType->getSelectedIndex())
831 {
832 case 0:
833 sale_type = LLSaleInfo::FS_ORIGINAL;
834 break;
835 case 1:
836 sale_type = LLSaleInfo::FS_COPY;
837 break;
838 case 2:
839 sale_type = LLSaleInfo::FS_CONTENTS;
840 break;
841 default:
842 sale_type = LLSaleInfo::FS_COPY;
843 break;
844 }
845 }
846
847 if (sale_type == LLSaleInfo::FS_COPY
848 && !gAgent.allowOperation(PERM_COPY, item->getPermissions(),
849 GP_OBJECT_SET_SALE))
850 {
851 sale_type = LLSaleInfo::FS_ORIGINAL;
852 }
853
854 LLLineEditor* EditPrice = LLUICtrlFactory::getLineEditorByName(this,"EditPrice");
855
856 S32 price = -1;
857 if(EditPrice)
858 {
859 price = atoi(EditPrice->getText().c_str());
860 }
861 // Invalid data - turn off the sale
862 if (price < 0)
863 {
864 sale_type = LLSaleInfo::FS_NOT;
865 price = 0;
866 }
867
868 sale_info.setSaleType(sale_type);
869 sale_info.setSalePrice(price);
870 }
871 else
872 {
873 sale_info.setSaleType(LLSaleInfo::FS_NOT);
874 }
875 if(sale_info != item->getSaleInfo()
876 && item->isComplete())
877 {
878 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
879 new_item->setSaleInfo(sale_info);
880 if(mObjectID.isNull())
881 {
882 // This is in the agent's inventory.
883 new_item->updateServer(FALSE);
884 gInventory.updateItem(new_item);
885 gInventory.notifyObservers();
886 }
887 else
888 {
889 // This is in an object's contents.
890 LLViewerObject* object = gObjectList.findObject(mObjectID);
891 if(object)
892 {
893 object->updateInventory(
894 new_item,
895 TASK_INVENTORY_ITEM_KEY,
896 false);
897 }
898 }
899 }
900 else
901 {
902 // need to make sure we don't just follow the click
903 refresh();
904 }
905}
906
907LLInventoryItem* LLFloaterProperties::findItem() const
908{
909 LLInventoryItem* item = NULL;
910 if(mObjectID.isNull())
911 {
912 // it is in agent inventory
913 item = gInventory.getItem(mItemID);
914 }
915 else
916 {
917 LLViewerObject* object = gObjectList.findObject(mObjectID);
918 if(object)
919 {
920 item = (LLInventoryItem*)object->getInventoryObject(mItemID);
921 }
922 }
923 return item;
924}
925
926void LLFloaterProperties::closeByID(const LLUUID& item_id, const LLUUID &object_id)
927{
928 LLFloaterProperties* floaterp = find(item_id, object_id);
929
930 if (floaterp)
931 {
932 floaterp->close();
933 }
934}
935
936///----------------------------------------------------------------------------
937/// LLMultiProperties
938///----------------------------------------------------------------------------
939
940LLMultiProperties::LLMultiProperties(const LLRect &rect) : LLMultiFloater("Properties", rect)
941{
942}
943
944///----------------------------------------------------------------------------
945/// Local function definitions
946///----------------------------------------------------------------------------