diff options
Diffstat (limited to 'indra/newview')
48 files changed, 657 insertions, 236 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ce42cb6038..65502209f7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1150,10 +1150,12 @@ endif (LINUX) if (WINDOWS) list(APPEND viewer_SOURCE_FILES llappviewerwin32.cpp + llwindebug.cpp ) list(APPEND viewer_HEADER_FILES llappviewerwin32.h + llwindebug.h ) # precompiled header configuration @@ -1319,8 +1321,6 @@ set(viewer_APPSETTINGS_FILES ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ) -use_prebuilt_binary(artwork-common) - source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) set_source_files_properties(${viewer_APPSETTINGS_FILES} diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b493f38d76..d51498f6d1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11404,9 +11404,9 @@ <key>Persist</key> <integer>0</integer> <key>Type</key> - <string>Boolean</string> + <string>S32</string> <key>Value</key> - <integer>0</integer> + <integer>-1</integer> </map> <key>WaterEditPresets</key> <map> diff --git a/indra/newview/app_settings/static_data.db2 b/indra/newview/app_settings/static_data.db2 Binary files differnew file mode 100644 index 0000000000..f85aa81601 --- /dev/null +++ b/indra/newview/app_settings/static_data.db2 diff --git a/indra/newview/app_settings/static_index.db2 b/indra/newview/app_settings/static_index.db2 Binary files differnew file mode 100644 index 0000000000..a5440f96f2 --- /dev/null +++ b/indra/newview/app_settings/static_index.db2 diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index e8591ca086..1c763453dc 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -58,6 +58,8 @@ Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 RenderShaderLightingMaxLevel 1 3 SkyUseClassicClouds 1 1 +WatchdogDisabled 1 1 + // // Low Graphics Settings diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 779490c9f7..45de51f3cf 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -57,6 +57,7 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 SkyUseClassicClouds 1 1 +WatchdogDisabled 1 1 // // Low Graphics Settings diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 47033efc47..e89b0cc49d 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -59,6 +59,7 @@ RenderTextureMemoryMultiple 1 0.5 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 SkyUseClassicClouds 1 1 +WatchdogDisabled 1 1 // // Low Graphics Settings diff --git a/indra/newview/featuretable_solaris.txt b/indra/newview/featuretable_solaris.txt index 6edd280686..0ae463332c 100644 --- a/indra/newview/featuretable_solaris.txt +++ b/indra/newview/featuretable_solaris.txt @@ -37,6 +37,8 @@ VertexShaderEnable 1 1 RenderTextureMemoryMultiple 1 1.0 UseOcclusion 1 1 RenderCubeMap 1 1 +WatchdogDisabled 1 1 + // // Class 0 Hardware (Unknown or just old) diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index ec3c7452e5..c70bbb985f 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2310,6 +2310,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); } + gAgentAvatarp->invalidateAll(); gAgentAvatarp->updateMeshTextures(); } } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index e70511ce6e..efa5eca217 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -511,7 +511,11 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type, void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) { LLWearable* wearable = getWearable(type, index); - wearable->revertValues(); + llassert(wearable); + if (wearable) + { + wearable->revertValues(); + } gAgent.sendAgentSetAppearance(); } @@ -543,6 +547,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& { LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j); llassert(old_wearable); + if (!old_wearable) continue; std::string old_name = old_wearable->getName(); old_wearable->setName(new_name); @@ -1940,7 +1945,11 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake) for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) { LLWearable *wearable = getWearable((LLWearableType::EType)type,count); - wearable->animateParams(delta, upload_bake); + llassert(wearable); + if (wearable) + { + wearable->animateParams(delta, upload_bake); + } } } } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index b5ad5c7a11..f8cff42412 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -989,22 +989,15 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); } + addCOFItemLink(item_to_wear, do_update); } + break; case LLAssetType::AT_BODYPART: - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return false; - } - + // TODO: investigate wearables may not be loaded at this point EXT-8231 + // Remove the existing wearables of the same type. // Remove existing body parts anyway because we must not be able to wear e.g. two skins. - if (item_to_wear->getType() == LLAssetType::AT_BODYPART) - { - removeCOFLinksOfType(item_to_wear->getWearableType(), false); - } + removeCOFLinksOfType(item_to_wear->getWearableType(), false); addCOFItemLink(item_to_wear, do_update); break; @@ -2596,7 +2589,7 @@ void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items, { asset_id = linked_item->getAssetUUID(); } - llinfos << msg << " " << i <<" " << item->getName() << " " << asset_id.asString() << llendl; + llinfos << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << llendl; } llinfos << llendl; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 1ed63555b0..682e3eb874 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -81,7 +81,9 @@ #include "llvoicechannel.h" #include "llvoavatarself.h" #include "llsidetray.h" - +#include "llfeaturemanager.h" +#include "llurlmatch.h" +#include "lltextutil.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -192,6 +194,7 @@ #include "llviewerthrottle.h" #include "llparcel.h" #include "llavatariconctrl.h" +#include "llgroupiconctrl.h" // Include for security api initialization #include "llsecapi.h" @@ -351,6 +354,45 @@ static void ui_audio_callback(const LLUUID& uuid) } } +bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) +{ + if(!match || !base) + return false; + + LLUUID match_id = match->getID(); + + LLIconCtrl* icon; + + if(gAgent.isInGroup(match_id, TRUE)) + { + LLGroupIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLGroupIconCtrl>(); + icon_params.group_id = match_id; + icon_params.rect = LLRect(0, 16, 16, 0); + icon_params.visible = true; + icon = LLUICtrlFactory::instance().createWidget<LLGroupIconCtrl>(icon_params); + } + else + { + LLAvatarIconCtrl::Params icon_params = LLUICtrlFactory::instance().getDefaultParams<LLAvatarIconCtrl>(); + icon_params.avatar_id = match_id; + icon_params.rect = LLRect(0, 16, 16, 0); + icon_params.visible = true; + icon = LLUICtrlFactory::instance().createWidget<LLAvatarIconCtrl>(icon_params); + } + + LLInlineViewSegment::Params params; + params.force_newline = false; + params.view = icon; + params.left_pad = 4; + params.right_pad = 4; + params.top_pad = 2; + params.bottom_pad = 2; + + base->appendWidget(params," ",false); + + return true; +} + void request_initial_instant_messages() { static BOOL requested = FALSE; @@ -379,14 +421,8 @@ bool handleCrashSubmitBehaviorChanged(const LLSD& newvalue) const S32 NEVER_SUBMIT_REPORT = 2; if(cb == NEVER_SUBMIT_REPORT) { -// LLWatchdog::getInstance()->cleanup(); // SJB: cleaning up a running watchdog thread is unsafe LLAppViewer::instance()->destroyMainloopTimeout(); } - else if(gSavedSettings.getBOOL("WatchdogEnabled") == TRUE) - { - // Don't re-enable the watchdog when we change the setting; this may get called before it's started -// LLWatchdog::getInstance()->init(); - } return true; } @@ -893,6 +929,7 @@ bool LLAppViewer::init() } LLViewerMedia::initClass(); + LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; //EXT-7013 - On windows for some locale (Japanese) standard //datetime formatting functions didn't support some parameters such as "weekday". @@ -1689,14 +1726,6 @@ bool LLAppViewer::initThreads() static const bool enable_threads = true; #endif - const S32 NEVER_SUBMIT_REPORT = 2; - bool use_watchdog = gSavedSettings.getBOOL("WatchdogEnabled"); - bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT; - if(use_watchdog && send_reports) - { - LLWatchdog::getInstance()->init(watchdog_killer_callback); - } - LLVFSThread::initClass(enable_threads && false); LLLFSThread::initClass(enable_threads && false); @@ -1925,18 +1954,11 @@ bool LLAppViewer::initConfiguration() } #endif - //*FIX:Mani - Set default to disabling watchdog mainloop - // timeout for mac and linux. There is no call stack info - // on these platform to help debug. #ifndef LL_RELEASE_FOR_DOWNLOAD - gSavedSettings.setBOOL("WatchdogEnabled", FALSE); gSavedSettings.setBOOL("QAMode", TRUE ); + gSavedSettings.setS32("WatchdogEnabled", 0); #endif - -#ifndef LL_WINDOWS - gSavedSettings.setBOOL("WatchdogEnabled", FALSE); -#endif - + gCrashSettings.getControl(CRASH_BEHAVIOR_SETTING)->getSignal()->connect(boost::bind(&handleCrashSubmitBehaviorChanged, _2)); // These are warnings that appear on the first experience of that condition. @@ -2364,6 +2386,25 @@ bool LLAppViewer::initWindow() gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), FALSE, ignorePixelDepth); + // Need to load feature table before cheking to start watchdog. + const S32 NEVER_SUBMIT_REPORT = 2; + bool use_watchdog = false; + int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); + if(watchdog_enabled_setting == -1){ + use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); + } + else + { + // The user has explicitly set this setting; always use that value. + use_watchdog = bool(watchdog_enabled_setting); + } + + bool send_reports = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING) != NEVER_SUBMIT_REPORT; + if(use_watchdog && send_reports) + { + LLWatchdog::getInstance()->init(watchdog_killer_callback); + } + LLNotificationsUI::LLNotificationManager::getInstance(); if (gSavedSettings.getBOOL("WindowMaximized")) @@ -4133,7 +4174,7 @@ void LLAppViewer::forceErrorBreakpoint() void LLAppViewer::forceErrorBadMemoryAccess() { S32* crash = NULL; - *crash = 0xDEADBEEF; + *crash = 0xDEADBEEF; return; } diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index e3ef04d03d..8c9fd09dcb 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -64,6 +64,10 @@ #include "llcommandlineparser.h" #include "lltrans.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +#include "llwindebug.h" +#endif + // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert #ifdef LL_DEBUG @@ -342,6 +346,10 @@ bool LLAppViewerWin32::init() llinfos << "Turning off Windows error reporting." << llendl; disableWinErrorReporting(); +#ifndef LL_RELEASE_FOR_DOWNLOAD + LLWinDebug::instance().init(); +#endif + return LLAppViewer::init(); } diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 60a2392d87..b494470cbc 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -449,7 +449,7 @@ void LLCallFloater::updateAgentModeratorState() if(gAgent.isInGroup(mSpeakerManager->getSessionID())) { // This method can be called when LLVoiceChannel.mState == STATE_NO_CHANNEL_INFO - // in this case there are no any speakers yet. + // in this case there are not any speakers yet. if (mSpeakerManager->findSpeaker(gAgentID)) { // Agent is Moderator diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index ac12bffdfb..c0fa910f86 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -557,11 +557,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL { bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean(); - if(mEditor) + llassert(mEditor); + if (!mEditor) { - mEditor->setPlainText(use_plain_text_chat_history); + return; } + mEditor->setPlainText(use_plain_text_chat_history); + if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty()) { mUnreadChatSources.insert(chat.mFromName); @@ -740,7 +743,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mIsLastMessageFromLog = message_from_log; } - if (chat.mNotifId.notNull()) + if (chat.mNotifId.notNull()) { LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId); if (notification != NULL) @@ -832,6 +835,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendText(message, FALSE, style_params); } + mEditor->blockUndo(); // automatically scroll to end when receiving chat from myself diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index cbebc93306..f278fb6a7b 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -167,10 +167,18 @@ public: protected: static void replaceWearable() { - static LLButton* show_add_wearables_btn = - LLSideTray::getInstance()->getChild<LLButton>("show_add_wearables_btn"); - - show_add_wearables_btn->onCommit(); + // *TODO: Most probable that accessing to LLPanelOutfitEdit instance should be: + // LLSideTray::getInstance()->getSidepanelAppearance()->getPanelOutfitEdit() + // without casting. Getter methods provides possibility to check and construct + // absent instance. Explicit relations between components avoids situations + // when we tries to construct instance with unsatisfied implicit input conditions. + LLPanelOutfitEdit * panel_outfit_edit = + dynamic_cast<LLPanelOutfitEdit*> (LLSideTray::getInstance()->getPanel( + "panel_outfit_edit")); + if (panel_outfit_edit != NULL) + { + panel_outfit_edit->showAddWearablesPanel(true); + } } /*virtual*/ LLContextMenu* createMenu() @@ -364,6 +372,11 @@ void LLCOFWearables::refresh() iter != iter_end; ++iter) { LLFlatListView* list = iter->first; + if (!list) continue; + + //restoring selection should not fire commit callbacks + list->setCommitOnSelectionChange(false); + const values_vector_t& values = iter->second; for (values_vector_t::const_iterator value_it = values.begin(), @@ -377,6 +390,8 @@ void LLCOFWearables::refresh() list->selectItemByValue(*value_it); } } + + list->setCommitOnSelectionChange(true); } } diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 71bfae316a..d39ed77491 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -105,49 +105,23 @@ void LLFloaterOpenObject::refresh() mPanelInventoryObject->refresh(); std::string name = ""; - - // Enable the copy || copy & wear buttons only if we have something we can copy or copy & wear (respectively). - bool copy_enabled = false; - bool wear_enabled = false; + BOOL enabled = FALSE; LLSelectNode* node = mObjectSelection->getFirstRootNode(); if (node) { name = node->mName; - copy_enabled = true; - - LLViewerObject* object = node->getObject(); - if (object) - { - // this folder is coming from an object, as there is only one folder in an object, the root, - // we need to collect the entire contents and handle them as a group - LLInventoryObject::object_list_t inventory_objects; - object->getInventoryContents(inventory_objects); - - if (!inventory_objects.empty()) - { - for (LLInventoryObject::object_list_t::iterator it = inventory_objects.begin(); - it != inventory_objects.end(); - ++it) - { - LLInventoryItem* item = static_cast<LLInventoryItem*> ((LLInventoryObject*)(*it)); - LLInventoryType::EType type = item->getInventoryType(); - if (type == LLInventoryType::IT_OBJECT - || type == LLInventoryType::IT_ATTACHMENT - || type == LLInventoryType::IT_WEARABLE - || type == LLInventoryType::IT_GESTURE) - { - wear_enabled = true; - break; - } - } - } - } + enabled = TRUE; } - + else + { + name = ""; + enabled = FALSE; + } + childSetTextArg("object_name", "[DESC]", name); - childSetEnabled("copy_to_inventory_button", copy_enabled); - childSetEnabled("copy_and_wear_button", wear_enabled); + childSetEnabled("copy_to_inventory_button", enabled); + childSetEnabled("copy_and_wear_button", enabled); } diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 4792d761d8..0a5499b166 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -557,8 +557,6 @@ BOOL LLPanelScriptLimitsRegionMemory::getLandScriptResources() void LLPanelScriptLimitsRegionMemory::processParcelInfo(const LLParcelData& parcel_data) { - mParcelId = parcel_data.parcel_id; - if(!getLandScriptResources()) { std::string msg_error = LLTrans::getString("ScriptLimitsRequestError"); @@ -580,6 +578,7 @@ void LLPanelScriptLimitsRegionMemory::setParcelID(const LLUUID& parcel_id) LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this); mParcelId.setNull(); } + mParcelId = parcel_id; LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this); LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id); } diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index ca1f142760..61fe50e301 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -199,7 +199,12 @@ void LLFloaterVoiceEffect::refreshEffectList() if(sl_item) { LLFontGL::StyleFlags style = is_template_only ? LLFontGL::NORMAL : LLFontGL::BOLD; - dynamic_cast<LLScrollListText*>(sl_item->getColumn(0))->setFontStyle(style); + LLScrollListText* slt = dynamic_cast<LLScrollListText*>(sl_item->getColumn(0)); + llassert(slt); + if (slt) + { + slt->setFontStyle(style); + } } } } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 96dba5717a..3350497326 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2617,11 +2617,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) gInventory.addObserver(fetch); } } - else - { - mItems.push_back(std::string("--no options--")); - mDisabledItems.push_back(std::string("--no options--")); - } // Preemptively disable system folder removal if more than one item selected. if ((flags & FIRST_SELECTED_ITEM) == 0) @@ -2635,6 +2630,12 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) mDisabledItems.push_back(std::string("Share")); } + if (mItems.empty()) + { + mItems.push_back(std::string("--no options--")); + mDisabledItems.push_back(std::string("--no options--")); + } + hide_context_entries(menu, mItems, mDisabledItems); } @@ -2847,6 +2848,9 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response return false; } +// This is used both for testing whether an item can be dropped +// into the folder, as well as performing the actual drop, depending +// if drop == TRUE. BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop) { @@ -2866,8 +2870,23 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, LLViewerObject* object = NULL; if(LLToolDragAndDrop::SOURCE_AGENT == source) { + const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID ¤t_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); + + const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); + const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); + const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); + const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID()); + const BOOL folder_allows_reorder = (mUUID == favorites_id); + + //-------------------------------------------------------------------------------- + // Determine if item can be moved. + // + BOOL is_movable = TRUE; - switch( inv_item->getActualType() ) + + switch (inv_item->getActualType()) { case LLAssetType::AT_CATEGORY: is_movable = !LLFolderType::lookupIsProtectedType(((LLInventoryCategory*)inv_item)->getPreferredType()); @@ -2875,41 +2894,50 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, default: break; } - - const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); - const BOOL move_is_into_trash = (mUUID == trash_id) || model->isObjectDescendentOf(mUUID, trash_id); - const LLUUID current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id); - const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT); - const BOOL move_is_outof_current_outfit = LLAppearanceMgr::instance().getIsInCOF(inv_item->getUUID()); - // Can't explicitly drag things out of the COF. if (move_is_outof_current_outfit) { is_movable = FALSE; } - - if(is_movable && move_is_into_trash) + if (move_is_into_trash) { - is_movable = inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); + is_movable &= inv_item->getIsLinkType() || !get_is_item_worn(inv_item->getUUID()); } - - if ( is_movable ) + if (is_movable) { // Don't allow creating duplicates in the Calling Card/Friends // subfolders, see bug EXT-1599. Check is item direct descendent // of target folder and forbid item's movement if it so. // Note: isItemDirectDescendentOfCategory checks if // passed category is in the Calling Card/Friends folder - is_movable = ! LLFriendCardsManager::instance() - .isObjDirectDescendentOfCategory (inv_item, getCategory()); + is_movable &= !LLFriendCardsManager::instance().isObjDirectDescendentOfCategory(inv_item, getCategory()); + } + + // + //-------------------------------------------------------------------------------- + + //-------------------------------------------------------------------------------- + // Determine if item can be moved & dropped + // + + accept = TRUE; + + if (!is_movable) + accept = FALSE; + if ((mUUID == inv_item->getParentUUID()) && !folder_allows_reorder) + accept = FALSE; + if (move_is_into_current_outfit || move_is_into_outfit) + { + if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) && + (inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) && + (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT)) + accept = FALSE; + } + if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID())) + { + accept = FALSE; } - const LLUUID& favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); - const BOOL folder_allows_reorder = (mUUID == favorites_id); - - // we can move item inside a folder only if this folder is Favorites. See EXT-719 - accept = is_movable && ((mUUID != inv_item->getParentUUID()) || folder_allows_reorder); if(accept && drop) { if (inv_item->getType() == LLAssetType::AT_GESTURE @@ -2917,10 +2945,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { LLGestureMgr::instance().deactivateGesture(inv_item->getUUID()); } - // If an item is being dragged between windows, unselect - // everything in the active window so that we don't follow - // the selection to its new location (which is very - // annoying). + // If an item is being dragged between windows, unselect everything in the active window + // so that we don't follow the selection to its new location (which is very annoying). LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); if (active_panel) { @@ -2931,7 +2957,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, } } - // if dragging from/into favorites folder only reorder items + //-------------------------------------------------------------------------------- + // Destination folder logic + // + + // REORDER + // (only reorder the item) if ((mUUID == inv_item->getParentUUID()) && folder_allows_reorder) { LLInventoryPanel* panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get()); @@ -2943,7 +2974,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId); } } - else if (favorites_id == mUUID) // if target is the favorites folder we use copy + + // FAVORITES folder + // (copy the item) + else if (favorites_id == mUUID) { // use callback to rearrange favorite landmarks after adding // to have new one placed before target (on which it was dropped). See EXT-4312. @@ -2963,38 +2997,50 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, std::string(), cb); } + // CURRENT OUTFIT or OUTFIT folder + // (link the item) else if (move_is_into_current_outfit || move_is_into_outfit) { - // BAP - should skip if dup. - if (move_is_into_current_outfit) + if ((inv_item->getInventoryType() == LLInventoryType::IT_WEARABLE) || + (inv_item->getInventoryType() == LLInventoryType::IT_GESTURE) || + (inv_item->getInventoryType() == LLInventoryType::IT_OBJECT)) { - LLAppearanceMgr::instance().addCOFItemLink(inv_item); - } - else - { - LLPointer<LLInventoryCallback> cb = NULL; - link_inventory_item( - gAgent.getID(), - inv_item->getLinkedUUID(), - mUUID, - inv_item->getName(), - inv_item->getDescription(), - LLAssetType::AT_LINK, - cb); + // BAP - should skip if dup. + if (move_is_into_current_outfit) + { + LLAppearanceMgr::instance().addCOFItemLink(inv_item); + } + else + { + LLPointer<LLInventoryCallback> cb = NULL; + link_inventory_item( + gAgent.getID(), + inv_item->getLinkedUUID(), + mUUID, + inv_item->getName(), + inv_item->getDescription(), + LLAssetType::AT_LINK, + cb); + } } } + // NORMAL or TRASH folder + // (move the item, restamp if into trash) else { - // restamp if the move is into the trash. LLInvFVBridge::changeItemParent( model, (LLViewerInventoryItem*)inv_item, mUUID, move_is_into_trash); } + + // + //-------------------------------------------------------------------------------- + } } - else if(LLToolDragAndDrop::SOURCE_WORLD == source) + else if (LLToolDragAndDrop::SOURCE_WORLD == source) { // Make sure the object exists. If we allowed dragging from // anonymous objects, it would be possible to bypass @@ -3012,7 +3058,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, BOOL is_move = FALSE; if((perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID()) && perm.allowTransferTo(gAgent.getID()))) -// || gAgent.isGodlike()) + // || gAgent.isGodlike()) { accept = TRUE; @@ -4482,13 +4528,7 @@ void LLWearableBridge::onWearOnAvatar(void* user_data) void LLWearableBridge::wearOnAvatar() { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 LLViewerInventoryItem* item = getItem(); if(item) @@ -4499,13 +4539,7 @@ void LLWearableBridge::wearOnAvatar() void LLWearableBridge::wearAddOnAvatar() { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 LLViewerInventoryItem* item = getItem(); if(item) @@ -5063,13 +5097,7 @@ BOOL LLWearableBridgeAction::isAgentInventory() const void LLWearableBridgeAction::wearOnAvatar() { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 LLViewerInventoryItem* item = getItem(); if(item) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7463658003..2d11337955 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -433,13 +433,12 @@ void show_item_original(const LLUUID& item_uuid) LLPanelMainInventory* main_inventory = floater_inventory->getMainInventoryPanel(); main_inventory->onFilterEdit(""); - } - if(floater_inventory->getVisible()) - { - floater_inventory_visible = true; + if(floater_inventory->getVisible()) + { + floater_inventory_visible = true; + } } - } if(sidepanel_inventory && !floater_inventory_visible) { diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 53a11eff04..b8590d838e 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -231,7 +231,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) params.rect(text_entry_rect); params.default_text(LLStringUtil::null); params.max_length_bytes(p.max_chars); - params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1)); + params.keystroke_callback(boost::bind(&LLLocationInputCtrl::onTextEntry, this, _1)); params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params); @@ -484,13 +484,16 @@ void LLLocationInputCtrl::onTextEntry(LLLineEditor* line_editor) KEY key = gKeyboard->currentKey(); MASK mask = gKeyboard->currentMask(TRUE); + // Typing? (moving cursor should not affect showing the list) + bool typing = mask != MASK_CONTROL && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END; + bool pasting = mask == MASK_CONTROL && key == 'V'; + if (line_editor->getText().empty()) { prearrangeList(); // resets filter hideList(); } - // Typing? (moving cursor should not affect showing the list) - else if (mask != MASK_CONTROL && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) + else if (typing || pasting) { prearrangeList(line_editor->getText()); if (mList->getItemCount() != 0) @@ -966,7 +969,12 @@ void LLLocationInputCtrl::focusTextEntry() // if the "select_on_focus" parameter is true it places the cursor // at the beginning (after selecting text), thus screwing up updateSelection(). if (mTextEntry) + { gFocusMgr.setKeyboardFocus(mTextEntry); + + // Enable the text entry to handle accelerator keys (EXT-8104). + LLEditMenuHandler::gEditMenuHandler = mTextEntry; + } } void LLLocationInputCtrl::enableAddLandmarkButton(bool val) diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 23c7e64cce..dddfd9106f 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -657,10 +657,10 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata) } if (command_name == "take_off") { - // Enable "Take Off" only if a worn item or base outfit is selected. - return ( !hasItemSelected() - && LLAppearanceMgr::getInstance()->getBaseOutfitUUID() == mSelectedOutfitUUID ) - || hasWornItemSelected(); + // Enable "Take Off" if any of selected items can be taken off + // or the selected outfit contains items that can be taken off. + return ( hasItemSelected() && canTakeOffSelected() ) + || ( !hasItemSelected() && LLAppearanceMgr::getCanRemoveFromCOF(mSelectedOutfitUUID) ); } if (command_name == "wear_add") @@ -955,14 +955,19 @@ void LLOutfitsList::applyFilterToTab( } } -bool LLOutfitsList::hasWornItemSelected() +bool LLOutfitsList::canTakeOffSelected() { uuid_vec_t selected_uuids; getSelectedItemsUUIDs(selected_uuids); + LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false); + for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it) { - if (get_is_item_worn(*it)) return true; + LLViewerInventoryItem* item = gInventory.getItem(*it); + if (!item) continue; + + if (is_worn(NULL, item)) return true; } return false; } diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 26722f2a96..d7cf8a8c08 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -179,9 +179,9 @@ private: void applyFilterToTab(const LLUUID& category_id, LLAccordionCtrlTab* tab, const std::string& filter_substring); /** - * Returns true if there are any worn items among currently selected, otherwise false. + * Returns true if there are any items that can be taken off among currently selected, otherwise false. */ - bool hasWornItemSelected(); + bool canTakeOffSelected(); void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 709bb83fe4..b79a4f359a 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -37,6 +37,7 @@ #include "llpanelimcontrolpanel.h" #include "llagent.h" +#include "llappviewer.h" // for gDisconnected #include "llavataractions.h" #include "llavatariconctrl.h" #include "llbutton.h" @@ -163,7 +164,7 @@ BOOL LLPanelIMControlPanel::postBuild() childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this)); childSetEnabled("add_friend_btn", !LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId())); - + setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this)); return LLPanelChatControlPanel::postBuild(); } @@ -194,6 +195,15 @@ void LLPanelIMControlPanel::onShareButtonClicked() LLAvatarActions::share(mAvatarID); } +void LLPanelIMControlPanel::onFocusReceived() +{ + // Disable all the buttons (Call, Teleport, etc) if disconnected. + if (gDisconnected) + { + setAllChildrenEnabled(FALSE); + } +} + void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) { LLPanelChatControlPanel::setSessionId(session_id); diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index ce8fc58e56..0a1fd70c08 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -95,6 +95,7 @@ private: void onShareButtonClicked(); void onTeleportButtonClicked(); void onPayButtonClicked(); + void onFocusReceived(); LLUUID mAvatarID; }; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index fa7e06d323..29ce3449d1 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -53,6 +53,8 @@ #include "lltooldraganddrop.h" #include "llviewermenu.h" #include "llviewertexturelist.h" +#include "llsidepanelinventory.h" +#include "llsidetray.h" const std::string FILTERS_FILENAME("filters.xml"); @@ -1163,6 +1165,12 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) return FALSE; } + if (command_name == "share") + { + LLSidepanelInventory* parent = dynamic_cast<LLSidepanelInventory*>(LLSideTray::getInstance()->getPanel("sidepanel_inventory")); + return parent ? parent->canShare() : FALSE; + } + return TRUE; } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index ffd879dfd7..053c2d9498 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -726,24 +726,36 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) bool more_than_one_selected = ids.size() > 1; bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem())); - //resetting selection if no item is selected or than one item is selected - if (nothing_selected || more_than_one_selected) + //expanded accordion tab determines filtering when no item is selected + if (nothing_selected) { - if (nothing_selected) - { - showWearablesFolderView(); - applyFolderViewFilter(FVIT_ALL); - } + showWearablesListView(); - if (more_than_one_selected) + switch (mCOFWearables->getExpandedAccordionAssetType()) { - showWearablesListView(); - applyListViewFilter(LVIT_ALL); + case LLAssetType::AT_OBJECT: + applyListViewFilter(LVIT_ATTACHMENT); + break; + case LLAssetType::AT_BODYPART: + applyListViewFilter(LVIT_BODYPART); + break; + case LLAssetType::AT_CLOTHING: + default: + applyListViewFilter(LVIT_CLOTHING); + break; } return; } + //resetting selection if more than one item is selected + if (more_than_one_selected) + { + showWearablesListView(); + applyListViewFilter(LVIT_ALL); + return; + } + //filter wearables by a type represented by a dummy item if (one_selected && is_dummy_item) @@ -761,7 +773,7 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) return; } - if (one_selected && !is_dummy_item) + if (item && one_selected && !is_dummy_item) { if (item->isWearableType()) { diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index c5d259e517..ca5679d5b0 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -282,10 +282,17 @@ void LLPanelOutfitsInventory::showGearMenu() void LLPanelOutfitsInventory::onTrashButtonClick() { - mMyOutfitsPanel->removeSelected(); + LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLPanelOutfitsInventory::onOutfitsRemovalConfirmation, this, _1, _2)); +} - updateListCommands(); - updateVerbs(); +void LLPanelOutfitsInventory::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return; // canceled + + mMyOutfitsPanel->removeSelected(); + updateListCommands(); + updateVerbs(); } bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index a50e047140..5c397e9c29 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -94,6 +94,7 @@ protected: void onWearButtonClick(); void showGearMenu(); void onTrashButtonClick(); + void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); bool isActionEnabled(const LLSD& userdata); void setWearablesLoading(bool val); void onWearablesLoaded(); diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index fd470798ee..68fa9d1e5e 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -129,6 +129,8 @@ void LLPanelVoiceEffect::update(bool list_updated) if (mVoiceEffectCombo) { LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + llassert(effect_interface); + if (!effect_interface) return; if (list_updated) { // Add the default "No Voice Morph" entry. diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h index 951fdd630c..f2f2509f9a 100644 --- a/indra/newview/llsidepanelinventory.h +++ b/indra/newview/llsidepanelinventory.h @@ -58,6 +58,9 @@ public: void showTaskInfoPanel(); void showInventoryPanel(); + // checks can share selected item(s) + bool canShare(); + protected: // Tracks highlighted (selected) item in inventory panel. LLInventoryItem *getSelectedItem(); @@ -65,8 +68,6 @@ protected: void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action); // "wear", "teleport", etc. void performActionOnSelection(const std::string &action); - bool canShare(); - void updateVerbs(); // diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index cb65756764..e6b4aeb6c2 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -582,8 +582,6 @@ LLIMWellWindow::LLIMWellWindow(const LLSD& key) : LLSysWellWindow(key) { LLIMMgr::getInstance()->addSessionObserver(this); - LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1)); - LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1)); } LLIMWellWindow::~LLIMWellWindow() @@ -601,6 +599,10 @@ BOOL LLIMWellWindow::postBuild() { BOOL rv = LLSysWellWindow::postBuild(); setTitle(getString("title_im_well_window")); + + LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1)); + LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1)); + return rv; } @@ -641,6 +643,8 @@ void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) { + if (!mMessageList) return NULL; + LLChiclet* res = NULL; ObjectRowPanel* panel = mMessageList->getTypedItemByValue<ObjectRowPanel>(notification_id); if (panel != NULL) @@ -655,6 +659,8 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id) // PRIVATE METHODS LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId) { + if (!mMessageList) return NULL; + LLChiclet* res = NULL; RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId); if (panel != NULL) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 0b86cefa1d..fcb9deb20b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -423,8 +423,9 @@ BOOL LLFloaterTexturePicker::postBuild() mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); mInventoryPanel->setAllowMultiSelect(FALSE); - // store this filter as the default one - mInventoryPanel->getRootFolder()->getFilter()->markDefault(); + // Commented out to scroll to currently selected texture. See EXT-5403. + // // store this filter as the default one + // mInventoryPanel->getRootFolder()->getFilter()->markDefault(); // Commented out to stop opening all folders with textures // mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE); diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index c862c02b82..3f34fc174c 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1871,13 +1871,8 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( if (drop) { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return ACCEPT_NO; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); } return ACCEPT_YES_MULTI; @@ -1949,13 +1944,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( if (drop) { - // Don't wear anything until initial wearables are loaded, can - // destroy clothing items. - if (!gAgentWearables.areWearablesLoaded()) - { - LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); - return ACCEPT_NO; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 } if (mSource == SOURCE_AGENT) diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 868322699e..9f9a9bef35 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -269,13 +269,13 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt void LLPanelAttachmentListItem::updateItem(const std::string& name, EItemState item_state) { - std::string title_joint; + std::string title_joint = name; LLViewerInventoryItem* inv_item = getItem(); if (inv_item && isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(inv_item->getLinkedUUID())) { std::string joint = LLTrans::getString(gAgentAvatarp->getAttachedPointName(inv_item->getLinkedUUID())); - title_joint = name + " (" + joint + ")"; + title_joint = title_joint + " (" + joint + ")"; } LLPanelInventoryListItemBase::updateItem(title_joint, item_state); @@ -783,10 +783,7 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id) // static bool LLWearableItemsList::ContextMenu::canAddWearable(const LLUUID& item_id) { - if (!gAgentWearables.areWearablesLoaded()) - { - return false; - } + // TODO: investigate wearables may not be loaded at this point EXT-8231 LLViewerInventoryItem* item = gInventory.getItem(item_id); if (!item || item->getType() != LLAssetType::AT_CLOTHING) diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp new file mode 100644 index 0000000000..502fefd4ef --- /dev/null +++ b/indra/newview/llwindebug.cpp @@ -0,0 +1,188 @@ +/** + * @file llwindebug.cpp + * @brief Windows debugging functions + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" + +#include "llwindebug.h" +#include "lldir.h" + + +// based on dbghelp.h +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +MINIDUMPWRITEDUMP f_mdwp = NULL; + + +class LLMemoryReserve { +public: + LLMemoryReserve(); + ~LLMemoryReserve(); + void reserve(); + void release(); +protected: + unsigned char *mReserve; + static const size_t MEMORY_RESERVATION_SIZE; +}; + +LLMemoryReserve::LLMemoryReserve() : + mReserve(NULL) +{ +}; + +LLMemoryReserve::~LLMemoryReserve() +{ + release(); +} + +// I dunno - this just seemed like a pretty good value. +const size_t LLMemoryReserve::MEMORY_RESERVATION_SIZE = 5 * 1024 * 1024; + +void LLMemoryReserve::reserve() +{ + if(NULL == mReserve) + mReserve = new unsigned char[MEMORY_RESERVATION_SIZE]; +}; + +void LLMemoryReserve::release() +{ + delete [] mReserve; + mReserve = NULL; +}; + +static LLMemoryReserve gEmergencyMemoryReserve; + + +LONG NTAPI vectoredHandler(PEXCEPTION_POINTERS exception_infop) +{ + LLWinDebug::instance().generateMinidump(exception_infop); + return EXCEPTION_CONTINUE_SEARCH; +} + +// static +void LLWinDebug::init() +{ + static bool s_first_run = true; + // Load the dbghelp dll now, instead of waiting for the crash. + // Less potential for stack mangling + + if (s_first_run) + { + // First, try loading from the directory that the app resides in. + std::string local_dll_name = gDirUtilp->findFile("dbghelp.dll", gDirUtilp->getWorkingDir(), gDirUtilp->getExecutableDir()); + + HMODULE hDll = NULL; + hDll = LoadLibraryA(local_dll_name.c_str()); + if (!hDll) + { + hDll = LoadLibrary(L"dbghelp.dll"); + } + + if (!hDll) + { + LL_WARNS("AppInit") << "Couldn't find dbghelp.dll!" << LL_ENDL; + } + else + { + f_mdwp = (MINIDUMPWRITEDUMP) GetProcAddress(hDll, "MiniDumpWriteDump"); + + if (!f_mdwp) + { + FreeLibrary(hDll); + hDll = NULL; + } + } + + gEmergencyMemoryReserve.reserve(); + + s_first_run = false; + + // Add this exeption hanlder to save windows style minidump. + AddVectoredExceptionHandler(0, &vectoredHandler); + } +} + +void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename) +{ + if(f_mdwp == NULL || gDirUtilp == NULL) + { + return; + } + else + { + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename); + + HANDLE hFile = CreateFileA(dump_path.c_str(), + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hFile != INVALID_HANDLE_VALUE) + { + // Write the dump, ignoring the return value + f_mdwp(GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + type, + ExInfop, + NULL, + NULL); + + CloseHandle(hFile); + } + + } +} + +// static +void LLWinDebug::generateMinidump(struct _EXCEPTION_POINTERS *exception_infop) +{ + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, + "SecondLifeException"); + if (exception_infop) + { + // Since there is exception info... Release the hounds. + gEmergencyMemoryReserve.release(); + + _MINIDUMP_EXCEPTION_INFORMATION ExInfo; + + ExInfo.ThreadId = ::GetCurrentThreadId(); + ExInfo.ExceptionPointers = exception_infop; + ExInfo.ClientPointers = NULL; + writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLife.dmp"); + } +} diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h new file mode 100644 index 0000000000..809d1b8cc3 --- /dev/null +++ b/indra/newview/llwindebug.h @@ -0,0 +1,49 @@ +/** + * @file llwindebug.h + * @brief LLWinDebug class header file + * + * $LicenseInfo:firstyear=2004&license=viewergpl$ + * + * Copyright (c) 2004-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLWINDEBUG_H +#define LL_LLWINDEBUG_H + +#include "stdtypes.h" +#include <dbghelp.h> + +class LLWinDebug: + public LLSingleton<LLWinDebug> +{ +public: + static void init(); + static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); +private: + static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename); +}; + +#endif // LL_LLWINDEBUG_H diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 14aacafa9f..68e36ff0b3 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -191,9 +191,10 @@ type="string" length="1" follows="left|top" - height="16" + height="20" layout="topleft" left_pad="2" + valign="center" name="ContentRatingText" top_delta="0" width="250"> @@ -207,7 +208,7 @@ layout="topleft" left="10" name="Owner:" - top_pad="5" + top_pad="1" width="100"> Owner: </text> @@ -729,8 +730,10 @@ Leyla Linden </text> height="16" layout="topleft" left_pad="10" + top_delta="-3" mouse_opaque="false" name="region_maturity_text" + valign="center" width="150"> Adult </text> @@ -743,6 +746,7 @@ Leyla Linden </text> left="10" mouse_opaque="false" name="resellable_lbl" + top_pad="9" width="100"> Resale: </text> @@ -1924,6 +1928,8 @@ Only large parcels can be listed in search. left_delta="0" name="public_access" top_pad="5" + label_text.valign="center" + label_text.v_pad="-7" width="278" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 34c1b25f8c..194a93977f 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -823,7 +823,7 @@ height="10" left="10" name="Name:" - top="0" + top="5" width="90"> Name: </text> diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 72ab6195bc..a1ca910cbb 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -199,7 +199,15 @@ mouse_opaque="false" name="popup_holder" class="popup_holder" - width="1024"/> + width="1024"> + <icon follows="right|bottom" + image_name="Resize_Corner" + right="-1" + name="resize_corner" + width="11" + bottom="-1" + height="11" /> + </panel> <menu_holder top="0" follows="all" height="768" diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index 62365f7cc2..c394700081 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -81,6 +81,17 @@ function="Inventory.GearDefault.Enable" parameter="save_texture" /> </menu_item_call> + <menu_item_call + label="Share" + layout="topleft" + name="Share" + visible="true"> + <on_click + function="Inventory.Share" /> + <on_enable + function="Inventory.GearDefault.Enable" + parameter="share" /> + </menu_item_call> <menu_item_call label="Find Original" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 290c8c55a9..04a8a02ecd 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -817,6 +817,17 @@ Delete pick <nolink>[PICK]</nolink>? <notification icon="alertmodal.tga" + name="DeleteOutfits" + type="alertmodal"> + Delete the selected outfit/s? + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="PromptGoToEventsPage" type="alertmodal"> Go to the [SECOND_LIFE] events web page? diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index 4eff5bc48a..4b622691b3 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -503,5 +503,17 @@ image_pressed_selected "Lit" + "Selected" - there are new messages and the Well </button> </chiclet_notification> </layout_panel> + <icon + auto_resize="false" + color="0 0 0 0" + follows="left|right" + height="10" + image_name="spacer24.tga" + layout="topleft" + left="0" + min_width="4" + name="DUMMY2" + top="0" + width="8" /> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index d2c8ab159f..f438e3d42d 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -22,37 +22,40 @@ width="311"> <accordion_tab layout="topleft" - name="tab_attachments" - title="Attachments"> + name="tab_clothing" + title="Clothing"> <flat_list_view allow_select="true" follows="all" height="10" item_pad="3" + keep_selection_visible_on_reshape="true" layout="topleft" left="0" - keep_selection_visible_on_reshape="true" multi_select="true" - name="list_attachments" + name="list_clothing" top="0" width="311" /> </accordion_tab> <accordion_tab layout="topleft" - name="tab_clothing" - title="Clothing"> + name="tab_attachments" + title="Attachments"> <flat_list_view allow_select="true" follows="all" height="10" item_pad="3" - keep_selection_visible_on_reshape="true" layout="topleft" left="0" + keep_selection_visible_on_reshape="true" multi_select="true" - name="list_clothing" + name="list_attachments" top="0" - width="311" /> + width="311"> + <flat_list_view.no_items_text + value="No attachments worn" /> + </flat_list_view> </accordion_tab> <accordion_tab layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index 10d8c7dbb8..02ab0ffee5 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -52,14 +52,14 @@ width="333"> visible="false" /> <icon follows="top|left" - height="32" - image_name="TabIcon_Appearance_Off" + height="31" + image_name="Shirt_Large" name="outfit_icon" mouse_opaque="false" visible="true" - left="0" + left="1" top="0" - width="32" /> + width="31" /> <text font="SansSerifSmall" text_color="EmphasisColor" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f7611b6833..1e8d0d2fe5 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2159,6 +2159,7 @@ Clears (deletes) the media and all params from the given face. <string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string> <string name="ATTACH_HUD_BOTTOM">HUD Bottom</string> <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string> + <string name="Bad attachment point">Invalid Attachment Point</string> <!-- script editor --> <string name="CursorPos">Line [LINE], Column [COLUMN]</string> diff --git a/indra/newview/skins/default/xui/en/widgets/textbase.xml b/indra/newview/skins/default/xui/en/widgets/textbase.xml index f4dc192bc3..b2da2147c1 100644 --- a/indra/newview/skins/default/xui/en/widgets/textbase.xml +++ b/indra/newview/skins/default/xui/en/widgets/textbase.xml @@ -1,3 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <textbase clip_partial="false" + halign="left" + valign="top" font="SansSerif"/> |