diff options
Diffstat (limited to 'linden/indra/newview/llfloaterbulkpermission.cpp')
-rw-r--r-- | linden/indra/newview/llfloaterbulkpermission.cpp | 594 |
1 files changed, 594 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterbulkpermission.cpp b/linden/indra/newview/llfloaterbulkpermission.cpp new file mode 100644 index 0000000..e66d1af --- /dev/null +++ b/linden/indra/newview/llfloaterbulkpermission.cpp | |||
@@ -0,0 +1,594 @@ | |||
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 | bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func); | ||
212 | if(fail) | ||
213 | { | ||
214 | if ( !func.modifiable ) | ||
215 | { | ||
216 | gViewerWindow->alertXml("NO MODIFY"); | ||
217 | } | ||
218 | else | ||
219 | { | ||
220 | llwarns << "Bad logic. Are there actualy any items in that prim?" << llendl; | ||
221 | } | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | if (!q->start()) | ||
226 | { | ||
227 | llwarns << "Unexpected failure attepmting to set permissions." << llendl; | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | |||
232 | // Destroys the object | ||
233 | LLFloaterBulkPermission::~LLFloaterBulkPermission() | ||
234 | { | ||
235 | sInstances.removeData(mID); | ||
236 | } | ||
237 | |||
238 | // find an instance by ID. Return NULL if it does not exist. | ||
239 | // static | ||
240 | LLFloaterBulkPermission* LLFloaterBulkPermission::findInstance(const LLUUID& id) | ||
241 | { | ||
242 | if(sInstances.checkData(id)) | ||
243 | { | ||
244 | return sInstances.getData(id); | ||
245 | } | ||
246 | return NULL; | ||
247 | } | ||
248 | |||
249 | |||
250 | // This is the callback method for the viewer object currently being | ||
251 | // worked on. | ||
252 | // NOT static, virtual! | ||
253 | void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object, | ||
254 | InventoryObjectList* inv, | ||
255 | S32, | ||
256 | void* q_id) | ||
257 | { | ||
258 | llinfos << "LLFloaterBulkPermission::inventoryChanged() for object " | ||
259 | << viewer_object->getID() << llendl; | ||
260 | |||
261 | //Remove this listener from the object since its | ||
262 | //listener callback is now being executed. | ||
263 | |||
264 | //We remove the listener here because the function | ||
265 | //removeVOInventoryListener removes the listener from a ViewerObject | ||
266 | //which it internally stores. | ||
267 | |||
268 | //If we call this further down in the function, calls to handleInventory | ||
269 | //and nextObject may update the interally stored viewer object causing | ||
270 | //the removal of the incorrect listener from an incorrect object. | ||
271 | |||
272 | //Fixes SL-6119:Recompile scripts fails to complete | ||
273 | removeVOInventoryListener(); | ||
274 | |||
275 | if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) ) | ||
276 | { | ||
277 | handleInventory(viewer_object, inv); | ||
278 | } | ||
279 | else | ||
280 | { | ||
281 | // something went wrong... | ||
282 | // note that we're not working on this one, and move onto the | ||
283 | // next object in the list. | ||
284 | llwarns << "No inventory for " << mCurrentObjectID | ||
285 | << llendl; | ||
286 | nextObject(); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | void LLFloaterBulkPermission::onApplyBtn(void* user_data) | ||
291 | { | ||
292 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data; | ||
293 | self->doApply(); | ||
294 | } | ||
295 | |||
296 | |||
297 | // static | ||
298 | void LLFloaterBulkPermission::InvSelection(LLUICtrl* ctrl, void* data) | ||
299 | { | ||
300 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
301 | |||
302 | self->processObject=self->getChild<LLCheckBoxCtrl>("objects")->get(); | ||
303 | self->processScript=self->getChild<LLCheckBoxCtrl>("scripts")->get(); | ||
304 | self->processTexture=self->getChild<LLCheckBoxCtrl>("textures")->get(); | ||
305 | self->processSound=self->getChild<LLCheckBoxCtrl>("sounds")->get(); | ||
306 | self->processAnimation=self->getChild<LLCheckBoxCtrl>("animations")->get(); | ||
307 | self->processNotecard=self->getChild<LLCheckBoxCtrl>("notecards")->get(); | ||
308 | self->processGesture=self->getChild<LLCheckBoxCtrl>("gestures")->get(); | ||
309 | self->processClothing=self->getChild<LLCheckBoxCtrl>("clothing")->get(); | ||
310 | self->processBodypart=self->getChild<LLCheckBoxCtrl>("bodyparts")->get(); | ||
311 | self->processLandmark=self->getChild<LLCheckBoxCtrl>("landmarks")->get(); | ||
312 | |||
313 | |||
314 | } | ||
315 | |||
316 | // static | ||
317 | void LLFloaterBulkPermission::onParent(LLUICtrl* ctrl, void* data) | ||
318 | { | ||
319 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
320 | self->parent=self->getChild<LLCheckBoxCtrl>("Parent")->get(); | ||
321 | } | ||
322 | |||
323 | // static | ||
324 | void LLFloaterBulkPermission::onRecurse(LLUICtrl* ctrl, void* data) | ||
325 | { | ||
326 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
327 | self->recurse=self->getChild<LLCheckBoxCtrl>("Recurse")->get(); | ||
328 | } | ||
329 | |||
330 | // static | ||
331 | void LLFloaterBulkPermission::onCommitPermissions(LLUICtrl* ctrl, void* data) | ||
332 | { | ||
333 | LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data; | ||
334 | LLCheckBoxCtrl* CheckModify = self->getChild<LLCheckBoxCtrl>("Modify"); | ||
335 | LLCheckBoxCtrl* CheckCopy = self->getChild<LLCheckBoxCtrl>("Copy"); | ||
336 | LLCheckBoxCtrl* CheckTrans = self->getChild<LLCheckBoxCtrl>("Trans"); | ||
337 | |||
338 | self->req_perm_mask=0; | ||
339 | |||
340 | if(CheckModify->get()) | ||
341 | { | ||
342 | self->req_perm_mask|=PERM_MODIFY; | ||
343 | } | ||
344 | else | ||
345 | { | ||
346 | self->req_perm_mask&=~PERM_MODIFY; | ||
347 | } | ||
348 | |||
349 | if(CheckCopy->get()) | ||
350 | { | ||
351 | self->req_perm_mask|=PERM_COPY; | ||
352 | } | ||
353 | else | ||
354 | { | ||
355 | self->req_perm_mask&=~PERM_COPY; | ||
356 | } | ||
357 | |||
358 | if(CheckTrans->get()) | ||
359 | { | ||
360 | self->req_perm_mask|=PERM_TRANSFER; | ||
361 | } | ||
362 | else | ||
363 | { | ||
364 | self->req_perm_mask&=~PERM_TRANSFER; | ||
365 | } | ||
366 | |||
367 | |||
368 | } | ||
369 | |||
370 | void LLFloaterBulkPermission::addObject(const LLUUID& id) | ||
371 | { | ||
372 | mObjectIDs.put(id); | ||
373 | } | ||
374 | |||
375 | BOOL LLFloaterBulkPermission::start() | ||
376 | { | ||
377 | llinfos << "LLFloaterBulkPermission::start()" << llendl; | ||
378 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
379 | snprintf(buffer, sizeof(buffer), "Starting %s of %d items.", mStartString, mObjectIDs.count()); /* Flawfinder: ignore */ | ||
380 | |||
381 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
382 | list->addCommentText(buffer); | ||
383 | |||
384 | return nextObject(); | ||
385 | } | ||
386 | |||
387 | BOOL LLFloaterBulkPermission::isDone() const | ||
388 | { | ||
389 | return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); | ||
390 | } | ||
391 | |||
392 | // go to the next object. If no objects left, it falls out silently | ||
393 | // and waits to be killed by the window being closed. | ||
394 | BOOL LLFloaterBulkPermission::nextObject() | ||
395 | { | ||
396 | S32 count; | ||
397 | BOOL successful_start = FALSE; | ||
398 | do | ||
399 | { | ||
400 | count = mObjectIDs.count(); | ||
401 | llinfos << "LLFloaterBulkPermission::nextObject() - " << count | ||
402 | << " objects left to process." << llendl; | ||
403 | mCurrentObjectID.setNull(); | ||
404 | if(count > 0) | ||
405 | { | ||
406 | successful_start = popNext(); | ||
407 | } | ||
408 | llinfos << "LLFloaterBulkPermission::nextObject() " | ||
409 | << (successful_start ? "successful" : "unsuccessful") | ||
410 | << llendl; | ||
411 | } while((mObjectIDs.count() > 0) && !successful_start); | ||
412 | |||
413 | if(isDone() && !mDone) | ||
414 | { | ||
415 | |||
416 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
417 | mDone = TRUE; | ||
418 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
419 | snprintf(buffer, sizeof(buffer), "Done."); /* Flawfinder: ignore */ | ||
420 | list->addCommentText(buffer); | ||
421 | |||
422 | } | ||
423 | return successful_start; | ||
424 | } | ||
425 | |||
426 | // returns true if the queue has started, otherwise false. This | ||
427 | // method pops the top object off of the queue. | ||
428 | BOOL LLFloaterBulkPermission::popNext() | ||
429 | { | ||
430 | // get the first element off of the container, and attempt to get | ||
431 | // the inventory. | ||
432 | BOOL rv = FALSE; | ||
433 | S32 count = mObjectIDs.count(); | ||
434 | if(mCurrentObjectID.isNull() && (count > 0)) | ||
435 | { | ||
436 | mCurrentObjectID = mObjectIDs.get(0); | ||
437 | llinfos << "LLFloaterBulkPermission::popNext() - mCurrentID: " | ||
438 | << mCurrentObjectID << llendl; | ||
439 | mObjectIDs.remove(0); | ||
440 | LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID); | ||
441 | if(obj) | ||
442 | { | ||
443 | llinfos << "LLFloaterBulkPermission::popNext() requesting inv for " | ||
444 | << mCurrentObjectID << llendl; | ||
445 | LLUUID* id = new LLUUID(mID); | ||
446 | |||
447 | registerVOInventoryListener(obj,id); | ||
448 | requestVOInventory(); | ||
449 | rv = TRUE; | ||
450 | } | ||
451 | else | ||
452 | { | ||
453 | llinfos<<"LLFloaterBulkPermission::popNext() returned a NULL LLViewerObject" <<llendl; | ||
454 | //Arrrg what do we do here? | ||
455 | } | ||
456 | } | ||
457 | |||
458 | return rv; | ||
459 | } | ||
460 | |||
461 | |||
462 | // static | ||
463 | LLFloaterBulkPermission* LLFloaterBulkPermission::create() | ||
464 | { | ||
465 | S32 left, top; | ||
466 | gFloaterView->getNewFloaterPosition(&left, &top); | ||
467 | LLRect rect = gSavedSettings.getRect("CompileOutputRect"); | ||
468 | rect.translate(left - rect.mLeft, top - rect.mTop); | ||
469 | LLFloaterBulkPermission* new_queue = new LLFloaterBulkPermission("queue",rect,"Setting Bulk permissions","Results"); | ||
470 | new_queue->open(); /*Flawfinder: ignore*/ | ||
471 | return new_queue; | ||
472 | } | ||
473 | |||
474 | |||
475 | void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv) | ||
476 | { | ||
477 | // find all of the lsl, leaving off duplicates. We'll remove | ||
478 | // all matching asset uuids on compilation success. | ||
479 | |||
480 | llinfos<<"handleInventory"<<llendl; | ||
481 | |||
482 | char buffer[MAX_STRING]; /*Flawfinder: ignore*/ | ||
483 | LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); | ||
484 | |||
485 | InventoryObjectList::const_iterator it = inv->begin(); | ||
486 | InventoryObjectList::const_iterator end = inv->end(); | ||
487 | for ( ; it != end; ++it) | ||
488 | { | ||
489 | llinfos<<"Doing iterator of inventory"<<llendl; | ||
490 | |||
491 | if( ( (*it)->getType() == LLAssetType::AT_LSL_TEXT && processScript) || | ||
492 | ( (*it)->getType() == LLAssetType::AT_TEXTURE && processTexture) || | ||
493 | ( (*it)->getType() == LLAssetType::AT_SOUND && processSound) || | ||
494 | ( (*it)->getType() == LLAssetType::AT_LANDMARK && processLandmark) || | ||
495 | ( (*it)->getType() == LLAssetType::AT_CLOTHING && processClothing) || | ||
496 | ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject) || | ||
497 | ( (*it)->getType() == LLAssetType::AT_NOTECARD && processNotecard) || | ||
498 | ( (*it)->getType() == LLAssetType::AT_BODYPART && processBodypart) || | ||
499 | ( (*it)->getType() == LLAssetType::AT_ANIMATION && processAnimation) || | ||
500 | ( (*it)->getType() == LLAssetType::AT_GESTURE && processGesture)) | ||
501 | { | ||
502 | |||
503 | LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); | ||
504 | |||
505 | if (object) | ||
506 | { | ||
507 | LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it)); | ||
508 | LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item; | ||
509 | LLPermissions perm(new_item->getPermissions()); | ||
510 | |||
511 | // chomp the inventory name so it fits in the scroll window nicely | ||
512 | // and the user can see the [OK] | ||
513 | std::string invname; | ||
514 | invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 ); | ||
515 | |||
516 | // My attempt at checking valid permissions, CHECK ME | ||
517 | // note its not actually bad to try to set permissions that are not allowed as the | ||
518 | // server will protect against this, but it will piss the user off if its wrong | ||
519 | if( | ||
520 | (perm.getCreator()==gAgentID) || | ||
521 | (perm.getMaskOwner() & PERM_TRANSFER) && (perm.getMaskOwner() & PERM_MODIFY) || | ||
522 | (gAgent.getGroupID()==perm.getGroup() && (perm.getMaskGroup() & PERM_TRANSFER) && (perm.getMaskGroup() & PERM_MODIFY)) | ||
523 | ){ | ||
524 | llinfos<<"Setting perms"<<llendl; | ||
525 | perm.setMaskNext(req_perm_mask); | ||
526 | new_item->setPermissions(perm); | ||
527 | updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE); | ||
528 | snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [OK]", invname.c_str()); /* Flawfinder: ignore */ | ||
529 | } | ||
530 | else | ||
531 | { | ||
532 | llinfos<<"NOT setting perms"<<llendl; | ||
533 | snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [FAILED]", invname.c_str()); /* Flawfinder: ignore */ | ||
534 | |||
535 | } | ||
536 | |||
537 | list->addCommentText(buffer); | ||
538 | |||
539 | if(recurse && ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject)) | ||
540 | { | ||
541 | //Add this object back to the queue to be processed as it has inventory | ||
542 | snprintf(buffer, sizeof(buffer), "Queueing object '%s' for open", invname.c_str()); | ||
543 | llwarns << "Queueing object "<< invname.c_str() << " ID "<< (*it)->getUUID()<<llendl; | ||
544 | mObjectIDs.put((*it)->getUUID()); | ||
545 | // This will not YET work. as this is not a viewer object the unpack will fail | ||
546 | } | ||
547 | |||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | nextObject(); | ||
553 | } | ||
554 | |||
555 | |||
556 | // Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update | ||
557 | // we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers | ||
558 | // us up and we would have a dodgy item iterator | ||
559 | |||
560 | void LLFloaterBulkPermission::updateInventory( | ||
561 | LLViewerObject* object, | ||
562 | LLViewerInventoryItem* item, | ||
563 | U8 key, | ||
564 | bool is_new) | ||
565 | { | ||
566 | LLMemType mt(LLMemType::MTYPE_OBJECT); | ||
567 | |||
568 | |||
569 | // This slices the object into what we're concerned about on the | ||
570 | // viewer. The simulator will take the permissions and transfer | ||
571 | // ownership. | ||
572 | LLPointer<LLViewerInventoryItem> task_item = | ||
573 | new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(), | ||
574 | item->getAssetUUID(), item->getType(), | ||
575 | item->getInventoryType(), | ||
576 | item->getName(), item->getDescription(), | ||
577 | item->getSaleInfo(), | ||
578 | item->getFlags(), | ||
579 | item->getCreationDate()); | ||
580 | task_item->setTransactionID(item->getTransactionID()); | ||
581 | LLMessageSystem* msg = gMessageSystem; | ||
582 | msg->newMessageFast(_PREHASH_UpdateTaskInventory); | ||
583 | msg->nextBlockFast(_PREHASH_AgentData); | ||
584 | msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
585 | msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
586 | msg->nextBlockFast(_PREHASH_UpdateData); | ||
587 | msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); | ||
588 | msg->addU8Fast(_PREHASH_Key, key); | ||
589 | msg->nextBlockFast(_PREHASH_InventoryData); | ||
590 | task_item->packMessage(msg); | ||
591 | msg->sendReliable(object->getRegion()->getHost()); | ||
592 | |||
593 | } | ||
594 | |||