diff options
Diffstat (limited to 'indra')
37 files changed, 727 insertions, 601 deletions
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h index d6d1ea5178..a73ada2931 100644 --- a/indra/llcommon/llevents.h +++ b/indra/llcommon/llevents.h @@ -702,12 +702,14 @@ public: mConnection(new LLBoundListener) { } + /// Copy constructor. Copy shared_ptrs to original instance data. LLListenerWrapperBase(const LLListenerWrapperBase& that): mName(that.mName), mConnection(that.mConnection) { } + virtual ~LLListenerWrapperBase() {} /// Ask LLEventPump::listen() for the listener name virtual void accept_name(const std::string& name) const diff --git a/indra/llplugin/llpluginmessage.cpp b/indra/llplugin/llpluginmessage.cpp index 34e02c356e..d06f3cefa0 100644 --- a/indra/llplugin/llpluginmessage.cpp +++ b/indra/llplugin/llpluginmessage.cpp @@ -37,31 +37,57 @@ #include "llsdserialize.h" #include "u64.h" +/** + * Constructor. + */ LLPluginMessage::LLPluginMessage() { } +/** + * Constructor. + * + * @param[in] p Existing message + */ LLPluginMessage::LLPluginMessage(const LLPluginMessage &p) { mMessage = p.mMessage; } +/** + * Constructor. + * + * @param[in] message_class Message class + * @param[in] message_name Message name + */ LLPluginMessage::LLPluginMessage(const std::string &message_class, const std::string &message_name) { setMessage(message_class, message_name); } +/** + * Destructor. + */ LLPluginMessage::~LLPluginMessage() { } +/** + * Reset all internal state. + */ void LLPluginMessage::clear() { mMessage = LLSD::emptyMap(); mMessage["params"] = LLSD::emptyMap(); } +/** + * Sets the message class and name. Also has the side-effect of clearing any key-value pairs in the message. + * + * @param[in] message_class Message class + * @param[in] message_name Message name + */ void LLPluginMessage::setMessage(const std::string &message_class, const std::string &message_name) { clear(); @@ -69,21 +95,45 @@ void LLPluginMessage::setMessage(const std::string &message_class, const std::st mMessage["name"] = message_name; } +/** + * Sets a key/value pair in the message, where the value is a string. + * + * @param[in] key Key + * @param[in] value String value + */ void LLPluginMessage::setValue(const std::string &key, const std::string &value) { mMessage["params"][key] = value; } +/** + * Sets a key/value pair in the message, where the value is LLSD. + * + * @param[in] key Key + * @param[in] value LLSD value + */ void LLPluginMessage::setValueLLSD(const std::string &key, const LLSD &value) { mMessage["params"][key] = value; } +/** + * Sets a key/value pair in the message, where the value is signed 32-bit. + * + * @param[in] key Key + * @param[in] value 32-bit signed value + */ void LLPluginMessage::setValueS32(const std::string &key, S32 value) { mMessage["params"][key] = value; } +/** + * Sets a key/value pair in the message, where the value is unsigned 32-bit. The value is stored as a string beginning with "0x". + * + * @param[in] key Key + * @param[in] value 32-bit unsigned value + */ void LLPluginMessage::setValueU32(const std::string &key, U32 value) { std::stringstream temp; @@ -91,16 +141,34 @@ void LLPluginMessage::setValueU32(const std::string &key, U32 value) setValue(key, temp.str()); } +/** + * Sets a key/value pair in the message, where the value is a bool. + * + * @param[in] key Key + * @param[in] value Boolean value + */ void LLPluginMessage::setValueBoolean(const std::string &key, bool value) { mMessage["params"][key] = value; } +/** + * Sets a key/value pair in the message, where the value is a double. + * + * @param[in] key Key + * @param[in] value Boolean value + */ void LLPluginMessage::setValueReal(const std::string &key, F64 value) { mMessage["params"][key] = value; } +/** + * Sets a key/value pair in the message, where the value is a pointer. The pointer is stored as a string. + * + * @param[in] key Key + * @param[in] value Pointer value + */ void LLPluginMessage::setValuePointer(const std::string &key, void* value) { std::stringstream temp; @@ -109,16 +177,33 @@ void LLPluginMessage::setValuePointer(const std::string &key, void* value) setValue(key, temp.str()); } +/** + * Gets the message class. + * + * @return Message class + */ std::string LLPluginMessage::getClass(void) const { return mMessage["class"]; } +/** + * Gets the message name. + * + * @return Message name + */ std::string LLPluginMessage::getName(void) const { return mMessage["name"]; } +/** + * Returns true if the specified key exists in this message (useful for optional parameters). + * + * @param[in] key Key + * + * @return True if key exists, false otherwise. + */ bool LLPluginMessage::hasValue(const std::string &key) const { bool result = false; @@ -131,6 +216,13 @@ bool LLPluginMessage::hasValue(const std::string &key) const return result; } +/** + * Gets the value of a key as a string. If the key does not exist, an empty string will be returned. + * + * @param[in] key Key + * + * @return String value of key if key exists, empty string if key does not exist. + */ std::string LLPluginMessage::getValue(const std::string &key) const { std::string result; @@ -143,6 +235,13 @@ std::string LLPluginMessage::getValue(const std::string &key) const return result; } +/** + * Gets the value of a key as LLSD. If the key does not exist, a null LLSD will be returned. + * + * @param[in] key Key + * + * @return LLSD value of key if key exists, null LLSD if key does not exist. + */ LLSD LLPluginMessage::getValueLLSD(const std::string &key) const { LLSD result; @@ -155,6 +254,13 @@ LLSD LLPluginMessage::getValueLLSD(const std::string &key) const return result; } +/** + * Gets the value of a key as signed 32-bit int. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Signed 32-bit int value of key if key exists, 0 if key does not exist. + */ S32 LLPluginMessage::getValueS32(const std::string &key) const { S32 result = 0; @@ -167,6 +273,13 @@ S32 LLPluginMessage::getValueS32(const std::string &key) const return result; } +/** + * Gets the value of a key as unsigned 32-bit int. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Unsigned 32-bit int value of key if key exists, 0 if key does not exist. + */ U32 LLPluginMessage::getValueU32(const std::string &key) const { U32 result = 0; @@ -181,6 +294,13 @@ U32 LLPluginMessage::getValueU32(const std::string &key) const return result; } +/** + * Gets the value of a key as a bool. If the key does not exist, false will be returned. + * + * @param[in] key Key + * + * @return Boolean value of key if it exists, false otherwise. + */ bool LLPluginMessage::getValueBoolean(const std::string &key) const { bool result = false; @@ -193,6 +313,13 @@ bool LLPluginMessage::getValueBoolean(const std::string &key) const return result; } +/** + * Gets the value of a key as a double. If the key does not exist, 0 will be returned. + * + * @param[in] key Key + * + * @return Value as a double if key exists, 0 otherwise. + */ F64 LLPluginMessage::getValueReal(const std::string &key) const { F64 result = 0.0f; @@ -205,6 +332,13 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const return result; } +/** + * Gets the value of a key as a pointer. If the key does not exist, NULL will be returned. + * + * @param[in] key Key + * + * @return Pointer value if key exists, NULL otherwise. + */ void* LLPluginMessage::getValuePointer(const std::string &key) const { void* result = NULL; @@ -219,6 +353,11 @@ void* LLPluginMessage::getValuePointer(const std::string &key) const return result; } +/** + * Flatten the message into a string. + * + * @return Message as a string. + */ std::string LLPluginMessage::generate(void) const { std::ostringstream result; @@ -230,7 +369,11 @@ std::string LLPluginMessage::generate(void) const return result.str(); } - +/** + * Parse an incoming message into component parts. Clears all existing state before starting the parse. + * + * @return Returns -1 on failure, otherwise returns the number of key/value pairs in the incoming message. + */ int LLPluginMessage::parse(const std::string &message) { // clear any previous state @@ -255,16 +398,31 @@ LLPluginMessageDispatcher::~LLPluginMessageDispatcher() } +/** + * Add a message listener. TODO:DOC need more info on what uses this. when are multiple listeners needed? + * + * @param[in] listener Message listener + */ void LLPluginMessageDispatcher::addPluginMessageListener(LLPluginMessageListener *listener) { mListeners.insert(listener); } +/** + * Remove a message listener. + * + * @param[in] listener Message listener + */ void LLPluginMessageDispatcher::removePluginMessageListener(LLPluginMessageListener *listener) { mListeners.erase(listener); } +/** + * Distribute a message to all message listeners. + * + * @param[in] message Message + */ void LLPluginMessageDispatcher::dispatchPluginMessage(const LLPluginMessage &message) { for (listener_set_t::iterator it = mListeners.begin(); diff --git a/indra/llplugin/llpluginmessage.h b/indra/llplugin/llpluginmessage.h index 99f8d1194f..e00022a245 100644 --- a/indra/llplugin/llpluginmessage.h +++ b/indra/llplugin/llpluginmessage.h @@ -104,6 +104,9 @@ private: }; +/** + * @brief Listens for plugin messages. + */ class LLPluginMessageListener { public: @@ -112,6 +115,11 @@ public: }; +/** + * @brief Dispatcher for plugin messages. + * + * Manages the set of plugin message listeners and distributes messages to plugin message listeners. + */ class LLPluginMessageDispatcher { public: @@ -122,7 +130,9 @@ public: protected: void dispatchPluginMessage(const LLPluginMessage &message); + /** A set of message listeners. */ typedef std::set<LLPluginMessageListener*> listener_set_t; + /** The set of message listeners. */ listener_set_t mListeners; }; diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp index 8c8fa24a65..658783e064 100644 --- a/indra/media_plugins/base/media_plugin_base.cpp +++ b/indra/media_plugins/base/media_plugin_base.cpp @@ -2,6 +2,8 @@ * @file media_plugin_base.cpp * @brief Media plugin base class for LLMedia API plugin system * + * All plugins should be a subclass of MediaPluginBase. + * * @cond * $LicenseInfo:firstyear=2008&license=viewergpl$ * @@ -37,7 +39,10 @@ // TODO: Make sure that the only symbol exported from this library is LLPluginInitEntryPoint //////////////////////////////////////////////////////////////////////////////// -// +/// Media plugin constructor. +/// +/// @param[in] host_send_func Function for sending messages from plugin to plugin loader shell +/// @param[in] host_user_data Message data for messages from plugin to plugin loader shell MediaPluginBase::MediaPluginBase( LLPluginInstance::sendMessageFunction host_send_func, @@ -55,6 +60,12 @@ MediaPluginBase::MediaPluginBase( mStatus = STATUS_NONE; } +/** + * Converts current media status enum value into string (STATUS_LOADING into "loading", etc.) + * + * @return Media status string ("loading", "playing", "paused", etc) + * + */ std::string MediaPluginBase::statusString() { std::string result; @@ -75,6 +86,12 @@ std::string MediaPluginBase::statusString() return result; } +/** + * Set media status. + * + * @param[in] status Media status (STATUS_LOADING, STATUS_PLAYING, STATUS_PAUSED, etc) + * + */ void MediaPluginBase::setStatus(EStatus status) { if(mStatus != status) @@ -85,6 +102,13 @@ void MediaPluginBase::setStatus(EStatus status) } +/** + * Receive message from plugin loader shell. + * + * @param[in] message_string Message string + * @param[in] user_data Message data + * + */ void MediaPluginBase::staticReceiveMessage(const char *message_string, void **user_data) { MediaPluginBase *self = (MediaPluginBase*)*user_data; @@ -102,12 +126,27 @@ void MediaPluginBase::staticReceiveMessage(const char *message_string, void **us } } +/** + * Send message to plugin loader shell. + * + * @param[in] message Message data being sent to plugin loader shell + * + */ void MediaPluginBase::sendMessage(const LLPluginMessage &message) { std::string output = message.generate(); mHostSendFunction(output.c_str(), &mHostUserData); } +/** + * Notifies plugin loader shell that part of display area needs to be redrawn. + * + * @param[in] left Left X coordinate of area to redraw (0,0 is at top left corner) + * @param[in] top Top Y coordinate of area to redraw (0,0 is at top left corner) + * @param[in] right Right X-coordinate of area to redraw (0,0 is at top left corner) + * @param[in] bottom Bottom Y-coordinate of area to redraw (0,0 is at top left corner) + * + */ void MediaPluginBase::setDirty(int left, int top, int right, int bottom) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); @@ -120,6 +159,10 @@ void MediaPluginBase::setDirty(int left, int top, int right, int bottom) sendMessage(message); } +/** + * Sends "media_status" message to plugin loader shell ("loading", "playing", "paused", etc.) + * + */ void MediaPluginBase::sendStatus() { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status"); @@ -143,6 +186,17 @@ extern "C" LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); } +/** + * Plugin initialization and entry point. Establishes communication channel for messages between plugin and plugin loader shell. TODO:DOC - Please check! + * + * @param[in] host_send_func Function for sending messages from plugin to plugin loader shell + * @param[in] host_user_data Message data for messages from plugin to plugin loader shell + * @param[out] plugin_send_func Function for plugin to receive messages from plugin loader shell + * @param[out] plugin_user_data Pointer to plugin instance + * + * @return int, where 0=success + * + */ LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) { diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h index 4dd157a07c..ed4dc0cfa9 100644 --- a/indra/media_plugins/base/media_plugin_base.h +++ b/indra/media_plugins/base/media_plugin_base.h @@ -42,14 +42,17 @@ class MediaPluginBase { public: MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); + /** Media plugin destructor. */ virtual ~MediaPluginBase() {} + /** Handle received message from plugin loader shell. */ virtual void receiveMessage(const char *message_string) = 0; static void staticReceiveMessage(const char *message_string, void **user_data); protected: + /** Plugin status. */ typedef enum { STATUS_NONE, @@ -61,10 +64,13 @@ protected: STATUS_DONE } EStatus; + /** Plugin shared memory. */ class SharedSegmentInfo { public: + /** Shared memory address. */ void *mAddress; + /** Shared memory size. */ size_t mSize; }; @@ -73,42 +79,56 @@ protected: std::string statusString(); void setStatus(EStatus status); - // The quicktime plugin overrides this to add current time and duration to the message... + /// Note: The quicktime plugin overrides this to add current time and duration to the message. virtual void setDirty(int left, int top, int right, int bottom); + /** Map of shared memory names to shared memory. */ typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap; + /** Function to send message from plugin to plugin loader shell. */ LLPluginInstance::sendMessageFunction mHostSendFunction; + /** Message data being sent to plugin loader shell by mHostSendFunction. */ void *mHostUserData; + /** Flag to delete plugin instance (self). */ bool mDeleteMe; + /** Pixel array to display. TODO:DOC are pixels always 24-bit RGB format, aligned on 32-bit boundary? Also: calling this a pixel array may be misleading since 1 pixel > 1 char. */ unsigned char* mPixels; + /** TODO:DOC what's this for -- does a texture have its own piece of shared memory? updated on size_change_request, cleared on shm_remove */ std::string mTextureSegmentName; + /** Width of plugin display in pixels. */ int mWidth; + /** Height of plugin display in pixels. */ int mHeight; + /** Width of plugin texture. */ int mTextureWidth; + /** Height of plugin texture. */ int mTextureHeight; + /** Pixel depth (pixel size in bytes). */ int mDepth; + /** Current status of plugin. */ EStatus mStatus; + /** Map of shared memory segments. */ SharedSegmentMap mSharedSegments; }; -// The plugin must define this function to create its instance. +/** The plugin <b>must</b> define this function to create its instance. + * It should look something like this: + * @code + * { + * MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data); + * *plugin_send_func = MediaPluginFoo::staticReceiveMessage; + * *plugin_user_data = (void*)self; + * + * return 0; + * } + * @endcode + */ int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data); -// It should look something like this: -/* -{ - MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data); - *plugin_send_func = MediaPluginFoo::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} -*/ diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index fa4dfe767b..6252bd002e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -386,17 +386,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AutoPlayMedia</key> - <map> - <key>Comment</key> - <string>Allow media objects to automatically play or navigate?</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AutoSnapshot</key> <map> <key>Comment</key> diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index b52b58f9e2..3114a37ada 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -37,7 +37,6 @@ #include "llcallbacklist.h" #include "llfloatercustomize.h" -#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" @@ -704,6 +703,7 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl void LLAgentWearables::wearableUpdated(LLWearable *wearable) { mAvatarObject->wearableUpdated(wearable->getType(), TRUE); + wearable->refreshName(); wearable->setLabelUpdated(); // Hack pt 2. If the wearable we just loaded has definition version 24, @@ -1361,10 +1361,10 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) // Open the inventory and select the first item we added. if (first_item_id.notNull()) { - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - if (view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) { - view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); + active_panel->setSelection(first_item_id, TAKE_FOCUS_NO); } } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index eb08707b61..84843138bf 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -899,6 +899,8 @@ bool LLAppViewer::init() loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort")); } + LLViewerMedia::initClass(); + return true; } diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index d5f9f7ca5d..1d03cc8823 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -42,7 +42,6 @@ #include "llnotify.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" -#include "llfloaterinventory.h" #include "llpermissionsflags.h" #include "llpreviewnotecard.h" #include "llpreviewscript.h" @@ -287,19 +286,18 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // Show the preview panel for textures and sounds to let // user know that the image (or snapshot) arrived intact. - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - if(view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) { - LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); - - view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); + active_panel->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD) { - view->getPanel()->openSelected(); + active_panel->openSelected(); } //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus + LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); gFocusMgr.setKeyboardFocus(focus); } } diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 4a2e1913cd..76c0a7637c 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -120,28 +120,6 @@ LLFloaterInventory* LLFloaterInventory::showAgentInventory() } // static -LLFloaterInventory* LLFloaterInventory::getActiveInventory() -{ - LLFloaterInventory* res = NULL; - LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); - S32 z_min = S32_MAX; - for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) - { - LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); - if (iv) - { - S32 z_order = gFloaterView->getZOrder(iv); - if (z_order < z_min) - { - res = iv; - z_min = z_order; - } - } - } - return res; -} - -// static void LLFloaterInventory::cleanup() { LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); diff --git a/indra/newview/llfloaterinventory.h b/indra/newview/llfloaterinventory.h index c0de89bff2..b661c391a7 100644 --- a/indra/newview/llfloaterinventory.h +++ b/indra/newview/llfloaterinventory.h @@ -55,11 +55,6 @@ public: BOOL postBuild(); - // Return the active inventory view if there is one. Active is - // defined as the inventory that is the closest to the front, and - // is visible. - static LLFloaterInventory* getActiveInventory(); - // This method makes sure that an inventory view exists, is // visible, and has focus. The view chosen is returned. static LLFloaterInventory* showAgentInventory(); diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 6caa0d60f9..56a86c2cb7 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -195,10 +195,10 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data) if (result == 0) { LLFloaterInventory::showAgentInventory(); - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - if (view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) { - view->getPanel()->setSelection(cat->mCatID, TAKE_FOCUS_NO); + active_panel->setSelection(cat->mCatID, TAKE_FOCUS_NO); } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index ac6aa307f2..5bfad0695c 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -38,7 +38,6 @@ #include "llappearancemgr.h" #include "llavataractions.h" #include "llfloatercustomize.h" -#include "llfloaterinventory.h" #include "llfloateropenobject.h" #include "llfloaterreg.h" #include "llfloaterworldmap.h" @@ -125,8 +124,8 @@ std::string ICON_NAME[ICON_NAME_COUNT] = "Inv_Animation", "Inv_Gesture", - "inv_item_linkitem.tga", - "inv_item_linkfolder.tga" + "Inv_LinkItem", + "Inv_LinkFolder" }; // +=================================================+ @@ -516,7 +515,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (obj && obj->getIsLinkType()) { items.push_back(std::string("Find Original")); - if (LLAssetType::lookupIsLinkType(obj->getType())) + if (isLinkedObjectMissing()) { disabled_items.push_back(std::string("Find Original")); } @@ -666,6 +665,20 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const return FALSE; } +BOOL LLInvFVBridge::isLinkedObjectMissing() const +{ + const LLInventoryObject *obj = getInventoryObject(); + if (!obj) + { + return TRUE; + } + if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType())) + { + return TRUE; + } + return FALSE; +} + BOOL LLInvFVBridge::isAgentInventory() const { const LLInventoryModel* model = getInventoryModel(); @@ -856,9 +869,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, new_listener = new LLFolderBridge(inventory, uuid); break; case LLAssetType::AT_LINK: - // Only should happen for broken links. - new_listener = new LLLinkItemBridge(inventory, uuid); - break; case LLAssetType::AT_LINK_FOLDER: // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, uuid); @@ -1055,7 +1065,7 @@ void LLItemBridge::gotoItem(LLFolderView *folder) LLInventoryObject *obj = getInventoryObject(); if (obj && obj->getIsLinkType()) { - LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); if (active_panel) { active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); @@ -2941,9 +2951,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, // everything in the active window so that we don't follow // the selection to its new location (which is very // annoying). - if (LLFloaterInventory::getActiveInventory()) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) { - LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel(); LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); if (active_panel && (panel != active_panel)) { @@ -4091,7 +4101,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Detach From Yourself")); } else - if( !isInTrash() && !isLinkedObjectInTrash() ) + if( !isInTrash() && !isLinkedObjectInTrash() && !isLinkedObjectMissing()) { items.push_back(std::string("Attach Separator")); items.push_back(std::string("Object Wear")); @@ -4490,16 +4500,20 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else { // FWIW, it looks like SUPPRESS_OPEN_ITEM is not set anywhere - BOOL no_open = ((flags & SUPPRESS_OPEN_ITEM) == SUPPRESS_OPEN_ITEM); + BOOL can_open = ((flags & SUPPRESS_OPEN_ITEM) != SUPPRESS_OPEN_ITEM); // If we have clothing, don't add "Open" as it's the same action as "Wear" SL-18976 LLViewerInventoryItem* item = getItem(); - if( !no_open && item ) + if (can_open && item) { - no_open = (item->getType() == LLAssetType::AT_CLOTHING) || - (item->getType() == LLAssetType::AT_BODYPART); + can_open = (item->getType() != LLAssetType::AT_CLOTHING) && + (item->getType() != LLAssetType::AT_BODYPART); } - if (!no_open) + if (isLinkedObjectMissing()) + { + can_open = FALSE; + } + if (can_open) { items.push_back(std::string("Open")); } @@ -4519,7 +4533,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("Wearable Edit")); } // Don't allow items to be worn if their baseobj is in the trash. - if (isLinkedObjectInTrash()) + if (isLinkedObjectInTrash() || isLinkedObjectMissing()) { disabled_items.push_back(std::string("Wearable Wear")); disabled_items.push_back(std::string("Wearable Add")); @@ -5091,7 +5105,7 @@ LLUIImagePtr LLLinkItemBridge::getIcon() const { if (LLViewerInventoryItem *item = getItem()) { - return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE); + return get_item_icon(item->getActualType(), item->getInventoryType(), 0, FALSE); } return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE); } @@ -5103,6 +5117,9 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) std::vector<std::string> items; std::vector<std::string> disabled_items; + items.push_back(std::string("Find Original")); + disabled_items.push_back(std::string("Find Original")); + if(isInTrash()) { items.push_back(std::string("Purge Item")); @@ -5115,6 +5132,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else { + items.push_back(std::string("Properties")); items.push_back(std::string("Delete")); if (!isItemRemovable()) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index ef340af0cb..67dfc5b6f9 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -191,6 +191,7 @@ protected: BOOL isInTrash() const; BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash? + BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory? BOOL isAgentInventory() const; // false if lost or in the inventory library BOOL isCOFFolder() const; // true if COF or descendent of. diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 9f96ebc366..29096ff718 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -36,10 +36,10 @@ #include "llagent.h" #include "llagentwearables.h" #include "llinventorypanel.h" -#include "llfloaterinventory.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" +#include "llinventorypanel.h" #include "llnotificationsutil.h" #include "llwindow.h" #include "llviewercontrol.h" @@ -871,46 +871,48 @@ void LLInventoryModel::moveObject(const LLUUID& object_id, const LLUUID& cat_id) // Delete a particular inventory object by ID. void LLInventoryModel::deleteObject(const LLUUID& id) { - // Disabling this; let users manually purge linked objects. - // purgeLinkedObjects(id); lldebugs << "LLInventoryModel::deleteObject()" << llendl; LLPointer<LLInventoryObject> obj = getObject(id); - if(obj) + if (!obj) { - lldebugs << "Deleting inventory object " << id << llendl; - mLastItem = NULL; - LLUUID parent_id = obj->getParentUUID(); - mCategoryMap.erase(id); - mItemMap.erase(id); - //mInventory.erase(id); - item_array_t* item_list = getUnlockedItemArray(parent_id); - if(item_list) - { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)((LLInventoryObject*)obj); - item_list->removeObj(item); - } - cat_array_t* cat_list = getUnlockedCatArray(parent_id); - if(cat_list) - { - LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)((LLInventoryObject*)obj); - cat_list->removeObj(cat); - } - item_list = getUnlockedItemArray(id); - if(item_list) - { - delete item_list; - mParentChildItemTree.erase(id); - } - cat_list = getUnlockedCatArray(id); - if(cat_list) - { - delete cat_list; - mParentChildCategoryTree.erase(id); - } - addChangedMask(LLInventoryObserver::REMOVE, id); - obj = NULL; // delete obj - gInventory.notifyObservers(); + llwarns << "Deleting non-existent object [ id: " << id << " ] " << llendl; + return; + } + + lldebugs << "Deleting inventory object " << id << llendl; + mLastItem = NULL; + LLUUID parent_id = obj->getParentUUID(); + mCategoryMap.erase(id); + mItemMap.erase(id); + //mInventory.erase(id); + item_array_t* item_list = getUnlockedItemArray(parent_id); + if(item_list) + { + LLViewerInventoryItem* item = (LLViewerInventoryItem*)((LLInventoryObject*)obj); + item_list->removeObj(item); } + cat_array_t* cat_list = getUnlockedCatArray(parent_id); + if(cat_list) + { + LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)((LLInventoryObject*)obj); + cat_list->removeObj(cat); + } + item_list = getUnlockedItemArray(id); + if(item_list) + { + delete item_list; + mParentChildItemTree.erase(id); + } + cat_list = getUnlockedCatArray(id); + if(cat_list) + { + delete cat_list; + mParentChildCategoryTree.erase(id); + } + addChangedMask(LLInventoryObserver::REMOVE, id); + obj = NULL; // delete obj + updateLinkedObjectsFromPurge(id); + gInventory.notifyObservers(); } // Delete a particular inventory item by ID, and remove it from the server. @@ -926,26 +928,23 @@ void LLInventoryModel::purgeObject(const LLUUID &id) } } -void LLInventoryModel::purgeLinkedObjects(const LLUUID &id) +void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) { - LLInventoryObject* objectp = getObject(id); - if (!objectp) return; - - if (objectp->getIsLinkType()) - { - return; - } + LLInventoryModel::item_array_t item_array = collectLinkedItems(baseobj_id); - LLInventoryModel::item_array_t item_array = collectLinkedItems(id); - - for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); + // REBUILD is expensive, so clear the current change list first else + // everything else on the changelist will also get rebuilt. + gInventory.notifyObservers(); + for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); iter != item_array.end(); iter++) { - LLViewerInventoryItem *linked_item = (*iter); - if (linked_item->getUUID() == id) continue; - purgeObject(linked_item->getUUID()); + const LLViewerInventoryItem *linked_item = (*iter); + const LLUUID &item_id = linked_item->getUUID(); + if (item_id == baseobj_id) continue; + addChangedMask(LLInventoryObserver::REBUILD, item_id); } + gInventory.notifyObservers(); } // This is a method which collects the descendents of the id @@ -3048,10 +3047,10 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg, gInventory.notifyObservers(); // *HACK: Do the 'show' logic for a new item in the inventory. - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - if(view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) { - view->getPanel()->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO); + active_panel->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO); } } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 50f54cb842..c3e04ab93c 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -82,6 +82,8 @@ public: // These are used a lot... typedef LLDynamicArray<LLPointer<LLViewerInventoryCategory> > cat_array_t; typedef LLDynamicArray<LLPointer<LLViewerInventoryItem> > item_array_t; + typedef std::set<LLUUID> changed_items_t; + // construction & destruction LLInventoryModel(); ~LLInventoryModel(); @@ -214,9 +216,9 @@ public: void deleteObject(const LLUUID& id); // delete a particular inventory object by ID, and delete it from - // the server. Also purges linked items via purgeLinkedObjects. + // the server. Also updates linked items. void purgeObject(const LLUUID& id); - void purgeLinkedObjects(const LLUUID& id); + void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id); // This is a method which collects the descendants of the id // provided. If the category is not found, no action is @@ -269,7 +271,7 @@ public: // that the next notify will include that notification. void addChangedMask(U32 mask, const LLUUID& referent); - const std::set<LLUUID>& getChangedIDs() { return mChangedItemIDs; } + const changed_items_t& getChangedIDs() const { return mChangedItemIDs; } // This method to prepares a set of mock inventory which provides // minimal functionality before the actual arrival of inventory. @@ -451,7 +453,6 @@ protected: private: // Variables used to track what has changed since the last notify. U32 mModifyMask; - typedef std::set<LLUUID> changed_items_t; changed_items_t mChangedItemIDs; std::map<LLUUID, bool> mCategoryLock; diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 4ee6c48cb1..99e6dbe3c8 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -56,11 +56,12 @@ public: { NONE = 0, LABEL = 1, // name changed - INTERNAL = 2, // internal change, eg, asset uuid different + INTERNAL = 2, // internal change (e.g. asset uuid different) ADD = 4, // something added REMOVE = 8, // something deleted - STRUCTURE = 16, // structural change, eg, item or folder moved - CALLING_CARD = 32, // online, grant status, cancel, etc change + STRUCTURE = 16, // structural change (eg item or folder moved) + CALLING_CARD = 32, // (eg online, grant status, cancel) + REBUILD = 64, // item UI changed (eg item type different) ALL = 0xffffffff }; LLInventoryObserver(); diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 0c893dddd6..baa659df7c 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -31,20 +31,22 @@ */ #include "llviewerprecompiledheaders.h" +#include "llinventorypanel.h" #include <utility> // for std::pair<> -#include "llinventorypanel.h" - #include "llagent.h" #include "llagentwearables.h" #include "llappearancemgr.h" +#include "llfloaterinventory.h" #include "llfloaterreg.h" +#include "llimfloater.h" #include "llimview.h" #include "llinventorybridge.h" +#include "llsidepanelinventory.h" +#include "llsidetray.h" #include "llscrollcontainer.h" #include "llviewerfoldertype.h" -#include "llimfloater.h" #include "llvoavatarself.h" static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel"); @@ -65,7 +67,10 @@ class LLInventoryPanelObserver : public LLInventoryObserver public: LLInventoryPanelObserver(LLInventoryPanel* ip) : mIP(ip) {} virtual ~LLInventoryPanelObserver() {} - virtual void changed(U32 mask); + virtual void changed(U32 mask) + { + mIP->modelChanged(mask); + } protected: LLInventoryPanel* mIP; }; @@ -109,7 +114,7 @@ BOOL LLInventoryPanel::postBuild() mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves - // create root folder + // Create root folder { LLRect folder_rect(0, 0, @@ -128,7 +133,7 @@ BOOL LLInventoryPanel::postBuild() mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); - // scroller + // Scroller { LLRect scroller_view_rect = getRect(); scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); @@ -139,23 +144,21 @@ BOOL LLInventoryPanel::postBuild() p.reserve_scroll_corner(true); p.tab_stop(true); mScroller = LLUICtrlFactory::create<LLScrollContainer>(p); + addChild(mScroller); + mScroller->addChild(mFolders); + mFolders->setScrollContainer(mScroller); } - addChild(mScroller); - mScroller->addChild(mFolders); - - mFolders->setScrollContainer(mScroller); - // set up the callbacks from the inventory we're viewing, and then - // build everything. + // Set up the callbacks from the inventory we're viewing, and then build everything. mInventoryObserver = new LLInventoryPanelObserver(this); mInventory->addObserver(mInventoryObserver); - // build view of inventory if we need default full hierarchy and inventory ready, otherwise wait for modelChanged() callback + // Build view of inventory if we need default full hierarchy and inventory ready, + // otherwise wait for idle callback. if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized) { initializeViews(); } - gIdleCallbacks.addFunction(onIdle, (void*)this); if (mSortOrderSetting != INHERIT_SORT_ORDER) @@ -173,7 +176,6 @@ BOOL LLInventoryPanel::postBuild() LLInventoryPanel::~LLInventoryPanel() { - // should this be a global setting? if (mFolders) { U32 sort_order = mFolders->getSortOrder(); @@ -189,17 +191,19 @@ LLInventoryPanel::~LLInventoryPanel() mScroller = NULL; } -LLMemType mt(LLMemType::MTYPE_INVENTORY_FROM_XML); // ! BUG ! Should this be removed? void LLInventoryPanel::draw() { - // select the desired item (in case it wasn't loaded when the selection was requested) + // Select the desired item (in case it wasn't loaded when the selection was requested) mFolders->updateSelection(); LLPanel::draw(); } LLInventoryFilter* LLInventoryPanel::getFilter() { - if (mFolders) return mFolders->getFilter(); + if (mFolders) + { + return mFolders->getFilter(); + } return NULL; } @@ -249,133 +253,152 @@ LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState() return mFolders->getFilter()->getShowFolderState(); } -static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); - void LLInventoryPanel::modelChanged(U32 mask) { + static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh"); LLFastTimer t2(FTM_REFRESH); bool handled = false; - if (!mViewsInitialized) - { - return; - } + if (!mViewsInitialized) return; - if (mask & LLInventoryObserver::LABEL) - { - handled = true; - // label change - empty out the display name for each object - // in this change set. - const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); - std::set<LLUUID>::const_iterator id_it = changed_items.begin(); - std::set<LLUUID>::const_iterator id_end = changed_items.end(); - LLFolderViewItem* view = NULL; - LLInvFVBridge* bridge = NULL; - for (;id_it != id_end; ++id_it) + const LLInventoryModel* model = getModel(); + if (!model) return; + + const LLInventoryModel::changed_items_t& changed_items = model->getChangedIDs(); + if (changed_items.empty()) return; + + for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin(); + items_iter != changed_items.end(); + ++items_iter) + { + const LLUUID& item_id = (*items_iter); + const LLInventoryObject* model_item = model->getObject(item_id); + LLFolderViewItem* view_item = mFolders->getItemByID(item_id); + + ////////////////////////////// + // LABEL Operation + // Empty out the display name for relabel. + if (mask & LLInventoryObserver::LABEL) { - view = mFolders->getItemByID(*id_it); - if(view) + handled = true; + if (view_item) { - // request refresh on this item (also flags for filtering) - bridge = (LLInvFVBridge*)view->getListener(); + // Request refresh on this item (also flags for filtering) + LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener(); if(bridge) { // Clear the display name first, so it gets properly re-built during refresh() bridge->clearDisplayName(); } - view->refresh(); + view_item->refresh(); } } - } - // We don't really care which of these masks the item is actually flagged with, since the masks - // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into - // Landmarks; this is a STRUCTURE change for that panel but is an ADD change for the Landmarks - // panel). What's relevant is that the item and UI are probably out of sync and thus need to be - // resynchronized. - if (mask & (LLInventoryObserver::STRUCTURE | - LLInventoryObserver::ADD | - LLInventoryObserver::REMOVE)) - { - handled = true; - // Record which folders are open by uuid. - LLInventoryModel* model = getModel(); - if (model) + ////////////////////////////// + // REBUILD Operation + // Destroy and regenerate the UI. + if (mask & LLInventoryObserver::REBUILD) { - const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + handled = true; + if (model_item && view_item) + { + view_item->destroyView(); + } + buildNewViews(item_id); + } - std::set<LLUUID>::const_iterator id_it = changed_items.begin(); - std::set<LLUUID>::const_iterator id_end = changed_items.end(); - for (;id_it != id_end; ++id_it) + ////////////////////////////// + // INTERNAL Operation + // This could be anything. For now, just refresh the item. + if (mask & LLInventoryObserver::INTERNAL) + { + if (view_item) { - // sync view with model - LLInventoryObject* model_item = model->getObject(*id_it); - LLFolderViewItem* view_item = mFolders->getItemByID(*id_it); + view_item->refresh(); + } + } + + // We don't typically care which of these masks the item is actually flagged with, since the masks + // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into + // Landmarks; this is a STRUCTURE change for that panel but is an ADD change for the Landmarks + // panel). What's relevant is that the item and UI are probably out of sync and thus need to be + // resynchronized. + if (mask & (LLInventoryObserver::STRUCTURE | + LLInventoryObserver::ADD | + LLInventoryObserver::REMOVE)) + { + handled = true; - // Item exists in memory but a UI element hasn't been created for it. - if (model_item && !view_item) + ////////////////////////////// + // ADD Operation + // Item exists in memory but a UI element hasn't been created for it. + if (model_item && !view_item) + { + // Add the UI element for this item. + buildNewViews(item_id); + // Select any newly created object that has the auto rename at top of folder root set. + if(mFolders->getRoot()->needsAutoRename()) { - // Add the UI element for this item. - buildNewViews(*id_it); - // Select any newly created object that has the auto rename at top of folder root set. - if(mFolders->getRoot()->needsAutoRename()) - { - setSelection(*id_it, FALSE); - } + setSelection(item_id, FALSE); } + } - // This item already exists in both memory and UI. It was probably moved - // around in the panel's directory structure (i.e. reparented). - if (model_item && view_item) + ////////////////////////////// + // STRUCTURE Operation + // This item already exists in both memory and UI. It was probably reparented. + if (model_item && view_item) + { + // Don't process the item if it's hanging from the root, since its + // model_item's parent will be NULL. + if (view_item->getRoot() != view_item->getParent()) { - // Don't process the item if it's hanging from the root, since its - // model_item's parent will be NULL. - if (view_item->getRoot() != view_item->getParent()) + LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); + // Item has been moved. + if (view_item->getParentFolder() != new_parent) { - LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolders->getItemByID(model_item->getParentUUID()); - // Item has been moved. - if (view_item->getParentFolder() != new_parent) + if (new_parent != NULL) + { + // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI. + view_item->getParentFolder()->extractItem(view_item); + view_item->addToFolder(new_parent, mFolders); + } + else { - if (new_parent != NULL) - { - // Item is to be moved and we found its new parent in the panel's directory, so move the item's UI. - view_item->getParentFolder()->extractItem(view_item); - view_item->addToFolder(new_parent, mFolders); - } - else - { - // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that - // doesn't include trash). Just remove the item's UI. - view_item->destroyView(); - } + // Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that + // doesn't include trash). Just remove the item's UI. + view_item->destroyView(); } } } - - // This item has been removed from memory, but its associated UI element still exists. - if (!model_item && view_item) - { - // Remove the item's UI. - view_item->destroyView(); - } + } + + ////////////////////////////// + // REMOVE Operation + // This item has been removed from memory, but its associated UI element still exists. + if (!model_item && view_item) + { + // Remove the item's UI. + view_item->destroyView(); } } } + /* I don't think we need this code, but not positive -- Seraph if (!handled) { - // it's a small change that only requires a refresh. + // It's a small change that only requires a refresh. // *TODO: figure out a more efficient way to do the refresh // since it is expensive on large inventories mFolders->refresh(); } + */ } // static void LLInventoryPanel::onIdle(void *userdata) { LLInventoryPanel *self = (LLInventoryPanel*)userdata; - // inventory just initialized, do complete build + // Inventory just initialized, do complete build if (!self->mViewsInitialized && gInventory.isInventoryUsable()) { self->initializeViews(); @@ -388,8 +411,7 @@ void LLInventoryPanel::onIdle(void *userdata) void LLInventoryPanel::initializeViews() { - if (!gInventory.isInventoryUsable()) - return; + if (!gInventory.isInventoryUsable()) return; // Determine the root folder in case specified, and // build the views starting with that folder. @@ -412,7 +434,7 @@ void LLInventoryPanel::initializeViews() void LLInventoryPanel::rebuildViewsFor(const LLUUID& id) { - // Destroy the old view for this ID so we can rebuild it + // Destroy the old view for this ID so we can rebuild it. LLFolderViewItem* old_view = mFolders->getItemByID(id); if (old_view && id.notNull()) { @@ -437,21 +459,21 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) } else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID))) { - // This item exists outside the inventory's hierarchy, - // so don't add it. + // This item exists outside the inventory's hierarchy, so don't add it. return; } if (objectp->getType() <= LLAssetType::AT_NONE || objectp->getType() >= LLAssetType::AT_COUNT) { - llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " << - ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() << llendl; + llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : " + << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() + << llendl; return; } - if (objectp->getType() == LLAssetType::AT_CATEGORY && - objectp->getActualType() != LLAssetType::AT_LINK_FOLDER) + if ((objectp->getType() == LLAssetType::AT_CATEGORY) && + (objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) { LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(), objectp->getType(), @@ -471,9 +493,8 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) folderp->setItemSortOrder(mFolders->getSortOrder()); itemp = folderp; - // Hide the root folder, so we can show the contents of a folder - // flat but still have the parent folder present for listener-related - // operations. + // Hide the root folder, so we can show the contents of a folder flat + // but still have the parent folder present for listener-related operations. if (id == mStartFolderID) { folderp->setDontShowInHierarchy(TRUE); @@ -482,7 +503,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) } else { - // Build new view for item + // Build new view for item. LLInventoryItem* item = (LLInventoryItem*)objectp; LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(), item->getActualType(), @@ -518,23 +539,26 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) { LLViewerInventoryCategory::cat_array_t* categories; LLViewerInventoryItem::item_array_t* items; - mInventory->lockDirectDescendentArrays(id, categories, items); + if(categories) { - S32 count = categories->count(); - for(S32 i = 0; i < count; ++i) + for (LLViewerInventoryCategory::cat_array_t::const_iterator cat_iter = categories->begin(); + cat_iter != categories->end(); + ++cat_iter) { - LLInventoryCategory* cat = categories->get(i); + const LLViewerInventoryCategory* cat = (*cat_iter); buildNewViews(cat->getUUID()); } } + if(items) { - S32 count = items->count(); - for(S32 i = 0; i < count; ++i) + for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin(); + item_iter != items->end(); + ++item_iter) { - LLInventoryItem* item = items->get(i); + const LLViewerInventoryItem* item = (*item_iter); buildNewViews(item->getUUID()); } } @@ -562,39 +586,6 @@ void LLInventoryPanel::defaultOpenInventory() } } -struct LLConfirmPurgeData -{ - LLUUID mID; - LLInventoryModel* mModel; -}; - -class LLIsNotWorn : public LLInventoryCollectFunctor -{ -public: - LLIsNotWorn() {} - virtual ~LLIsNotWorn() {} - virtual bool operator()(LLInventoryCategory* cat, - LLInventoryItem* item) - { - return !gAgentWearables.isWearingItem(item->getUUID()); - } -}; - -class LLOpenFolderByID : public LLFolderViewFunctor -{ -public: - LLOpenFolderByID(const LLUUID& id) : mID(id) {} - virtual ~LLOpenFolderByID() {} - virtual void doFolder(LLFolderViewFolder* folder) - { - if (folder->getListener() && folder->getListener()->getUUID() == mID) folder->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); - } - virtual void doItem(LLFolderViewItem* item) {} -protected: - const LLUUID& mID; -}; - - void LLInventoryPanel::openSelected() { LLFolderViewItem* folder_item = mFolders->getCurSelectedItem(); @@ -659,7 +650,6 @@ void LLInventoryPanel::onFocusReceived() LLPanel::onFocusReceived(); } - void LLInventoryPanel::openAllFolders() { mFolders->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN); @@ -696,8 +686,6 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it // Seraph - Put determineFolderType in here for ensemble typing? } -//---------------------------------------------------------------------------- - void LLInventoryPanel::doToSelected(const LLSD& userdata) { mFolders->doToSelected(&gInventory, userdata); @@ -855,55 +843,56 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata) return true; } +BOOL LLInventoryPanel::getSinceLogoff() +{ + return mFolders->getFilter()->isSinceLogoff(); +} -//---------------------------------------------------------------------------- - -// static DEBUG ONLY: +// DEBUG ONLY +// static void LLInventoryPanel::dumpSelectionInformation(void* user_data) { LLInventoryPanel* iv = (LLInventoryPanel*)user_data; iv->mFolders->dumpSelectionInformation(); } -BOOL LLInventoryPanel::getSinceLogoff() -{ - return mFolders->getFilter()->isSinceLogoff(); -} - -void example_param_block_usage() +// static +LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel() { - LLInventoryPanel::Params param_block; - param_block.name(std::string("inventory")); - - param_block.sort_order_setting(LLInventoryPanel::RECENTITEMS_SORT_ORDER); - param_block.allow_multi_select(true); - param_block.filter(LLInventoryPanel::Filter() - .sort_order(1) - .types(0xffff0000)); - param_block.inventory(&gInventory); - param_block.has_border(true); + LLInventoryPanel* res = NULL; - LLUICtrlFactory::create<LLInventoryPanel>(param_block); - - param_block = LLInventoryPanel::Params(); - param_block.name(std::string("inventory")); - - //LLSD param_block_sd; - //param_block_sd["sort_order_setting"] = LLInventoryPanel::RECENTITEMS_SORT_ORDER; - //param_block_sd["allow_multi_select"] = true; - //param_block_sd["filter"]["sort_order"] = 1; - //param_block_sd["filter"]["types"] = (S32)0xffff0000; - //param_block_sd["has_border"] = true; - - //LLInitParam::LLSDParser(param_block_sd).parse(param_block); + // Iterate through the inventory floaters and return whichever is on top. + LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory"); + S32 z_min = S32_MAX; + for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter) + { + LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter); + if (iv && iv->getVisible()) + { + S32 z_order = gFloaterView->getZOrder(iv); + if (z_order < z_min) + { + res = iv->getPanel(); + z_min = z_order; + } + } + } - LLUICtrlFactory::create<LLInventoryPanel>(param_block); -} + // Otherwise, open the inventorySP and use that. + if (!res) + { + LLSD key; + LLSidepanelInventory *sidepanel_inventory = + dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->showPanel("sidepanel_inventory", key)); + if (sidepanel_inventory) + { + res = sidepanel_inventory->getActivePanel(); + if (res) + { + return res; + } + } + } -// +=================================================+ -// | LLInventoryPanelObserver | -// +=================================================+ -void LLInventoryPanelObserver::changed(U32 mask) -{ - mIP->modelChanged(mask); + return res; } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index fd83729630..d65fe53812 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -162,11 +162,9 @@ public: static void onIdle(void* user_data); -private: + // Find whichever inventory panel is active / on top. + static LLInventoryPanel *getActiveInventoryPanel(); - // Given the id and the parent, build all of the folder views. - void rebuildViewsFor(const LLUUID& id); - virtual void buildNewViews(const LLUUID& id); // made virtual to support derived classes. EXT-719 protected: void defaultOpenInventory(); // open the first level of inventory @@ -193,12 +191,14 @@ protected: public: BOOL getIsViewsInitialized() const { return mViewsInitialized; } const LLUUID& getStartFolderID() const { return mStartFolderID; } -private: +protected: // Builds the UI. Call this once the inventory is usable. void initializeViews(); + void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views. + virtual void buildNewViews(const LLUUID& id); +private: BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild() BOOL mViewsInitialized; // Views have been generated - // UUID of category from which hierarchy should be built. Set with the // "start_folder" xml property. Default is LLUUID::null that means total Inventory hierarchy. std::string mStartFolderString; diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 824def3d92..9ab459080e 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -277,3 +277,16 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem() LLInventoryItem *item = gInventory.getItem(item_id); return item; } + +LLInventoryPanel *LLSidepanelInventory::getActivePanel() +{ + if (!getVisible()) + { + return NULL; + } + if (mInventoryPanel->getVisible()) + { + return mPanelMainInventory->getActivePanel(); + } + return NULL; +} diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 6aa9cc745f..c2ce3badb8 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -36,6 +36,7 @@ class LLFolderViewItem; class LLInventoryItem; +class LLInventoryPanel; class LLPanelMainInventory; class LLSidepanelItemInfo; class LLSidepanelTaskInfo; @@ -49,6 +50,8 @@ public: /*virtual*/ BOOL postBuild(); /*virtual*/ void onOpen(const LLSD& key); + LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any. + protected: // Tracks highlighted (selected) item in inventory panel. LLInventoryItem *getSelectedItem(); diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 268a18d2a2..bf6d715c31 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -56,6 +56,7 @@ #include "llfloaterchatterbox.h" #include "llfloaterfriends.h" #include "llfloatersnapshot.h" +#include "llinventorypanel.h" #include "lltoolmgr.h" #include "llui.h" #include "llviewermenu.h" @@ -157,12 +158,11 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, LLButton* inventory_btn = getChild<LLButton>("inventory_btn"); if (!inventory_btn) return FALSE; - LLFloaterInventory* active_inventory = LLFloaterInventory::getActiveInventory(); - LLRect button_screen_rect; inventory_btn->localRectToScreen(inventory_btn->getRect(),&button_screen_rect); - - if(active_inventory && active_inventory->getVisible()) + + const LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if(active_panel) { mInventoryAutoOpen = FALSE; } @@ -170,8 +170,8 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, { if (mInventoryAutoOpen) { - if (!(active_inventory && active_inventory->getVisible()) && - mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) + if (!active_panel && + mInventoryAutoOpenTimer.getElapsedTimeF32() > sInventoryAutoOpenTime) { LLFloaterInventory::showAgentInventory(); } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index f9e1a94def..5bdcbc79bd 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -912,8 +912,20 @@ void link_inventory_item( } LLUUID transaction_id; - std::string desc = "Link"; + std::string desc = "Broken link"; // This should only show if the object can't find its baseobj. LLInventoryType::EType inv_type = LLInventoryType::IT_NONE; + if (dynamic_cast<const LLInventoryCategory *>(baseobj)) + { + inv_type = LLInventoryType::IT_CATEGORY; + } + else + { + const LLViewerInventoryItem *baseitem = dynamic_cast<const LLViewerInventoryItem *>(baseobj); + if (baseitem) + { + inv_type = baseitem->getInventoryType(); + } + } LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_LinkInventoryItem); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 8fd646ee93..f757155b94 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -538,8 +538,9 @@ void start_chat( EKeystate s ) void start_gesture( EKeystate s ) { + LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (KEYSTATE_UP == s && - !(gFocusMgr.getKeyboardFocus() && dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus())->acceptsTextInput())) + ! (focus_ctrlp && focus_ctrlp->acceptsTextInput())) { if (LLNearbyChatBar::getInstance()->getCurrentChat().empty()) { diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index d5fd23ac51..858aab300b 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -45,6 +45,9 @@ #include "llviewertexturelist.h" #include "llvovolume.h" #include "llpluginclassmedia.h" +#include "llviewerwindow.h" +#include "llfocusmgr.h" +#include "llcallbacklist.h" #include "llevent.h" // LLSimpleListener #include "llnotificationsutil.h" @@ -55,7 +58,7 @@ #include <boost/bind.hpp> // for SkinFolder listener #include <boost/signals2.hpp> -/*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "AutoPlayMedia"; +/*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable"; // Move this to its own file. @@ -327,6 +330,8 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s media_impl->mMediaLoop = media_entry->getAutoLoop(); media_impl->mMediaWidth = media_entry->getWidthPixels(); media_impl->mMediaHeight = media_entry->getHeightPixels(); + media_impl->mMediaAutoPlay = media_entry->getAutoPlay(); + media_impl->mMediaEntryURL = media_entry->getCurrentURL(); if (media_impl->mMediaSource) { media_impl->mMediaSource->setAutoScale(media_impl->mMediaAutoScale); @@ -334,8 +339,8 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels()); } - bool url_changed = (media_entry->getCurrentURL() != previous_url); - if(media_entry->getCurrentURL().empty()) + bool url_changed = (media_impl->mMediaEntryURL != previous_url); + if(media_impl->mMediaEntryURL.empty()) { if(url_changed) { @@ -350,7 +355,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s // The current media URL is not empty. // If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent, // do a navigate. - bool auto_play = (media_entry->getAutoPlay() && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)); + bool auto_play = (media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)); if((was_loaded || auto_play) && !update_from_self) { @@ -372,8 +377,10 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s media_entry->getAutoLoop()); media_impl->setHomeURL(media_entry->getHomeURL()); + media_impl->mMediaAutoPlay = media_entry->getAutoPlay(); + media_impl->mMediaEntryURL = media_entry->getCurrentURL(); - if(media_entry->getAutoPlay() && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)) + if(media_impl->mMediaAutoPlay && gSavedSettings.getBOOL(AUTO_PLAY_MEDIA_SETTING)) { needs_navigate = true; } @@ -381,21 +388,20 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s if(media_impl) { - std::string url = media_entry->getCurrentURL(); if(needs_navigate) { - media_impl->navigateTo(url, "", true, true); - lldebugs << "navigating to URL " << url << llendl; + media_impl->navigateTo(media_impl->mMediaEntryURL, "", true, true); + lldebugs << "navigating to URL " << media_impl->mMediaEntryURL << llendl; } - else if(!media_impl->mMediaURL.empty() && (media_impl->mMediaURL != url)) + else if(!media_impl->mMediaURL.empty() && (media_impl->mMediaURL != media_impl->mMediaEntryURL)) { // If we already have a non-empty media URL set and we aren't doing a navigate, update the media URL to match the media entry. - media_impl->mMediaURL = url; + media_impl->mMediaURL = media_impl->mMediaEntryURL; // If this causes a navigate at some point (such as after a reload), it should be considered server-driven so it isn't broadcast. media_impl->mNavigateServerRequest = true; - lldebugs << "updating URL in the media impl to " << url << llendl; + lldebugs << "updating URL in the media impl to " << media_impl->mMediaEntryURL << llendl; } } @@ -625,7 +631,7 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi ////////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMedia::updateMedia() +void LLViewerMedia::updateMedia(void *dummy_arg) { impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); @@ -747,6 +753,19 @@ void LLViewerMedia::updateMedia() impl_count_total++; } + // Overrides if the window is minimized or we lost focus (taking care + // not to accidentally "raise" the priority either) + if (!gViewerWindow->getActive() /* viewer window minimized? */ + && new_priority > LLPluginClassMedia::PRIORITY_HIDDEN) + { + new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; + } + else if (!gFocusMgr.getAppHasFocus() /* viewer window lost focus? */ + && new_priority > LLPluginClassMedia::PRIORITY_LOW) + { + new_priority = LLPluginClassMedia::PRIORITY_LOW; + } + pimpl->setPriority(new_priority); if(pimpl->getUsedInUI()) @@ -785,9 +804,16 @@ void LLViewerMedia::updateMedia() ////////////////////////////////////////////////////////////////////////////////////////// // static +void LLViewerMedia::initClass() +{ + gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static void LLViewerMedia::cleanupClass() { - // This is no longer necessary, since sViewerMediaImplList is no longer smart pointers. + gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -830,6 +856,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, mProximity(-1), mProximityDistance(0.0f), mMimeTypeProbe(NULL), + mMediaAutoPlay(false), mIsUpdated(false) { @@ -1911,6 +1938,33 @@ void LLViewerMediaImpl::resetPreviousMediaState() mPreviousMediaTime = 0.0f; } + +////////////////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaImpl::setDisabled(bool disabled) +{ + if(mIsDisabled != disabled) + { + // Only do this on actual state transitions. + mIsDisabled = disabled; + + if(mIsDisabled) + { + // We just disabled this media. Clear all state. + unload(); + } + else + { + // We just (re)enabled this media. Do a navigate if auto-play is in order. + if(mMediaAutoPlay && gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)) + { + navigateTo(mMediaEntryURL, "", true, true); + } + } + + } +}; + ////////////////////////////////////////////////////////////////////////////////////////// // bool LLViewerMediaImpl::isForcedUnloaded() const diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index e2d159304f..713eb2710b 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -96,9 +96,10 @@ class LLViewerMedia static bool textureHasMedia(const LLUUID& texture_id); static void setVolume(F32 volume); - static void updateMedia(); + static void updateMedia(void* dummy_arg = NULL); static bool isMusicPlaying(); + static void initClass(); static void cleanupClass(); static void toggleMusicPlay(void*); @@ -201,7 +202,7 @@ public: bool isMediaFailed() const { return mMediaSourceFailed; }; void resetPreviousMediaState(); - void setDisabled(bool disabled) { mIsDisabled = disabled; }; + void setDisabled(bool disabled); bool isMediaDisabled() const { return mIsDisabled; }; // returns true if this instance should not be loaded (disabled, muted object, crashed, etc.) @@ -345,6 +346,8 @@ public: S32 mProximity; F64 mProximityDistance; LLMimeDiscoveryResponder *mMimeTypeProbe; + bool mMediaAutoPlay; + std::string mMediaEntryURL; private: BOOL mIsUpdated ; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 0b40492391..e68594ed6f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -31,188 +31,75 @@ */ #include "llviewerprecompiledheaders.h" - #include "llviewermenu.h" -// system library includes -#include <iostream> -#include <fstream> -#include <sstream> - // linden library includes -#include "llaudioengine.h" #include "llfloaterreg.h" -#include "indra_constants.h" -#include "llassetstorage.h" -#include "llchat.h" #include "llcombobox.h" -#include "llfeaturemanager.h" -#include "llfocusmgr.h" -#include "llfontgl.h" -#include "llinstantmessage.h" #include "llinventorypanel.h" #include "llnotifications.h" #include "llnotificationsutil.h" -#include "llpermissionsflags.h" -#include "llrect.h" -#include "llsecondlifeurls.h" -#include "lltransactiontypes.h" -#include "llui.h" -#include "llview.h" -#include "llxfermanager.h" -#include "message.h" -#include "raytrace.h" -#include "llsdserialize.h" -#include "lltimer.h" -#include "llvfile.h" -#include "llvolumemgr.h" // newview includes #include "llagent.h" #include "llagentwearables.h" #include "llagentpilot.h" -#include "llbox.h" -#include "llcallingcard.h" -#include "llclipboard.h" #include "llcompilequeue.h" -#include "llconsole.h" -#include "llviewercontrol.h" #include "lldebugview.h" -#include "lldir.h" -#include "lldrawable.h" -#include "lldrawpoolalpha.h" -#include "lldrawpooltree.h" -#include "llface.h" #include "llfilepicker.h" #include "llfirstuse.h" -#include "llfloater.h" -#include "llfloaterabout.h" -#include "llfloaterbuycurrency.h" -#include "llfloateractivespeakers.h" -#include "llfloateranimpreview.h" -#include "llfloateravatartextures.h" -#include "llfloaterbuildoptions.h" -#include "llfloaterbump.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" #include "llfloaterbuycurrency.h" -#include "llfloaterbuyland.h" #include "llfloaterchat.h" #include "llfloatercustomize.h" -#include "llfloaterdaycycle.h" #include "llfloaterchatterbox.h" -#include "llfloaterfonttest.h" #include "llfloatergodtools.h" -#include "llfloatergroupinvite.h" -#include "llfloatergroups.h" -#include "llfloaterhud.h" -#include "llfloaterinspect.h" -#include "llfloaterlagmeter.h" #include "llfloaterland.h" -#include "llfloaterlandholdings.h" -#include "llfloatermap.h" -#include "llfloateropenobject.h" #include "llfloaterpay.h" -#include "llfloaterperms.h" -#include "llfloaterpostprocess.h" -#include "llfloaterpreference.h" -#include "llfloaterreg.h" -#include "llfloaterregioninfo.h" #include "llfloaterreporter.h" #include "llfloaterscriptdebug.h" -#include "llfloatersettingsdebug.h" -#include "llfloaterenvsettings.h" #include "llfloatertools.h" -#include "llfloaterwater.h" -#include "llfloaterwindlight.h" #include "llfloaterworldmap.h" -#include "llfloatermemleak.h" -#include "llfasttimerview.h" #include "llavataractions.h" #include "lllandmarkactions.h" -#include "llmemoryview.h" #include "llgroupmgr.h" #include "lltooltip.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llimage.h" -#include "llimagebmp.h" -#include "llimagej2c.h" -#include "llimagetga.h" #include "llinventorybridge.h" -#include "llinventorymodel.h" -#include "llfloaterinventory.h" -#include "llkeyboard.h" #include "llpanellogin.h" #include "llpanelblockedlist.h" #include "llmenucommands.h" -#include "llmenugl.h" -#include "llmimetypes.h" #include "llmoveview.h" -#include "llmutelist.h" -#include "llnotify.h" -#include "llpanelobject.h" #include "llparcel.h" -#include "llprimitive.h" -#include "llresmgr.h" #include "llrootview.h" #include "llselectmgr.h" #include "llsidetray.h" -#include "llsky.h" #include "llstatusbar.h" -#include "llstatview.h" -#include "llstring.h" -#include "llsurfacepatch.h" -#include "llimview.h" #include "lltextureview.h" -#include "lltool.h" #include "lltoolbar.h" #include "lltoolcomp.h" -#include "lltoolfocus.h" -#include "lltoolgrab.h" #include "lltoolmgr.h" #include "lltoolpie.h" #include "lltoolselectland.h" -#include "lltrans.h" -#include "lluictrlfactory.h" -#include "lluploaddialog.h" -#include "lluserauth.h" -#include "lluuid.h" -#include "llviewercamera.h" #include "llviewergenericmessage.h" #include "llviewerhelp.h" -#include "llviewertexturelist.h" // gTextureList -#include "llviewerinventory.h" #include "llviewermenufile.h" // init_menu_file() #include "llviewermessage.h" #include "llviewernetwork.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" -#include "llviewerparceloverlay.h" -#include "llviewerregion.h" #include "llviewerstats.h" -#include "llviewerwindow.h" -#include "llvoavatar.h" #include "llvoavatarself.h" -#include "llvolume.h" -#include "llweb.h" -#include "llworld.h" #include "llworldmap.h" -#include "object_flags.h" #include "pipeline.h" -#include "llappviewer.h" -#include "roles_constants.h" #include "llviewerjoystick.h" #include "llwlanimator.h" #include "llwlparammanager.h" -#include "llwaterparammanager.h" -#include "llfloaternotificationsconsole.h" #include "llfloatercamera.h" #include "lluilistener.h" - -#include "lltexlayer.h" #include "llappearancemgr.h" -#include "llimfloater.h" using namespace LLVOAvatarDefines; @@ -6963,16 +6850,15 @@ void handle_grab_texture(void* data) gInventory.updateItem(item); gInventory.notifyObservers(); - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); - // Show the preview panel for textures to let // user know that the image is now in inventory. - if(view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if(active_panel) { LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); - view->getPanel()->openSelected(); + active_panel->setSelection(item_id, TAKE_FOCUS_NO); + active_panel->openSelected(); //LLFloaterInventory::dumpSelectionInformation((void*)view); // restore keyboard focus gFocusMgr.setKeyboardFocus(focus_ctrl); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 23d02af73d..2ae8aca6ad 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -31,70 +31,31 @@ */ #include "llviewerprecompiledheaders.h" - #include "llviewermessage.h" -#include <deque> - #include "llaudioengine.h" -#include "indra_constants.h" #include "lscript_byteformat.h" -#include "mean_collision_data.h" -#include "llfloaterbump.h" -#include "llassetstorage.h" -#include "llcachename.h" - -#include "lldbstrings.h" #include "lleconomy.h" -#include "llfilepicker.h" #include "llfloaterreg.h" -#include "llfocusmgr.h" #include "llfollowcamparams.h" -#include "llinstantmessage.h" -#include "llquantize.h" -#include "llregionflags.h" -#include "llregionhandle.h" #include "llsdserialize.h" -#include "llstring.h" -#include "llteleportflags.h" -#include "lltracker.h" #include "lltransactionflags.h" -#include "llxfermanager.h" -#include "message.h" -#include "sound_ids.h" -#include "lltimer.h" -#include "llmd5.h" #include "llagent.h" #include "llcallingcard.h" -#include "llconsole.h" -#include "llvieweraudio.h" -#include "llviewercontrol.h" -#include "lldrawpool.h" #include "llfirstuse.h" -#include "llfloateranimpreview.h" #include "llfloaterbuycurrency.h" #include "llfloaterbuyland.h" #include "llfloaterchat.h" -#include "llfloaterimagepreview.h" #include "llfloaterland.h" #include "llfloaterregioninfo.h" #include "llfloaterlandholdings.h" -#include "llurldispatcher.h" #include "llfloaterpostcard.h" #include "llfloaterpreference.h" -#include "llfollowcam.h" -#include "llgroupnotify.h" -#include "llhudeffect.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" -#include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" -#include "llfloaterinventory.h" -#include "llmenugl.h" -#include "llmoveview.h" -#include "llmutelist.h" #include "llnearbychat.h" #include "llnotifications.h" #include "llnotificationsutil.h" @@ -111,22 +72,11 @@ #include "llstatenums.h" #include "llstatusbar.h" #include "llimview.h" -#include "lltool.h" -#include "lltoolbar.h" -#include "lltoolmgr.h" #include "lltrans.h" -#include "llui.h" // for make_ui_sound -#include "lluploaddialog.h" -#include "llviewercamera.h" -#include "llviewerchat.h" #include "llviewergenericmessage.h" -#include "llviewerinventory.h" #include "llviewermenu.h" -#include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" -#include "llviewerpartsource.h" -#include "llviewerregion.h" #include "llviewerstats.h" #include "llviewertexteditor.h" #include "llviewerthrottle.h" @@ -134,10 +84,8 @@ #include "llvlmanager.h" #include "llvoavatarself.h" #include "llvotextbubble.h" -#include "llweb.h" #include "llworld.h" #include "pipeline.h" -#include "llappviewer.h" #include "llfloaterworldmap.h" #include "llviewerdisplay.h" #include "llkeythrottle.h" @@ -146,15 +94,13 @@ #include "llpanelblockedlist.h" #include "llpanelplaceprofile.h" -#include <boost/tokenizer.hpp> -#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/split.hpp> // #if LL_WINDOWS // For Windows specific error handler #include "llwindebug.h" // For the invalid message handler #endif -//#include "llnearbychathistory.h" -#include "llnotificationmanager.h" +#include "llnotificationmanager.h" // // // Constants @@ -933,56 +879,46 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f //highlight item, if it's not in the trash or lost+found // Don't auto-open the inventory floater - LLFloaterInventory* view = NULL; if(gSavedSettings.getBOOL("ShowInInventory") && asset_type != LLAssetType::AT_CALLINGCARD && item->getInventoryType() != LLInventoryType::IT_ATTACHMENT && !from_name.empty()) { - view = LLFloaterInventory::showAgentInventory(); //TODO:this should be moved to the end of method after all the checks, //but first decide what to do with active inventory if any (EK) LLSD key; key["select"] = item->getUUID(); LLSideTray::getInstance()->showPanel("sidepanel_inventory", key); } - else - { - view = LLFloaterInventory::getActiveInventory(); - } - if(!view) + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if(active_panel) { - return; - } - - //Trash Check - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) - { - return; - } - const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); - //BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view); - BOOL user_is_away = gAwayTimer.getStarted(); + //Trash Check + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + { + return; + } + const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + //BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view); + BOOL user_is_away = gAwayTimer.getStarted(); - // don't select lost and found items if the user is active - if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id) - && !user_is_away) - { - return; - } + // don't select lost and found items if the user is active + if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id) + && !user_is_away) + { + return; + } - //Not sure about this check. Could make it easy to miss incoming items. - //don't dick with highlight while the user is working - //if(inventory_has_focus && !user_is_away) - // break; - LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID() << LL_ENDL; - //highlight item + //Not sure about this check. Could make it easy to miss incoming items. + //don't dick with highlight while the user is working + //if(inventory_has_focus && !user_is_away) + // break; + LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID() << LL_ENDL; + //highlight item - if (view->getPanel()) - { LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus(); - view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); + active_panel->setSelection(item->getUUID(), TAKE_FOCUS_NO); gFocusMgr.setKeyboardFocus(focus_ctrl); } } @@ -5038,7 +4974,7 @@ void container_inventory_arrived(LLViewerObject* object, gAgent.changeCameraToDefault(); } - LLFloaterInventory* view = LLFloaterInventory::getActiveInventory(); + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); if (inventory->size() > 2) { @@ -5076,9 +5012,9 @@ void container_inventory_arrived(LLViewerObject* object, } } gInventory.notifyObservers(); - if(view) + if(active_panel) { - view->getPanel()->setSelection(cat_id, TAKE_FOCUS_NO); + active_panel->setSelection(cat_id, TAKE_FOCUS_NO); } } else if (inventory->size() == 2) @@ -5112,9 +5048,9 @@ void container_inventory_arrived(LLViewerObject* object, new_item->updateServer(TRUE); gInventory.updateItem(new_item); gInventory.notifyObservers(); - if(view) + if(active_panel) { - view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); + active_panel->setSelection(item_id, TAKE_FOCUS_NO); } } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index dbcf563010..5be7f2945f 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -614,10 +614,6 @@ void LLViewerTextureList::updateImages(F32 max_time) didone = image->doLoadedCallbacks(); } } - if (!gNoRender && !gGLManager.mIsDisabled) - { - LLViewerMedia::updateMedia(); - } updateImagesUpdateStats(); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 9ba056a17c..8529a93527 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1011,6 +1011,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) else { mActive = FALSE; + if (gSavedSettings.getBOOL("AllowIdleAFK")) { gAgent.setAFK(); @@ -3244,8 +3245,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_trans } else { - llwarns << "List of last picks is empty" << llendl; - llwarns << "Using stub pick" << llendl; + lldebugs << "List of last picks is empty: Using stub pick" << llendl; mLastPick = LLPickInfo(); } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 3cb0ec4bad..0405b9d28b 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -1094,6 +1094,16 @@ void LLWearable::setLabelUpdated() const gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID()); } +void LLWearable::refreshName() +{ + LLUUID item_id = getItemID(); + LLInventoryItem* item = gInventory.getItem(item_id); + if( item ) + { + mName = item->getName(); + } +} + struct LLWearableSaveData { EWearableType mType; diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 43ffa12420..82d388ab7e 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -133,6 +133,10 @@ public: // Something happened that requires the wearable's label to be updated (e.g. worn/unworn). void setLabelUpdated() const; + // the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem, + // not the wearable asset itself. + void refreshName(); + private: typedef std::map<S32, LLLocalTextureObject*> te_map_t; typedef std::map<S32, LLVisualParam *> visual_param_index_map_t; diff --git a/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png b/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png Binary files differnew file mode 100644 index 0000000000..73a708782c --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LinkFolder.png diff --git a/indra/newview/skins/default/textures/icons/Inv_LinkItem.png b/indra/newview/skins/default/textures/icons/Inv_LinkItem.png Binary files differnew file mode 100644 index 0000000000..73a708782c --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_LinkItem.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 607b33fbb1..3e0820544a 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -230,6 +230,8 @@ with the same filename but different name <texture name="Inv_Gesture" file_name="icons/Inv_Gesture.png" preload="false" /> <texture name="Inv_Gloves" file_name="icons/Inv_Gloves.png" preload="false" /> <texture name="Inv_Hair" file_name="icons/Inv_Hair.png" preload="false" /> + <texture name="Inv_LinkItem" file_name="icons/Inv_LinkItem.png" preload="false" /> + <texture name="Inv_LinkFolder" file_name="icons/Inv_LinkFolder.png" preload="false" /> <texture name="Inv_Jacket" file_name="icons/Inv_Jacket.png" preload="false" /> <texture name="Inv_LookFolderOpen" file_name="icons/Inv_LookFolderOpen.png" preload="false" /> <texture name="Inv_LookFolderClosed" file_name="icons/Inv_LookFolderClosed.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index d805209bf5..51997a2813 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -17,7 +17,7 @@ <accordion_tab layout="topleft" name="tab_outfits" - title="Outfits bar"> + title="Outfits"> <inventory_panel allow_multi_select="true" border="true" @@ -33,7 +33,7 @@ <accordion_tab layout="topleft" name="tab_cof" - title="Current Outfit bar"> + title="Current Outfit"> <inventory_panel allow_multi_select="true" border="true" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 23832ba120..29e9b476eb 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -78,7 +78,7 @@ top_pad="10" width="350" /> <check_box - control_name="AutoPlayMedia" + control_name="ParcelMediaAutoPlayEnable" height="16" label="Allow Media Autoplay" layout="topleft" @@ -86,15 +86,6 @@ name="autoplay_enabled" top_pad="10" width="350" /> - <check_box - control_name="ParcelMediaAutoPlayEnable" - height="16" - label="Automatically Play Parcel Media" - layout="topleft" - left="30" - name="parcel_autoplay_enabled" - top_pad="10" - width="350" /> <text type="string" length="1" |