diff options
author | Michelle2 Zenovka | 2008-09-20 13:16:14 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-09-20 13:16:14 -0500 |
commit | 3282c5ff73176cb9fe8a8be6a372790516237448 (patch) | |
tree | 07d019937b7d6ad84c4213f609de1f48da1e207f | |
parent | New optional SConstruct flag to specify an exact path to build (diff) | |
download | meta-impy-3282c5ff73176cb9fe8a8be6a372790516237448.zip meta-impy-3282c5ff73176cb9fe8a8be6a372790516237448.tar.gz meta-impy-3282c5ff73176cb9fe8a8be6a372790516237448.tar.bz2 meta-impy-3282c5ff73176cb9fe8a8be6a372790516237448.tar.xz |
VWR-5082: 'Set permissions on selected task inventory' feature.
Diffstat (limited to '')
-rw-r--r-- | ChangeLog.txt | 13 | ||||
-rw-r--r-- | linden/indra/newview/llfloaterbulkpermission.cpp | 595 | ||||
-rw-r--r-- | linden/indra/newview/llfloaterbulkpermission.h | 143 | ||||
-rw-r--r-- | linden/indra/newview/llviewermenu.cpp | 13 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml | 127 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml | 5 |
6 files changed, 896 insertions, 0 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index 31bfe4a..a0d5bfc 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt | |||
@@ -1,3 +1,16 @@ | |||
1 | 2008-09-20 Michelle2 Zenovka <robin.cornelius@gmail.com> | ||
2 | |||
3 | * linden/indra/newview/llfloaterbulkpermission.h: | ||
4 | VWR-5082: 'Set permissions on selected task inventory' feature. | ||
5 | * linden/indra/newview/llfloaterbulkpermission.cpp: | ||
6 | Ditto. | ||
7 | * linden/indra/newview/llviewermenu.cpp: | ||
8 | Ditto. | ||
9 | * linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml: | ||
10 | Ditto. | ||
11 | * linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml: | ||
12 | Ditto. | ||
13 | |||
1 | 2008-09-19 Jacek Antonelli <jacek.antonelli@gmail.com> | 14 | 2008-09-19 Jacek Antonelli <jacek.antonelli@gmail.com> |
2 | 15 | ||
3 | * linden/indra/SConstruct: | 16 | * linden/indra/SConstruct: |
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 | |||
diff --git a/linden/indra/newview/llfloaterbulkpermission.h b/linden/indra/newview/llfloaterbulkpermission.h new file mode 100644 index 0000000..3de871b --- /dev/null +++ b/linden/indra/newview/llfloaterbulkpermission.h | |||
@@ -0,0 +1,143 @@ | |||
1 | /** | ||
2 | * @file llfloaterbulkpermissions.h | ||
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 | #ifndef LL_LLBULKPERMISSION_H | ||
35 | #define LL_LLBULKPERMISSION_H | ||
36 | |||
37 | #include "lldarray.h" | ||
38 | #include "llinventory.h" | ||
39 | #include "llviewerobject.h" | ||
40 | #include "llvoinventorylistener.h" | ||
41 | #include "llmap.h" | ||
42 | #include "lluuid.h" | ||
43 | |||
44 | #include "llfloater.h" | ||
45 | #include "llscrolllistctrl.h" | ||
46 | |||
47 | #include "llviewerinventory.h" | ||
48 | |||
49 | class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener | ||
50 | { | ||
51 | public: | ||
52 | // addObject() accepts an object id. | ||
53 | void addObject(const LLUUID& id); | ||
54 | |||
55 | // start() returns TRUE if the queue has started, otherwise FALSE. | ||
56 | BOOL start(); | ||
57 | |||
58 | // Use this method to create a reset queue. Once created, it | ||
59 | // will be responsible for it's own destruction. | ||
60 | static LLFloaterBulkPermission * create(); | ||
61 | |||
62 | protected: | ||
63 | LLFloaterBulkPermission(const std::string& name, const LLRect& rect, | ||
64 | const char* title, const char* start_string); | ||
65 | virtual ~LLFloaterBulkPermission(); | ||
66 | |||
67 | // This is the callback method for the viewer object currently | ||
68 | // being worked on. | ||
69 | /*virtual*/ void inventoryChanged(LLViewerObject* obj, | ||
70 | InventoryObjectList* inv, | ||
71 | S32 serial_num, | ||
72 | void* queue); | ||
73 | |||
74 | // This is called by inventoryChanged | ||
75 | void handleInventory(LLViewerObject* viewer_obj, | ||
76 | InventoryObjectList* inv); | ||
77 | |||
78 | |||
79 | void updateInventory(LLViewerObject* object, | ||
80 | LLViewerInventoryItem* item, | ||
81 | U8 key, | ||
82 | bool is_new); | ||
83 | |||
84 | |||
85 | static void onCloseBtn(void* user_data); | ||
86 | static void onApplyBtn(void* user_data); | ||
87 | static void onCommitPermissions(LLUICtrl* ctrl, void* data); | ||
88 | static void InvSelection(LLUICtrl* ctrl, void* data); | ||
89 | static void onRecurse(LLUICtrl* ctrl, void* data); | ||
90 | static void onParent(LLUICtrl* ctrl, void* data); | ||
91 | |||
92 | // returns true if this is done | ||
93 | BOOL isDone() const; | ||
94 | |||
95 | //Read the settings and Apply the permissions | ||
96 | void doApply(); | ||
97 | |||
98 | // go to the next object. If no objects left, it falls out | ||
99 | // silently and waits to be killed by the deleteIfDone() callback. | ||
100 | BOOL nextObject(); | ||
101 | BOOL popNext(); | ||
102 | |||
103 | // Get this instances ID. | ||
104 | const LLUUID& getID() const { return mID; } | ||
105 | |||
106 | // find an instance by ID. Return NULL if it does not exist. | ||
107 | static LLFloaterBulkPermission* findInstance(const LLUUID& id); | ||
108 | |||
109 | U32 req_perm_mask; | ||
110 | |||
111 | BOOL processObject; | ||
112 | BOOL processScript; | ||
113 | BOOL processTexture; | ||
114 | BOOL processSound; | ||
115 | BOOL processAnimation; | ||
116 | BOOL processCallingcard; | ||
117 | BOOL processNotecard; | ||
118 | BOOL processGesture; | ||
119 | BOOL processClothing; | ||
120 | BOOL processBodypart; | ||
121 | BOOL processLandmark; | ||
122 | |||
123 | BOOL recurse; | ||
124 | BOOL parent; | ||
125 | |||
126 | protected: | ||
127 | // UI | ||
128 | LLScrollListCtrl* mMessages; | ||
129 | LLButton* mCloseBtn; | ||
130 | |||
131 | // Object Queue | ||
132 | LLDynamicArray<LLUUID> mObjectIDs; | ||
133 | LLUUID mCurrentObjectID; | ||
134 | BOOL mDone; | ||
135 | |||
136 | LLUUID mID; | ||
137 | static LLMap<LLUUID, LLFloaterBulkPermission*> sInstances; | ||
138 | |||
139 | const char* mStartString; | ||
140 | |||
141 | }; | ||
142 | |||
143 | #endif | ||
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 3e99384..1ec71ac 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -86,6 +86,7 @@ | |||
86 | #include "llfloateravatarinfo.h" | 86 | #include "llfloateravatarinfo.h" |
87 | #include "llfloateravatartextures.h" | 87 | #include "llfloateravatartextures.h" |
88 | #include "llfloaterbuildoptions.h" | 88 | #include "llfloaterbuildoptions.h" |
89 | #include "llfloaterbulkpermission.h" | ||
89 | #include "llfloaterbump.h" | 90 | #include "llfloaterbump.h" |
90 | #include "llfloaterbuy.h" | 91 | #include "llfloaterbuy.h" |
91 | #include "llfloaterbuycontents.h" | 92 | #include "llfloaterbuycontents.h" |
@@ -6239,6 +6240,17 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons | |||
6239 | } | 6240 | } |
6240 | } | 6241 | } |
6241 | 6242 | ||
6243 | class LLToolsSetBulkPerms : public view_listener_t | ||
6244 | { | ||
6245 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | ||
6246 | { | ||
6247 | LLFloaterBulkPermission* queue = NULL; | ||
6248 | queue = LLFloaterBulkPermission::create(); | ||
6249 | return true; | ||
6250 | } | ||
6251 | }; | ||
6252 | |||
6253 | |||
6242 | class LLToolsSelectedScriptAction : public view_listener_t | 6254 | class LLToolsSelectedScriptAction : public view_listener_t |
6243 | { | 6255 | { |
6244 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 6256 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
@@ -7827,6 +7839,7 @@ void initialize_menus() | |||
7827 | addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory"); | 7839 | addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory"); |
7828 | addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); | 7840 | addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); |
7829 | addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); | 7841 | addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); |
7842 | addMenu(new LLToolsSetBulkPerms(), "Tools.SetBulkPerms"); | ||
7830 | 7843 | ||
7831 | addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); | 7844 | addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); |
7832 | addMenu(new LLToolsEnableLink(), "Tools.EnableLink"); | 7845 | addMenu(new LLToolsEnableLink(), "Tools.EnableLink"); |
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml b/linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml new file mode 100644 index 0000000..3dd838a --- /dev/null +++ b/linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml | |||
@@ -0,0 +1,127 @@ | |||
1 | <?xml version="1.0" encoding="utf-8" standalone="yes" ?> | ||
2 | <floater bottom="-554" can_close="true" can_drag_on_left="false" can_minimize="true" | ||
3 | can_resize="false" can_tear_off="false" enabled="true" height="420" | ||
4 | left="367" min_height="1000" min_width="460" mouse_opaque="true" | ||
5 | name="floaterrecursiveperms" title="Bulk permission settings" | ||
6 | width="460"> | ||
7 | |||
8 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
9 | bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top" | ||
10 | font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10" | ||
11 | mouse_opaque="true" name="applyto" v_pad="0" width="206">Apply to</text> | ||
12 | |||
13 | <check_box bottom="-70" enabled="true" follows="left|top" font="SansSerifSmall" | ||
14 | height="16" initial_value="false" | ||
15 | label="Scripts" left="10" mouse_opaque="true" | ||
16 | name="scripts" radio_style="false" | ||
17 | tool_tip="Apply bulk permissions to scripts" | ||
18 | width="219"/> | ||
19 | |||
20 | <check_box bottom="-90" enabled="true" follows="left|top" font="SansSerifSmall" | ||
21 | height="16" initial_value="false" | ||
22 | label="Textures" left="10" mouse_opaque="true" | ||
23 | name="textures" radio_style="false" | ||
24 | tool_tip="Apply bulk permissions to textures" | ||
25 | width="219"/> | ||
26 | |||
27 | <check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall" | ||
28 | height="16" initial_value="false" | ||
29 | label="Animations" left="10" mouse_opaque="true" | ||
30 | name="animations" radio_style="false" | ||
31 | tool_tip="Apply bulk permissions to animations" | ||
32 | width="219"/> | ||
33 | |||
34 | <check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall" | ||
35 | height="16" initial_value="false" | ||
36 | label="Sounds" left="10" mouse_opaque="true" | ||
37 | name="sounds" radio_style="false" | ||
38 | tool_tip="Apply bulk permissions to sounds" | ||
39 | width="219"/> | ||
40 | |||
41 | <check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall" | ||
42 | height="16" initial_value="false" | ||
43 | label="Contained objects" left="10" mouse_opaque="true" | ||
44 | name="objects" radio_style="false" | ||
45 | tool_tip="Apply bulk permissions to objects inside inventory" | ||
46 | width="219"/> | ||
47 | |||
48 | <check_box bottom="-170" enabled="true" follows="left|top" font="SansSerifSmall" | ||
49 | height="16" initial_value="false" | ||
50 | label="Landmarks" left="10" mouse_opaque="true" | ||
51 | name="landmarks" radio_style="false" | ||
52 | tool_tip="Apply bulk permissions to landmarks" | ||
53 | width="219"/> | ||
54 | |||
55 | <check_box bottom="-190" enabled="true" follows="left|top" font="SansSerifSmall" | ||
56 | height="16" initial_value="false" | ||
57 | label="Notecards" left="10" mouse_opaque="true" | ||
58 | name="notecards" radio_style="false" | ||
59 | tool_tip="Apply bulk permissions to notecards" | ||
60 | width="219"/> | ||
61 | |||
62 | <check_box bottom="-210" enabled="true" follows="left|top" font="SansSerifSmall" | ||
63 | height="16" initial_value="false" | ||
64 | label="Gesture" left="10" mouse_opaque="true" | ||
65 | name="gestures" radio_style="false" | ||
66 | tool_tip="Apply bulk permissions to gestures" | ||
67 | width="219"/> | ||
68 | |||
69 | <check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall" | ||
70 | height="16" initial_value="false" | ||
71 | label="Clothing" left="10" mouse_opaque="true" | ||
72 | name="clothing" radio_style="false" | ||
73 | tool_tip="Apply bulk permissions to clothing" | ||
74 | width="219"/> | ||
75 | |||
76 | <check_box bottom="-250" enabled="true" follows="left|top" font="SansSerifSmall" | ||
77 | height="16" initial_value="false" | ||
78 | label="Bodypart" left="10" mouse_opaque="true" | ||
79 | name="bodyparts" radio_style="false" | ||
80 | tool_tip="Apply bulk permissions to bodyparts" | ||
81 | width="219"/> | ||
82 | |||
83 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
84 | bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top" | ||
85 | font="SansSerifSmall" h_pad="0" halign="left" height="10" left="200" | ||
86 | mouse_opaque="true" name="applyto" v_pad="0" width="206">Permissions</text> | ||
87 | |||
88 | |||
89 | <check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall" | ||
90 | height="16" initial_value="false" | ||
91 | label="Copy" left="200" mouse_opaque="true" | ||
92 | name="Copy" radio_style="false" | ||
93 | tool_tip="Next owner can copy" | ||
94 | width="219"/> | ||
95 | |||
96 | <check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall" | ||
97 | height="16" initial_value="false" | ||
98 | label="Modify" left="200" mouse_opaque="true" | ||
99 | name="Modify" radio_style="false" | ||
100 | tool_tip="Next owner can modify" | ||
101 | width="219"/> | ||
102 | |||
103 | <check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall" | ||
104 | height="16" initial_value="false" | ||
105 | label="Trans" left="200" mouse_opaque="true" | ||
106 | name="Trans" radio_style="false" | ||
107 | tool_tip="Next owner can transfer" | ||
108 | width="219"/> | ||
109 | |||
110 | <check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall" | ||
111 | height="16" initial_value="false" | ||
112 | label="Modify Parent Prims" left="200" mouse_opaque="true" | ||
113 | name="Parent" radio_style="false" | ||
114 | tool_tip="Modify parent prims not just inventory" | ||
115 | width="219" default="true"/> | ||
116 | |||
117 | <scroll_list background_visible="true" bottom="-410" column_padding="5" draw_border="true" | ||
118 | draw_heading="false" draw_stripes="true" enabled="true" | ||
119 | follows="left|top|right|bottom" height="140" left="10" mouse_opaque="true" | ||
120 | multi_select="false" name="queue output" width="440" /> | ||
121 | |||
122 | <button bottom="-70" enabled="true" follows="left|top" font="SansSerif" | ||
123 | halign="center" height="20" label="Apply..." | ||
124 | label_selected="Apply..." left="295" mouse_opaque="true" | ||
125 | name="Apply..." scale_image="true" width="145" /> | ||
126 | |||
127 | </floater> | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml index 054f867..eacd0ed 100644 --- a/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml +++ b/linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml | |||
@@ -756,6 +756,11 @@ | |||
756 | <on_click function="Tools.SelectedScriptAction" userdata="stop" /> | 756 | <on_click function="Tools.SelectedScriptAction" userdata="stop" /> |
757 | <on_enable function="EditableSelected" /> | 757 | <on_enable function="EditableSelected" /> |
758 | </menu_item_call> | 758 | </menu_item_call> |
759 | <menu_item_call bottom="-468" enabled="false" height="19" label="Set permissions on selected task inventory" | ||
760 | left="0" mouse_opaque="true" name="Set permissions on selected task inventory" width="250"> | ||
761 | <on_click function="Tools.SetBulkPerms" userdata="" /> | ||
762 | <on_enable function="EditableSelected" /> | ||
763 | </menu_item_call> | ||
759 | </menu> | 764 | </menu> |
760 | <menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true" | 765 | <menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true" |
761 | height="317" label="Help" left="227" mouse_opaque="false" name="Help" | 766 | height="317" label="Help" left="227" mouse_opaque="false" name="Help" |