diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
---|---|---|
committer | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
commit | 1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch) | |
tree | ab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llpreview.cpp | |
parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
parent | e1623bb276f83a43ce7a197e388720c05bdefe61 (diff) |
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
# autobuild.xml
# indra/cmake/CMakeLists.txt
# indra/cmake/GoogleMock.cmake
# indra/llaudio/llaudioengine_fmodstudio.cpp
# indra/llaudio/llaudioengine_fmodstudio.h
# indra/llaudio/lllistener_fmodstudio.cpp
# indra/llaudio/lllistener_fmodstudio.h
# indra/llaudio/llstreamingaudio_fmodstudio.cpp
# indra/llaudio/llstreamingaudio_fmodstudio.h
# indra/llcharacter/llmultigesture.cpp
# indra/llcharacter/llmultigesture.h
# indra/llimage/llimage.cpp
# indra/llimage/llimagepng.cpp
# indra/llimage/llimageworker.cpp
# indra/llimage/tests/llimageworker_test.cpp
# indra/llmessage/tests/llmockhttpclient.h
# indra/llprimitive/llgltfmaterial.h
# indra/llrender/llfontfreetype.cpp
# indra/llui/llcombobox.cpp
# indra/llui/llfolderview.cpp
# indra/llui/llfolderviewmodel.h
# indra/llui/lllineeditor.cpp
# indra/llui/lllineeditor.h
# indra/llui/lltextbase.cpp
# indra/llui/lltextbase.h
# indra/llui/lltexteditor.cpp
# indra/llui/lltextvalidate.cpp
# indra/llui/lltextvalidate.h
# indra/llui/lluictrl.h
# indra/llui/llview.cpp
# indra/llwindow/llwindowmacosx.cpp
# indra/newview/app_settings/settings.xml
# indra/newview/llappearancemgr.cpp
# indra/newview/llappearancemgr.h
# indra/newview/llavatarpropertiesprocessor.cpp
# indra/newview/llavatarpropertiesprocessor.h
# indra/newview/llbreadcrumbview.cpp
# indra/newview/llbreadcrumbview.h
# indra/newview/llbreastmotion.cpp
# indra/newview/llbreastmotion.h
# indra/newview/llconversationmodel.h
# indra/newview/lldensityctrl.cpp
# indra/newview/lldensityctrl.h
# indra/newview/llface.inl
# indra/newview/llfloatereditsky.cpp
# indra/newview/llfloatereditwater.cpp
# indra/newview/llfloateremojipicker.h
# indra/newview/llfloaterimsessiontab.cpp
# indra/newview/llfloaterprofiletexture.cpp
# indra/newview/llfloaterprofiletexture.h
# indra/newview/llgesturemgr.cpp
# indra/newview/llgesturemgr.h
# indra/newview/llimpanel.cpp
# indra/newview/llimpanel.h
# indra/newview/llinventorybridge.cpp
# indra/newview/llinventorybridge.h
# indra/newview/llinventoryclipboard.cpp
# indra/newview/llinventoryclipboard.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llinventoryfunctions.h
# indra/newview/llinventorygallery.cpp
# indra/newview/lllistbrowser.cpp
# indra/newview/lllistbrowser.h
# indra/newview/llpanelobjectinventory.cpp
# indra/newview/llpanelprofile.cpp
# indra/newview/llpanelprofile.h
# indra/newview/llpreviewgesture.cpp
# indra/newview/llsavedsettingsglue.cpp
# indra/newview/llsavedsettingsglue.h
# indra/newview/lltooldraganddrop.cpp
# indra/newview/llurllineeditorctrl.cpp
# indra/newview/llvectorperfoptions.cpp
# indra/newview/llvectorperfoptions.h
# indra/newview/llviewerparceloverlay.cpp
# indra/newview/llviewertexlayer.cpp
# indra/newview/llviewertexturelist.cpp
# indra/newview/macmain.h
# indra/test/test.cpp
Diffstat (limited to 'indra/newview/llpreview.cpp')
-rw-r--r-- | indra/newview/llpreview.cpp | 1136 |
1 files changed, 568 insertions, 568 deletions
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index 22600f7fc3..b44c015d87 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -1,568 +1,568 @@ -/** - * @file llpreview.cpp - * @brief LLPreview class implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llpreview.h" - -#include "lllineeditor.h" -#include "llinventorydefines.h" -#include "llinventorymodel.h" -#include "llresmgr.h" -#include "lltextbox.h" -#include "llfloaterreg.h" -#include "llfocusmgr.h" -#include "lltooldraganddrop.h" -#include "llradiogroup.h" -#include "llassetstorage.h" -#include "llviewerassettype.h" -#include "llviewermessage.h" -#include "llviewerobject.h" -#include "llviewerobjectlist.h" -#include "lldbstrings.h" -#include "llagent.h" -#include "llvoavatarself.h" -#include "llselectmgr.h" -#include "llviewerinventory.h" -#include "llviewerwindow.h" -#include "lltrans.h" -#include "roles_constants.h" - -// Constants - -LLPreview::LLPreview(const LLSD& key) -: LLFloater(key), - mItemUUID(key.has("itemid") ? key.get("itemid").asUUID() : key.asUUID()), - mObjectUUID(), // set later by setObjectID() - mCopyToInvBtn( NULL ), - mForceClose(false), - mUserResized(false), - mCloseAfterSave(false), - mAssetStatus(PREVIEW_ASSET_UNLOADED), - mDirty(true), - mSaveDialogShown(false) -{ - mAuxItem = new LLInventoryItem; - // don't necessarily steal focus on creation -- sometimes these guys pop up without user action - setAutoFocus(false); - - gInventory.addObserver(this); - - refreshFromItem(); -} - -bool LLPreview::postBuild() -{ - refreshFromItem(); - return true; -} - -LLPreview::~LLPreview() -{ - gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() - gInventory.removeObserver(this); -} - -void LLPreview::setObjectID(const LLUUID& object_id) -{ - mObjectUUID = object_id; - if (getAssetStatus() == PREVIEW_ASSET_UNLOADED) - { - loadAsset(); - } - refreshFromItem(); -} - -void LLPreview::setItem( LLInventoryItem* item ) -{ - mItem = item; - if (mItem && getAssetStatus() == PREVIEW_ASSET_UNLOADED) - { - loadAsset(); - } - refreshFromItem(); -} - -const LLInventoryItem *LLPreview::getItem() const -{ - const LLInventoryItem *item = NULL; - if (mItem.notNull()) - { - item = mItem; - } - else if (mObjectUUID.isNull()) - { - if (mItemUUID.notNull()) - { - // it's an inventory item, so get the item. - item = gInventory.getItem(mItemUUID); - } - } - else - { - // it's an object's inventory item. - LLViewerObject* object = gObjectList.findObject(mObjectUUID); - if(object) - { - item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mItemUUID)); - } - } - return item; -} - -// Sub-classes should override this function if they allow editing -void LLPreview::onCommit() -{ - const LLViewerInventoryItem *item = dynamic_cast<const LLViewerInventoryItem*>(getItem()); - if(item) - { - if (!item->isFinished()) - { - // We are attempting to save an item that was never loaded - LL_WARNS() << "LLPreview::onCommit() called with mIsComplete == false" - << " Type: " << item->getType() - << " ID: " << item->getUUID() - << LL_ENDL; - return; - } - - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setDescription(getChild<LLUICtrl>("desc")->getValue().asString()); - - std::string new_name = getChild<LLUICtrl>("name")->getValue().asString(); - if ( (new_item->getName() != new_name) && !new_name.empty()) - { - new_item->rename(getChild<LLUICtrl>("name")->getValue().asString()); - } - - if(mObjectUUID.notNull()) - { - // must be in an object - LLViewerObject* object = gObjectList.findObject(mObjectUUID); - if(object) - { - object->updateInventory( - new_item, - TASK_INVENTORY_ITEM_KEY, - false); - } - } - else if(item->getPermissions().getOwner() == gAgent.getID()) - { - new_item->updateServer(false); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - - // If the item is an attachment that is currently being worn, - // update the object itself. - if( item->getType() == LLAssetType::AT_OBJECT ) - { - if (isAgentAvatarValid()) - { - LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() ); - if( obj ) - { - LLSelectMgr::getInstance()->deselectAll(); - LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, false ); - LLSelectMgr::getInstance()->selectionSetObjectDescription( getChild<LLUICtrl>("desc")->getValue().asString() ); - - LLSelectMgr::getInstance()->deselectAll(); - } - } - } - } - } -} - -void LLPreview::changed(U32 mask) -{ - mDirty = true; -} - -void LLPreview::setNotecardInfo(const LLUUID& notecard_inv_id, - const LLUUID& object_id) -{ - mNotecardInventoryID = notecard_inv_id; - mNotecardObjectID = object_id; -} - -void LLPreview::draw() -{ - LLFloater::draw(); - if (mDirty) - { - mDirty = false; - refreshFromItem(); - } -} - -void LLPreview::refreshFromItem() -{ - const LLInventoryItem* item = getItem(); - if (!item) - { - return; - } - if (hasString("Title")) - { - LLStringUtil::format_map_t args; - args["[NAME]"] = item->getName(); - LLUIString title = getString("Title", args); - setTitle(title.getString()); - } - getChild<LLUICtrl>("desc")->setValue(item->getDescription()); - - getChildView("desc")->setEnabled(canModify(mObjectUUID, item)); -} - -// static -bool LLPreview::canModify(const LLUUID taskUUID, const LLInventoryItem* item) -{ - const LLViewerObject* object = nullptr; - if (taskUUID.notNull()) - { - object = gObjectList.findObject(taskUUID); - } - - return canModify(object, item); -} - -// static -bool LLPreview::canModify(const LLViewerObject* object, const LLInventoryItem* item) -{ - if (object && !object->permModify()) - { - // No permission to edit in-world inventory - return false; - } - - return item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE); -} - -// static -void LLPreview::onText(LLUICtrl*, void* userdata) -{ - LLPreview* self = (LLPreview*) userdata; - self->onCommit(); -} - -// static -void LLPreview::onRadio(LLUICtrl*, void* userdata) -{ - LLPreview* self = (LLPreview*) userdata; - self->onCommit(); -} - -// static -void LLPreview::hide(const LLUUID& item_uuid, bool no_saving /* = false */ ) -{ - LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid)); - if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid)); - - LLPreview* preview = dynamic_cast<LLPreview*>(floater); - if (preview) - { - if ( no_saving ) - { - preview->mForceClose = true; - } - preview->closeFloater(); - } -} - -// static -void LLPreview::dirty(const LLUUID& item_uuid) -{ - LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid)); - if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid)); - - LLPreview* preview = dynamic_cast<LLPreview*>(floater); - if(preview) - { - preview->mDirty = true; - } -} - -bool LLPreview::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if(mClientRect.pointInRect(x, y)) - { - // No handler needed for focus lost since this class has no - // state that depends on it. - bringToFront(x, y); - gFocusMgr.setMouseCapture(this); - S32 screen_x; - S32 screen_y; - localPointToScreen(x, y, &screen_x, &screen_y ); - LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y); - return true; - } - return LLFloater::handleMouseDown(x, y, mask); -} - -bool LLPreview::handleMouseUp(S32 x, S32 y, MASK mask) -{ - if(hasMouseCapture()) - { - gFocusMgr.setMouseCapture(NULL); - return true; - } - return LLFloater::handleMouseUp(x, y, mask); -} - -bool LLPreview::handleHover(S32 x, S32 y, MASK mask) -{ - if(hasMouseCapture()) - { - S32 screen_x; - S32 screen_y; - const LLInventoryItem *item = getItem(); - - localPointToScreen(x, y, &screen_x, &screen_y ); - if(item - && item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID()) - && LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y)) - { - EDragAndDropType type; - type = LLViewerAssetType::lookupDragAndDropType(item->getType()); - LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_LIBRARY; - if(!mObjectUUID.isNull()) - { - src = LLToolDragAndDrop::SOURCE_WORLD; - } - else if(item->getPermissions().getOwner() == gAgent.getID()) - { - src = LLToolDragAndDrop::SOURCE_AGENT; - } - LLToolDragAndDrop::getInstance()->beginDrag(type, - item->getUUID(), - src, - mObjectUUID); - return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask ); - } - } - return LLFloater::handleHover(x,y,mask); -} - -void LLPreview::onOpen(const LLSD& key) -{ - if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED) - { - loadAsset(); - } -} - -void LLPreview::setAuxItem( const LLInventoryItem* item ) -{ - if ( mAuxItem ) - mAuxItem->copyItem(item); -} - -// static -void LLPreview::onBtnCopyToInv(void* userdata) -{ - LLPreview* self = (LLPreview*) userdata; - LLInventoryItem *item = self->mAuxItem; - - if(item && item->getUUID().notNull()) - { - // Copy to inventory - if (self->mNotecardInventoryID.notNull()) - { - copy_inventory_from_notecard(LLUUID::null, - self->mNotecardObjectID, - self->mNotecardInventoryID, - item); - } - else if (self->mObjectUUID.notNull()) - { - // item is in in-world inventory - LLViewerObject* object = gObjectList.findObject(self->mObjectUUID); - LLPermissions perm(item->getPermissions()); - if(object - &&(perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) - && perm.allowTransferTo(gAgent.getID()))) - { - // copy to default folder - set_dad_inventory_item(item, LLUUID::null); - object->moveInventory(LLUUID::null, item->getUUID()); - } - } - else - { - LLPointer<LLInventoryCallback> cb = NULL; - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - } - self->closeFloater(); -} - -// static -void LLPreview::onKeepBtn(void* data) -{ - LLPreview* self = (LLPreview*)data; - self->closeFloater(); -} - -// static -void LLPreview::onDiscardBtn(void* data) -{ - LLPreview* self = (LLPreview*)data; - - const LLInventoryItem* item = self->getItem(); - if (!item) return; - - self->mForceClose = true; - self->closeFloater(); - - // Move the item to the trash - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (item->getParentUUID() != trash_id) - { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setParent(trash_id); - // no need to restamp it though it's a move into trash because - // it's a brand new item already. - new_item->updateParentOnServer(false); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } -} - -void LLPreview::handleReshape(const LLRect& new_rect, bool by_user) -{ - if(by_user - && (new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight())) - { - userResized(); - } - LLFloater::handleReshape(new_rect, by_user); -} - -// -// LLMultiPreview -// - -LLMultiPreview::LLMultiPreview() - : LLMultiFloater(LLSD()) -{ - // start with a rect in the top-left corner ; will get resized - LLRect rect; - rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 400); - setRect(rect); - - LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("preview"); - if (last_floater) - { - stackWith(*last_floater); - } - setTitle(LLTrans::getString("MultiPreviewTitle")); - buildTabContainer(); - setCanResize(true); -} - -void LLMultiPreview::onOpen(const LLSD& key) -{ - // Floater could be something else than LLPreview, eg LLFloaterProfile. - LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); - - if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) - { - frontmost_preview->loadAsset(); - } - LLMultiFloater::onOpen(key); -} - - -void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user) -{ - if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()) - { - // Floater could be something else than LLPreview, eg LLFloaterProfile. - LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel()); - - if (frontmost_preview) - { - frontmost_preview->userResized(); - } - } - LLFloater::handleReshape(new_rect, by_user); -} - - -void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) -{ - // Floater could be something else than LLPreview, eg LLFloaterProfile. - LLPreview* opened_preview = dynamic_cast<LLPreview*>(opened_floater); - - if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED) - { - opened_preview->loadAsset(); - } -} - - -void LLPreview::setAssetId(const LLUUID& asset_id) -{ - const LLViewerInventoryItem* item = dynamic_cast<const LLViewerInventoryItem*>(getItem()); - if(NULL == item) - { - return; - } - - if(mObjectUUID.isNull()) - { - // Update avatar inventory asset_id. - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setAssetUUID(asset_id); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - else - { - // Update object inventory asset_id. - LLViewerObject* object = gObjectList.findObject(mObjectUUID); - if(NULL == object) - { - return; - } - object->updateViewerInventoryAsset(item, asset_id); - } -} +/**
+ * @file llpreview.cpp
+ * @brief LLPreview class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpreview.h"
+
+#include "lllineeditor.h"
+#include "llinventorydefines.h"
+#include "llinventorymodel.h"
+#include "llresmgr.h"
+#include "lltextbox.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "lltooldraganddrop.h"
+#include "llradiogroup.h"
+#include "llassetstorage.h"
+#include "llviewerassettype.h"
+#include "llviewermessage.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "lldbstrings.h"
+#include "llagent.h"
+#include "llvoavatarself.h"
+#include "llselectmgr.h"
+#include "llviewerinventory.h"
+#include "llviewerwindow.h"
+#include "lltrans.h"
+#include "roles_constants.h"
+
+// Constants
+
+LLPreview::LLPreview(const LLSD& key)
+: LLFloater(key),
+ mItemUUID(key.has("itemid") ? key.get("itemid").asUUID() : key.asUUID()),
+ mObjectUUID(), // set later by setObjectID()
+ mCopyToInvBtn( NULL ),
+ mForceClose(false),
+ mUserResized(false),
+ mCloseAfterSave(false),
+ mAssetStatus(PREVIEW_ASSET_UNLOADED),
+ mDirty(true),
+ mSaveDialogShown(false)
+{
+ mAuxItem = new LLInventoryItem;
+ // don't necessarily steal focus on creation -- sometimes these guys pop up without user action
+ setAutoFocus(false);
+
+ gInventory.addObserver(this);
+
+ refreshFromItem();
+}
+
+bool LLPreview::postBuild()
+{
+ refreshFromItem();
+ return true;
+}
+
+LLPreview::~LLPreview()
+{
+ gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+ gInventory.removeObserver(this);
+}
+
+void LLPreview::setObjectID(const LLUUID& object_id)
+{
+ mObjectUUID = object_id;
+ if (getAssetStatus() == PREVIEW_ASSET_UNLOADED)
+ {
+ loadAsset();
+ }
+ refreshFromItem();
+}
+
+void LLPreview::setItem( LLInventoryItem* item )
+{
+ mItem = item;
+ if (mItem && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
+ {
+ loadAsset();
+ }
+ refreshFromItem();
+}
+
+const LLInventoryItem *LLPreview::getItem() const
+{
+ const LLInventoryItem *item = NULL;
+ if (mItem.notNull())
+ {
+ item = mItem;
+ }
+ else if (mObjectUUID.isNull())
+ {
+ if (mItemUUID.notNull())
+ {
+ // it's an inventory item, so get the item.
+ item = gInventory.getItem(mItemUUID);
+ }
+ }
+ else
+ {
+ // it's an object's inventory item.
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
+ if(object)
+ {
+ item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mItemUUID));
+ }
+ }
+ return item;
+}
+
+// Sub-classes should override this function if they allow editing
+void LLPreview::onCommit()
+{
+ const LLViewerInventoryItem *item = dynamic_cast<const LLViewerInventoryItem*>(getItem());
+ if(item)
+ {
+ if (!item->isFinished())
+ {
+ // We are attempting to save an item that was never loaded
+ LL_WARNS() << "LLPreview::onCommit() called with mIsComplete == false"
+ << " Type: " << item->getType()
+ << " ID: " << item->getUUID()
+ << LL_ENDL;
+ return;
+ }
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setDescription(getChild<LLUICtrl>("desc")->getValue().asString());
+
+ std::string new_name = getChild<LLUICtrl>("name")->getValue().asString();
+ if ( (new_item->getName() != new_name) && !new_name.empty())
+ {
+ new_item->rename(getChild<LLUICtrl>("name")->getValue().asString());
+ }
+
+ if(mObjectUUID.notNull())
+ {
+ // must be in an object
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
+ if(object)
+ {
+ object->updateInventory(
+ new_item,
+ TASK_INVENTORY_ITEM_KEY,
+ false);
+ }
+ }
+ else if(item->getPermissions().getOwner() == gAgent.getID())
+ {
+ new_item->updateServer(false);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+
+ // If the item is an attachment that is currently being worn,
+ // update the object itself.
+ if( item->getType() == LLAssetType::AT_OBJECT )
+ {
+ if (isAgentAvatarValid())
+ {
+ LLViewerObject* obj = gAgentAvatarp->getWornAttachment( item->getUUID() );
+ if( obj )
+ {
+ LLSelectMgr::getInstance()->deselectAll();
+ LLSelectMgr::getInstance()->addAsIndividual( obj, SELECT_ALL_TES, false );
+ LLSelectMgr::getInstance()->selectionSetObjectDescription( getChild<LLUICtrl>("desc")->getValue().asString() );
+
+ LLSelectMgr::getInstance()->deselectAll();
+ }
+ }
+ }
+ }
+ }
+}
+
+void LLPreview::changed(U32 mask)
+{
+ mDirty = true;
+}
+
+void LLPreview::setNotecardInfo(const LLUUID& notecard_inv_id,
+ const LLUUID& object_id)
+{
+ mNotecardInventoryID = notecard_inv_id;
+ mNotecardObjectID = object_id;
+}
+
+void LLPreview::draw()
+{
+ LLFloater::draw();
+ if (mDirty)
+ {
+ mDirty = false;
+ refreshFromItem();
+ }
+}
+
+void LLPreview::refreshFromItem()
+{
+ const LLInventoryItem* item = getItem();
+ if (!item)
+ {
+ return;
+ }
+ if (hasString("Title"))
+ {
+ LLStringUtil::format_map_t args;
+ args["[NAME]"] = item->getName();
+ LLUIString title = getString("Title", args);
+ setTitle(title.getString());
+ }
+ getChild<LLUICtrl>("desc")->setValue(item->getDescription());
+
+ getChildView("desc")->setEnabled(canModify(mObjectUUID, item));
+}
+
+// static
+bool LLPreview::canModify(const LLUUID taskUUID, const LLInventoryItem* item)
+{
+ const LLViewerObject* object = nullptr;
+ if (taskUUID.notNull())
+ {
+ object = gObjectList.findObject(taskUUID);
+ }
+
+ return canModify(object, item);
+}
+
+// static
+bool LLPreview::canModify(const LLViewerObject* object, const LLInventoryItem* item)
+{
+ if (object && !object->permModify())
+ {
+ // No permission to edit in-world inventory
+ return false;
+ }
+
+ return item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE);
+}
+
+// static
+void LLPreview::onText(LLUICtrl*, void* userdata)
+{
+ LLPreview* self = (LLPreview*) userdata;
+ self->onCommit();
+}
+
+// static
+void LLPreview::onRadio(LLUICtrl*, void* userdata)
+{
+ LLPreview* self = (LLPreview*) userdata;
+ self->onCommit();
+}
+
+// static
+void LLPreview::hide(const LLUUID& item_uuid, bool no_saving /* = false */ )
+{
+ LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid));
+ if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid));
+
+ LLPreview* preview = dynamic_cast<LLPreview*>(floater);
+ if (preview)
+ {
+ if ( no_saving )
+ {
+ preview->mForceClose = true;
+ }
+ preview->closeFloater();
+ }
+}
+
+// static
+void LLPreview::dirty(const LLUUID& item_uuid)
+{
+ LLFloater* floater = LLFloaterReg::findInstance("preview", LLSD(item_uuid));
+ if (!floater) floater = LLFloaterReg::findInstance("preview_avatar", LLSD(item_uuid));
+
+ LLPreview* preview = dynamic_cast<LLPreview*>(floater);
+ if(preview)
+ {
+ preview->mDirty = true;
+ }
+}
+
+bool LLPreview::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if(mClientRect.pointInRect(x, y))
+ {
+ // No handler needed for focus lost since this class has no
+ // state that depends on it.
+ bringToFront(x, y);
+ gFocusMgr.setMouseCapture(this);
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y );
+ LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+ return true;
+ }
+ return LLFloater::handleMouseDown(x, y, mask);
+}
+
+bool LLPreview::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ if(hasMouseCapture())
+ {
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+ return LLFloater::handleMouseUp(x, y, mask);
+}
+
+bool LLPreview::handleHover(S32 x, S32 y, MASK mask)
+{
+ if(hasMouseCapture())
+ {
+ S32 screen_x;
+ S32 screen_y;
+ const LLInventoryItem *item = getItem();
+
+ localPointToScreen(x, y, &screen_x, &screen_y );
+ if(item
+ && item->getPermissions().allowCopyBy(gAgent.getID(),
+ gAgent.getGroupID())
+ && LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+ {
+ EDragAndDropType type;
+ type = LLViewerAssetType::lookupDragAndDropType(item->getType());
+ LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_LIBRARY;
+ if(!mObjectUUID.isNull())
+ {
+ src = LLToolDragAndDrop::SOURCE_WORLD;
+ }
+ else if(item->getPermissions().getOwner() == gAgent.getID())
+ {
+ src = LLToolDragAndDrop::SOURCE_AGENT;
+ }
+ LLToolDragAndDrop::getInstance()->beginDrag(type,
+ item->getUUID(),
+ src,
+ mObjectUUID);
+ return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask );
+ }
+ }
+ return LLFloater::handleHover(x,y,mask);
+}
+
+void LLPreview::onOpen(const LLSD& key)
+{
+ if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED)
+ {
+ loadAsset();
+ }
+}
+
+void LLPreview::setAuxItem( const LLInventoryItem* item )
+{
+ if ( mAuxItem )
+ mAuxItem->copyItem(item);
+}
+
+// static
+void LLPreview::onBtnCopyToInv(void* userdata)
+{
+ LLPreview* self = (LLPreview*) userdata;
+ LLInventoryItem *item = self->mAuxItem;
+
+ if(item && item->getUUID().notNull())
+ {
+ // Copy to inventory
+ if (self->mNotecardInventoryID.notNull())
+ {
+ copy_inventory_from_notecard(LLUUID::null,
+ self->mNotecardObjectID,
+ self->mNotecardInventoryID,
+ item);
+ }
+ else if (self->mObjectUUID.notNull())
+ {
+ // item is in in-world inventory
+ LLViewerObject* object = gObjectList.findObject(self->mObjectUUID);
+ LLPermissions perm(item->getPermissions());
+ if(object
+ &&(perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID())
+ && perm.allowTransferTo(gAgent.getID())))
+ {
+ // copy to default folder
+ set_dad_inventory_item(item, LLUUID::null);
+ object->moveInventory(LLUUID::null, item->getUUID());
+ }
+ }
+ else
+ {
+ LLPointer<LLInventoryCallback> cb = NULL;
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ LLUUID::null,
+ std::string(),
+ cb);
+ }
+ }
+ self->closeFloater();
+}
+
+// static
+void LLPreview::onKeepBtn(void* data)
+{
+ LLPreview* self = (LLPreview*)data;
+ self->closeFloater();
+}
+
+// static
+void LLPreview::onDiscardBtn(void* data)
+{
+ LLPreview* self = (LLPreview*)data;
+
+ const LLInventoryItem* item = self->getItem();
+ if (!item) return;
+
+ self->mForceClose = true;
+ self->closeFloater();
+
+ // Move the item to the trash
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (item->getParentUUID() != trash_id)
+ {
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
+ update.push_back(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(trash_id, 1);
+ update.push_back(new_folder);
+ gInventory.accountForUpdate(update);
+
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setParent(trash_id);
+ // no need to restamp it though it's a move into trash because
+ // it's a brand new item already.
+ new_item->updateParentOnServer(false);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+}
+
+void LLPreview::handleReshape(const LLRect& new_rect, bool by_user)
+{
+ if(by_user
+ && (new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight()))
+ {
+ userResized();
+ }
+ LLFloater::handleReshape(new_rect, by_user);
+}
+
+//
+// LLMultiPreview
+//
+
+LLMultiPreview::LLMultiPreview()
+ : LLMultiFloater(LLSD())
+{
+ // start with a rect in the top-left corner ; will get resized
+ LLRect rect;
+ rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 400);
+ setRect(rect);
+
+ LLFloater* last_floater = LLFloaterReg::getLastFloaterInGroup("preview");
+ if (last_floater)
+ {
+ stackWith(*last_floater);
+ }
+ setTitle(LLTrans::getString("MultiPreviewTitle"));
+ buildTabContainer();
+ setCanResize(true);
+}
+
+void LLMultiPreview::onOpen(const LLSD& key)
+{
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel());
+
+ if (frontmost_preview && frontmost_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
+ {
+ frontmost_preview->loadAsset();
+ }
+ LLMultiFloater::onOpen(key);
+}
+
+
+void LLMultiPreview::handleReshape(const LLRect& new_rect, bool by_user)
+{
+ if(new_rect.getWidth() != getRect().getWidth() || new_rect.getHeight() != getRect().getHeight())
+ {
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* frontmost_preview = dynamic_cast<LLPreview*>(mTabContainer->getCurrentPanel());
+
+ if (frontmost_preview)
+ {
+ frontmost_preview->userResized();
+ }
+ }
+ LLFloater::handleReshape(new_rect, by_user);
+}
+
+
+void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click)
+{
+ // Floater could be something else than LLPreview, eg LLFloaterProfile.
+ LLPreview* opened_preview = dynamic_cast<LLPreview*>(opened_floater);
+
+ if (opened_preview && opened_preview->getAssetStatus() == LLPreview::PREVIEW_ASSET_UNLOADED)
+ {
+ opened_preview->loadAsset();
+ }
+}
+
+
+void LLPreview::setAssetId(const LLUUID& asset_id)
+{
+ const LLViewerInventoryItem* item = dynamic_cast<const LLViewerInventoryItem*>(getItem());
+ if(NULL == item)
+ {
+ return;
+ }
+
+ if(mObjectUUID.isNull())
+ {
+ // Update avatar inventory asset_id.
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+ new_item->setAssetUUID(asset_id);
+ gInventory.updateItem(new_item);
+ gInventory.notifyObservers();
+ }
+ else
+ {
+ // Update object inventory asset_id.
+ LLViewerObject* object = gObjectList.findObject(mObjectUUID);
+ if(NULL == object)
+ {
+ return;
+ }
+ object->updateViewerInventoryAsset(item, asset_id);
+ }
+}
|