diff options
41 files changed, 536 insertions, 154 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 6f4e88e836..dabae001a3 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -215,6 +215,7 @@ Ansariel Hiller MAINT-7028 MAINT-7059 MAINT-6519 + MAINT-7899 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 3ffce4810a..934f04287d 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -40,6 +40,10 @@ #include "stringize.h" #include "llexception.h" +#if LL_WINDOWS +#include <excpt.h> +#endif + namespace { void no_op() {} } // anonymous namespace @@ -272,6 +276,43 @@ void LLCoros::setStackSize(S32 stacksize) mStackSize = stacksize; } +#if LL_WINDOWS + +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ + if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it + return EXCEPTION_EXECUTE_HANDLER; + } +} + +void LLCoros::winlevel(const callable_t& callable) +{ + __try + { + callable(); + } + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + { + // convert to C++ styled exception + // Note: it might be better to use _se_set_translator + // if you want exception to inherit full callstack + char integer_string[32]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } +} + +#endif + // Top-level wrapper around caller's coroutine callable. This function accepts // the coroutine library's implicit coro::self& parameter and saves it, but // does not pass it down to the caller's callable. @@ -282,7 +323,11 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla // run the code the caller actually wants in the coroutine try { +#if LL_WINDOWS + winlevel(callable); +#else callable(); +#endif } catch (const LLContinueError&) { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index bbe2d22af4..884d6b159c 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -182,6 +182,9 @@ private: bool cleanup(const LLSD&); struct CoroData; static void no_cleanup(CoroData*); +#if LL_WINDOWS + static void winlevel(const callable_t& callable); +#endif static void toplevel(coro::self& self, CoroData* data, const callable_t& callable); static CoroData& get_CoroData(const std::string& caller); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 8c7df45884..510a2537b9 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -808,11 +808,12 @@ void LLButton::draw() } else { - imagep->draw(0, 0, (enabled ? mImageColor.get() : disabled_color) % alpha ); + S32 y = getLocalRect().getHeight() - imagep->getHeight(); + imagep->draw(0, y, (enabled ? mImageColor.get() : disabled_color) % alpha); if (mCurGlowStrength > 0.01f) { gGL.setSceneBlendType(glow_type); - imagep->drawSolid(0, 0, glow_color % (mCurGlowStrength * alpha)); + imagep->drawSolid(0, y, glow_color % (mCurGlowStrength * alpha)); gGL.setSceneBlendType(LLRender::BT_ALPHA); } } @@ -954,7 +955,8 @@ void LLButton::drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size) } else { - imagep->drawBorder(0, 0, color, size); + S32 y = getLocalRect().getHeight() - imagep->getHeight(); + imagep->drawBorder(0, y, color, size); } } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 3ece1c12bf..a245dd8f78 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1145,11 +1145,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) { setDocked( false, false); } - storeRectControl(); mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; LLRect screen_rect = calcScreenRect(); mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); - } + } + storeRectControl(); // gather all snapped dependents for(handle_set_iter_t dependent_it = mDependents.begin(); diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8dd0b06ed2..f67bb22f5b 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -47,7 +47,9 @@ #include "llfloatercamera.h" #include "llfloaterimcontainer.h" #include "llfloaterperms.h" +#include "llfloaterpreference.h" #include "llfloaterreg.h" +#include "llfloatersnapshot.h" #include "llfloatertools.h" #include "llgroupactions.h" #include "llgroupmgr.h" @@ -4334,15 +4336,145 @@ void LLAgent::sendAgentDataUpdateRequest() void LLAgent::sendAgentUserInfoRequest() { - if(getID().isNull()) - return; // not logged in - gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - sendReliableMessage(); + std::string cap; + + if (getID().isNull()) + return; // not logged in + + if (mRegionp) + cap = mRegionp->getCapability("UserInfo"); + + if (!cap.empty()) + { + LLCoros::instance().launch("requestAgentUserInfoCoro", + boost::bind(&LLAgent::requestAgentUserInfoCoro, this, cap)); + } + else + { + sendAgentUserInfoRequestMessage(); + } } +void LLAgent::requestAgentUserInfoCoro(std::string capurl) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAgentUserInfoCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, capurl, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("UserInfo") << "Failed to get user information." << LL_ENDL; + return; + } + else if (!result["success"].asBoolean()) + { + LL_WARNS("UserInfo") << "Failed to get user information: " << result["message"] << LL_ENDL; + return; + } + + bool im_via_email; + bool is_verified_email; + std::string email; + std::string dir_visibility; + + im_via_email = result["im_via_email"].asBoolean(); + is_verified_email = result["is_verified"].asBoolean(); + email = result["email"].asString(); + dir_visibility = result["directory_visibility"].asString(); + + // TODO: This should probably be changed. I'm not entirely comfortable + // having LLAgent interact directly with the UI in this way. + LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, is_verified_email); + LLFloaterSnapshot::setAgentEmail(email); +} + +void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility) +{ + std::string cap; + + if (getID().isNull()) + return; // not logged in + + if (mRegionp) + cap = mRegionp->getCapability("UserInfo"); + + if (!cap.empty()) + { + LLCoros::instance().launch("updateAgentUserInfoCoro", + boost::bind(&LLAgent::updateAgentUserInfoCoro, this, cap, im_via_email, directory_visibility)); + } + else + { + sendAgentUpdateUserInfoMessage(im_via_email, directory_visibility); + } +} + + +void LLAgent::updateAgentUserInfoCoro(std::string capurl, bool im_via_email, std::string directory_visibility) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAgentUserInfoCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + LLSD body(LLSDMap + ("dir_visibility", LLSD::String(directory_visibility)) + ("im_via_email", LLSD::Boolean(im_via_email))); + + LLSD result = httpAdapter->postAndSuspend(httpRequest, capurl, body, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("UserInfo") << "Failed to set user information." << LL_ENDL; + } + else if (!result["success"].asBoolean()) + { + LL_WARNS("UserInfo") << "Failed to set user information: " << result["message"] << LL_ENDL; + } +} + +// deprecated: +// May be removed when UserInfo cap propagates to all simhosts in grid +void LLAgent::sendAgentUserInfoRequestMessage() +{ + gMessageSystem->newMessageFast(_PREHASH_UserInfoRequest); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); + sendReliableMessage(); +} + +void LLAgent::sendAgentUpdateUserInfoMessage(bool im_via_email, const std::string& directory_visibility) +{ + gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_UserData); + gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email); + gMessageSystem->addString("DirectoryVisibility", directory_visibility); + gAgent.sendReliableMessage(); + +} +// end deprecated +//------ + void LLAgent::observeFriends() { if(!mFriendObserver) @@ -4410,18 +4542,6 @@ const void LLAgent::getTeleportSourceSLURL(LLSLURL& slurl) const slurl = *mTeleportSourceSLURL; } -void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility ) -{ - gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - gMessageSystem->nextBlockFast(_PREHASH_UserData); - gMessageSystem->addBOOLFast(_PREHASH_IMViaEMail, im_via_email); - gMessageSystem->addString("DirectoryVisibility", directory_visibility); - gAgent.sendReliableMessage(); -} - // static void LLAgent::dumpGroupInfo() { diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index b5da5e9062..4bb4d317e8 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -912,9 +912,17 @@ public: void sendReliableMessage(); void sendAgentDataUpdateRequest(); void sendAgentUserInfoRequest(); - // IM to Email and Online visibility + +// IM to Email and Online visibility void sendAgentUpdateUserInfo(bool im_to_email, const std::string& directory_visibility); +private: + void requestAgentUserInfoCoro(std::string capurl); + void updateAgentUserInfoCoro(std::string capurl, bool im_via_email, std::string directory_visibility); + // DEPRECATED: may be removed when User Info cap propagates + void sendAgentUserInfoRequestMessage(); + void sendAgentUpdateUserInfoMessage(bool im_via_email, const std::string& directory_visibility); + //-------------------------------------------------------------------- // Receive //-------------------------------------------------------------------- diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b7267fbdfe..3f4a111a9a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -693,7 +693,6 @@ LLAppViewer::LLAppViewer() mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded. mQuitRequested(false), mLogoutRequestSent(false), - mYieldTime(-1), mLastAgentControlFlags(0), mLastAgentForceUpdate(0), mMainloopTimeout(NULL), @@ -1457,10 +1456,11 @@ bool LLAppViewer::frame() LL_RECORD_BLOCK_TIME(FTM_SLEEP); // yield some time to the os based on command line option - if(mYieldTime >= 0) + static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1); + if(yield_time >= 0) { LL_RECORD_BLOCK_TIME(FTM_YIELD); - ms_sleep(mYieldTime); + ms_sleep(yield_time); } // yield cooperatively when not running as foreground window @@ -2751,8 +2751,6 @@ bool LLAppViewer::initConfiguration() } } - mYieldTime = gSavedSettings.getS32("YieldTime"); - // Display splash screen. Must be after above check for previous // crash as this dialog is always frontmost. diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 520ff68a02..52d2bce42b 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -291,7 +291,6 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. - S32 mYieldTime; U32 mLastAgentControlFlags; F32 mLastAgentForceUpdate; struct SettingsFiles* mSettingsLocationList; diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 5ea7efc045..76d965b1f1 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -134,7 +134,11 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, { break; } - + //skip initial request from external browser before STATE_BROWSER_INIT + if (LLStartUp::getStartupState() == STATE_FIRST) + { + return true; + } cur_time = LLTimer::getElapsedSeconds(); if (cur_time < last_throttle_time + THROTTLE_PERIOD) { diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 4e69896b69..9ccf9b98f7 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -196,8 +196,6 @@ LLConversationLog::LLConversationLog() : keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2)); if (log_mode > 0) { - loadFromFile(getFileName()); - enableLogging(log_mode); } } @@ -483,16 +481,15 @@ bool LLConversationLog::saveToFile(const std::string& filename) // examples of two file entries // [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe| // [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a| - fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n", (S64)conv_it->getTime().value(), (S32)conv_it->getConversationType(), (S32)0, (S32)conv_it->hasOfflineMessages(), - conv_it->getConversationName().c_str(), + conv_it->getConversationName().c_str(), participant_id.c_str(), conversation_id.c_str(), - conv_it->getHistoryFileName().c_str()); + LLURI::escape(conv_it->getHistoryFileName()).c_str()); } fclose(fp); return true; @@ -511,6 +508,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename) LL_WARNS() << "Couldn't open call log list" << filename << LL_ENDL; return false; } + bool purge_required = false; char buffer[MAX_STRING]; char conv_name_buffer[MAX_STRING]; @@ -546,7 +544,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename) .conversation_name(conv_name_buffer) .participant_id(LLUUID(part_id_buffer)) .session_id(LLUUID(conv_id_buffer)) - .history_filename(history_file_name); + .history_filename(LLURI::unescape(history_file_name)); LLConversation conversation(params); @@ -555,6 +553,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename) // being over 30 days old should be purged from the conversation log text file on login. if (conversation.isOlderThan(CONVERSATION_LIFETIME)) { + purge_required = true; continue; } @@ -562,8 +561,11 @@ bool LLConversationLog::loadFromFile(const std::string& filename) } fclose(fp); - LLFile::remove(filename); - cache(); + if(purge_required) + { + LLFile::remove(filename); + cache(); + } notifyObservers(); return true; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1f460c05ec..5222637039 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1016,12 +1016,12 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata) } // static -void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email) +void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, bool is_verified_email) { LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); if (instance) { - instance->setPersonalInfo(visibility, im_via_email); + instance->setPersonalInfo(visibility, im_via_email, is_verified_email); } } @@ -1830,7 +1830,7 @@ bool LLFloaterPreference::moveTranscriptsAndLog() return true; } -void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email) +void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, bool is_verified_email) { mGotPersonalInfo = true; mOriginalIMViaEmail = im_via_email; @@ -1855,8 +1855,16 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im getChildView("friends_online_notify_checkbox")->setEnabled(TRUE); getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility); - getChildView("send_im_to_email")->setEnabled(TRUE); - getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email); + getChildView("send_im_to_email")->setEnabled(is_verified_email); + + std::string tooltip; + if (!is_verified_email) + tooltip = getString("email_unverified_tooltip"); + + getChildView("send_im_to_email")->setToolTip(tooltip); + + // *TODO: Show or hide verify email text here based on is_verified_email + getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email); getChildView("favorites_on_login_check")->setEnabled(TRUE); getChildView("log_path_button")->setEnabled(TRUE); getChildView("chat_font_size")->setEnabled(TRUE); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 2bb2e7e9ff..444ad5a928 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -75,7 +75,7 @@ public: /*virtual*/ void changed(const LLUUID& session_id, U32 mask) {}; // static data update, called from message handler - static void updateUserInfo(const std::string& visibility, bool im_via_email); + static void updateUserInfo(const std::string& visibility, bool im_via_email, bool is_verified_email); // refresh all the graphics preferences menus static void refreshEnabledGraphics(); @@ -147,7 +147,7 @@ public: void onClickLogPath(); bool moveTranscriptsAndLog(); void enableHistory(); - void setPersonalInfo(const std::string& visibility, bool im_via_email); + void setPersonalInfo(const std::string& visibility, bool im_via_email, bool is_verified_email); void refreshEnabledState(); void onCommitWindowedMode(); void refresh(); // Refresh enable/disable diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 1743d0fc69..4de34f13dd 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -75,7 +75,9 @@ BOOL LLFloaterTOS::postBuild() // disable Agree to TOS radio button until the page has fully loaded LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); - tos_agreement->setEnabled( false ); + tos_agreement->setEnabled(false); + LLTextBox* tos_list = getChild<LLTextBox>("agree_list"); + tos_list->setEnabled(false); // hide the SL text widget if we're displaying TOS with using a browser widget. LLUICtrl *editor = getChild<LLUICtrl>("tos_text"); @@ -150,6 +152,8 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) // but if the page is unavailable, we need to do this now LLCheckBoxCtrl* tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); tos_agreement->setEnabled( true ); + LLTextBox* tos_list = getChild<LLTextBox>("agree_list"); + tos_list->setEnabled(true); } } #endif @@ -230,6 +234,8 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev // enable Agree to TOS radio button now that page has loaded LLCheckBoxCtrl * tos_agreement = getChild<LLCheckBoxCtrl>("agree_chk"); tos_agreement->setEnabled( true ); + LLTextBox* tos_list = getChild<LLTextBox>("agree_list"); + tos_list->setEnabled(true); } } } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 67ddd79230..8b50e4248e 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -264,7 +264,9 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc // is limited to 4. // We also take care of degenerated cases so we don't update all folders in the inventory by mistake. - if (cur_uuid.isNull()) + if (cur_uuid.isNull() + || gInventory.getCategory(cur_uuid) == NULL + || gInventory.getCategory(cur_uuid)->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) { return; } @@ -275,9 +277,13 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc { // Retrieve the listing uuid this object is in LLUUID listing_uuid = nested_parent_id(cur_uuid, depth); + LLViewerInventoryCategory* listing_cat = gInventory.getCategory(listing_uuid); + bool listing_cat_loaded = listing_cat != NULL && listing_cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; // Verify marketplace data consistency for this listing - if (perform_consistency_enforcement && LLMarketplaceData::instance().isListed(listing_uuid)) + if (perform_consistency_enforcement + && listing_cat_loaded + && LLMarketplaceData::instance().isListed(listing_uuid)) { LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); S32 version_depth = depth_nesting_in_marketplace(version_folder_uuid); @@ -299,7 +305,9 @@ void update_marketplace_category(const LLUUID& cur_uuid, bool perform_consistenc } // Check if the count on hand needs to be updated on SLM - if (perform_consistency_enforcement && (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) + if (perform_consistency_enforcement + && listing_cat_loaded + && (compute_stock_count(listing_uuid) != LLMarketplaceData::instance().getCountOnHand(listing_uuid))) { LLMarketplaceData::instance().updateCountOnHand(listing_uuid,1); } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index dc75e09ad9..054db2a3ec 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2058,11 +2058,6 @@ bool LLInventoryModel::loadSkeleton( // correct contents the next time the viewer opens the folder. tcat->setVersion(NO_VERSION); } - else if (tcat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) - { - // Do not trust stock folders being updated - tcat->setVersion(NO_VERSION); - } else { cached_ids.insert(tcat->getUUID()); diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 00043d1e72..a8025906c7 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -805,44 +805,8 @@ void LLMediaCtrl::draw() F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth(); F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight(); - LLRect r = getRect(); - S32 width, height; - S32 x_offset = 0; - S32 y_offset = 0; - - if(mStretchToFill) - { - if(mMaintainAspectRatio) - { - F32 media_aspect = (F32)(media_plugin->getWidth()) / (F32)(media_plugin->getHeight()); - F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); - if(media_aspect > view_aspect) - { - // max width, adjusted height - width = r.getWidth(); - height = llmin(llmax(ll_round(width / media_aspect), 0), r.getHeight()); - } - else - { - // max height, adjusted width - height = r.getHeight(); - width = llmin(llmax(ll_round(height * media_aspect), 0), r.getWidth()); - } - } - else - { - width = r.getWidth(); - height = r.getHeight(); - } - } - else - { - width = llmin(media_plugin->getWidth(), r.getWidth()); - height = llmin(media_plugin->getHeight(), r.getHeight()); - } - - x_offset = (r.getWidth() - width) / 2; - y_offset = (r.getHeight() - height) / 2; + S32 x_offset, y_offset, width, height; + calcOffsetsAndSize(&x_offset, &y_offset, &width, &height); // draw the browser gGL.begin( LLRender::QUADS ); @@ -901,8 +865,56 @@ void LLMediaCtrl::draw() //////////////////////////////////////////////////////////////////////////////// // +void LLMediaCtrl::calcOffsetsAndSize(S32 *x_offset, S32 *y_offset, S32 *width, S32 *height) +{ + const LLRect &r = getRect(); + *x_offset = *y_offset = 0; + + if (mStretchToFill) + { + if (mMaintainAspectRatio && mMediaSource && mMediaSource->getMediaPlugin()) + { + F32 media_aspect = (F32)(mMediaSource->getMediaPlugin()->getWidth()) / (F32)(mMediaSource->getMediaPlugin()->getHeight()); + F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); + if (media_aspect > view_aspect) + { + // max width, adjusted height + *width = r.getWidth(); + *height = llmin(llmax(ll_round(*width / media_aspect), 0), r.getHeight()); + } + else + { + // max height, adjusted width + *height = r.getHeight(); + *width = llmin(llmax(ll_round(*height * media_aspect), 0), r.getWidth()); + } + } + else + { + *width = r.getWidth(); + *height = r.getHeight(); + } + } + else + { + *width = llmin(mMediaSource->getMediaPlugin()->getWidth(), r.getWidth()); + *height = llmin(mMediaSource->getMediaPlugin()->getHeight(), r.getHeight()); + } + + *x_offset = (r.getWidth() - *width) / 2; + *y_offset = (r.getHeight() - *height) / 2; +} + +//////////////////////////////////////////////////////////////////////////////// +// void LLMediaCtrl::convertInputCoords(S32& x, S32& y) { + S32 x_offset, y_offset, width, height; + calcOffsetsAndSize(&x_offset, &y_offset, &width, &height); + + x -= x_offset; + y -= y_offset; + bool coords_opengl = false; if(mMediaSource && mMediaSource->hasMedia()) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 125a67e23e..11400c8274 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -181,6 +181,9 @@ public: protected: void convertInputCoords(S32& x, S32& y); + private: + void calcOffsetsAndSize(S32 *x_offset, S32 *y_offset, S32 *width, S32 *height); + private: void onVisibilityChanged ( const LLSD& new_visibility ); void onPopup(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index cca65f2ce1..c38d3ab140 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -72,6 +72,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p) mItemsAddedCount(0), mOutfitLinkPending(NULL), mOutfitRenamePending(NULL), + mSnapshotFolderID(NULL), mRowPanelHeight(p.row_panel_height), mVerticalGap(p.vertical_gap), mHorizontalGap(p.horizontal_gap), @@ -1011,8 +1012,8 @@ void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp) void LLOutfitGallery::loadPhotos() { //Iterate over inventory - LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE); - LLViewerInventoryCategory* textures_category = gInventory.getCategory(textures); + mSnapshotFolderID = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE); + LLViewerInventoryCategory* textures_category = gInventory.getCategory(mSnapshotFolderID); if (!textures_category) return; if (mTexturesObserver == NULL) @@ -1022,12 +1023,26 @@ void LLOutfitGallery::loadPhotos() } // Start observing changes in "Textures" category. - mTexturesObserver->addCategory(textures, - boost::bind(&LLOutfitGallery::refreshTextures, this, textures)); - + mTexturesObserver->addCategory(mSnapshotFolderID, + boost::bind(&LLOutfitGallery::refreshTextures, this, mSnapshotFolderID)); + textures_category->fetch(); } +void LLOutfitGallery::updateSnapshotFolderObserver() +{ + if(mSnapshotFolderID != gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE)) + { + if (gInventory.containsObserver(mTexturesObserver)) + { + gInventory.removeObserver(mTexturesObserver); + } + delete mTexturesObserver; + mTexturesObserver = NULL; + loadPhotos(); + } +} + void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) { LLViewerInventoryCategory* category = gInventory.getCategory(category_id); @@ -1200,7 +1215,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id) LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id); if (!outfit_cat) return; - + updateSnapshotFolderObserver(); checkRemovePhoto(outfit_id); std::string upload_pending_name = outfit_id.asString(); std::string upload_pending_desc = ""; @@ -1372,6 +1387,7 @@ void LLOutfitGallery::onBeforeOutfitSnapshotSave() if (!selected_outfit_id.isNull()) { checkRemovePhoto(selected_outfit_id); + updateSnapshotFolderObserver(); } } diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index b1ca850508..383924a7d6 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -130,6 +130,7 @@ protected: private: void loadPhotos(); void uploadPhoto(LLUUID outfit_id); + void updateSnapshotFolderObserver(); LLUUID getPhotoAssetId(const LLUUID& outfit_id); LLUUID getDefaultPhoto(); void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id); @@ -168,6 +169,7 @@ private: LLPanel* mLastRowPanel; LLUUID mOutfitLinkPending; LLUUID mOutfitRenamePending; + LLUUID mSnapshotFolderID; LLTextBox* mMessageTextBox; bool mGalleryCreated; int mRowCount; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index a16259886d..7e75dca908 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1623,6 +1623,15 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh } } } + else + { + if (shiny_texture_ID.isNull() && comboShiny && comboShiny->itemExists(USE_TEXTURE)) + { + comboShiny->remove(SHINY_TEXTURE); + comboShiny->selectFirstItem(); + } + } + LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); @@ -2368,8 +2377,8 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp) { LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL; - LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); - if(radio_mat_type) + LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type"); + if(!radio_mat_type) { return; } diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index a88c10521c..0bcbdf7e67 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -75,6 +75,7 @@ LLPanelLogin *LLPanelLogin::sInstance = NULL; BOOL LLPanelLogin::sCapslockDidNotification = FALSE; +BOOL LLPanelLogin::sCredentialSet = FALSE; class LLLoginLocationAutoHandler : public LLCommandHandler { @@ -176,6 +177,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, setBackgroundOpaque(TRUE); mPasswordModified = FALSE; + LLPanelLogin::sInstance = this; LLView* login_holder = gViewerWindow->getLoginPanelHolder(); @@ -458,6 +460,7 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential, LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL; return; } + sCredentialSet = TRUE; LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL; LLSD identifier = credential->getIdentifier(); @@ -680,10 +683,8 @@ void LLPanelLogin::onUpdateStartSLURL(const LLSLURL& new_start_slurl) } if ( new_start_slurl.getLocationString().length() ) { - if (location_combo->getCurrentIndex() == -1) - { - location_combo->setLabel(new_start_slurl.getLocationString()); - } + + location_combo->setLabel(new_start_slurl.getLocationString()); sInstance->mLocationLength = new_start_slurl.getLocationString().length(); sInstance->updateLoginButtons(); } @@ -862,6 +863,7 @@ void LLPanelLogin::onClickConnect(void *) } else { + sCredentialSet = FALSE; LLPointer<LLCredential> cred; BOOL remember; getFields(cred, remember); diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 869f2f8d39..82ef048493 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -56,9 +56,11 @@ public: void* callback_data); static void setFields(LLPointer<LLCredential> credential, BOOL remember); - + static void getFields(LLPointer<LLCredential>& credential, BOOL& remember); + static BOOL isCredentialSet() { return sCredentialSet; } + static BOOL areCredentialFieldsDirty(); static void setLocation(const LLSLURL& slurl); static void autologinToLocation(const LLSLURL& slurl); @@ -115,6 +117,8 @@ private: static LLPanelLogin* sInstance; static BOOL sCapslockDidNotification; bool mFirstLoginThisInstall; + + static BOOL sCredentialSet; unsigned int mUsernameLength; unsigned int mPasswordLength; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index c9f8683e0e..b1895bfc9b 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -710,22 +710,20 @@ void LLPanelVolume::onLightCancelColor(const LLSD& data) void LLPanelVolume::onLightCancelTexture(const LLSD& data) { LLTextureCtrl* LightTextureCtrl = getChild<LLTextureCtrl>("light texture control"); - - if (LightTextureCtrl) - { - LightTextureCtrl->setImageAssetID(mLightSavedTexture); - } - LLVOVolume *volobjp = (LLVOVolume *) mObject.get(); - if(volobjp) + + if (volobjp && LightTextureCtrl) { // Cancel the light texture as requested // NORSPEC-292 - // + // + // Texture picker triggers cancel both in case of actual cancel and in case of + // selection of "None" texture. + LLUUID tex_id = LightTextureCtrl->getImageAssetID(); bool is_spotlight = volobjp->isLightSpotlight(); - volobjp->setLightTextureID(mLightSavedTexture); //updates spotlight + volobjp->setLightTextureID(tex_id); //updates spotlight - if (!is_spotlight && mLightSavedTexture.notNull()) + if (!is_spotlight && tex_id.notNull()) { LLVector3 spot_params = volobjp->getSpotLightParams(); getChild<LLUICtrl>("Light FOV")->setValue(spot_params.mV[0]); @@ -769,7 +767,6 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data) { LLUUID id = LightTextureCtrl->getImageAssetID(); volobjp->setLightTextureID(id); - mLightSavedTexture = id; } } diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index deb6b6f2a6..e3453ae99c 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -111,7 +111,6 @@ protected: LLColor4 mLightSavedColor; - LLUUID mLightSavedTexture; LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 850c3b350d..d4a8bbdf45 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -163,6 +163,16 @@ BOOL LLPreviewNotecard::canClose() } } +/* virtual */ +void LLPreviewNotecard::setObjectID(const LLUUID& object_id) +{ + LLPreview::setObjectID(object_id); + + LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); + editor->setNotecardObjectID(mObjectUUID); + editor->makePristine(); +} + const LLInventoryItem* LLPreviewNotecard::getDragItem() { LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 017c4485ba..46a6d0ef50 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -47,6 +47,7 @@ public: virtual ~LLPreviewNotecard(); bool saveItem(); + void setObjectID(const LLUUID& object_id); // llview virtual void draw(); diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index b2c450aa0c..da912ef3d4 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -349,8 +349,8 @@ void LLScriptFloater::hideToastsIfNeeded() ////////////////////////////////////////////////////////////////////////// LLScriptFloaterManager::LLScriptFloaterManager() + : mDialogLimitationsSlot() { - gSavedSettings.getControl("ScriptDialogLimitations")->getCommitSignal()->connect(boost::bind(&clearScriptNotifications)); } void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) @@ -361,6 +361,19 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) return; } + if (!mDialogLimitationsSlot.connected()) + { + LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl("ScriptDialogLimitations"); + if (cntrl_ptr.notNull()) + { + mDialogLimitationsSlot = cntrl_ptr->getCommitSignal()->connect(boost::bind(&clearScriptNotifications)); + } + else + { + LL_WARNS() << "Unable to set signal on setting 'ScriptDialogLimitations'" << LL_ENDL; + } + } + // get scripted Object's ID LLUUID object_id = notification_id_to_object_id(notification_id); diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h index 0192a8893e..3695b8a3e1 100644 --- a/indra/newview/llscriptfloater.h +++ b/indra/newview/llscriptfloater.h @@ -139,6 +139,7 @@ private: typedef std::map<LLUUID, FloaterPositionInfo> floater_position_map_t; floater_position_map_t mFloaterPositions; + boost::signals2::connection mDialogLimitationsSlot; }; /** diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8295ce029b..df1d2a3946 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -766,7 +766,7 @@ bool idle_startup() // Show the login dialog login_show(); // connect dialog is already shown, so fill in the names - if (gUserCredential.notNull()) + if (gUserCredential.notNull() && !LLPanelLogin::isCredentialSet()) { LLPanelLogin::setFields( gUserCredential, gRememberPassword); } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index f0c28041d1..71d3731f93 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -53,6 +53,7 @@ const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate) const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD; +const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .01f; // 10ms class LLTextureCacheWorker : public LLWorkerClass { @@ -550,9 +551,11 @@ bool LLTextureCacheRemoteWorker::doWrite() { if ((mOffset != 0) // We currently do not support write offsets || (mDataSize <= 0) // Things will go badly wrong if mDataSize is nul or negative... - || (mImageSize < mDataSize)) + || (mImageSize < mDataSize) + || (mRawDiscardLevel < 0) + || (mRawImage->isBufferInvalid())) // decode failed or malfunctioned, don't write { - LL_WARNS() << "INIT state check failed" << LL_ENDL; + LL_WARNS() << "INIT state check failed for image: " << mID << " Size: " << mImageSize << " DataSize: " << mDataSize << " Discard:" << mRawDiscardLevel << LL_ENDL; mDataSize = -1; // failed done = true; } @@ -577,15 +580,12 @@ bool LLTextureCacheRemoteWorker::doWrite() idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry. if(idx >= 0) { - // (almost always) write to the fast cache. - if (mRawImage->getDataSize()) + // write to the fast cache. + if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)) { - if(!mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel)) - { - LL_WARNS() << "writeToFastCache failed" << LL_ENDL; - mDataSize = -1; // failed - done = true; - } + LL_WARNS() << "writeToFastCache failed" << LL_ENDL; + mDataSize = -1; // failed + done = true; } } } @@ -1635,6 +1635,92 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) LL_INFOS() << "The entire texture cache is cleared." << LL_ENDL ; } +void LLTextureCache::purgeTexturesLazy(F32 time_limit) +{ + if (mReadOnly) + { + return; + } + + if (!mThreaded) + { + // *FIX:Mani - watchdog off. + LLAppViewer::instance()->pauseMainloopTimeout(); + } + + // time_limit doesn't account for lock time + LLMutexLock lock(&mHeaderMutex); + + if (mPurgeEntryList.empty()) + { + // Read the entries list and form list of textures to purge + std::vector<Entry> entries; + U32 num_entries = openAndReadEntries(entries); + if (!num_entries) + { + return; // nothing to purge + } + + // Use mTexturesSizeMap to collect UUIDs of textures with bodies + typedef std::set<std::pair<U32, S32> > time_idx_set_t; + std::set<std::pair<U32, S32> > time_idx_set; + for (size_map_t::iterator iter1 = mTexturesSizeMap.begin(); + iter1 != mTexturesSizeMap.end(); ++iter1) + { + if (iter1->second > 0) + { + id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first); + if (iter2 != mHeaderIDMap.end()) + { + S32 idx = iter2->second; + time_idx_set.insert(std::make_pair(entries[idx].mTime, idx)); + } + else + { + LL_ERRS() << "mTexturesSizeMap / mHeaderIDMap corrupted." << LL_ENDL; + } + } + } + + S64 cache_size = mTexturesSizeTotal; + S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100; + for (time_idx_set_t::iterator iter = time_idx_set.begin(); + iter != time_idx_set.end(); ++iter) + { + S32 idx = iter->second; + if (cache_size >= purged_cache_size) + { + cache_size -= entries[idx].mBodySize; + mPurgeEntryList.push_back(std::pair<S32, Entry>(idx, entries[idx])); + } + else + { + break; + } + } + LL_DEBUGS() << "Formed Purge list of " << mPurgeEntryList.size() << " entries" << LL_ENDL; + } + else + { + // Remove collected entried + LLTimer timer; + while (!mPurgeEntryList.empty() && timer.getElapsedTimeF32() < time_limit) + { + S32 idx = mPurgeEntryList.back().first; + Entry entry = mPurgeEntryList.back().second; + mPurgeEntryList.pop_back(); + // make sure record is still valid + id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID); + if (iter_header != mHeaderIDMap.end() && iter_header->second == idx) + { + std::string tex_filename = getTextureFileName(entry.mID); + removeEntry(idx, entry, tex_filename); + writeEntryToHeaderImmediately(idx, entry); + } + } + } +} + void LLTextureCache::purgeTextures(bool validate) { if (mReadOnly) @@ -1793,24 +1879,27 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry) S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize) { mHeaderMutex.lock(); - S32 idx = openAndReadEntry(id, entry, true); + S32 idx = openAndReadEntry(id, entry, true); // read or create mHeaderMutex.unlock(); - if (idx >= 0) - { - updateEntry(idx, entry, imagesize, datasize); - } - - if(idx < 0) // retry + if(idx < 0) // retry once { readHeaderCache(); // We couldn't write an entry, so refresh the LRU - + mHeaderMutex.lock(); - llassert_always(!mLRU.empty() || mHeaderEntriesInfo.mEntries < sCacheMaxEntries); + idx = openAndReadEntry(id, entry, true); mHeaderMutex.unlock(); + } - idx = setHeaderCacheEntry(id, entry, imagesize, datasize); // assert above ensures no inf. recursion + if (idx >= 0) + { + updateEntry(idx, entry, imagesize, datasize); } + else + { + LL_WARNS() << "Failed to set cache entry for image: " << id << LL_ENDL; + } + return idx; } @@ -1888,11 +1977,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio } if (mDoPurge) { - // NOTE: This may cause an occasional hiccup, - // but it really needs to be done on the control thread - // (i.e. here) - purgeTextures(false); - mDoPurge = FALSE; + // NOTE: Needs to be done on the control thread + // (i.e. here) + purgeTexturesLazy(TEXTURE_LAZY_PURGE_TIME_LIMIT); + mDoPurge = !mPurgeEntryList.empty(); } LLMutexLock lock(&mWorkersMutex); LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id, diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index 95f9afc2bc..bcc27c6598 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -155,6 +155,7 @@ private: void readHeaderCache(); void clearCorruptedCache(); void purgeAllTextures(bool purge_directories); + void purgeTexturesLazy(F32 time_limit); void purgeTextures(bool validate); LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset); void closeHeaderEntriesFile(); @@ -225,6 +226,8 @@ private: typedef std::map<S32, Entry> idx_entry_map_t; idx_entry_map_t mUpdatedEntryMap; + typedef std::vector<std::pair<S32, Entry> > idx_entry_vector_t; + idx_entry_vector_t mPurgeEntryList; // Statics static F32 sHeaderCacheVersion; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index bfa9fa03fa..6d4fc94b63 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -441,6 +441,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); + gViewerWindow->setProgressMessage(gAgent.mMOTD); break; case LLAgent::TELEPORT_REQUESTED: @@ -518,6 +519,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } gViewerWindow->setProgressPercent( percent_done ); + gViewerWindow->setProgressMessage(std::string()); } else if (gRestoreGL) @@ -539,6 +541,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gViewerWindow->setProgressPercent( percent_done ); } + gViewerWindow->setProgressMessage(std::string()); } ////////////////////////// diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 1ce18f5496..2144c7d481 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5664,7 +5664,8 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) args["NAME"] = source_slurl; is_name_group = is_source_group; name_id = source_id; - if (!reason.empty()) + + if (!reason.empty() && !LLMuteList::getInstance()->isMuted(source_id)) { message = LLTrans::getString("paid_you_ldollars" + gift_suffix, args); } @@ -7258,7 +7259,7 @@ void send_places_query(const LLUUID& query_id, gAgent.sendReliableMessage(); } - +// Deprecated in favor of cap "UserInfo" void process_user_info_reply(LLMessageSystem* msg, void**) { LLUUID agent_id; @@ -7276,7 +7277,8 @@ void process_user_info_reply(LLMessageSystem* msg, void**) std::string dir_visibility; msg->getString( "UserData", "DirectoryVisibility", dir_visibility); - LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email); + // For Message based user info information the is_verified is assumed to be false. + LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, false); LLFloaterSnapshot::setAgentEmail(email); } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 3fd2af87de..3f479802aa 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2896,6 +2896,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); + capabilityNames.append("UserInfo"); capabilityNames.append("ViewerAsset"); capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h index 33cfca4f90..44f104dde1 100644 --- a/indra/newview/llviewertexteditor.h +++ b/indra/newview/llviewertexteditor.h @@ -71,7 +71,8 @@ public: mObjectID = object_id; mPreviewID = preview_id; } - + void setNotecardObjectID(const LLUUID& object_id){ mObjectID = object_id;} + void setASCIIEmbeddedText(const std::string& instr); void setEmbeddedText(const std::string& instr); std::string getEmbeddedText(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index b052a48424..7b4895b862 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4379,6 +4379,8 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke else pick_type = LLFilePicker::FFSAVE_ALL; // ??? + BOOL is_snapshot_name_loc_set = isSnapshotLocSet(); + // Get a base file location if needed. if (force_picker || !isSnapshotLocSet()) { @@ -4427,7 +4429,12 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke filepath = sSnapshotDir; filepath += gDirUtilp->getDirDelimiter(); filepath += sSnapshotBaseName; - filepath += llformat("_%.3d",i); + + if (is_snapshot_name_loc_set) + { + filepath += llformat("_%.3d",i); + } + filepath += extension; llstat stat_info; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index efcdb07176..cc708ea275 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7025,7 +7025,7 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse record["elapsed"] = elapsed; record["completed"] = completed; U32 grid_x(0), grid_y(0); - if (getRegion()) + if (getRegion() && LLWorld::instance().isRegionListed(getRegion())) { record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion()); grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y); diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index 5ca527ad20..845c1efe4d 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -11,6 +11,12 @@ single_instance="true" title="PREFERENCES" width="658"> + <floater.string + name="email_unverified_tooltip"> + Please verify your email to enable IM to Email by visiting +https://accounts.secondlife.com/change_email/ + </floater.string> + <button follows="right|bottom" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index e3b49bf917..0d52a5652d 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -74,7 +74,9 @@ name="agree_list" top_delta="15" word_wrap="true" - width="552">the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements. + width="552" + text_color="LabelTextColor" + text_readonly_color="LabelDisabledColor">the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements. </text> <button enabled="false" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index ee1ff372a7..9af4b299de 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -3991,7 +3991,8 @@ http://secondlife.com/download. <notification icon="alertmodal.tga" name="UpdaterServiceNotRunning" - type="alertmodal"> + type="alertmodal" + force_urls_external="true"> There is a required update for your Second Life Installation. You may download this update from http://www.secondlife.com/downloads |