aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llpreview.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llpreview.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llpreview.cpp')
-rw-r--r--linden/indra/newview/llpreview.cpp513
1 files changed, 513 insertions, 0 deletions
diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp
new file mode 100644
index 0000000..c5dc414
--- /dev/null
+++ b/linden/indra/newview/llpreview.cpp
@@ -0,0 +1,513 @@
1/**
2 * @file llpreview.cpp
3 * @brief LLPreview class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29#include "stdenums.h"
30
31#include "llpreview.h"
32#include "lllineeditor.h"
33#include "llinventory.h"
34#include "llinventorymodel.h"
35#include "llresmgr.h"
36#include "lltextbox.h"
37#include "llfocusmgr.h"
38#include "lltooldraganddrop.h"
39#include "llradiogroup.h"
40#include "llassetstorage.h"
41#include "llviewerobject.h"
42#include "llviewerobjectlist.h"
43#include "lldbstrings.h"
44#include "llagent.h"
45#include "llvoavatar.h"
46#include "llselectmgr.h"
47#include "llinventoryview.h"
48#include "llviewerinventory.h"
49
50// Constants
51
52// Globals and statics
53LLPreview::preview_multimap_t LLPreview::sPreviewsBySource;
54LLPreview::preview_map_t LLPreview::sInstances;
55
56// Functions
57LLPreview::LLPreview(const std::string& name) :
58 LLFloater(name),
59 mCopyToInvBtn(NULL),
60 mForceClose(FALSE),
61 mCloseAfterSave(FALSE),
62 mAssetStatus(PREVIEW_ASSET_UNLOADED)
63{
64 // don't add to instance list, since ItemID is null
65 mAuxItem = new LLInventoryItem; // (LLPointer is auto-deleted)
66 // don't necessarily steal focus on creation -- sometimes these guys pop up without user action
67 mAutoFocus = FALSE;
68}
69
70LLPreview::LLPreview(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid, const LLUUID& object_uuid, BOOL allow_resize, S32 min_width, S32 min_height )
71: LLFloater(name, rect, title, allow_resize, min_width, min_height ),
72 mItemUUID(item_uuid),
73 mSourceID(LLUUID::null),
74 mObjectUUID(object_uuid),
75 mCopyToInvBtn( NULL ),
76 mForceClose( FALSE ),
77 mCloseAfterSave(FALSE),
78 mAssetStatus(PREVIEW_ASSET_UNLOADED)
79{
80 mAuxItem = new LLInventoryItem;
81 // don't necessarily steal focus on creation -- sometimes these guys pop up without user action
82 mAutoFocus = FALSE;
83
84 if (mItemUUID.notNull())
85 {
86 sInstances[mItemUUID] = this;
87 }
88
89}
90
91LLPreview::~LLPreview()
92{
93 gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
94
95 if (mItemUUID.notNull())
96 {
97 sInstances.erase( mItemUUID );
98 }
99
100 if (mSourceID.notNull())
101 {
102 preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
103 for (; found_it != sPreviewsBySource.end(); ++found_it)
104 {
105 if (found_it->second == mViewHandle)
106 {
107 sPreviewsBySource.erase(found_it);
108 break;
109 }
110 }
111 }
112}
113
114void LLPreview::setItemID(const LLUUID& item_id)
115{
116 if (mItemUUID.notNull())
117 {
118 sInstances.erase(mItemUUID);
119 }
120
121 mItemUUID = item_id;
122
123 if (mItemUUID.notNull())
124 {
125 sInstances[mItemUUID] = this;
126 }
127}
128
129void LLPreview::setObjectID(const LLUUID& object_id)
130{
131 mObjectUUID = object_id;
132}
133
134void LLPreview::setSourceID(const LLUUID& source_id)
135{
136 if (mSourceID.notNull())
137 {
138 // erase old one
139 preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
140 for (; found_it != sPreviewsBySource.end(); ++found_it)
141 {
142 if (found_it->second == mViewHandle)
143 {
144 sPreviewsBySource.erase(found_it);
145 break;
146 }
147 }
148 }
149 mSourceID = source_id;
150 sPreviewsBySource.insert(preview_multimap_t::value_type(mSourceID, mViewHandle));
151}
152
153LLViewerInventoryItem* LLPreview::getItem() const
154{
155 LLViewerInventoryItem* item = NULL;
156 if(mObjectUUID.isNull())
157 {
158 // it's an inventory item, so get the item.
159 item = gInventory.getItem(mItemUUID);
160 }
161 else
162 {
163 // it's an object's inventory item.
164 LLViewerObject* object = gObjectList.findObject(mObjectUUID);
165 if(object)
166 {
167 item = (LLViewerInventoryItem*)object->getInventoryObject(mItemUUID);
168 }
169 }
170 return item;
171}
172
173// Sub-classes should override this function if they allow editing
174void LLPreview::onCommit()
175{
176 LLViewerInventoryItem* item = getItem();
177 if(item)
178 {
179 if (!item->isComplete())
180 {
181 // We are attempting to save an item that was never loaded
182 llwarns << "LLPreview::onCommit() called with mIsComplete == FALSE"
183 << " Type: " << item->getType()
184 << " ID: " << item->getUUID()
185 << llendl;
186 return;
187 }
188
189 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
190 BOOL has_sale_info = FALSE;
191 LLSaleInfo sale_info;
192 new_item->setDescription(childGetText("desc"));
193 if(mObjectUUID.notNull())
194 {
195 // must be in an object
196 LLViewerObject* object = gObjectList.findObject(mObjectUUID);
197 if(object)
198 {
199 object->updateInventory(
200 new_item,
201 TASK_INVENTORY_ITEM_KEY,
202 false);
203 }
204 }
205 else if(item->getPermissions().getOwner() == gAgent.getID())
206 {
207 new_item->updateServer(FALSE);
208 gInventory.updateItem(new_item);
209
210 // If the item is an attachment that is currently being worn,
211 // update the object itself.
212 if( item->getType() == LLAssetType::AT_OBJECT )
213 {
214 LLVOAvatar* avatar = gAgent.getAvatarObject();
215 if( avatar )
216 {
217 LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
218 if( obj )
219 {
220 gSelectMgr->deselectAll();
221 gSelectMgr->addAsIndividual( obj, SELECT_ALL_TES, FALSE );
222 gSelectMgr->setObjectDescription( childGetText("desc") );
223
224 if( has_sale_info )
225 {
226 gSelectMgr->setObjectSaleInfo( sale_info );
227 }
228
229 gSelectMgr->deselectAll();
230 }
231 }
232 }
233 }
234 }
235}
236
237// static
238void LLPreview::onText(LLUICtrl*, void* userdata)
239{
240 LLPreview* self = (LLPreview*) userdata;
241 self->onCommit();
242}
243
244// static
245void LLPreview::onRadio(LLUICtrl*, void* userdata)
246{
247 LLPreview* self = (LLPreview*) userdata;
248 self->onCommit();
249}
250
251// static
252LLPreview* LLPreview::find(const LLUUID& item_uuid)
253{
254 LLPreview* instance = NULL;
255 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
256 if(found_it != LLPreview::sInstances.end())
257 {
258 instance = found_it->second;
259 }
260 return instance;
261}
262
263// static
264LLPreview* LLPreview::show( const LLUUID& item_uuid, BOOL take_focus )
265{
266 LLPreview* instance = LLPreview::find(item_uuid);
267 if(instance)
268 {
269 if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost())
270 {
271 // this preview window is being opened in a new context
272 // needs to be rehosted
273 LLFloater::getFloaterHost()->addFloater(instance, TRUE);
274 }
275 instance->open();
276 if (take_focus)
277 {
278 instance->setFocus(TRUE);
279 }
280 }
281
282 return instance;
283}
284
285// static
286bool LLPreview::save( const LLUUID& item_uuid, LLPointer<LLInventoryItem>* itemptr )
287{
288 bool res = false;
289 LLPreview* instance = LLPreview::find(item_uuid);
290 if(instance)
291 {
292 res = instance->saveItem(itemptr);
293 }
294 if (!res)
295 {
296 delete itemptr;
297 }
298 return res;
299}
300
301// static
302void LLPreview::hide(const LLUUID& item_uuid)
303{
304 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
305 if(found_it != LLPreview::sInstances.end())
306 {
307 LLPreview* instance = found_it->second;
308 instance->close();
309 }
310}
311
312// static
313void LLPreview::rename(const LLUUID& item_uuid, const std::string& new_name)
314{
315 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
316 if(found_it != LLPreview::sInstances.end())
317 {
318 LLPreview* instance = found_it->second;
319 instance->setTitle( new_name );
320 }
321}
322
323BOOL LLPreview::handleMouseDown(S32 x, S32 y, MASK mask)
324{
325 if(mClientRect.pointInRect(x, y))
326 {
327 // No handler needed for focus lost since this class has no
328 // state that depends on it.
329 bringToFront(x, y);
330 gFocusMgr.setMouseCapture(this, NULL);
331 S32 screen_x;
332 S32 screen_y;
333 localPointToScreen(x, y, &screen_x, &screen_y );
334 gToolDragAndDrop->setDragStart(screen_x, screen_y);
335 return TRUE;
336 }
337 return LLFloater::handleMouseDown(x, y, mask);
338}
339
340BOOL LLPreview::handleMouseUp(S32 x, S32 y, MASK mask)
341{
342 if(gFocusMgr.getMouseCapture() == this)
343 {
344 gFocusMgr.setMouseCapture(NULL, NULL);
345 return TRUE;
346 }
347 return LLFloater::handleMouseUp(x, y, mask);
348}
349
350BOOL LLPreview::handleHover(S32 x, S32 y, MASK mask)
351{
352 if(gFocusMgr.getMouseCapture() == this)
353 {
354 S32 screen_x;
355 S32 screen_y;
356 LLViewerInventoryItem *item = getItem();
357
358 localPointToScreen(x, y, &screen_x, &screen_y );
359 if(item
360 && item->getPermissions().allowCopyBy(gAgent.getID(),
361 gAgent.getGroupID())
362 && gToolDragAndDrop->isOverThreshold(screen_x, screen_y))
363 {
364 EDragAndDropType type;
365 type = LLAssetType::lookupDragAndDropType(item->getType());
366 LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_LIBRARY;
367 if(!mObjectUUID.isNull())
368 {
369 src = LLToolDragAndDrop::SOURCE_WORLD;
370 }
371 else if(item->getPermissions().getOwner() == gAgent.getID())
372 {
373 src = LLToolDragAndDrop::SOURCE_AGENT;
374 }
375 gToolDragAndDrop->beginDrag(type,
376 item->getUUID(),
377 src,
378 mObjectUUID);
379 return gToolDragAndDrop->handleHover(x, y, mask );
380 }
381 }
382 return LLFloater::handleHover(x,y,mask);
383}
384
385void LLPreview::open()
386{
387 LLMultiFloater* hostp = getHost();
388 if (!sHostp && !hostp && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
389 {
390 loadAsset();
391 }
392 LLFloater::open();
393}
394
395// virtual
396bool LLPreview::saveItem(LLPointer<LLInventoryItem>* itemptr)
397{
398 return false;
399}
400
401
402// static
403void LLPreview::onBtnCopyToInv(void* userdata)
404{
405 LLPreview* self = (LLPreview*) userdata;
406 LLInventoryItem *item = self->mAuxItem;
407
408 if(item && item->getUUID().notNull())
409 {
410 // Copy to inventory
411 if (self->mNotecardInventoryID.notNull())
412 {
413 copy_inventory_from_notecard(self->mObjectID,
414 self->mNotecardInventoryID, item);
415 }
416 else
417 {
418 LLPointer<LLInventoryCallback> cb = NULL;
419 copy_inventory_item(
420 gAgent.getID(),
421 item->getPermissions().getOwner(),
422 item->getUUID(),
423 LLUUID::null,
424 std::string(),
425 cb);
426 }
427 }
428}
429
430// static
431void LLPreview::onKeepBtn(void* data)
432{
433 LLPreview* self = (LLPreview*)data;
434 self->close();
435}
436
437// static
438void LLPreview::onDiscardBtn(void* data)
439{
440 LLPreview* self = (LLPreview*)data;
441
442 LLViewerInventoryItem* item = self->getItem();
443 if (!item) return;
444
445 self->mForceClose = TRUE;
446 self->close();
447
448 // Delete the item entirely
449 /*
450 item->removeFromServer();
451 gInventory.deleteObject(item->getUUID());
452 gInventory.notifyObservers();
453 */
454
455 // Move the item to the trash
456 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
457 if (item->getParentUUID() != trash_id)
458 {
459 LLInventoryModel::update_list_t update;
460 LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
461 update.push_back(old_folder);
462 LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
463 update.push_back(new_folder);
464 gInventory.accountForUpdate(update);
465
466 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
467 new_item->setParent(trash_id);
468 // no need to restamp it though it's a move into trash because
469 // it's a brand new item already.
470 new_item->updateParentOnServer(FALSE);
471 gInventory.updateItem(new_item);
472 gInventory.notifyObservers();
473 }
474}
475
476//static
477LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id)
478{
479 preview_multimap_t::iterator found_it = sPreviewsBySource.find(source_id);
480 if (found_it != sPreviewsBySource.end())
481 {
482 // just return first one
483 return (LLPreview*)LLFloater::getFloaterByHandle(found_it->second);
484 }
485 return NULL;
486}
487
488//
489// LLMultiPreview
490//
491
492LLMultiPreview::LLMultiPreview(const LLRect& rect) : LLMultiFloater("Preview", rect)
493{
494}
495
496void LLMultiPreview::open()
497{
498 LLMultiFloater::open();
499 LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
500 if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
501 {
502 frontmost_preview->loadAsset();
503 }
504}
505
506void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
507{
508 LLPreview* opened_preview = (LLPreview*)opened_floater;
509 if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
510 {
511 opened_preview->loadAsset();
512 }
513}