diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloaterproperties.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 946 |
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 | |||
62 | const char* YOU_CAN = "You can:"; | ||
63 | const char* OWNER_CAN = "Owner can: "; | ||
64 | |||
65 | |||
66 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
67 | // Class LLPropertiesObserver | ||
68 | // | ||
69 | // helper class to watch the inventory. | ||
70 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
71 | |||
72 | class LLPropertiesObserver : public LLInventoryObserver | ||
73 | { | ||
74 | public: | ||
75 | LLPropertiesObserver() {} | ||
76 | virtual ~LLPropertiesObserver() {} | ||
77 | virtual void changed(U32 mask); | ||
78 | }; | ||
79 | |||
80 | LLPropertiesObserver* gPropertiesObserver = NULL; | ||
81 | void 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 | |||
96 | LLFloaterProperties::instance_map LLFloaterProperties::sInstances; | ||
97 | |||
98 | // static | ||
99 | LLFloaterProperties* 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 | ||
115 | LLFloaterProperties* 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 | |||
134 | void 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 | ||
145 | LLFloaterProperties::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 | ||
192 | LLFloaterProperties::~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 | |||
202 | void 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 | |||
253 | void 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 | |||
265 | void 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 | ||
581 | void 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 | ||
594 | void 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 | ||
614 | void 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 | ||
656 | void 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 | ||
696 | void 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 | ||
795 | void 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 | ||
804 | void 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 | |||
812 | void 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 | |||
907 | LLInventoryItem* 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 | |||
926 | void 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 | |||
940 | LLMultiProperties::LLMultiProperties(const LLRect &rect) : LLMultiFloater("Properties", rect) | ||
941 | { | ||
942 | } | ||
943 | |||
944 | ///---------------------------------------------------------------------------- | ||
945 | /// Local function definitions | ||
946 | ///---------------------------------------------------------------------------- | ||