diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a7644e7a7b..e06affab37 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -4118,7 +4118,7 @@ bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w { height = 0; width = 0; - if (num_chars > 0) + if (num_chars > 0 && (mStart + first_char >= 0)) { height = mFontHeight; const LLWString &text = getWText(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ffd8a85838..34af7617ea 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -61,6 +61,7 @@ #include "lllocationhistory.h" #include "llgltfmateriallist.h" #include "llimageworker.h" +#include "llregex.h" #include "llloginflags.h" #include "llmd5.h" @@ -3491,6 +3492,27 @@ void release_notes_coro(const std::string url) LLWeb::loadURLInternal(url); } +void validate_release_notes_coro(const std::string url) +{ + LLVersionInfo& versionInfo(LLVersionInfo::instance()); + const boost::regex version_regex(R"(\b\d+\.\d+\.\d+\.\d+\b)"); + + if (url.find(versionInfo.getVersion()) == std::string::npos // has no our build version + && ll_regex_search(url, version_regex)) // has any version + { + LL_INFOS() << "Received release notes url \"" << url << "\" wwith mismatching build, falling back to locally generated url" << LL_ENDL; + // Updater only provides notes for a most recent version, if it is not + // the current one, fall back to the hardcoded URL. + LLSD info(LLAppViewer::instance()->getViewerInfo()); + std::string alt_url = info["VIEWER_RELEASE_NOTES_URL"].asString(); + release_notes_coro(alt_url); + } + else + { + release_notes_coro(url); + } +} + /** * Check if user is running a new version of the viewer. * Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting. @@ -3524,7 +3546,7 @@ void show_release_notes_if_required() "showrelnotes", [](const LLSD& url) { LLCoros::instance().launch("releaseNotesCoro", - boost::bind(&release_notes_coro, url.asString())); + boost::bind(&validate_release_notes_coro, url.asString())); return false; }); } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 5b2b5ffbd9..f8a9e653cc 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -188,6 +188,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mOnUpdateImageStatsCallback(NULL), mBakeTextureEnabled(false), mLocalTextureEnabled(false), + mNoCopyTextureSelected(false), mInventoryPickType(pick_type) { setTentative(tentative); @@ -301,6 +302,7 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti if (set_selection) { + // This is going to cause a callback mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); } } @@ -666,7 +668,6 @@ bool LLFloaterTexturePicker::postBuild() refreshInventoryFilter(); mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); - mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS); // Disable auto selecting first filtered item because it takes away @@ -685,8 +686,25 @@ bool LLFloaterTexturePicker::postBuild() if(!mImageAssetID.isNull() || mInventoryPickType == PICK_MATERIAL) { - mInventoryPanel->setSelection(findItemID(mImageAssetID, false), TAKE_FOCUS_NO); + LLViewerInventoryItem* itemp = findInvItem(mImageAssetID, false); + LLUUID item_id; + if (itemp) + { + item_id = itemp->getUUID(); + } + + mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); + + if (item_id.notNull() && itemp) + { + if (!itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + mNoCopyTextureSelected = true; + } + } } + // Don't call before setSelection, setSelection will mark view as dirty + mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); } childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); @@ -875,12 +893,12 @@ void LLFloaterTexturePicker::draw() } } -const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library) +LLViewerInventoryItem* LLFloaterTexturePicker::findInvItem(const LLUUID& asset_id, bool copyable_only, bool ignore_library) const { if (asset_id.isNull()) { // null asset id means, no material or texture assigned - return LLUUID::null; + return nullptr; } LLUUID loockup_id = asset_id; @@ -920,30 +938,41 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, bool co // search for copyable version first for (S32 i = 0; i < items.size(); i++) { - LLInventoryItem* itemp = items[i]; + LLViewerInventoryItem* itemp = items[i]; LLPermissions item_permissions = itemp->getPermissions(); if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) { - if(!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(),gInventory.getLibraryRootFolderID())) + if (!ignore_library || !gInventory.isObjectDescendentOf(itemp->getUUID(), gInventory.getLibraryRootFolderID())) { - return itemp->getUUID(); + return itemp; } } } // otherwise just return first instance, unless copyable requested if (copyable_only) { - return LLUUID::null; + return nullptr; } else { - if(!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(),gInventory.getLibraryRootFolderID())) + if (!ignore_library || !gInventory.isObjectDescendentOf(items[0]->getUUID(), gInventory.getLibraryRootFolderID())) { - return items[0]->getUUID(); + return items[0]; } } } + return nullptr; +} + +const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library) const +{ + LLViewerInventoryItem* itemp = findInvItem(asset_id, copyable_only, ignore_library); + if (itemp) + { + return itemp->getUUID(); + } + return LLUUID::null; } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 82e7c7367a..6a9892bd55 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -369,7 +369,7 @@ public: void setImageID(const LLUUID& image_asset_id, bool set_selection = true); bool updateImageStats(); // true if within limits const LLUUID& getAssetID() { return mImageAssetID; } - const LLUUID& findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false); + const LLUUID& findItemID(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false) const; void setCanApplyImmediately(bool b); void setActive(bool active); @@ -430,6 +430,7 @@ protected: void refreshLocalList(); void refreshInventoryFilter(); void setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection = true); + LLViewerInventoryItem* findInvItem(const LLUUID& asset_id, bool copyable_only, bool ignore_library = false) const; LLPointer mTexturep; LLPointer mGLTFMaterial;