diff options
author | Jacek Antonelli | 2008-08-15 23:45:16 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:16 -0500 |
commit | 3f27ba891ac4d032753b219b4b96d1ffbc9fb488 (patch) | |
tree | 504932ee91a0356fba7ea48798887c96867e492f /linden/indra/newview/llfloaterlandmark.cpp | |
parent | Second Life viewer sources 1.18.4.3 (diff) | |
download | meta-impy-3f27ba891ac4d032753b219b4b96d1ffbc9fb488.zip meta-impy-3f27ba891ac4d032753b219b4b96d1ffbc9fb488.tar.gz meta-impy-3f27ba891ac4d032753b219b4b96d1ffbc9fb488.tar.bz2 meta-impy-3f27ba891ac4d032753b219b4b96d1ffbc9fb488.tar.xz |
Second Life viewer sources 1.18.5.0-RC
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llfloaterlandmark.cpp | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterlandmark.cpp b/linden/indra/newview/llfloaterlandmark.cpp new file mode 100644 index 0000000..14277c6 --- /dev/null +++ b/linden/indra/newview/llfloaterlandmark.cpp | |||
@@ -0,0 +1,471 @@ | |||
1 | /** | ||
2 | * @file lllandmark.cpp | ||
3 | * @author Richard Nelson, James Cook, Sam Kolb | ||
4 | * @brief LLLandmarkCtrl class implementation including related functions | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2002&license=internal$ | ||
7 | * | ||
8 | * Copyright (c) 2002-2007, Linden Research, Inc. | ||
9 | * | ||
10 | * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of | ||
11 | * this source code is governed by the Linden Lab Source Code Disclosure | ||
12 | * Agreement ("Agreement") previously entered between you and Linden | ||
13 | * Lab. By accessing, using, copying, modifying or distributing this | ||
14 | * software, you acknowledge that you have been informed of your | ||
15 | * obligations under the Agreement and agree to abide by those obligations. | ||
16 | * | ||
17 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
18 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
19 | * COMPLETENESS OR PERFORMANCE. | ||
20 | * $/LicenseInfo$ | ||
21 | */ | ||
22 | |||
23 | #include "llviewerprecompiledheaders.h" | ||
24 | |||
25 | #include "llfloaterlandmark.h" | ||
26 | |||
27 | #include "llagent.h" | ||
28 | #include "llviewerimagelist.h" | ||
29 | #include "llcheckboxctrl.h" | ||
30 | #include "llcombobox.h" | ||
31 | #include "llbutton.h" | ||
32 | #include "lldraghandle.h" | ||
33 | #include "llfocusmgr.h" | ||
34 | #include "llviewerimage.h" | ||
35 | #include "llviewerparcelmgr.h" | ||
36 | #include "llfolderview.h" | ||
37 | #include "llinventory.h" | ||
38 | #include "llinventorymodel.h" | ||
39 | #include "llinventoryview.h" | ||
40 | #include "lllineeditor.h" | ||
41 | #include "llui.h" | ||
42 | #include "llviewerinventory.h" | ||
43 | #include "llpermissions.h" | ||
44 | #include "llsaleinfo.h" | ||
45 | #include "llassetstorage.h" | ||
46 | #include "lltextbox.h" | ||
47 | #include "llparcel.h" | ||
48 | #include "llresizehandle.h" | ||
49 | #include "llscrollcontainer.h" | ||
50 | #include "lltoolmgr.h" | ||
51 | #include "lltoolpipette.h" | ||
52 | |||
53 | #include "lltool.h" | ||
54 | #include "llviewerwindow.h" | ||
55 | #include "llviewerobject.h" | ||
56 | #include "llviewercontrol.h" | ||
57 | #include "llglheaders.h" | ||
58 | #include "llvieweruictrlfactory.h" | ||
59 | |||
60 | #include "roles_constants.h" | ||
61 | |||
62 | |||
63 | |||
64 | static const S32 CLOSE_BTN_WIDTH = 100; | ||
65 | const S32 PIPETTE_BTN_WIDTH = 32; | ||
66 | static const S32 HPAD = 4; | ||
67 | static const S32 VPAD = 4; | ||
68 | static const S32 LINE = 16; | ||
69 | static const S32 SMALL_BTN_WIDTH = 64; | ||
70 | static const S32 TEX_PICKER_MIN_WIDTH = | ||
71 | (HPAD + | ||
72 | CLOSE_BTN_WIDTH + | ||
73 | HPAD + | ||
74 | CLOSE_BTN_WIDTH + | ||
75 | HPAD + | ||
76 | SMALL_BTN_WIDTH + | ||
77 | HPAD + | ||
78 | SMALL_BTN_WIDTH + | ||
79 | HPAD + | ||
80 | 30 + | ||
81 | RESIZE_HANDLE_WIDTH * 2); | ||
82 | static const S32 CLEAR_BTN_WIDTH = 50; | ||
83 | static const S32 TEX_PICKER_MIN_HEIGHT = 290; | ||
84 | static const S32 FOOTER_HEIGHT = 100; | ||
85 | static const S32 BORDER_PAD = HPAD; | ||
86 | static const S32 TEXTURE_INVENTORY_PADDING = 30; | ||
87 | static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f; | ||
88 | static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; | ||
89 | static const F32 CONTEXT_FADE_TIME = 0.08f; | ||
90 | |||
91 | //static const char CURRENT_IMAGE_NAME[] = "Current Landmark"; | ||
92 | //static const char WHITE_IMAGE_NAME[] = "Blank Landmark"; | ||
93 | //static const char NO_IMAGE_NAME[] = "None"; | ||
94 | |||
95 | |||
96 | LLFloaterLandmark::LLFloaterLandmark(const LLSD& data) | ||
97 | : | ||
98 | mTentativeLabel(NULL), | ||
99 | mResolutionLabel(NULL), | ||
100 | mIsDirty( FALSE ), | ||
101 | mActive( TRUE ), | ||
102 | mSearchEdit(NULL), | ||
103 | mContextConeOpacity(0.f) | ||
104 | { | ||
105 | gUICtrlFactory->buildFloater(this,"floater_landmark_ctrl.xml"); | ||
106 | |||
107 | mTentativeLabel = LLUICtrlFactory::getTextBoxByName(this,"Multiple"); | ||
108 | |||
109 | mResolutionLabel = LLUICtrlFactory::getTextBoxByName(this,"unknown"); | ||
110 | |||
111 | |||
112 | childSetCommitCallback("show_folders_check", onShowFolders, this); | ||
113 | childSetVisible("show_folders_check", FALSE); | ||
114 | |||
115 | mSearchEdit = (LLSearchEditor*)getCtrlByNameAndType("inventory search editor", WIDGET_TYPE_SEARCH_EDITOR); | ||
116 | mSearchEdit->setSearchCallback(onSearchEdit, this); | ||
117 | |||
118 | mInventoryPanel = (LLInventoryPanel*)this->getCtrlByNameAndType("inventory panel", WIDGET_TYPE_INVENTORY_PANEL); | ||
119 | |||
120 | if(mInventoryPanel) | ||
121 | { | ||
122 | U32 filter_types = 0x0; | ||
123 | filter_types |= 0x1 << LLInventoryType::IT_LANDMARK; | ||
124 | // filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; | ||
125 | |||
126 | mInventoryPanel->setFilterTypes(filter_types); | ||
127 | //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss. | ||
128 | mInventoryPanel->setSelectCallback(onSelectionChange, this); | ||
129 | mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); | ||
130 | mInventoryPanel->setAllowMultiSelect(FALSE); | ||
131 | |||
132 | // store this filter as the default one | ||
133 | mInventoryPanel->getRootFolder()->getFilter()->markDefault(); | ||
134 | |||
135 | // Commented out to stop opening all folders with textures | ||
136 | mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_LANDMARK); | ||
137 | |||
138 | // don't put keyboard focus on selected item, because the selection callback | ||
139 | // will assume that this was user input | ||
140 | mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); | ||
141 | } | ||
142 | |||
143 | mSavedFolderState = new LLSaveFolderState(); | ||
144 | mNoCopyLandmarkSelected = FALSE; | ||
145 | |||
146 | childSetAction("Close", LLFloaterLandmark::onBtnClose,this); | ||
147 | childSetAction("New", LLFloaterLandmark::onBtnNew,this); | ||
148 | childSetAction("NewFolder", LLFloaterLandmark::onBtnNewFolder,this); | ||
149 | childSetAction("Edit", LLFloaterLandmark::onBtnEdit,this); | ||
150 | childSetAction("Rename", LLFloaterLandmark::onBtnRename,this); | ||
151 | childSetAction("Delete", LLFloaterLandmark::onBtnDelete,this); | ||
152 | |||
153 | setCanMinimize(FALSE); | ||
154 | |||
155 | mSavedFolderState->setApply(FALSE); | ||
156 | } | ||
157 | |||
158 | LLFloaterLandmark::~LLFloaterLandmark() | ||
159 | { | ||
160 | delete mSavedFolderState; | ||
161 | } | ||
162 | |||
163 | void LLFloaterLandmark::setActive( BOOL active ) | ||
164 | { | ||
165 | mActive = active; | ||
166 | } | ||
167 | |||
168 | // virtual | ||
169 | BOOL LLFloaterLandmark::handleDragAndDrop( | ||
170 | S32 x, S32 y, MASK mask, | ||
171 | BOOL drop, | ||
172 | EDragAndDropType cargo_type, void *cargo_data, | ||
173 | EAcceptance *accept, | ||
174 | LLString& tooltip_msg) | ||
175 | { | ||
176 | BOOL handled = FALSE; | ||
177 | |||
178 | if (cargo_type == DAD_LANDMARK) | ||
179 | { | ||
180 | LLInventoryItem *item = (LLInventoryItem *)cargo_data; | ||
181 | |||
182 | BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID()); | ||
183 | BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID()); | ||
184 | BOOL xfer = item->getPermissions().allowOperationBy(PERM_TRANSFER, | ||
185 | gAgent.getID()); | ||
186 | |||
187 | PermissionMask item_perm_mask = 0; | ||
188 | if (copy) item_perm_mask |= PERM_COPY; | ||
189 | if (mod) item_perm_mask |= PERM_MODIFY; | ||
190 | if (xfer) item_perm_mask |= PERM_TRANSFER; | ||
191 | |||
192 | //PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss. | ||
193 | PermissionMask filter_perm_mask = mImmediateFilterPermMask; | ||
194 | if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask ) | ||
195 | { | ||
196 | |||
197 | *accept = ACCEPT_YES_SINGLE; | ||
198 | } | ||
199 | else | ||
200 | { | ||
201 | *accept = ACCEPT_NO; | ||
202 | } | ||
203 | } | ||
204 | else | ||
205 | { | ||
206 | *accept = ACCEPT_NO; | ||
207 | } | ||
208 | |||
209 | handled = TRUE; | ||
210 | lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFloaterLandmark " << getName() << llendl; | ||
211 | |||
212 | return handled; | ||
213 | } | ||
214 | |||
215 | BOOL LLFloaterLandmark::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent) | ||
216 | { | ||
217 | LLFolderView* root_folder = mInventoryPanel->getRootFolder(); | ||
218 | |||
219 | if (root_folder && mSearchEdit) | ||
220 | { | ||
221 | if (!called_from_parent && mSearchEdit->hasFocus() && | ||
222 | (key == KEY_RETURN || key == KEY_DOWN) && | ||
223 | mask == MASK_NONE) | ||
224 | { | ||
225 | if (!root_folder->getCurSelectedItem()) | ||
226 | { | ||
227 | LLFolderViewItem* itemp = root_folder->getItemByID(gAgent.getInventoryRootID()); | ||
228 | if (itemp) | ||
229 | { | ||
230 | root_folder->setSelection(itemp, FALSE, FALSE); | ||
231 | } | ||
232 | } | ||
233 | root_folder->scrollToShowSelection(); | ||
234 | |||
235 | // move focus to inventory proper | ||
236 | root_folder->setFocus(TRUE); | ||
237 | |||
238 | return TRUE; | ||
239 | } | ||
240 | |||
241 | if (root_folder->hasFocus() && key == KEY_UP) | ||
242 | { | ||
243 | mSearchEdit->focusFirstItem(TRUE); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | return LLFloater::handleKeyHere(key, mask, called_from_parent); | ||
248 | } | ||
249 | |||
250 | // virtual | ||
251 | void LLFloaterLandmark::onClose(bool app_quitting) | ||
252 | { | ||
253 | destroy(); | ||
254 | } | ||
255 | |||
256 | |||
257 | |||
258 | const LLUUID& LLFloaterLandmark::findItemID(const LLUUID& asset_id, BOOL copyable_only) | ||
259 | { | ||
260 | LLViewerInventoryCategory::cat_array_t cats; | ||
261 | LLViewerInventoryItem::item_array_t items; | ||
262 | LLAssetIDMatches asset_id_matches(asset_id); | ||
263 | gInventory.collectDescendentsIf(LLUUID::null, | ||
264 | cats, | ||
265 | items, | ||
266 | LLInventoryModel::INCLUDE_TRASH, | ||
267 | asset_id_matches); | ||
268 | |||
269 | if (items.count()) | ||
270 | { | ||
271 | // search for copyable version first | ||
272 | for (S32 i = 0; i < items.count(); i++) | ||
273 | { | ||
274 | LLInventoryItem* itemp = items[i]; | ||
275 | LLPermissions item_permissions = itemp->getPermissions(); | ||
276 | if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) | ||
277 | { | ||
278 | return itemp->getUUID(); | ||
279 | } | ||
280 | } | ||
281 | // otherwise just return first instance, unless copyable requested | ||
282 | if (copyable_only) | ||
283 | { | ||
284 | return LLUUID::null; | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | return items[0]->getUUID(); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | return LLUUID::null; | ||
293 | } | ||
294 | |||
295 | // static | ||
296 | void LLFloaterLandmark::onBtnClose(void* userdata) | ||
297 | { | ||
298 | LLFloaterLandmark* self = (LLFloaterLandmark*) userdata; | ||
299 | self->mIsDirty = FALSE; | ||
300 | self->close(); | ||
301 | } | ||
302 | |||
303 | // static | ||
304 | void LLFloaterLandmark::onBtnEdit(void* userdata) | ||
305 | { | ||
306 | LLFloaterLandmark* self = (LLFloaterLandmark*) userdata; | ||
307 | // There isn't one, so make a new preview | ||
308 | LLViewerInventoryItem* itemp = gInventory.getItem(self->mImageAssetID); | ||
309 | if(itemp) | ||
310 | { | ||
311 | open_landmark(itemp, itemp->getName(), TRUE); | ||
312 | } | ||
313 | } | ||
314 | // static | ||
315 | void LLFloaterLandmark::onBtnNew(void* userdata) | ||
316 | { | ||
317 | LLViewerRegion* agent_region = gAgent.getRegion(); | ||
318 | if(!agent_region) | ||
319 | { | ||
320 | llwarns << "No agent region" << llendl; | ||
321 | return; | ||
322 | } | ||
323 | LLParcel* agent_parcel = gParcelMgr->getAgentParcel(); | ||
324 | if (!agent_parcel) | ||
325 | { | ||
326 | llwarns << "No agent parcel" << llendl; | ||
327 | return; | ||
328 | } | ||
329 | if (!agent_parcel->getAllowLandmark() | ||
330 | && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) | ||
331 | { | ||
332 | gViewerWindow->alertXml("CannotCreateLandmarkNotOwner"); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | LLUUID folder_id; | ||
337 | folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); | ||
338 | std::string pos_string; | ||
339 | gAgent.buildLocationString(pos_string); | ||
340 | |||
341 | create_inventory_item(gAgent.getID(), gAgent.getSessionID(), | ||
342 | folder_id, LLTransactionID::tnull, | ||
343 | pos_string, pos_string, // name, desc | ||
344 | LLAssetType::AT_LANDMARK, | ||
345 | LLInventoryType::IT_LANDMARK, | ||
346 | NOT_WEARABLE, PERM_ALL, | ||
347 | NULL); | ||
348 | } | ||
349 | // static | ||
350 | void LLFloaterLandmark::onBtnNewFolder(void* userdata) | ||
351 | { | ||
352 | |||
353 | } | ||
354 | // static | ||
355 | void LLFloaterLandmark::onBtnDelete(void* userdata) | ||
356 | { | ||
357 | LLFloaterLandmark* self = (LLFloaterLandmark*)userdata; | ||
358 | |||
359 | LLViewerInventoryItem* item = gInventory.getItem(self->mImageAssetID); | ||
360 | if(item) | ||
361 | { | ||
362 | // Move the item to the trash | ||
363 | LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); | ||
364 | if (item->getParentUUID() != trash_id) | ||
365 | { | ||
366 | LLInventoryModel::update_list_t update; | ||
367 | LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); | ||
368 | update.push_back(old_folder); | ||
369 | LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1); | ||
370 | update.push_back(new_folder); | ||
371 | gInventory.accountForUpdate(update); | ||
372 | |||
373 | LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); | ||
374 | new_item->setParent(trash_id); | ||
375 | // no need to restamp it though it's a move into trash because | ||
376 | // it's a brand new item already. | ||
377 | new_item->updateParentOnServer(FALSE); | ||
378 | gInventory.updateItem(new_item); | ||
379 | gInventory.notifyObservers(); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | // Delete the item entirely | ||
384 | /* | ||
385 | item->removeFromServer(); | ||
386 | gInventory.deleteObject(item->getUUID()); | ||
387 | gInventory.notifyObservers(); | ||
388 | */ | ||
389 | |||
390 | |||
391 | } | ||
392 | |||
393 | // static | ||
394 | void LLFloaterLandmark::onBtnRename(void* userdata) | ||
395 | { | ||
396 | |||
397 | } | ||
398 | |||
399 | // static | ||
400 | void LLFloaterLandmark::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data) | ||
401 | { | ||
402 | LLFloaterLandmark* self = (LLFloaterLandmark*)data; | ||
403 | if (items.size()) | ||
404 | { | ||
405 | LLFolderViewItem* first_item = items.front(); | ||
406 | LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID()); | ||
407 | self->mNoCopyLandmarkSelected = FALSE; | ||
408 | if (itemp) | ||
409 | { | ||
410 | if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) | ||
411 | { | ||
412 | self->mNoCopyLandmarkSelected = TRUE; | ||
413 | } | ||
414 | self->mImageAssetID = itemp->getUUID(); | ||
415 | self->mIsDirty = TRUE; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | // static | ||
421 | void LLFloaterLandmark::onShowFolders(LLUICtrl* ctrl, void *user_data) | ||
422 | { | ||
423 | LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; | ||
424 | LLFloaterLandmark* picker = (LLFloaterLandmark*)user_data; | ||
425 | |||
426 | if (check_box->get()) | ||
427 | { | ||
428 | picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); | ||
429 | } | ||
430 | else | ||
431 | { | ||
432 | picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | void LLFloaterLandmark::onSearchEdit(const LLString& search_string, void* user_data ) | ||
437 | { | ||
438 | LLFloaterLandmark* picker = (LLFloaterLandmark*)user_data; | ||
439 | |||
440 | std::string upper_case_search_string = search_string; | ||
441 | LLString::toUpper(upper_case_search_string); | ||
442 | |||
443 | if (upper_case_search_string.empty()) | ||
444 | { | ||
445 | if (picker->mInventoryPanel->getFilterSubString().empty()) | ||
446 | { | ||
447 | // current filter and new filter empty, do nothing | ||
448 | return; | ||
449 | } | ||
450 | |||
451 | picker->mSavedFolderState->setApply(TRUE); | ||
452 | picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(*picker->mSavedFolderState); | ||
453 | // add folder with current item to list of previously opened folders | ||
454 | LLOpenFoldersWithSelection opener; | ||
455 | picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(opener); | ||
456 | picker->mInventoryPanel->getRootFolder()->scrollToShowSelection(); | ||
457 | |||
458 | } | ||
459 | else if (picker->mInventoryPanel->getFilterSubString().empty()) | ||
460 | { | ||
461 | // first letter in search term, save existing folder open state | ||
462 | if (!picker->mInventoryPanel->getRootFolder()->isFilterModified()) | ||
463 | { | ||
464 | picker->mSavedFolderState->setApply(FALSE); | ||
465 | picker->mInventoryPanel->getRootFolder()->applyFunctorRecursively(*picker->mSavedFolderState); | ||
466 | } | ||
467 | } | ||
468 | |||
469 | picker->mInventoryPanel->setFilterSubString(upper_case_search_string); | ||
470 | } | ||
471 | |||