00001
00032 #include "llviewerprecompiledheaders.h"
00033 #include "stdenums.h"
00034
00035 #include "llpreview.h"
00036 #include "lllineeditor.h"
00037 #include "llinventory.h"
00038 #include "llinventorymodel.h"
00039 #include "llresmgr.h"
00040 #include "lltextbox.h"
00041 #include "llfocusmgr.h"
00042 #include "lltooldraganddrop.h"
00043 #include "llradiogroup.h"
00044 #include "llassetstorage.h"
00045 #include "llviewerobject.h"
00046 #include "llviewerobjectlist.h"
00047 #include "lldbstrings.h"
00048 #include "llagent.h"
00049 #include "llvoavatar.h"
00050 #include "llselectmgr.h"
00051 #include "llinventoryview.h"
00052 #include "llviewerinventory.h"
00053
00054
00055
00056
00057 LLPreview::preview_multimap_t LLPreview::sPreviewsBySource;
00058 LLPreview::preview_map_t LLPreview::sInstances;
00059 std::map<LLUUID, LLViewHandle> LLMultiPreview::sAutoOpenPreviewHandles;
00060
00061
00062 LLPreview::LLPreview(const std::string& name) :
00063 LLFloater(name),
00064 mCopyToInvBtn(NULL),
00065 mForceClose(FALSE),
00066 mUserResized(FALSE),
00067 mCloseAfterSave(FALSE),
00068 mAssetStatus(PREVIEW_ASSET_UNLOADED),
00069 mItem(NULL)
00070 {
00071
00072 mAuxItem = new LLInventoryItem;
00073
00074 mAutoFocus = FALSE;
00075 }
00076
00077 LLPreview::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, LLPointer<LLViewerInventoryItem> inv_item )
00078 : LLFloater(name, rect, title, allow_resize, min_width, min_height ),
00079 mItemUUID(item_uuid),
00080 mSourceID(LLUUID::null),
00081 mObjectUUID(object_uuid),
00082 mCopyToInvBtn( NULL ),
00083 mForceClose( FALSE ),
00084 mUserResized(FALSE),
00085 mCloseAfterSave(FALSE),
00086 mAssetStatus(PREVIEW_ASSET_UNLOADED),
00087 mItem(inv_item)
00088 {
00089 mAuxItem = new LLInventoryItem;
00090
00091 mAutoFocus = FALSE;
00092
00093 if (mItemUUID.notNull())
00094 {
00095 sInstances[mItemUUID] = this;
00096 }
00097
00098 }
00099
00100 LLPreview::~LLPreview()
00101 {
00102 gFocusMgr.releaseFocusIfNeeded( this );
00103
00104 if (mItemUUID.notNull())
00105 {
00106 sInstances.erase( mItemUUID );
00107 }
00108
00109 if (mSourceID.notNull())
00110 {
00111 preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
00112 for (; found_it != sPreviewsBySource.end(); ++found_it)
00113 {
00114 if (found_it->second == mViewHandle)
00115 {
00116 sPreviewsBySource.erase(found_it);
00117 break;
00118 }
00119 }
00120 }
00121 }
00122
00123 void LLPreview::setItemID(const LLUUID& item_id)
00124 {
00125 if (mItemUUID.notNull())
00126 {
00127 sInstances.erase(mItemUUID);
00128 }
00129
00130 mItemUUID = item_id;
00131
00132 if (mItemUUID.notNull())
00133 {
00134 sInstances[mItemUUID] = this;
00135 }
00136 }
00137
00138 void LLPreview::setObjectID(const LLUUID& object_id)
00139 {
00140 mObjectUUID = object_id;
00141 }
00142
00143 void LLPreview::setSourceID(const LLUUID& source_id)
00144 {
00145 if (mSourceID.notNull())
00146 {
00147
00148 preview_multimap_t::iterator found_it = sPreviewsBySource.find(mSourceID);
00149 for (; found_it != sPreviewsBySource.end(); ++found_it)
00150 {
00151 if (found_it->second == mViewHandle)
00152 {
00153 sPreviewsBySource.erase(found_it);
00154 break;
00155 }
00156 }
00157 }
00158 mSourceID = source_id;
00159 sPreviewsBySource.insert(preview_multimap_t::value_type(mSourceID, mViewHandle));
00160 }
00161
00162 const LLViewerInventoryItem *LLPreview::getItem() const
00163 {
00164 if(mItem)
00165 return mItem;
00166 const LLViewerInventoryItem *item = NULL;
00167 if(mObjectUUID.isNull())
00168 {
00169
00170 item = gInventory.getItem(mItemUUID);
00171 }
00172 else
00173 {
00174
00175 LLViewerObject* object = gObjectList.findObject(mObjectUUID);
00176 if(object)
00177 {
00178 item = (LLViewerInventoryItem*)object->getInventoryObject(mItemUUID);
00179 }
00180 }
00181 return item;
00182 }
00183
00184
00185 void LLPreview::onCommit()
00186 {
00187 const LLViewerInventoryItem *item = getItem();
00188 if(item)
00189 {
00190 if (!item->isComplete())
00191 {
00192
00193 llwarns << "LLPreview::onCommit() called with mIsComplete == FALSE"
00194 << " Type: " << item->getType()
00195 << " ID: " << item->getUUID()
00196 << llendl;
00197 return;
00198 }
00199
00200 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00201 new_item->setDescription(childGetText("desc"));
00202 if(mObjectUUID.notNull())
00203 {
00204
00205 LLViewerObject* object = gObjectList.findObject(mObjectUUID);
00206 if(object)
00207 {
00208 object->updateInventory(
00209 new_item,
00210 TASK_INVENTORY_ITEM_KEY,
00211 false);
00212 }
00213 }
00214 else if(item->getPermissions().getOwner() == gAgent.getID())
00215 {
00216 new_item->updateServer(FALSE);
00217 gInventory.updateItem(new_item);
00218
00219
00220
00221 if( item->getType() == LLAssetType::AT_OBJECT )
00222 {
00223 LLVOAvatar* avatar = gAgent.getAvatarObject();
00224 if( avatar )
00225 {
00226 LLViewerObject* obj = avatar->getWornAttachment( item->getUUID() );
00227 if( obj )
00228 {
00229 gSelectMgr->deselectAll();
00230 gSelectMgr->addAsIndividual( obj, SELECT_ALL_TES, FALSE );
00231 gSelectMgr->selectionSetObjectDescription( childGetText("desc") );
00232
00233 gSelectMgr->deselectAll();
00234 }
00235 }
00236 }
00237 }
00238 }
00239 }
00240
00241
00242 void LLPreview::onText(LLUICtrl*, void* userdata)
00243 {
00244 LLPreview* self = (LLPreview*) userdata;
00245 self->onCommit();
00246 }
00247
00248
00249 void LLPreview::onRadio(LLUICtrl*, void* userdata)
00250 {
00251 LLPreview* self = (LLPreview*) userdata;
00252 self->onCommit();
00253 }
00254
00255
00256 LLPreview* LLPreview::find(const LLUUID& item_uuid)
00257 {
00258 LLPreview* instance = NULL;
00259 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
00260 if(found_it != LLPreview::sInstances.end())
00261 {
00262 instance = found_it->second;
00263 }
00264 return instance;
00265 }
00266
00267
00268 LLPreview* LLPreview::show( const LLUUID& item_uuid, BOOL take_focus )
00269 {
00270 LLPreview* instance = LLPreview::find(item_uuid);
00271 if(instance)
00272 {
00273 if (LLFloater::getFloaterHost() && LLFloater::getFloaterHost() != instance->getHost())
00274 {
00275
00276
00277 LLFloater::getFloaterHost()->addFloater(instance, TRUE);
00278 }
00279 instance->open();
00280 if (take_focus)
00281 {
00282 instance->setFocus(TRUE);
00283 }
00284 }
00285
00286 return instance;
00287 }
00288
00289
00290 bool LLPreview::save( const LLUUID& item_uuid, LLPointer<LLInventoryItem>* itemptr )
00291 {
00292 bool res = false;
00293 LLPreview* instance = LLPreview::find(item_uuid);
00294 if(instance)
00295 {
00296 res = instance->saveItem(itemptr);
00297 }
00298 if (!res)
00299 {
00300 delete itemptr;
00301 }
00302 return res;
00303 }
00304
00305
00306 void LLPreview::hide(const LLUUID& item_uuid, BOOL no_saving )
00307 {
00308 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
00309 if(found_it != LLPreview::sInstances.end())
00310 {
00311 LLPreview* instance = found_it->second;
00312
00313 if ( no_saving )
00314 {
00315 instance->mForceClose = TRUE;
00316 }
00317
00318 instance->close();
00319 }
00320 }
00321
00322
00323 void LLPreview::rename(const LLUUID& item_uuid, const std::string& new_name)
00324 {
00325 preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid);
00326 if(found_it != LLPreview::sInstances.end())
00327 {
00328 LLPreview* instance = found_it->second;
00329 instance->setTitle( new_name );
00330 }
00331 }
00332
00333 BOOL LLPreview::handleMouseDown(S32 x, S32 y, MASK mask)
00334 {
00335 if(mClientRect.pointInRect(x, y))
00336 {
00337
00338
00339 bringToFront(x, y);
00340 gFocusMgr.setMouseCapture(this);
00341 S32 screen_x;
00342 S32 screen_y;
00343 localPointToScreen(x, y, &screen_x, &screen_y );
00344 gToolDragAndDrop->setDragStart(screen_x, screen_y);
00345 return TRUE;
00346 }
00347 return LLFloater::handleMouseDown(x, y, mask);
00348 }
00349
00350 BOOL LLPreview::handleMouseUp(S32 x, S32 y, MASK mask)
00351 {
00352 if(hasMouseCapture())
00353 {
00354 gFocusMgr.setMouseCapture(NULL);
00355 return TRUE;
00356 }
00357 return LLFloater::handleMouseUp(x, y, mask);
00358 }
00359
00360 BOOL LLPreview::handleHover(S32 x, S32 y, MASK mask)
00361 {
00362 if(hasMouseCapture())
00363 {
00364 S32 screen_x;
00365 S32 screen_y;
00366 const LLViewerInventoryItem *item = getItem();
00367
00368 localPointToScreen(x, y, &screen_x, &screen_y );
00369 if(item
00370 && item->getPermissions().allowCopyBy(gAgent.getID(),
00371 gAgent.getGroupID())
00372 && gToolDragAndDrop->isOverThreshold(screen_x, screen_y))
00373 {
00374 EDragAndDropType type;
00375 type = LLAssetType::lookupDragAndDropType(item->getType());
00376 LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_LIBRARY;
00377 if(!mObjectUUID.isNull())
00378 {
00379 src = LLToolDragAndDrop::SOURCE_WORLD;
00380 }
00381 else if(item->getPermissions().getOwner() == gAgent.getID())
00382 {
00383 src = LLToolDragAndDrop::SOURCE_AGENT;
00384 }
00385 gToolDragAndDrop->beginDrag(type,
00386 item->getUUID(),
00387 src,
00388 mObjectUUID);
00389 return gToolDragAndDrop->handleHover(x, y, mask );
00390 }
00391 }
00392 return LLFloater::handleHover(x,y,mask);
00393 }
00394
00395 void LLPreview::open()
00396 {
00397 LLMultiFloater* hostp = getHost();
00398 if (!sHostp && !hostp && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
00399 {
00400 loadAsset();
00401 }
00402 LLFloater::open();
00403 }
00404
00405
00406 bool LLPreview::saveItem(LLPointer<LLInventoryItem>* itemptr)
00407 {
00408 return false;
00409 }
00410
00411
00412
00413 void LLPreview::onBtnCopyToInv(void* userdata)
00414 {
00415 LLPreview* self = (LLPreview*) userdata;
00416 LLInventoryItem *item = self->mAuxItem;
00417
00418 if(item && item->getUUID().notNull())
00419 {
00420
00421 if (self->mNotecardInventoryID.notNull())
00422 {
00423 copy_inventory_from_notecard(self->mObjectID,
00424 self->mNotecardInventoryID, item);
00425 }
00426 else
00427 {
00428 LLPointer<LLInventoryCallback> cb = NULL;
00429 copy_inventory_item(
00430 gAgent.getID(),
00431 item->getPermissions().getOwner(),
00432 item->getUUID(),
00433 LLUUID::null,
00434 std::string(),
00435 cb);
00436 }
00437 }
00438 }
00439
00440
00441 void LLPreview::onKeepBtn(void* data)
00442 {
00443 LLPreview* self = (LLPreview*)data;
00444 self->close();
00445 }
00446
00447
00448 void LLPreview::onDiscardBtn(void* data)
00449 {
00450 LLPreview* self = (LLPreview*)data;
00451
00452 const LLViewerInventoryItem* item = self->getItem();
00453 if (!item) return;
00454
00455 self->mForceClose = TRUE;
00456 self->close();
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 LLUUID trash_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
00467 if (item->getParentUUID() != trash_id)
00468 {
00469 LLInventoryModel::update_list_t update;
00470 LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
00471 update.push_back(old_folder);
00472 LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
00473 update.push_back(new_folder);
00474 gInventory.accountForUpdate(update);
00475
00476 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00477 new_item->setParent(trash_id);
00478
00479
00480 new_item->updateParentOnServer(FALSE);
00481 gInventory.updateItem(new_item);
00482 gInventory.notifyObservers();
00483 }
00484 }
00485
00486
00487 LLPreview* LLPreview::getFirstPreviewForSource(const LLUUID& source_id)
00488 {
00489 preview_multimap_t::iterator found_it = sPreviewsBySource.find(source_id);
00490 if (found_it != sPreviewsBySource.end())
00491 {
00492
00493 return (LLPreview*)LLFloater::getFloaterByHandle(found_it->second);
00494 }
00495 return NULL;
00496 }
00497
00498 void LLPreview::userSetShape(const LLRect& new_rect)
00499 {
00500 if(new_rect.getWidth() != mRect.getWidth() || new_rect.getHeight() != mRect.getHeight())
00501 {
00502 userResized();
00503 }
00504 LLFloater::userSetShape(new_rect);
00505 }
00506
00507
00508
00509
00510
00511 LLMultiPreview::LLMultiPreview(const LLRect& rect) : LLMultiFloater("Preview", rect)
00512 {
00513 setCanResize(TRUE);
00514 }
00515
00516 void LLMultiPreview::open()
00517 {
00518 LLMultiFloater::open();
00519 LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
00520 if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
00521 {
00522 frontmost_preview->loadAsset();
00523 }
00524 }
00525
00526
00527 void LLMultiPreview::userSetShape(const LLRect& new_rect)
00528 {
00529 if(new_rect.getWidth() != mRect.getWidth() || new_rect.getHeight() != mRect.getHeight())
00530 {
00531 LLPreview* frontmost_preview = (LLPreview*)mTabContainer->getCurrentPanel();
00532 if (frontmost_preview) frontmost_preview->userResized();
00533 }
00534 LLFloater::userSetShape(new_rect);
00535 }
00536
00537
00538 void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
00539 {
00540 LLPreview* opened_preview = (LLPreview*)opened_floater;
00541 if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
00542 {
00543 opened_preview->loadAsset();
00544 }
00545 }
00546
00547
00548 LLMultiPreview* LLMultiPreview::getAutoOpenInstance(const LLUUID& id)
00549 {
00550 handle_map_t::iterator found_it = sAutoOpenPreviewHandles.find(id);
00551 if (found_it != sAutoOpenPreviewHandles.end())
00552 {
00553 return (LLMultiPreview*)gFloaterView->getFloaterByHandle(found_it->second);
00554 }
00555 return NULL;
00556 }
00557
00558
00559 void LLMultiPreview::setAutoOpenInstance(LLMultiPreview* previewp, const LLUUID& id)
00560 {
00561 if (previewp)
00562 {
00563 sAutoOpenPreviewHandles[id] = previewp->getHandle();
00564 }
00565 }