diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloaterbulkpermission.cpp | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterbulkpermission.cpp b/linden/indra/newview/llfloaterbulkpermission.cpp new file mode 100644 index 0000000..29d94bc --- /dev/null +++ b/linden/indra/newview/llfloaterbulkpermission.cpp | |||
@@ -0,0 +1,595 @@ | |||
1 | /** | ||
2 | * @file llfloaterbulkpermissions.cpp | ||
3 | * @brief A floater which allows task inventory item's properties to be changed on mass. | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2008&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | /* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */ | ||
33 | |||
34 | /* TODO | ||
35 | |||
36 | * Add in the option to select objects or task inventory | ||
37 | s | ||
38 | |||
39 | It would be nice to set the permissions on groups of prims as well as task inventory | ||
40 | |||
41 | */ | ||
42 | |||
43 | |||
44 | #include "llviewerprecompiledheaders.h" | ||
45 | #include "llfloaterbulkpermission.h" | ||
46 | #include "llagent.h" | ||
47 | #include "llchat.h" | ||
48 | #include "llviewerwindow.h" | ||
49 | #include "llviewerobject.h" | ||
50 | #include "llviewerobjectlist.h" | ||
51 | #include "llviewerregion.h" | ||
52 | #include "lscript_rt_interface.h" | ||
53 | #include "llviewercontrol.h" | ||
54 | #include "llviewerobject.h" | ||
55 | #include "llviewerregion.h" | ||
56 | #include "llresmgr.h" | ||
57 | #include "llbutton.h" | ||
58 | #include "lldir.h" | ||
59 | #include "llfloaterchat.h" | ||
60 | #include "llviewerstats.h" | ||
61 | #include "lluictrlfactory.h" | ||
62 | #include "llselectmgr.h" | ||
63 | #include "llinventory.h" | ||
64 | |||
65 | |||
66 | #include <algorithm> | ||
67 | #include <functional> | ||
68 | #include "llcachename.h" | ||
69 | #include "lldbstrings.h" | ||
70 | #include "llinventory.h" | ||
71 | |||
72 | #include "llagent.h" | ||
73 | #include "llbutton.h" | ||
74 | #include "llcheckboxctrl.h" | ||
75 | #include "llfloateravatarinfo.h" | ||
76 | #include "llfloatergroupinfo.h" | ||
77 | #include "llinventorymodel.h" | ||
78 | #include "lllineeditor.h" | ||
79 | #include "llradiogroup.h" | ||
80 | #include "llresmgr.h" | ||
81 | #include "roles_constants.h" | ||
82 | #include "llselectmgr.h" | ||
83 | #include "lltextbox.h" | ||
84 | #include "lluiconstants.h" | ||
85 | #include "llviewerinventory.h" | ||
86 | #include "llviewerobjectlist.h" | ||
87 | #include "llviewerregion.h" | ||
88 | #include "llviewercontrol.h" | ||
89 | |||
90 | #include "lluictrlfactory.h" | ||
91 | |||
92 | |||
93 | const char* BULKPERM_QUEUE_TITLE = "Update Progress"; | ||
94 | const char* BULKPERM_START_STRING = "update"; | ||
95 | |||
96 | namespace | ||
97 | { | ||
98 | struct BulkQueueObjects : public LLSelectedObjectFunctor | ||
99 | { | ||
100 | BOOL scripted; | ||
101 | BOOL modifiable; | ||
102 | LLFloaterBulkPermission* mQueue; | ||
103 | BulkQueueObjects(LLFloaterBulkPermission* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {} | ||
104 | virtual bool apply(LLViewerObject* obj) | ||
105 | { | ||
106 | scripted = obj->flagScripted(); | ||
107 | modifiable = obj->permModify(); | ||
108 | |||
109 | mQueue->addObject(obj->getID()); | ||
110 | return false; | ||
111 | |||
112 | } | ||
113 | }; | ||
114 | } | ||
115 | |||
116 | ///---------------------------------------------------------------------------- | ||
117 | /// Class LLFloaterBulkPermission | ||
118 | ///---------------------------------------------------------------------------- | ||
119 | |||
120 | // static | ||
121 | LLMap<LLUUID, LLFloaterBulkPermission*> LLFloaterBulkPermission::sInstances; | ||
122 | |||
123 | |||
124 | // Default constructor | ||
125 | LLFloaterBulkPermission::LLFloaterBulkPermission(const std::string& name, | ||
126 | const LLRect& rect, | ||
127 | const char* title, | ||
128 | const char* start_string) : | ||
129 | LLFloater(name, rect, title, | ||
130 | RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT, | ||
131 | DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES) | ||
132 | { | ||
133 | |||
134 | req_perm_mask=0; // This should match the default state the checkboxes are set to | ||
135 | recurse=false; | ||
136 | |||
137 | LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml"); | ||
138 | |||
139 | childSetAction("Apply...",onApplyBtn,this); | ||
140 | childSetEnabled("Apply...",TRUE); | ||
141 | |||
142 | childSetCommitCallback("Modify",&onCommitPermissions, this); | ||
143 | childSetCommitCallback("Trans",&onCommitPermissions, this); | ||
144 | childSetCommitCallback("Copy",&onCommitPermissions, this); | ||
145 | |||
146 | //childSetCommitCallback("Recurse",&onRecurse, this); | ||
147 | |||
148 | childSetCommitCallback("Parent",&onParent, this); | ||
149 | |||
150 | childSetCommitCallback("objects",&InvSelection, this); | ||
151 | childSetCommitCallback("scripts",&InvSelection, this); | ||
152 | childSetCommitCallback("textures",&InvSelection, this); | ||
153 | childSetCommitCallback("sounds",&InvSelection, this); | ||
154 | childSetCommitCallback("animations",&InvSelection, this); | ||
155 | childSetCommitCallback("notecards",&InvSelection, this); | ||
156 | childSetCommitCallback("landmarks",&InvSelection, this); | ||
157 | childSetCommitCallback("bodyparts",&InvSelection, this); | ||
158 | childSetCommitCallback("clothing",&InvSelection, this); | ||
159 | childSetCommitCallback("gestures",&InvSelection, this); | ||
160 | |||
161 | //Set variable state to XUI default state consistancy | ||
162 | processObject=getChild<LLCheckBoxCtrl>("objects")->get(); | ||
163 | processScript=getChild<LLCheckBoxCtrl>("scripts")->get(); | ||
164 | processTexture=getChild<LLCheckBoxCtrl>("textures")->get(); | ||
165 | processSound=getChild<LLCheckBoxCtrl>("sounds")->get(); | ||
166 | processAnimation=getChild<LLCheckBoxCtrl>("animations")->get(); | ||
167 | processNotecard=getChild<LLCheckBoxCtrl>("notecards")->get(); | ||
168 | processGesture=getChild<LLCheckBoxCtrl>("gestures")->get(); | ||
169 | processClothing=getChild<LLCheckBoxCtrl>("clothing")->get(); | ||
170 | processBodypart=getChild<LLCheckBoxCtrl>("bodyparts")->get(); | ||
171 | processLandmark=getChild<LLCheckBoxCtrl>("landmarks")->get(); | ||
172 | parent=getChild<LLCheckBoxCtrl>("Parent")->get(); | ||
173 | |||
174 | |||
175 | setTitle(title); | ||
176 | |||
177 | if (!getHost()) | ||
178 | { | ||
179 | LLRect curRect = getRect(); | ||
180 | translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); | ||
181 | } | ||
182 | |||
183 | mStartString = start_string; | ||
184 | mDone = FALSE; | ||
185 | sInstances.addData(mID, this); | ||
186 | |||
187 | } | ||
188 | |||
189 | void LLFloaterBulkPermission::doApply() | ||
190 | { | ||
191 | // Its alive now do the nasty work that the ScriptQueue and friends try to do in the menu code | ||
192 | // but first grab the user options | ||
193 | |||
194 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
195 | list->deleteAllItems(); | ||
196 | |||
197 | //Apply to selected objects if requested first | ||
198 | |||
199 | if(parent) | ||
200 | { | ||
201 | llinfos<< "Setting permission on parent items" << llendl; | ||
202 | LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,true, req_perm_mask); | ||
203 | LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,false, ~req_perm_mask); //How annoying need to set and unset | ||
204 | } | ||
205 | |||
206 | |||
207 | LLFloaterBulkPermission* q; | ||
208 | q=(LLFloaterBulkPermission*)this; | ||
209 | |||
210 | BulkQueueObjects func(q); | ||
211 | const bool firstonly = false; | ||
212 | bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func, firstonly); | ||
213 | if(fail) | ||
214 | { | ||
215 | if ( !func.modifiable ) | ||
216 | { | ||
217 | gViewerWindow->alertXml("NO MODIFY"); | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | llwarns << "Bad logic. Are there actualy any items in that prim?" << llendl; | ||
222 | } | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | if (!q->start()) | ||
227 | { | ||
228 | llwarns << "Unexpected failure attepmting to set permissions." << llendl; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | // Destroys the object | ||
234 | LLFloaterBulkPermission::~LLFloaterBulkPermission() | ||
235 | { | ||
236 | sInstances.removeData(mID); | ||
237 | } | ||
238 | |||
239 | // find an instance by ID. Return NULL if it does not exist. | ||
240 | // static | ||
241 | LLFloaterBulkPermission* LLFloaterBulkPermission::findInstance(const LLUUID& id) | ||
242 | { | ||
243 | if(sInstances.checkData(id)) | ||
244 | { | ||
245 | return sInstances.getData(id); | ||
246 | } | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | |||
251 | // This is the callback method for the viewer object currently being | ||
252 | // worked on. | ||
253 | // NOT static, virtual! | ||
254 | void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, | ||
255 | InventoryObjectList* inv, | ||
256 | S32, | ||
257 | void* q_id) | ||
258 | { | ||
259 | llinfos << "LLFloaterBulkPermission::inventoryChanged() for object " | ||
260 | << viewer_object->getID() << llendl; | ||
261 | |||
262 | //Remove this listener from the object since its | ||
263 | //listener callback is now being executed. | ||
264 | |||
265 | //We remove the listener here because the function | ||
266 | //removeVOInventoryListener removes the listener from a ViewerObject | ||
267 | //which it internally stores. | ||
268 | |||
269 | //If we call this further down in the function, calls to handleInventory | ||
270 | //and nextObject may update the interally stored viewer object causing | ||
271 | //the removal of the incorrect listener from an incorrect object. | ||
272 | |||
273 | //Fixes SL-6119:Recompile scripts fails to complete | ||
274 | removeVOInventoryListener(); | ||
275 | |||
276 | if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) | ||
277 | { | ||
278 | handleInventory(viewer_object, inv); | ||
279 | } | ||
280 | else | ||
281 | { | ||
282 | // something went wrong... | ||
283 | // note that we're not working on this one, and move onto the | ||
284 | // next object in the list. | ||
285 | llwarns << "No inventory for " << mCurrentObjectID | ||
286 | << llendl; | ||
287 | nextObject(); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | void LLFloaterBulkPermission::onApplyBtn(void* user_data) | ||
292 | { | ||
293 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data; | ||
294 | self->doApply(); | ||
295 | } | ||
296 | |||
297 | |||
298 | // static | ||
299 | void LLFloaterBulkPermission::InvSelection(LLUICtrl* ctrl, void* data) | ||
300 | { | ||
301 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
302 | |||
303 | self->processObject=self->getChild<LLCheckBoxCtrl>("objects")->get(); | ||
304 | self->processScript=self->getChild<LLCheckBoxCtrl>("scripts")->get(); | ||
305 | self->processTexture=self->getChild<LLCheckBoxCtrl>("textures")->get(); | ||
306 | self->processSound=self->getChild<LLCheckBoxCtrl>("sounds")->get(); | ||
307 | self->processAnimation=self->getChild<LLCheckBoxCtrl>("animations")->get(); | ||
308 | self->processNotecard=self->getChild<LLCheckBoxCtrl>("notecards")->get(); | ||
309 | self->processGesture=self->getChild<LLCheckBoxCtrl>("gestures")->get(); | ||
310 | self->processClothing=self->getChild<LLCheckBoxCtrl>("clothing")->get(); | ||
311 | self->processBodypart=self->getChild<LLCheckBoxCtrl>("bodyparts")->get(); | ||
312 | self->processLandmark=self->getChild<LLCheckBoxCtrl>("landmarks")->get(); | ||
313 | |||
314 | |||
315 | } | ||
316 | |||
317 | // static | ||
318 | void LLFloaterBulkPermission::onParent(LLUICtrl* ctrl, void* data) | ||
319 | { | ||
320 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
321 | self->parent=self->getChild<LLCheckBoxCtrl>("Parent")->get(); | ||
322 | } | ||
323 | |||
324 | // static | ||
325 | void LLFloaterBulkPermission::onRecurse(LLUICtrl* ctrl, void* data) | ||
326 | { | ||
327 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
328 | self->recurse=self->getChild<LLCheckBoxCtrl>("Recurse")->get(); | ||
329 | } | ||
330 | |||
331 | // static | ||
332 | void LLFloaterBulkPermission::onCommitPermissions(LLUICtrl* ctrl, void* data) | ||
333 | { | ||
334 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
335 | LLCheckBoxCtrl* CheckModify = self->getChild<LLCheckBoxCtrl>("Modify"); | ||
336 | LLCheckBoxCtrl* CheckCopy = self->getChild<LLCheckBoxCtrl>("Copy"); | ||
337 | LLCheckBoxCtrl* CheckTrans = self->getChild<LLCheckBoxCtrl>("Trans"); | ||
338 | |||
339 | self->req_perm_mask=0; | ||
340 | |||
341 | if(CheckModify->get()) | ||
342 | { | ||
343 | self->req_perm_mask|=PERM_MODIFY; | ||
344 | } | ||
345 | else | ||
346 | { | ||
347 | self->req_perm_mask&=~PERM_MODIFY; | ||
348 | } | ||
349 | |||
350 | if(CheckCopy->get()) | ||
351 | { | ||
352 | self->req_perm_mask|=PERM_COPY; | ||
353 | } | ||
354 | else | ||
355 | { | ||
356 | self->req_perm_mask&=~PERM_COPY; | ||
357 | } | ||
358 | |||
359 | if(CheckTrans->get()) | ||
360 | { | ||
361 | self->req_perm_mask|=PERM_TRANSFER; | ||
362 | } | ||
363 | else | ||
364 | { | ||
365 | self->req_perm_mask&=~PERM_TRANSFER; | ||
366 | } | ||
367 | |||
368 | |||
369 | } | ||
370 | |||
371 | void LLFloaterBulkPermission::addObject(const LLUUID& id) | ||
372 | { | ||
373 | mObjectIDs.put(id); | ||
374 | } | ||
375 | |||
376 | BOOL LLFloaterBulkPermission::start() | ||
377 | { | ||
378 | llinfos << "LLFloaterBulkPermission::start()" << llendl; | ||
379 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
380 | snprintf(buffer, sizeof(buffer), "Starting %s of %d items.", mStartString, mObjectIDs.count()); /* Flawfinder: ignore */ | ||
381 | |||
382 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
383 | list->addCommentText(buffer); | ||
384 | |||
385 | return nextObject(); | ||
386 | } | ||
387 | |||
388 | BOOL LLFloaterBulkPermission::isDone() const | ||
389 | { | ||
390 | return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); | ||
391 | } | ||
392 | |||
393 | // go to the next object. If no objects left, it falls out silently | ||
394 | // and waits to be killed by the window being closed. | ||
395 | BOOL LLFloaterBulkPermission::nextObject() | ||
396 | { | ||
397 | S32 count; | ||
398 | BOOL successful_start = FALSE; | ||
399 | do | ||
400 | { | ||
401 | count = mObjectIDs.count(); | ||
402 | llinfos << "LLFloaterBulkPermission::nextObject() - " << count | ||
403 | << " objects left to process." << llendl; | ||
404 | mCurrentObjectID.setNull(); | ||
405 | if(count > 0) | ||
406 | { | ||
407 | successful_start = popNext(); | ||
408 | } | ||
409 | llinfos << "LLFloaterBulkPermission::nextObject() " | ||
410 | << (successful_start ? "successful" : "unsuccessful") | ||
411 | << llendl; | ||
412 | } while((mObjectIDs.count() > 0) && !successful_start); | ||
413 | |||
414 | if(isDone() && !mDone) | ||
415 | { | ||
416 | |||
417 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
418 | mDone = TRUE; | ||
419 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
420 | snprintf(buffer, sizeof(buffer), "Done."); /* Flawfinder: ignore */ | ||
421 | list->addCommentText(buffer); | ||
422 | |||
423 | } | ||
424 | return successful_start; | ||
425 | } | ||
426 | |||
427 | // returns true if the queue has started, otherwise false. This | ||
428 | // method pops the top object off of the queue. | ||
429 | BOOL LLFloaterBulkPermission::popNext() | ||
430 | { | ||
431 | // get the first element off of the container, and attempt to get | ||
432 | // the inventory. | ||
433 | BOOL rv = FALSE; | ||
434 | S32 count = mObjectIDs.count(); | ||
435 | if(mCurrentObjectID.isNull() && (count > 0)) | ||
436 | { | ||
437 | mCurrentObjectID = mObjectIDs.get(0); | ||
438 | llinfos << "LLFloaterBulkPermission::popNext() - mCurrentID: " | ||
439 | << mCurrentObjectID << llendl; | ||
440 | mObjectIDs.remove(0); | ||
441 | LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); | ||
442 | if(obj) | ||
443 | { | ||
444 | llinfos << "LLFloaterBulkPermission::popNext() requesting inv for " | ||
445 | << mCurrentObjectID << llendl; | ||
446 | LLUUID* id = new LLUUID(mID); | ||
447 | |||
448 | registerVOInventoryListener(obj,id); | ||
449 | requestVOInventory(); | ||
450 | rv = TRUE; | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | llinfos<<"LLFloaterBulkPermission::popNext() returned a NULL LLViewerObject" <<llendl; | ||
455 | //Arrrg what do we do here? | ||
456 | } | ||
457 | } | ||
458 | |||
459 | return rv; | ||
460 | } | ||
461 | |||
462 | |||
463 | // static | ||
464 | LLFloaterBulkPermission* LLFloaterBulkPermission::create() | ||
465 | { | ||
466 | S32 left, top; | ||
467 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
468 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
469 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
470 | LLFloaterBulkPermission* new_queue = new LLFloaterBulkPermission("queue",rect,"Setting Bulk permissions","Results"); | ||
471 | new_queue->open(); /*Flawfinder: ignore*/ | ||
472 | return new_queue; | ||
473 | } | ||
474 | |||
475 | |||
476 | void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv) | ||
477 | { | ||
478 | // find all of the lsl, leaving off duplicates. We'll remove | ||
479 | // all matching asset uuids on compilation success. | ||
480 | |||
481 | llinfos<<"handleInventory"<<llendl; | ||
482 | |||
483 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
484 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
485 | |||
486 | InventoryObjectList::const_iterator it = inv->begin(); | ||
487 | InventoryObjectList::const_iterator end = inv->end(); | ||
488 | for ( ; it != end; ++it) | ||
489 | { | ||
490 | llinfos<<"Doing iterator of inventory"<<llendl; | ||
491 | |||
492 | if( ( (*it)->getType() == LLAssetType::AT_LSL_TEXT && processScript) || | ||
493 | ( (*it)->getType() == LLAssetType::AT_TEXTURE && processTexture) || | ||
494 | ( (*it)->getType() == LLAssetType::AT_SOUND && processSound) || | ||
495 | ( (*it)->getType() == LLAssetType::AT_LANDMARK && processLandmark) || | ||
496 | ( (*it)->getType() == LLAssetType::AT_CLOTHING && processClothing) || | ||
497 | ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject) || | ||
498 | ( (*it)->getType() == LLAssetType::AT_NOTECARD && processNotecard) || | ||
499 | ( (*it)->getType() == LLAssetType::AT_BODYPART && processBodypart) || | ||
500 | ( (*it)->getType() == LLAssetType::AT_ANIMATION && processAnimation) || | ||
501 | ( (*it)->getType() == LLAssetType::AT_GESTURE && processGesture)) | ||
502 | { | ||
503 | |||
504 | LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); | ||
505 | |||
506 | if (object) | ||
507 | { | ||
508 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
509 | LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item; | ||
510 | LLPermissions perm(new_item->getPermissions()); | ||
511 | |||
512 | // chomp the inventory name so it fits in the scroll window nicely | ||
513 | // and the user can see the [OK] | ||
514 | std::string invname; | ||
515 | invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 ); | ||
516 | |||
517 | // My attempt at checking valid permissions, CHECK ME | ||
518 | // note its not actually bad to try to set permissions that are not allowed as the | ||
519 | // server will protect against this, but it will piss the user off if its wrong | ||
520 | if( | ||
521 | (perm.getCreator()==gAgentID) || | ||
522 | (perm.getMaskOwner() & PERM_TRANSFER) && (perm.getMaskOwner() & PERM_MODIFY) || | ||
523 | (gAgent.getGroupID()==perm.getGroup() && (perm.getMaskGroup() & PERM_TRANSFER) && (perm.getMaskGroup() & PERM_MODIFY)) | ||
524 | ){ | ||
525 | llinfos<<"Setting perms"<<llendl; | ||
526 | perm.setMaskNext(req_perm_mask); | ||
527 | new_item->setPermissions(perm); | ||
528 | updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE); | ||
529 | snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [OK]", invname.c_str()); /* Flawfinder: ignore */ | ||
530 | } | ||
531 | else | ||
532 | { | ||
533 | llinfos<<"NOT setting perms"<<llendl; | ||
534 | snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [FAILED]", invname.c_str()); /* Flawfinder: ignore */ | ||
535 | |||
536 | } | ||
537 | |||
538 | list->addCommentText(buffer); | ||
539 | |||
540 | if(recurse && ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject)) | ||
541 | { | ||
542 | //Add this object back to the queue to be processed as it has inventory | ||
543 | snprintf(buffer, sizeof(buffer), "Queueing object '%s' for open", invname.c_str()); | ||
544 | llwarns << "Queueing object "<< invname.c_str() << " ID "<< (*it)->getUUID()<<llendl; | ||
545 | mObjectIDs.put((*it)->getUUID()); | ||
546 | // This will not YET work. as this is not a viewer object the unpack will fail | ||
547 | } | ||
548 | |||
549 | } | ||
550 | } | ||
551 | } | ||
552 | |||
553 | nextObject(); | ||
554 | } | ||
555 | |||
556 | |||
557 | // Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update | ||
558 | // we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers | ||
559 | // us up and we would have a dodgy item iterator | ||
560 | |||
561 | void LLFloaterBulkPermission::updateInventory( | ||
562 | LLViewerObject* object, | ||
563 | LLViewerInventoryItem* item, | ||
564 | U8 key, | ||
565 | bool is_new) | ||
566 | { | ||
567 | LLMemType mt(LLMemType::MTYPE_OBJECT); | ||
568 | |||
569 | |||
570 | // This slices the object into what we're concerned about on the | ||
571 | // viewer. The simulator will take the permissions and transfer | ||
572 | // ownership. | ||
573 | LLPointer<LLViewerInventoryItem> task_item = | ||
574 | new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), | ||
575 | item->getAssetUUID(), item->getType(), | ||
576 | item->getInventoryType(), | ||
577 | item->getName(), item->getDescription(), | ||
578 | item->getSaleInfo(), | ||
579 | item->getFlags(), | ||
580 | item->getCreationDate()); | ||
581 | task_item->setTransactionID(item->getTransactionID()); | ||
582 | LLMessageSystem* msg = gMessageSystem; | ||
583 | msg->newMessageFast(_PREHASH_UpdateTaskInventory); | ||
584 | msg->nextBlockFast(_PREHASH_AgentData); | ||
585 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
586 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
587 | msg->nextBlockFast(_PREHASH_UpdateData); | ||
588 | msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); | ||
589 | msg->addU8Fast(_PREHASH_Key, key); | ||
590 | msg->nextBlockFast(_PREHASH_InventoryData); | ||
591 | task_item->packMessage(msg); | ||
592 | msg->sendReliable(object->getRegion()->getHost()); | ||
593 | |||
594 | } | ||
595 | |||