diff --git a/doc/contributions.txt b/doc/contributions.txt index cee8646d22..2541acea87 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -830,6 +830,7 @@ Kitty Barnett MAINT-6154 MAINT-6568 STORM-2149 + MAINT-7581 Kolor Fall Komiko Okamoto Korvel Noh diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index f518812261..598fd70c71 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -67,7 +67,8 @@ LLNotificationForm::FormIgnore::FormIgnore() : text("text"), control("control"), invert_control("invert_control", false), - save_option("save_option", false) + save_option("save_option", false), + session_only("session_only", false) {} LLNotificationForm::FormButton::FormButton() @@ -126,6 +127,7 @@ bool handleIgnoredNotification(const LLSD& payload) switch(form->getIgnoreType()) { case LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE: + case LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY: response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON); break; case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE: @@ -198,7 +200,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica if (!p.ignore.save_option) { - mIgnore = IGNORE_WITH_DEFAULT_RESPONSE; + mIgnore = p.ignore.session_only ? IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY : IGNORE_WITH_DEFAULT_RESPONSE; } else { @@ -1808,6 +1810,12 @@ bool LLNotifications::getIgnoreAllNotifications() return mIgnoreAllNotifications; } +void LLNotifications::setIgnored(const std::string& name, bool ignored) +{ + LLNotificationTemplatePtr templatep = getTemplate(name); + templatep->mForm->setIgnored(ignored); +} + bool LLNotifications::getIgnored(const std::string& name) { LLNotificationTemplatePtr templatep = getTemplate(name); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 0a74b2cac0..02036e4ff6 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -180,6 +180,7 @@ public: Optional save_option; Optional control; Optional invert_control; + Optional session_only; FormIgnore(); }; @@ -234,7 +235,8 @@ public: typedef enum e_ignore_type { IGNORE_NO, - IGNORE_WITH_DEFAULT_RESPONSE, + IGNORE_WITH_DEFAULT_RESPONSE, + IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY, IGNORE_WITH_LAST_RESPONSE, IGNORE_SHOW_AGAIN } EIgnoreType; @@ -970,6 +972,7 @@ public: void setIgnoreAllNotifications(bool ignore); bool getIgnoreAllNotifications(); + void setIgnored(const std::string& name, bool ignored); bool getIgnored(const std::string& name); bool isVisibleByRules(LLNotificationPtr pNotification); diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 2d342bf630..ceb90084cc 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -465,11 +465,13 @@ public: if (gAgent.isInGroup(mSessionID)) { LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); - const LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()); - - if (NULL != speakerp) + if(speaker_mgr) { - return !speakerp->mModeratorMutedText; + const LLSpeaker * speakerp = speaker_mgr->findSpeaker(getAvatarId()); + if (NULL != speakerp) + { + return !speakerp->mModeratorMutedText; + } } } return false; diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp index 3f80d6f1a4..10cce3bd22 100644 --- a/indra/newview/llfloaterlinkreplace.cpp +++ b/indra/newview/llfloaterlinkreplace.cpp @@ -41,16 +41,13 @@ LLFloaterLinkReplace::LLFloaterLinkReplace(const LLSD& key) mRemainingItems(0), mSourceUUID(LLUUID::null), mTargetUUID(LLUUID::null), - mInstance(NULL), mBatchSize(gSavedSettings.getU32("LinkReplaceBatchSize")) { mEventTimer.stop(); - mInstance = this; } LLFloaterLinkReplace::~LLFloaterLinkReplace() { - mInstance = NULL; } BOOL LLFloaterLinkReplace::postBuild() @@ -180,11 +177,9 @@ void LLFloaterLinkReplace::onStartClicked() } } -void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id, - const LLUUID& target_item_id, - bool needs_wearable_ordering_update, - bool needs_description_update, - const LLUUID& outfit_folder_id) +// static +void LLFloaterLinkReplace::linkCreatedCallback(LLHandle floater_handle, const LLUUID& old_item_id, const LLUUID& target_item_id, + bool needs_wearable_ordering_update, bool needs_description_update, const LLUUID& outfit_folder_id) { LL_DEBUGS() << "Inventory link replace:" << LL_NEWLINE << " - old_item_id = " << old_item_id.asString() << LL_NEWLINE @@ -239,20 +234,21 @@ void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id, outfit_update_folder = outfit_folder_id; } - LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, this, outfit_update_folder)); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, floater_handle, outfit_update_folder)); remove_inventory_object(old_item_id, cb); } -void LLFloaterLinkReplace::itemRemovedCallback(const LLUUID& outfit_folder_id) +// static +void LLFloaterLinkReplace::itemRemovedCallback(LLHandle floater_handle, const LLUUID& outfit_folder_id) { if (outfit_folder_id.notNull()) { LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(outfit_folder_id); } - if (mInstance) + if (!floater_handle.isDead()) { - decreaseOpenItemCount(); + floater_handle.get()->decreaseOpenItemCount(); } } @@ -324,7 +320,7 @@ void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items) LLInventoryObject::const_object_list_t obj_array; obj_array.push_back(LLConstPointer(target_item)); LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::linkCreatedCallback, - this, + getDerivedHandle(), source_item->getUUID(), target_item->getUUID(), needs_wearable_ordering_update, diff --git a/indra/newview/llfloaterlinkreplace.h b/indra/newview/llfloaterlinkreplace.h index 377dd1d450..dd5c301206 100644 --- a/indra/newview/llfloaterlinkreplace.h +++ b/indra/newview/llfloaterlinkreplace.h @@ -98,12 +98,9 @@ private: void updateFoundLinks(); void processBatch(LLInventoryModel::item_array_t items); - void linkCreatedCallback(const LLUUID& old_item_id, - const LLUUID& target_item_id, - bool needs_wearable_ordering_update, - bool needs_description_update, - const LLUUID& outfit_folder_id); - void itemRemovedCallback(const LLUUID& outfit_folder_id); + static void linkCreatedCallback(LLHandle floater_handle, const LLUUID& old_item_id, const LLUUID& target_item_id, + bool needs_wearable_ordering_update, bool needs_description_update, const LLUUID& outfit_folder_id); + static void itemRemovedCallback(LLHandle floater_handle, const LLUUID& outfit_folder_id); void onSourceItemDrop(const LLUUID& source_item_id); void onTargetItemDrop(const LLUUID& target_item_id); @@ -120,8 +117,6 @@ private: U32 mBatchSize; LLInventoryModel::item_array_t mRemainingInventoryItems; - - LLFloaterLinkReplace* mInstance; }; #endif // LL_FLOATERLINKREPLACE_H diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 3fa1e782fb..7ec6bee909 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -100,8 +100,6 @@ BOOL LLInventoryState::sWearNewClothing = FALSE; LLUUID LLInventoryState::sWearNewClothingTransactionID; std::list LLInventoryAction::sMarketplaceFolders; -const int LLInventoryAction::sConfirmOnDeleteItemsNumber = 5; - // Helper function : callback to update a folder after inventory action happened in the background void update_folder_cb(const LLUUID& dest_folder) { @@ -2430,29 +2428,6 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root if ("delete" == action) { static bool sDisplayedAtSession = false; - - bool has_folder_items = false; - for (std::set::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter) - { - LLFolderViewModelItemInventory * viewModel = dynamic_cast((*set_iter)->getViewModelItem()); - if (viewModel && viewModel->hasChildren()) - { - has_folder_items = true; - break; - } - } - if (root->getSelectedCount() >= sConfirmOnDeleteItemsNumber || has_folder_items) - { - bool ignore = !(LLUI::sSettingGroups["ignores"]->getBOOL("DeleteItems")); - if (ignore) - { - if (!sDisplayedAtSession) - { - LLUI::sSettingGroups["ignores"]->setBOOL("DeleteItems", TRUE); - sDisplayedAtSession = true; - } - } - } LLAllDescendentsPassedFilter f; for (std::set::iterator it = selected_items.begin(); (it != selected_items.end()) && (f.allDescendentsPassedFilter()); ++it) @@ -2462,7 +2437,6 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root folder->applyFunctorRecursively(f); } } - // Fall through to the generic confirmation if the user choose to ignore the specialized one if ( (!f.allDescendentsPassedFilter()) && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) ) { @@ -2470,6 +2444,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } else { + if (!sDisplayedAtSession) // ask for the confirmation at least once per session + { + LLNotifications::instance().setIgnored("DeleteItems", false); + sDisplayedAtSession = true; + } + LLSD args; args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" : "DeleteItem"); LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle())); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0ef21bccfc..3dbc4f1581 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1669,7 +1669,12 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) LLMeshRepository::sCacheBytesRead += size; ++LLMeshRepository::sCacheReads; file.seek(offset); - U8* buffer = new U8[size]; + U8* buffer = new(std::nothrow) U8[size]; + if (!buffer) + { + LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh LOD" << LL_ENDL; + return false; + } file.read(buffer, size); //make sure buffer isn't all 0's by checking the first 1KB (reserved block but not written) diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 8241254457..2ca590a4ba 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -219,19 +219,21 @@ void LLPanelClassifiedInfo::onOpen(const LLSD& key) LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId()); gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough); - // While we're at it let's get the stats from the new table if that - // capability exists. - std::string url = gAgent.getRegion()->getCapability("SearchStatRequest"); - if (!url.empty()) + if (gAgent.getRegion()) { - LL_INFOS() << "Classified stat request via capability" << LL_ENDL; - LLSD body; - LLUUID classifiedId = getClassifiedId(); - body["classified_id"] = classifiedId; - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, - boost::bind(&LLPanelClassifiedInfo::handleSearchStatResponse, classifiedId, _1)); + // While we're at it let's get the stats from the new table if that + // capability exists. + std::string url = gAgent.getRegion()->getCapability("SearchStatRequest"); + if (!url.empty()) + { + LL_INFOS() << "Classified stat request via capability" << LL_ENDL; + LLSD body; + LLUUID classifiedId = getClassifiedId(); + body["classified_id"] = classifiedId; + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body, + boost::bind(&LLPanelClassifiedInfo::handleSearchStatResponse, classifiedId, _1)); + } } - // Update classified click stats. // *TODO: Should we do this when opening not from search? sendClickMessage("profile"); @@ -559,21 +561,24 @@ void LLPanelClassifiedInfo::sendClickMessage( const LLVector3d& global_pos, const std::string& sim_name) { - // You're allowed to click on your own ads to reassure yourself - // that the system is working. - LLSD body; - body["type"] = type; - body["from_search"] = from_search; - body["classified_id"] = classified_id; - body["parcel_id"] = parcel_id; - body["dest_pos_global"] = global_pos.getValue(); - body["region_name"] = sim_name; + if (gAgent.getRegion()) + { + // You're allowed to click on your own ads to reassure yourself + // that the system is working. + LLSD body; + body["type"] = type; + body["from_search"] = from_search; + body["classified_id"] = classified_id; + body["parcel_id"] = parcel_id; + body["dest_pos_global"] = global_pos.getValue(); + body["region_name"] = sim_name; - std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); - LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL; - LL_INFOS() << "body: [" << body << "]" << LL_ENDL; - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, - "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent."); + std::string url = gAgent.getRegion()->getCapability("SearchStatTracking"); + LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL; + LL_INFOS() << "body: [" << body << "]" << LL_ENDL; + LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, + "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent."); + } } void LLPanelClassifiedInfo::sendClickMessage(const std::string& type) diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 9d4a798e61..c784bd10f2 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -2322,6 +2322,7 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) mScriptEd->sync(); } + if (!gAgent.getRegion()) return; const LLInventoryItem *inv_item = getItem(); // save it out to asset server std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 73cddd60cf..e1b2fa670d 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -46,6 +46,8 @@ #include "lltransientfloatermgr.h" #include "llviewercontrol.h" // for gSavedSettings +#include + const S32 MAX_ALLOWED_MSG_WIDTH = 400; const F32 DEFAULT_BUTTON_DELAY = 0.5f; @@ -365,6 +367,10 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal { setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label); } + if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY) + { + setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label); + } else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE) { setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label); @@ -399,15 +405,18 @@ bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std:: const LLFontGL* font = mCheck->getFont(); const S32 LINE_HEIGHT = font->getLineHeight(); + + std::vector lines; + boost::split(lines, check_title, boost::is_any_of("\n")); // Extend dialog for "check next time" S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD; - S32 check_width = S32(font->getWidth(check_title) + 0.99f) + 16; + S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line max_msg_width = llmax(max_msg_width, check_width); S32 dialog_width = max_msg_width + 2 * HPAD; S32 dialog_height = LLToastPanel::getRect().getHeight(); - dialog_height += LINE_HEIGHT; + dialog_height += LINE_HEIGHT * lines.size(); dialog_height += LINE_HEIGHT / 2; LLToastPanel::reshape( dialog_width, dialog_height, FALSE ); @@ -416,7 +425,7 @@ bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std:: // set check_box's attributes LLRect check_rect; - mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT)); + mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT*lines.size())); mCheck->setLabel(check_title); mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1)); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 8e6b9db40d..fd8e405d79 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5,6 +5,11 @@ Do not show me this again + +Don't show me this again +(for current session) + + Always choose this option @@ -6294,11 +6299,20 @@ You cannot undo this action. [QUESTION] confirm - +
+ +