From 6a02f5bbcec2b1a530ceeacb0dc564cfeb7cbc7f Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 11 Dec 2015 19:58:08 +0200
Subject: Initial version of Visual Outfit Browser

---
 indra/llui/llfocusmgr.cpp                          |    1 -
 indra/llui/lllayoutstack.cpp                       |    2 +-
 indra/newview/CMakeLists.txt                       |    2 +
 indra/newview/lloutfitgallery.cpp                  |  699 +++++++++++
 indra/newview/lloutfitgallery.h                    |  152 +++
 indra/newview/lloutfitslist.cpp                    | 1234 +++++++++++++-------
 indra/newview/lloutfitslist.h                      |  204 +++-
 indra/newview/llpaneloutfitsinventory.cpp          |    6 +
 indra/newview/llpaneloutfitsinventory.h            |    4 +-
 indra/newview/lltexturectrl.cpp                    |    2 +
 indra/newview/skins/default/textures/textures.xml  |    1 +
 .../skins/default/xui/en/floater_snapshot.xml      |    4 +-
 .../skins/default/xui/en/menu_outfit_gear.xml      |   16 +-
 .../skins/default/xui/en/panel_outfit_gallery.xml  |  128 ++
 .../default/xui/en/panel_outfit_gallery_item.xml   |   49 +
 .../default/xui/en/panel_outfits_inventory.xml     |   11 +
 16 files changed, 2022 insertions(+), 493 deletions(-)
 create mode 100644 indra/newview/lloutfitgallery.cpp
 create mode 100644 indra/newview/lloutfitgallery.h
 create mode 100644 indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml

diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 547f0bd398..87c50ad465 100755
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -168,7 +168,6 @@ void LLFocusMgr::releaseFocusIfNeeded( LLView* view )
 	LLUI::removePopup(view);
 }
 
-
 void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL keystrokes_only)
 {
 	// notes if keyboard focus is changed again (by onFocusLost/onFocusReceived)
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 69246a2f57..11769760aa 100755
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -283,7 +283,7 @@ void LLLayoutStack::removeChild(LLView* view)
 	if (embedded_panelp)
 	{
 		mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
-		delete embedded_panelp;
+		//delete embedded_panelp;
 		updateFractionalSizes();
 		mNeedsLayout = true;
 	}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 536c7740bb..f18d9f04f9 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -414,6 +414,7 @@ set(viewer_SOURCE_FILES
     llnotificationscripthandler.cpp
     llnotificationstorage.cpp
     llnotificationtiphandler.cpp
+    lloutfitgallery.cpp
     lloutfitslist.cpp
     lloutfitobserver.cpp
     lloutputmonitorctrl.cpp
@@ -1024,6 +1025,7 @@ set(viewer_HEADER_FILES
     llnotificationhandler.h
     llnotificationmanager.h
     llnotificationstorage.h
+    lloutfitgallery.h
     lloutfitslist.h
     lloutfitobserver.h
     lloutputmonitorctrl.h
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
new file mode 100644
index 0000000000..2d8085e128
--- /dev/null
+++ b/indra/newview/lloutfitgallery.cpp
@@ -0,0 +1,699 @@
+/** 
+ * @file lloutfitgallery.cpp
+ * @author Pavlo Kryvych
+ * @brief Visual gallery of agent's outfits for My Appearance side panel
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h" // must be first include
+#include "lloutfitgallery.h"
+
+#include <boost/foreach.hpp>
+
+// llcommon
+#include "llcommonutils.h"
+#include "llvfile.h"
+
+#include "llappearancemgr.h"
+#include "lleconomy.h"
+#include "llerror.h"
+#include "llfilepicker.h"
+#include "llfloaterperms.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
+#include "lllocalbitmaps.h"
+#include "llviewermenufile.h"
+#include "llwearableitemslist.h"
+
+
+static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
+static LLOutfitGallery* gOutfitGallery = NULL;
+
+LLOutfitGallery::LLOutfitGallery()
+    : LLOutfitListBase(),
+      mTexturesObserver(NULL)
+{
+//    mGearMenu = new LLOutfitGalleryGearMenu(this);
+}
+
+BOOL LLOutfitGallery::postBuild()
+{
+    BOOL rv = LLOutfitListBase::postBuild();
+    return rv;
+}
+
+void LLOutfitGallery::onOpen(const LLSD& info)
+{
+    LLOutfitListBase::onOpen(info);
+    rebuildGallery();
+    loadPhotos();
+}
+
+#define LAYOUT_STACK_HEIGHT 180
+#define GALLERY_VERTICAL_GAP 10
+#define GALLERY_HORIZONTAL_GAP 10
+#define GALLERY_ITEM_WIDTH 150
+#define GALLERY_ITEM_HEIGHT 175
+#define GALLERY_ITEM_HGAP 16 
+#define ITEMS_IN_ROW 3
+#define LAYOUT_STACK_WIDTH 166 * ITEMS_IN_ROW//498
+#define GALLERY_WIDTH 163 * ITEMS_IN_ROW//485//290
+
+void LLOutfitGallery::rebuildGallery()
+{
+    LLView::child_list_t child_list(*getChild<LLPanel>("gallery_panel")->getChildList());
+    BOOST_FOREACH(LLView* view, child_list)
+    {
+        LLLayoutStack* lstack = dynamic_cast<LLLayoutStack*>(view);
+        if (lstack != NULL)
+        {
+            LLView::child_list_t panel_list(*lstack->getChildList());
+            BOOST_FOREACH(LLView* panel, panel_list)
+            {
+                //LLLayoutPanel* lpanel = dynamic_cast<LLLayoutPanel*>(panel);
+                //if (!lpanel)
+                //    continue;
+                LLView::child_list_t panel_children(*panel->getChildList());
+                if (panel_children.size() > 0)
+                {
+                    //Assume OutfitGalleryItem is the only one child of layout panel
+                    LLView* view_item = panel_children.back();
+                    LLOutfitGalleryItem* gallery_item = dynamic_cast<LLOutfitGalleryItem*>(view_item);
+                    if (gallery_item != NULL)
+                        panel->removeChild(gallery_item);
+                }
+                lstack->removeChild(panel);
+                //delete panel;
+            }
+            getChild<LLPanel>("gallery_panel")->removeChild(lstack);
+            delete lstack;
+        }
+        else
+        {
+            getChild<LLPanel>("gallery_panel")->removeChild(view);
+        }
+    }
+    uuid_vec_t cats;
+    getCurrentCategories(cats);
+    int n = cats.size();
+    int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
+    getChild<LLPanel>("gallery_panel")->reshape(
+        GALLERY_WIDTH, row_count * (LAYOUT_STACK_HEIGHT + GALLERY_VERTICAL_GAP));
+    int vgap = 0;
+    uuid_vec_t::reverse_iterator rit = cats.rbegin();
+    for (int i = row_count - 1; i >= 0; i--)
+    {
+        LLLayoutStack* stack = buildLayoutStak(0, (row_count - 1 - i) * LAYOUT_STACK_HEIGHT + vgap);
+        getChild<LLPanel>("gallery_panel")->addChild(stack);
+        int items_in_cur_row = (n % ITEMS_IN_ROW) == 0 ? ITEMS_IN_ROW : (i == row_count - 1 ? n % ITEMS_IN_ROW : ITEMS_IN_ROW);
+        int hgap = 0;
+        for (int j = 0; j < items_in_cur_row && rit != cats.rend(); j++)
+        {
+            LLLayoutPanel* lpanel = buildLayoutPanel(j * GALLERY_ITEM_WIDTH + hgap);
+            LLOutfitGalleryItem* item = mOutfitMap[*rit];
+            lpanel->addChild(item);
+            stack->addChild(lpanel);
+            rit++;
+            hgap += GALLERY_HORIZONTAL_GAP;
+        }
+        vgap += GALLERY_VERTICAL_GAP;
+    }
+}
+
+LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
+{
+    LLOutfitGalleryItem::Params giparams;
+    LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams);
+    LLRect girect = LLRect(0, GALLERY_ITEM_HEIGHT - GALLERY_ITEM_HEIGHT,
+        GALLERY_ITEM_WIDTH, 0);
+    //gitem->setRect(girect);
+    gitem->reshape(GALLERY_ITEM_WIDTH, GALLERY_ITEM_HEIGHT);
+    gitem->setVisible(true);
+    gitem->setFollowsLeft();
+    gitem->setFollowsTop();
+    gitem->setOutfitName(name);
+    return gitem;
+}
+
+LLLayoutPanel* LLOutfitGallery::buildLayoutPanel(int left)
+{
+    LLLayoutPanel::Params lpparams;
+    int top = 0;
+    LLLayoutPanel* lpanel = LLUICtrlFactory::create<LLLayoutPanel>(lpparams);
+    LLRect rect = LLRect(left, top + GALLERY_ITEM_HEIGHT, left + GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, top);
+    lpanel->setRect(rect);
+    lpanel->reshape(GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, GALLERY_ITEM_HEIGHT);
+    lpanel->setVisible(true);
+    lpanel->setFollowsLeft();
+    lpanel->setFollowsTop();
+    return lpanel;
+}
+
+LLLayoutStack* LLOutfitGallery::buildLayoutStak(int left, int top)
+{
+    LLLayoutStack::Params sparams;
+    LLLayoutStack* stack = LLUICtrlFactory::create<LLLayoutStack>(sparams);
+    LLRect rect = LLRect(left, top + LAYOUT_STACK_HEIGHT, left + LAYOUT_STACK_WIDTH, top);
+    stack->setRect(rect);
+    stack->reshape(LAYOUT_STACK_WIDTH, LAYOUT_STACK_HEIGHT);
+    stack->setVisible(true);
+    stack->setFollowsLeft();
+    stack->setFollowsTop();
+    return stack;
+}
+
+
+LLOutfitGallery::~LLOutfitGallery()
+{
+    if (gInventory.containsObserver(mTexturesObserver))
+    {
+        gInventory.removeObserver(mTexturesObserver);
+    }
+    delete mTexturesObserver;
+}
+
+void LLOutfitGallery::setFilterSubString(const std::string& string)
+{
+    //TODO: Implement filtering
+
+    sFilterSubString = string;
+}
+
+void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
+{
+    if (mOutfitMap[base_id])
+    {
+        mOutfitMap[base_id]->setOutfitWorn(true);
+    }
+    if (mOutfitMap[prev_id])
+    {
+        mOutfitMap[prev_id]->setOutfitWorn(false);
+    }
+}
+
+void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
+{
+}
+
+void LLOutfitGallery::getCurrentCategories(uuid_vec_t& vcur)
+{
+    for (outfit_map_t::const_iterator iter = mOutfitMap.begin();
+        iter != mOutfitMap.end();
+        iter++)
+    {
+        if ((*iter).second != NULL)
+        {
+            vcur.push_back((*iter).first);
+        }
+    }
+}
+
+void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
+{
+    LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+    if (!cat) return;
+
+    std::string name = cat->getName();
+    LLOutfitGalleryItem* item = buildGalleryItem(name);
+    mOutfitMap.insert(LLOutfitGallery::outfit_map_value_t(cat_id, item));
+    item->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this,
+        _1, _2, _3, cat_id));
+    LLWearableItemsList* list = NULL;
+    item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::�hangeOutfitSelection, this, list, cat_id));
+
+}
+
+void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
+{
+    outfit_map_t::iterator outfits_iter = mOutfitMap.find(cat_id);
+    if (outfits_iter != mOutfitMap.end())
+    {
+        //const LLUUID& outfit_id = outfits_iter->first;
+        LLOutfitGalleryItem* item = outfits_iter->second;
+
+        // An outfit is removed from the list. Do the following:
+        // 2. Remove the outfit from selection.
+        //deselectOutfit(outfit_id);
+
+        // 3. Remove category UUID to accordion tab mapping.
+        mOutfitMap.erase(outfits_iter);
+
+        // 4. Remove outfit from gallery.
+        rebuildGallery();
+
+        // kill removed item
+        if (item != NULL)
+        {
+            item->die();
+        }
+    }
+
+}
+
+void LLOutfitGallery::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name)
+{
+    outfit_map_t::iterator outfit_iter = mOutfitMap.find(cat->getUUID());
+    if (outfit_iter != mOutfitMap.end())
+    {
+        // Update name of outfit in gallery
+        LLOutfitGalleryItem* item = outfit_iter->second;
+        if (item)
+        {
+            item->setOutfitName(name);
+        }
+    }
+}
+
+void LLOutfitGallery::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
+{
+    if (mOutfitMenu && cat_id.notNull())
+    {
+        uuid_vec_t selected_uuids;
+        selected_uuids.push_back(cat_id);
+        mOutfitMenu->show(ctrl, selected_uuids, x, y);
+    }
+}
+
+void LLOutfitGallery::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
+{
+    if (mSelectedOutfitUUID == category_id)
+        return;
+    if (mOutfitMap[mSelectedOutfitUUID])
+    {
+        mOutfitMap[mSelectedOutfitUUID]->setSelected(FALSE);
+    }
+    if (mOutfitMap[category_id])
+    {
+        mOutfitMap[category_id]->setSelected(TRUE);
+    }
+}
+
+bool LLOutfitGallery::hasItemSelected()
+{
+    return false;
+}
+
+bool LLOutfitGallery::canWearSelected()
+{
+    return false;
+}
+
+LLOutfitListGearMenuBase* LLOutfitGallery::createGearMenu()
+{
+    return new LLOutfitGalleryGearMenu(this);
+}
+
+static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_item");
+
+LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
+    : LLPanel(p),
+    mTexturep(NULL)
+{
+    buildFromFile("panel_outfit_gallery_item.xml");
+}
+
+LLOutfitGalleryItem::~LLOutfitGalleryItem()
+{
+
+}
+
+BOOL LLOutfitGalleryItem::postBuild()
+{
+    setDefaultImage();
+
+    mOutfitNameText = getChild<LLTextBox>("outfit_name");
+    mOutfitWornText = getChild<LLTextBox>("outfit_worn_text");
+    setOutfitWorn(false);
+    return TRUE;
+}
+
+void LLOutfitGalleryItem::draw()
+{
+    LLPanel::draw();
+
+    // In case texture is not set, don't draw it over default image
+    if (!mTexturep)
+    {
+        return;
+    }
+
+    // Border
+    LLRect border = getChildView("preview_outfit")->getRect();
+    //gl_rect_2d(border, LLColor4::black, FALSE);
+
+
+    // Interior
+    LLRect interior = border;
+    //interior.stretch(-1);
+
+    // If the floater is focused, don't apply its alpha to the texture (STORM-677).
+    const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+    if (mTexturep)
+    {
+        if (mTexturep->getComponents() == 4)
+        {
+            gl_rect_2d_checkerboard(interior, alpha);
+        }
+
+        gl_draw_scaled_image(interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
+
+        // Pump the priority
+        mTexturep->addTextureStats((F32)(interior.getWidth() * interior.getHeight()));
+    }
+}
+
+void LLOutfitGalleryItem::setOutfitName(std::string name)
+{
+    mOutfitNameText->setText(name);
+}
+
+void LLOutfitGalleryItem::setOutfitWorn(bool value)
+{
+    //LLStringUtil::format_map_t string_args;
+    //std::string worn_text = getString("worn_text", string_args);
+
+    if (value)
+    {
+        mOutfitWornText->setValue("(worn)");
+    }
+    else
+    {
+        mOutfitWornText->setValue("");
+    }
+}
+
+void LLOutfitGalleryItem::setSelected(bool value)
+{
+    if (value)
+    {
+        mOutfitWornText->setValue("(selected)");
+    }
+    else
+    {
+        mOutfitWornText->setValue("");
+    }
+}
+
+BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+    setFocus(TRUE);
+    return LLUICtrl::handleMouseDown(x, y, mask);
+}
+
+void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
+{
+    mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+    mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+}
+
+void LLOutfitGalleryItem::setDefaultImage()
+{
+    /*
+    LLUUID imageAssetID("e417f443-a199-bac1-86b0-0530e177fb54");
+    mTexturep = LLViewerTextureManager::getFetchedTexture(imageAssetID);
+    mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+    */
+    mTexturep = NULL;
+}
+
+LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
+    : LLOutfitListGearMenuBase(olist)
+{
+}
+
+void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
+{
+    if (!mMenu) return;
+    mMenu->setItemVisible("expand", FALSE);
+    mMenu->setItemVisible("collapse", FALSE);
+    mMenu->setItemVisible("upload_foto", TRUE);
+    mMenu->setItemVisible("load_assets", TRUE);
+    LLOutfitListGearMenuBase::onUpdateItemsVisibility();
+}
+
+void LLOutfitGalleryGearMenu::onUploadFoto()
+{
+    LLUUID selected_outfit_id = getSelectedOutfitID();
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery && selected_outfit_id.notNull())
+    {
+        gallery->uploadPhoto(selected_outfit_id);
+    }
+    if (selected_outfit_id.notNull())
+    {
+
+    }
+}
+
+void LLOutfitGalleryGearMenu::onLoadAssets()
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery != NULL)
+    {
+        gallery->loadPhotos();
+    }
+}
+
+void LLOutfitGallery::loadPhotos()
+{
+    //Iterate over inventory
+    LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::EType::FT_TEXTURE);
+    LLViewerInventoryCategory* category = gInventory.getCategory(textures);
+    if (!category)
+        return;
+
+    if (mTexturesObserver == NULL)
+    {
+        mTexturesObserver = new LLInventoryCategoriesObserver();
+        gInventory.addObserver(mTexturesObserver);
+    }
+
+    // Start observing changes in "My Outfits" category.
+    mTexturesObserver->addCategory(textures,
+        boost::bind(&LLOutfitGallery::refreshTextures, this, textures));
+
+    category->fetch();
+    refreshTextures(textures);
+}
+
+void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
+{
+    LLInventoryModel::cat_array_t cat_array;
+    LLInventoryModel::item_array_t item_array;
+
+    // Collect all sub-categories of a given category.
+    LLIsType is_texture(LLAssetType::AT_TEXTURE);
+    gInventory.collectDescendentsIf(
+        category_id,
+        cat_array,
+        item_array,
+        LLInventoryModel::EXCLUDE_TRASH,
+        is_texture);
+
+    //Find textures which contain outfit UUID string in description
+    LLInventoryModel::item_array_t uploaded_item_array;
+    BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
+    {
+        std::string desc = item->getDescription();
+
+        LLUUID outfit_id(desc);
+
+        //Check whether description contains correct UUID of outfit
+        if (outfit_id.isNull())
+            continue;
+
+        outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
+        if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
+        {
+            uploaded_item_array.push_back(item);
+        }
+    }
+
+    uuid_vec_t vadded;
+    uuid_vec_t vremoved;
+
+    // Create added and removed items vectors.
+    computeDifferenceOfTextures(uploaded_item_array, vadded, vremoved);
+
+    BOOST_FOREACH(LLUUID item_id, vadded)
+    {
+        LLViewerInventoryItem* added_item = gInventory.getItem(item_id);
+        LLUUID asset_id = added_item->getAssetUUID();
+        std::string desc = added_item->getDescription();
+        LLUUID outfit_id(desc);
+        mOutfitMap[outfit_id]->setImageAssetId(asset_id);
+        mTextureMap[outfit_id] = added_item;
+    }
+
+    BOOST_FOREACH(LLUUID item_id, vremoved)
+    {
+        LLViewerInventoryItem* rm_item = gInventory.getItem(item_id);
+        std::string desc = rm_item->getDescription();
+        LLUUID outfit_id(desc);
+        mOutfitMap[outfit_id]->setDefaultImage();
+        mTextureMap.erase(outfit_id);
+    }
+
+    /*
+    LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
+    for ( ; it != item_array.end(); it++)
+    {
+        LLViewerInventoryItem* item = (*it);
+        LLUUID asset_id = item->getAssetUUID();
+
+        std::string desc = item->getDescription();
+
+        LLUUID outfit_id(desc);
+
+        //Check whether description contains correct UUID of outfit
+        if (outfit_id.isNull())
+            continue;
+
+        outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
+        if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
+        {
+            outfit_it->second->setImageAssetId(asset_id);
+            mTextureMap[outfit_id] = item;
+        }
+
+        
+        //LLUUID* item_idp = new LLUUID();
+
+        //gOutfitGallery = this;
+        //const BOOL high_priority = TRUE;
+        //gAssetStorage->getAssetData(asset_id,
+        //    LLAssetType::AT_TEXTURE,
+        //    onLoadComplete,
+        //    (void**)item_idp,
+        //    high_priority);
+        //
+        ////mAssetStatus = PREVIEW_ASSET_LOADING;
+        
+    }
+    */
+}
+
+void LLOutfitGallery::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
+{
+    LL_WARNS() << "asset_uuid: " << asset_uuid.asString() << LL_ENDL;
+
+    LLUUID* outfit_id = (LLUUID*)user_data;
+        if (!user_data)
+        return;
+    LL_WARNS() << "outfit_id: " << outfit_id->asString() << LL_ENDL;
+
+    outfit_map_t::iterator it = gOutfitGallery->mOutfitMap.find(*outfit_id);
+    if (it != gOutfitGallery->mOutfitMap.end() && !it->first.isNull())
+    {
+    }
+}
+
+void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
+{
+    outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
+    if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
+    {
+        return;
+    }
+
+    bool add_successful = false;
+    LLFilePicker& picker = LLFilePicker::instance();
+    if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
+    {
+        std::string filename = picker.getFirstFile();
+        LLLocalBitmap* unit = new LLLocalBitmap(filename);
+        if (unit->getValid())
+        {
+            add_successful = true;
+            LLAssetStorage::LLStoreAssetCallback callback = NULL;
+            S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
+            void *nruserdata = NULL;
+            nruserdata = (void *)&outfit_id;
+
+            LL_WARNS() << "selected_outfit_id: " << outfit_id.asString() << LL_ENDL;
+
+            //LLViewerInventoryItem *outfit = gInventory.getItem(selected_outfit_id);
+            LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
+            if (!outfit_cat) return;
+
+            checkRemovePhoto(outfit_id);
+
+            LLStringUtil::format_map_t foto_string_args;
+            foto_string_args["OUTFIT_NAME"] = outfit_cat->getName();
+            std::string display_name = getString("outfit_foto_string", foto_string_args);
+
+            upload_new_resource(filename, // file
+                display_name,
+                outfit_id.asString(),
+                0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+                LLFloaterPerms::getNextOwnerPerms("Uploads"),
+                LLFloaterPerms::getGroupPerms("Uploads"),
+                LLFloaterPerms::getEveryonePerms("Uploads"),
+                display_name, callback, expected_upload_cost, nruserdata);
+        }
+    }
+}
+
+bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
+{
+    //remove existing photo of outfit from inventory
+    texture_map_t::iterator texture_it = mTextureMap.find(outfit_id);
+    if (texture_it != mTextureMap.end()) {
+        gInventory.removeItem(texture_it->second->getUUID());
+        return true;
+    }
+    return false;
+}
+
+void LLOutfitGallery::setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id)
+{
+
+}
+
+void LLOutfitGallery::computeDifferenceOfTextures(
+    const LLInventoryModel::item_array_t& vtextures,
+    uuid_vec_t& vadded,
+    uuid_vec_t& vremoved)
+{
+    uuid_vec_t vnew;
+    // Creating a vector of newly collected sub-categories UUIDs.
+    for (LLInventoryModel::item_array_t::const_iterator iter = vtextures.begin();
+        iter != vtextures.end();
+        iter++)
+    {
+        vnew.push_back((*iter)->getUUID());
+    }
+
+    uuid_vec_t vcur;
+    // Creating a vector of currently uploaded texture UUIDs.
+    for (texture_map_t::const_iterator iter = mTextureMap.begin();
+        iter != mTextureMap.end();
+        iter++)
+    {
+        vcur.push_back((*iter).second->getUUID());
+    }
+//    getCurrentCategories(vcur);
+
+    LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
+
+}
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
new file mode 100644
index 0000000000..93b9ba1e3f
--- /dev/null
+++ b/indra/newview/lloutfitgallery.h
@@ -0,0 +1,152 @@
+/** 
+ * @file lloutfitgallery.h
+ * @author Pavlo Kryvych
+ * @brief Visual gallery of agent's outfits for My Appearance side panel
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLOUTFITGALLERYCTRL_H
+#define LL_LLOUTFITGALLERYCTRL_H
+
+#include "llextendedstatus.h"
+#include "lliconctrl.h"
+#include "lllayoutstack.h"
+#include "lloutfitslist.h"
+#include "llpanelappearancetab.h"
+#include "llviewertexture.h"
+
+#include <vector>
+
+class LLVFS;
+class LLOutfitGalleryItem;
+class LLOutfitListGearMenuBase;
+class LLOutfitGalleryGearMenu;
+
+class LLOutfitGallery : public LLOutfitListBase
+{
+public:
+    friend class LLOutfitGalleryGearMenu;
+    LLOutfitGallery();
+    virtual ~LLOutfitGallery();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& info);
+
+    /*virtual*/ void setFilterSubString(const std::string& string);
+
+    /*virtual*/ void getCurrentCategories(uuid_vec_t& vcur);
+    /*virtual*/ void updateAddedCategory(LLUUID cat_id);
+    /*virtual*/ void updateRemovedCategory(LLUUID cat_id);
+    /*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
+
+    /*virtual*/ bool hasItemSelected();
+    /*virtual*/ bool canWearSelected();
+
+    /*virtual*/ bool getHasExpandableFolders() { return FALSE; }
+
+    void refreshTextures(const LLUUID& category_id);
+    void computeDifferenceOfTextures(const LLInventoryModel::item_array_t& vtextures, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+
+protected:
+    /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
+    /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
+    /*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
+    /*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
+
+    /*virtual*/ void onCollapseAllFolders() {}
+    /*virtual*/ void onExpandAllFolders() {}
+    /*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
+
+private:
+    void rebuildGallery();
+    void loadPhotos();
+    void uploadPhoto(LLUUID outfit_id);
+    bool checkRemovePhoto(LLUUID outfit_id);
+    void setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id);
+
+    static void onLoadComplete(LLVFS *vfs,
+        const LLUUID& asset_uuid,
+        LLAssetType::EType type,
+        void* user_data, S32 status, LLExtStat ext_status);
+
+    LLOutfitGalleryItem* buildGalleryItem(std::string name);
+    LLLayoutPanel* buildLayoutPanel(int left);
+    LLLayoutStack* buildLayoutStak(int left, int top);
+
+    LLView* mView;
+    std::vector<LLLayoutStack*> mLayouts;
+    std::vector<LLLayoutPanel*> mPanels;
+    std::vector<LLOutfitGalleryItem*> mItems;
+
+    typedef	std::map<LLUUID, LLOutfitGalleryItem*>		outfit_map_t;
+    typedef outfit_map_t::value_type					outfit_map_value_t;
+    outfit_map_t					mOutfitMap;
+    typedef	std::map<LLUUID, LLViewerInventoryItem*>    texture_map_t;
+    typedef texture_map_t::value_type	                texture_map_value_t;
+    texture_map_t                    mTextureMap;
+
+    LLInventoryCategoriesObserver* 	mTexturesObserver;
+
+};
+
+//static LLOutfitGallery* gOutfitGallery;
+
+class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase
+{
+public:
+    friend class LLOutfitGallery;
+    LLOutfitGalleryGearMenu(LLOutfitListBase* olist);
+
+protected:
+    /*virtual*/ void onUpdateItemsVisibility();
+
+private:
+    /*virtual*/ void onUploadFoto();
+    /*virtual*/ void onLoadAssets();
+};
+
+class LLOutfitGalleryItem : public LLPanel
+{
+public:
+    struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+    {};
+
+    LLOutfitGalleryItem(const Params& p);
+    virtual ~LLOutfitGalleryItem();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void draw();
+    /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+    void setDefaultImage();
+    void setImageAssetId(LLUUID asset_id);
+    void setOutfitName(std::string name);
+    void setOutfitWorn(bool value);
+    void setSelected(bool value);
+private:
+    LLPointer<LLViewerTexture> mTexturep;
+    LLTextBox* mOutfitNameText;
+    LLTextBox* mOutfitWornText;
+};
+
+#endif  // LL_LLOUTFITGALLERYCTRL_H
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 883221382c..736da5d411 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -38,7 +38,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
-#include "lllistcontextmenu.h"
+//#include "lllistcontextmenu.h"
 #include "llmenubutton.h"
 #include "llnotificationsutil.h"
 #include "lloutfitobserver.h"
@@ -98,339 +98,204 @@ const outfit_accordion_tab_params& get_accordion_tab_params()
 }
 
 
-//////////////////////////////////////////////////////////////////////////
+static LLPanelInjector<LLOutfitsList> t_outfits_list("outfits_list");
 
-class LLOutfitListGearMenu
+LLOutfitsList::LLOutfitsList()
+    :   LLOutfitListBase()
+    ,   mAccordion(NULL)
+	,	mListCommands(NULL)
+	,	mItemSelected(false)
 {
-public:
-	LLOutfitListGearMenu(LLOutfitsList* olist)
-	:	mOutfitList(olist),
-		mMenu(NULL)
-	{
-		llassert_always(mOutfitList);
+//	mCategoriesObserver = new LLInventoryCategoriesObserver();
 
-		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-		registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this));
-		registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this));
-		registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
-		registrar.add("Gear.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList));
-		registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
-		registrar.add("Gear.Collapse", boost::bind(&LLOutfitsList::collapse_all_folders, mOutfitList));
-		registrar.add("Gear.Expand", boost::bind(&LLOutfitsList::expand_all_folders, mOutfitList));
-
-		registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this));
-
-		enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
-		enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
-
-		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
-			"menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-		llassert(mMenu);
-	}
-
-	void updateItemsVisibility()
-	{
-		if (!mMenu) return;
+//	mGearMenu = new LLOutfitListGearMenu(this);
+}
 
-		bool have_selection = getSelectedOutfitID().notNull();
-		mMenu->setItemVisible("sepatator1", have_selection);
-		mMenu->setItemVisible("sepatator2", have_selection);
-		mMenu->arrangeAndClear(); // update menu height
-	}
+LLOutfitsList::~LLOutfitsList()
+{
+//	delete mGearMenu;
+}
 
-	LLToggleableMenu* getMenu() { return mMenu; }
+BOOL LLOutfitsList::postBuild()
+{
+	mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
+	mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
 
-private:
-	const LLUUID& getSelectedOutfitID()
-	{
-		return mOutfitList->getSelectedOutfitUUID();
-	}
+	//LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
 
-	LLViewerInventoryCategory* getSelectedOutfit()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.isNull())
-		{
-			return NULL;
-		}
+	//menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenu::updateItemsVisibility, mGearMenu));
+	//menu_gear_btn->setMenu(mGearMenu->getMenu());
 
-		LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
-		return cat;
-	}
+    return LLOutfitListBase::postBuild();
+}
 
-	void onWear()
-	{
-		LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
-		if (selected_outfit)
-		{
-			LLAppearanceMgr::instance().wearInventoryCategory(
-				selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
-		}
-	}
+//virtual
+void LLOutfitsList::onOpen(const LLSD& info)
+{
+    if (!mIsInitialized)
+    {
+        const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+        // Start observing changes in Current Outfit category.
+        mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
+    }
 
-	void onAdd()
-	{
-		const LLUUID& selected_id = getSelectedOutfitID();
+    LLOutfitListBase::onOpen(info);
 
-		if (selected_id.notNull())
-		{
-			LLAppearanceMgr::getInstance()->addCategoryToCurrentOutfit(selected_id);
-		}
-	}
+ //   if (!mIsInitialized)
+	//{
+	//	// *TODO: I'm not sure is this check necessary but it never match while developing.
+	//	if (!gInventory.isInventoryUsable())
+	//		return;
 
-	void onTakeOff()
-	{
-		// Take off selected outfit.
-			const LLUUID& selected_outfit_id = getSelectedOutfitID();
-			if (selected_outfit_id.notNull())
-			{
-				LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
-			}
-		}
+	//	const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
 
-	void onRename()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.notNull())
-		{
-			LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
-		}
-	}
+	//	// *TODO: I'm not sure is this check necessary but it never match while developing.
+	//	LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
+	//	if (!category)
+	//		return;
 
-	void onCreate(const LLSD& data)
-	{
-		LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
-		if (type == LLWearableType::WT_NONE)
-		{
-			LL_WARNS() << "Invalid wearable type" << LL_ENDL;
-			return;
-		}
+	//	gInventory.addObserver(mCategoriesObserver);
 
-		LLAgentWearables::createWearable(type, true);
-	}
+	//	// Start observing changes in "My Outfits" category.
+	//	mCategoriesObserver->addCategory(outfits,
+	//		boost::bind(&LLOutfitsList::refreshList, this, outfits));
 
-	bool onEnable(LLSD::String param)
-	{
-		// Handle the "Wear - Replace Current Outfit" menu option specially
-		// because LLOutfitList::isActionEnabled() checks whether it's allowed
-		// to wear selected outfit OR selected items, while we're only
-		// interested in the outfit (STORM-183).
-		if ("wear" == param)
-		{
-			return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID());
-		}
+	//	const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 
-		return mOutfitList->isActionEnabled(param);
-	}
+	//	// Start observing changes in Current Outfit category.
+	//	mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
 
-	bool onVisible(LLSD::String param)
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
-		{
-			return false;
-		}
+	//	LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
+	//	LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
 
-		// *TODO This condition leads to menu item behavior inconsistent with
-		// "Wear" button behavior and should be modified or removed.
-		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
+	//	// Fetch "My Outfits" contents and refresh the list to display
+	//	// initially fetched items. If not all items are fetched now
+	//	// the observer will refresh the list as soon as the new items
+	//	// arrive.
+	//	category->fetch();
+	//	refreshList(outfits);
+	//	highlightBaseOutfit();
 
-		if ("wear" == param)
-		{
-			return !is_worn;
-		}
+	//	mIsInitialized = true;
+	//}
 
-		return true;
-	}
+	LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
+	if (!selected_tab) return;
 
-	LLOutfitsList*			mOutfitList;
-	LLToggleableMenu*		mMenu;
-};
+	// Pass focus to the selected outfit tab.
+	selected_tab->showAndFocusHeader();
+}
 
-//////////////////////////////////////////////////////////////////////////
 
-class LLOutfitContextMenu : public LLListContextMenu
+void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
 {
-public:
-
-	LLOutfitContextMenu(LLOutfitsList* outfit_list)
-	:		LLListContextMenu(),
-	 		mOutfitList(outfit_list)
-	{}
-protected:
-	/* virtual */ LLContextMenu* createMenu()
-	{
-		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-		LLUUID selected_id = mUUIDs.front();
-
-		registrar.add("Outfit.WearReplace",
-			boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
-		registrar.add("Outfit.WearAdd",
-			boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
-		registrar.add("Outfit.TakeOff",
-				boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id));
-		registrar.add("Outfit.Edit", boost::bind(editOutfit));
-		registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
-		registrar.add("Outfit.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList));
-
-		enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2));
-		enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2));
-
-		return createFromFile("menu_outfit_tab.xml");
-	}
+    LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+    if (!cat) return;
 
-	bool onEnable(LLSD::String param)
-	{
-		LLUUID outfit_cat_id = mUUIDs.back();
+    std::string name = cat->getName();
 
-		if ("rename" == param)
-		{
-			return get_is_category_renameable(&gInventory, outfit_cat_id);
-		}
-		else if ("wear_replace" == param)
-		{
-			return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id);
-		}
-		else if ("wear_add" == param)
-		{
-			return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id);
-		}
-		else if ("take_off" == param)
-		{
-			return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id);
-		}
+    outfit_accordion_tab_params tab_params(get_accordion_tab_params());
+    LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
+    if (!tab) return;
+    LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
+    wearable_list->setShape(tab->getLocalRect());
+    tab->addChild(wearable_list);
 
-		return true;
-	}
+    tab->setName(name);
+    tab->setTitle(name);
 
-	bool onVisible(LLSD::String param)
-	{
-		LLUUID outfit_cat_id = mUUIDs.back();
-		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;
+    // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
+    tab->setDisplayChildren(false);
+    mAccordion->addCollapsibleCtrl(tab);
 
-		if ("edit" == param)
-		{
-			return is_worn;
-		}
-		else if ("wear_replace" == param)
-		{
-			return !is_worn;
-		}
-		else if ("delete" == param)
-		{
-			return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id);
-		}
+    // Start observing the new outfit category.
+    LLWearableItemsList* list = tab->getChild<LLWearableItemsList>("wearable_items_list");
+    if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
+    {
+        // Remove accordion tab if category could not be added to observer.
+        mAccordion->removeCollapsibleCtrl(tab);
 
-		return true;
-	}
+        // kill removed tab
+        tab->die();
+        return;
+    }
 
-	static void editOutfit()
-	{
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
+    // Map the new tab with outfit category UUID.
+    mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
 
-	static void renameOutfit(const LLUUID& outfit_cat_id)
-	{
-		LLAppearanceMgr::instance().renameOutfit(outfit_cat_id);
-	}
+    tab->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this,
+        _1, _2, _3, cat_id));
 
-private:
-	LLOutfitsList*	mOutfitList;
-};
+    // Setting tab focus callback to monitor currently selected outfit.
+    tab->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::�hangeOutfitSelection, this, list, cat_id));
 
-//////////////////////////////////////////////////////////////////////////
+    // Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
+    tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
 
-static LLPanelInjector<LLOutfitsList> t_outfits_list("outfits_list");
+    // force showing list items that don't match current filter(EXT-7158)
+    list->setForceShowingUnmatchedItems(true);
 
-LLOutfitsList::LLOutfitsList()
-	:	LLPanelAppearanceTab()
-	,	mAccordion(NULL)
-	,	mListCommands(NULL)
-	,	mIsInitialized(false)
-	,	mItemSelected(false)
-{
-	mCategoriesObserver = new LLInventoryCategoriesObserver();
+    // Setting list commit callback to monitor currently selected wearable item.
+    list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1));
 
-	mGearMenu = new LLOutfitListGearMenu(this);
-	mOutfitMenu = new LLOutfitContextMenu(this);
-}
+    // Setting list refresh callback to apply filter on list change.
+    list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
 
-LLOutfitsList::~LLOutfitsList()
-{
-	delete mGearMenu;
-	delete mOutfitMenu;
+    list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
 
-	if (gInventory.containsObserver(mCategoriesObserver))
-	{
-		gInventory.removeObserver(mCategoriesObserver);
-	}
-	delete mCategoriesObserver;
-}
+    // Fetch the new outfit contents.
+    cat->fetch();
 
-BOOL LLOutfitsList::postBuild()
-{
-	mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
-	mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
+    // Refresh the list of outfit items after fetch().
+    // Further list updates will be triggered by the category observer.
+    list->updateList(cat_id);
 
-	LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
+    // If filter is currently applied we store the initial tab state and
+    // open it to show matched items if any.
+    if (!sFilterSubString.empty())
+    {
+        tab->notifyChildren(LLSD().with("action", "store_state"));
+        tab->setDisplayChildren(true);
 
-	menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenu::updateItemsVisibility, mGearMenu));
-	menu_gear_btn->setMenu(mGearMenu->getMenu());
+        // Setting mForceRefresh flag will make the list refresh its contents
+        // even if it is not currently visible. This is required to apply the
+        // filter to the newly added list.
+        list->setForceRefresh(true);
 
-	return TRUE;
+        list->setFilterSubString(sFilterSubString);
+    }
 }
 
-//virtual
-void LLOutfitsList::onOpen(const LLSD& /*info*/)
+void LLOutfitsList::updateRemovedCategory(LLUUID cat_id)
 {
-	if (!mIsInitialized)
-	{
-		// *TODO: I'm not sure is this check necessary but it never match while developing.
-		if (!gInventory.isInventoryUsable())
-			return;
-
-		const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
-
-		// *TODO: I'm not sure is this check necessary but it never match while developing.
-		LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
-		if (!category)
-			return;
-
-		gInventory.addObserver(mCategoriesObserver);
-
-		// Start observing changes in "My Outfits" category.
-		mCategoriesObserver->addCategory(outfits,
-			boost::bind(&LLOutfitsList::refreshList, this, outfits));
-
-		const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
-
-		// Start observing changes in Current Outfit category.
-		mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
-
-		LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
-		LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
-
-		// Fetch "My Outfits" contents and refresh the list to display
-		// initially fetched items. If not all items are fetched now
-		// the observer will refresh the list as soon as the new items
-		// arrive.
-		category->fetch();
-		refreshList(outfits);
-		highlightBaseOutfit();
-
-		mIsInitialized = true;
-	}
-
-	LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
-	if (!selected_tab) return;
-
-	// Pass focus to the selected outfit tab.
-	selected_tab->showAndFocusHeader();
+    outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat_id);
+    if (outfits_iter != mOutfitsMap.end())
+    {
+    	const LLUUID& outfit_id = outfits_iter->first;
+    	LLAccordionCtrlTab* tab = outfits_iter->second;
+
+    	// An outfit is removed from the list. Do the following:
+    	// 1. Remove outfit category from observer to stop monitoring its changes.
+    	mCategoriesObserver->removeCategory(outfit_id);
+
+    	// 2. Remove the outfit from selection.
+    	deselectOutfit(outfit_id);
+
+    	// 3. Remove category UUID to accordion tab mapping.
+    	mOutfitsMap.erase(outfits_iter);
+
+    	// 4. Remove outfit tab from accordion.
+    	mAccordion->removeCollapsibleCtrl(tab);
+
+    	// kill removed tab
+    	if (tab != NULL)
+    	{
+    		tab->die();
+    	}
+    }
 }
 
+/*
 void LLOutfitsList::refreshList(const LLUUID& category_id)
 {
 	LLInventoryModel::cat_array_t cat_array;
@@ -457,111 +322,114 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
 		 ++iter)
 	{
 		const LLUUID cat_id = (*iter);
-		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
-		if (!cat) continue;
+        updateAddedCategory(cat_id);
+		//LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+		//if (!cat) continue;
 
-		std::string name = cat->getName();
+		//std::string name = cat->getName();
 
-		outfit_accordion_tab_params tab_params(get_accordion_tab_params());
-		LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
-		if (!tab) continue;
-		LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
-		wearable_list->setShape(tab->getLocalRect());
-		tab->addChild(wearable_list);
+		//outfit_accordion_tab_params tab_params(get_accordion_tab_params());
+		//LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
+		//if (!tab) continue;
+		//LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
+		//wearable_list->setShape(tab->getLocalRect());
+		//tab->addChild(wearable_list);
 
-		tab->setName(name);
-		tab->setTitle(name);
+		//tab->setName(name);
+		//tab->setTitle(name);
 
-		// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
-		tab->setDisplayChildren(false);
-		mAccordion->addCollapsibleCtrl(tab);
+		//// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
+		//tab->setDisplayChildren(false);
+		//mAccordion->addCollapsibleCtrl(tab);
 
-		// Start observing the new outfit category.
-		LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list");
-		if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
-		{
-			// Remove accordion tab if category could not be added to observer.
-			mAccordion->removeCollapsibleCtrl(tab);
+		//// Start observing the new outfit category.
+		//LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list");
+		//if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
+		//{
+		//	// Remove accordion tab if category could not be added to observer.
+		//	mAccordion->removeCollapsibleCtrl(tab);
 
-			// kill removed tab
-				tab->die();
-			continue;
-		}
+		//	// kill removed tab
+		//		tab->die();
+		//	continue;
+		//}
 
-		// Map the new tab with outfit category UUID.
-		mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
+		//// Map the new tab with outfit category UUID.
+		//mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
 
-		tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
-			_1, _2, _3, cat_id));
+		//tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
+		//	_1, _2, _3, cat_id));
 
-		// Setting tab focus callback to monitor currently selected outfit.
-		tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));
+		//// Setting tab focus callback to monitor currently selected outfit.
+		//tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));
 
-		// Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
-		tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
+		//// Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
+		//tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
 
-		// force showing list items that don't match current filter(EXT-7158)
-		list->setForceShowingUnmatchedItems(true);
+		//// force showing list items that don't match current filter(EXT-7158)
+		//list->setForceShowingUnmatchedItems(true);
 
-		// Setting list commit callback to monitor currently selected wearable item.
-		list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
+		//// Setting list commit callback to monitor currently selected wearable item.
+		//list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
 
-		// Setting list refresh callback to apply filter on list change.
-		list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
+		//// Setting list refresh callback to apply filter on list change.
+		//list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
 
-		list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
+		//list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
 
-		// Fetch the new outfit contents.
-		cat->fetch();
+		//// Fetch the new outfit contents.
+		//cat->fetch();
 
-		// Refresh the list of outfit items after fetch().
-		// Further list updates will be triggered by the category observer.
-		list->updateList(cat_id);
+		//// Refresh the list of outfit items after fetch().
+		//// Further list updates will be triggered by the category observer.
+		//list->updateList(cat_id);
 
-		// If filter is currently applied we store the initial tab state and
-		// open it to show matched items if any.
-		if (!sFilterSubString.empty())
-		{
-			tab->notifyChildren(LLSD().with("action","store_state"));
-			tab->setDisplayChildren(true);
+		//// If filter is currently applied we store the initial tab state and
+		//// open it to show matched items if any.
+		//if (!sFilterSubString.empty())
+		//{
+		//	tab->notifyChildren(LLSD().with("action","store_state"));
+		//	tab->setDisplayChildren(true);
 
-			// Setting mForceRefresh flag will make the list refresh its contents
-			// even if it is not currently visible. This is required to apply the
-			// filter to the newly added list.
-			list->setForceRefresh(true);
+		//	// Setting mForceRefresh flag will make the list refresh its contents
+		//	// even if it is not currently visible. This is required to apply the
+		//	// filter to the newly added list.
+		//	list->setForceRefresh(true);
 
-			list->setFilterSubString(sFilterSubString);
-		}
+		//	list->setFilterSubString(sFilterSubString);
+		//}
 	}
 
 	// Handle removed tabs.
 	for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); ++iter)
 	{
-		outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));
-		if (outfits_iter != mOutfitsMap.end())
-		{
-			const LLUUID& outfit_id = outfits_iter->first;
-			LLAccordionCtrlTab* tab = outfits_iter->second;
-
-			// An outfit is removed from the list. Do the following:
-			// 1. Remove outfit category from observer to stop monitoring its changes.
-			mCategoriesObserver->removeCategory(outfit_id);
-
-			// 2. Remove the outfit from selection.
-			deselectOutfit(outfit_id);
-
-			// 3. Remove category UUID to accordion tab mapping.
-			mOutfitsMap.erase(outfits_iter);
-
-			// 4. Remove outfit tab from accordion.
-			mAccordion->removeCollapsibleCtrl(tab);
-
-			// kill removed tab
-			if (tab != NULL)
-			{
-				tab->die();
-			}
-		}
+        const LLUUID cat_id = (*iter);
+        updateRemovedCategory(cat_id);
+        //outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat_id);
+		//if (outfits_iter != mOutfitsMap.end())
+		//{
+		//	const LLUUID& outfit_id = outfits_iter->first;
+		//	LLAccordionCtrlTab* tab = outfits_iter->second;
+
+		//	// An outfit is removed from the list. Do the following:
+		//	// 1. Remove outfit category from observer to stop monitoring its changes.
+		//	mCategoriesObserver->removeCategory(outfit_id);
+
+		//	// 2. Remove the outfit from selection.
+		//	deselectOutfit(outfit_id);
+
+		//	// 3. Remove category UUID to accordion tab mapping.
+		//	mOutfitsMap.erase(outfits_iter);
+
+		//	// 4. Remove outfit tab from accordion.
+		//	mAccordion->removeCollapsibleCtrl(tab);
+
+		//	// kill removed tab
+		//	if (tab != NULL)
+		//	{
+		//		tab->die();
+		//	}
+		//}
 	}
 
 	// Get changed items from inventory model and update outfit tabs
@@ -571,34 +439,29 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
 		 items_iter != changed_items.end();
 		 ++items_iter)
 	{
-		updateOutfitTab(*items_iter);
+		updateChangedCategoryName(*items_iter);
 	}
 
 	mAccordion->sort();
 }
+*/
 
-void LLOutfitsList::highlightBaseOutfit()
+//virtual
+void LLOutfitsList::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
 {
-	// id of base outfit
-	LLUUID base_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
-	if (base_id != mHighlightedOutfitUUID)
-	{
-		if (mOutfitsMap[mHighlightedOutfitUUID])
-		{
-			mOutfitsMap[mHighlightedOutfitUUID]->setTitleFontStyle("NORMAL");
-			mOutfitsMap[mHighlightedOutfitUUID]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor"));
-		}
-
-		mHighlightedOutfitUUID = base_id;
-	}
-	if (mOutfitsMap[base_id])
+    if (mOutfitsMap[prev_id])
+    {
+        mOutfitsMap[prev_id]->setTitleFontStyle("NORMAL");
+        mOutfitsMap[prev_id]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor"));
+    }
+    if (mOutfitsMap[base_id])
 	{
 		mOutfitsMap[base_id]->setTitleFontStyle("BOLD");
 		mOutfitsMap[base_id]->setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor"));
 	}
 }
 
-void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
+void LLOutfitsList::onListSelectionChange(LLUICtrl* ctrl)
 {
 	LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(ctrl);
 	if (!list) return;
@@ -606,10 +469,10 @@ void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
 	LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID());
 	if (!item) return;
 
-	changeOutfitSelection(list, item->getParentUUID());
+	�hangeOutfitSelection(list, item->getParentUUID());
 }
 
-void LLOutfitsList::performAction(std::string action)
+void LLOutfitListBase::performAction(std::string action)
 {
 	if (mSelectedOutfitUUID.isNull()) return;
 
@@ -630,23 +493,7 @@ void LLOutfitsList::performAction(std::string action)
 	}
 }
 
-void LLOutfitsList::removeSelected()
-{
-	LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitsList::onOutfitsRemovalConfirmation, this, _1, _2));
-}
-
-void LLOutfitsList::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0) return; // canceled
-
-	if (mSelectedOutfitUUID.notNull())
-	{
-		gInventory.removeCategory(mSelectedOutfitUUID);
-	}
-}
-
-void LLOutfitsList::setSelectedOutfitByUUID(const LLUUID& outfit_uuid)
+void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
 {
 	for (outfits_map_t::iterator iter = mOutfitsMap.begin();
 			iter != mOutfitsMap.end();
@@ -661,7 +508,7 @@ void LLOutfitsList::setSelectedOutfitByUUID(const LLUUID& outfit_uuid)
 			if (!list) continue;
 
 			tab->setFocus(TRUE);
-			changeOutfitSelection(list, outfit_uuid);
+			�hangeOutfitSelection(list, outfit_uuid);
 
 			tab->setDisplayChildren(true);
 		}
@@ -677,14 +524,14 @@ void LLOutfitsList::setFilterSubString(const std::string& string)
 }
 
 // virtual
-bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
+bool LLOutfitListBase::isActionEnabled(const LLSD& userdata)
 {
 	if (mSelectedOutfitUUID.isNull()) return false;
 
 	const std::string command_name = userdata.asString();
 	if (command_name == "delete")
 	{
-		return !mItemSelected && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID);
+        return !hasItemSelected() && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID);
 	}
 	if (command_name == "rename")
 	{
@@ -745,7 +592,7 @@ void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
 	}
 }
 
-void LLOutfitsList::collapse_all_folders()
+void LLOutfitsList::onCollapseAllFolders()
 {
 	for (outfits_map_t::iterator iter = mOutfitsMap.begin();
 			iter != mOutfitsMap.end();
@@ -759,7 +606,7 @@ void LLOutfitsList::collapse_all_folders()
 	}
 }
 
-void LLOutfitsList::expand_all_folders()
+void LLOutfitsList::onExpandAllFolders()
 {
 	for (outfits_map_t::iterator iter = mOutfitsMap.begin();
 			iter != mOutfitsMap.end();
@@ -773,11 +620,6 @@ void LLOutfitsList::expand_all_folders()
 	}
 }
 
-boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb)
-{
-	return mSelectionChangeSignal.connect(cb);
-}
-
 bool LLOutfitsList::hasItemSelected()
 {
 	return mItemSelected;
@@ -786,6 +628,7 @@ bool LLOutfitsList::hasItemSelected()
 //////////////////////////////////////////////////////////////////////////
 // Private methods
 //////////////////////////////////////////////////////////////////////////
+/*
 void LLOutfitsList::computeDifference(
 	const LLInventoryModel::cat_array_t& vcats, 
 	uuid_vec_t& vadded, 
@@ -811,17 +654,13 @@ void LLOutfitsList::computeDifference(
 
 	LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
 }
+*/
 
-void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
+void LLOutfitsList::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name)
 {
-	outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id);
+    outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat->getUUID());
 	if (outfits_iter != mOutfitsMap.end())
 	{
-		LLViewerInventoryCategory *cat = gInventory.getCategory(category_id);
-		if (!cat) return;
-
-		std::string name = cat->getName();
-
 		// Update tab name with the new category name.
 		LLAccordionCtrlTab* tab = outfits_iter->second;
 		if (tab)
@@ -836,10 +675,10 @@ void LLOutfitsList::resetItemSelection(LLWearableItemsList* list, const LLUUID&
 {
 	list->resetSelection();
 	mItemSelected = false;
-	setSelectedOutfitUUID(category_id);
+	signalSelectionOutfitUUID(category_id);
 }
 
-void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
+void LLOutfitsList::onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
 {
 	MASK mask = gKeyboard->currentMask(TRUE);
 
@@ -865,12 +704,6 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI
 	mItemSelected = list && (list->getSelectedItem() != NULL);
 
 	mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list));
-	setSelectedOutfitUUID(category_id);
-}
-
-void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id)
-{
-	mSelectionChangeSignal(mSelectedOutfitUUID = category_id);
 }
 
 void LLOutfitsList::deselectOutfit(const LLUUID& category_id)
@@ -881,7 +714,7 @@ void LLOutfitsList::deselectOutfit(const LLUUID& category_id)
 	// Reset selection if the outfit is selected.
 	if (category_id == mSelectedOutfitUUID)
 	{
-		setSelectedOutfitUUID(LLUUID::null);
+		signalSelectionOutfitUUID(LLUUID::null);
 	}
 }
 
@@ -890,7 +723,7 @@ void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID
 	// Try restoring outfit selection after filtering.
 	if (mAccordion->getSelectedTab() == tab)
 	{
-		setSelectedOutfitUUID(category_id);
+		signalSelectionOutfitUUID(category_id);
 	}
 }
 
@@ -1036,24 +869,6 @@ bool LLOutfitsList::canWearSelected()
 	return true;
 }
 
-void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
-{
-	LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
-	if(mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull())
-	{
-		// Focus tab header to trigger tab selection change.
-		LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header");
-		if (header)
-		{
-			header->setFocus(TRUE);
-		}
-
-		uuid_vec_t selected_uuids;
-		selected_uuids.push_back(cat_id);
-		mOutfitMenu->show(ctrl, selected_uuids, x, y);
-	}
-}
-
 void LLOutfitsList::wearSelectedItems()
 {
 	uuid_vec_t selected_uuids;
@@ -1132,6 +947,47 @@ void LLOutfitsList::onCOFChanged()
 	}
 }
 
+void LLOutfitsList::getCurrentCategories(uuid_vec_t& vcur)
+{
+    // Creating a vector of currently displayed sub-categories UUIDs.
+    for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
+        iter != mOutfitsMap.end();
+        iter++)
+    {
+        vcur.push_back((*iter).first);
+    }
+}
+
+
+void LLOutfitsList::sortOutfits()
+{
+    mAccordion->sort();
+}
+
+void LLOutfitsList::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
+{
+    LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
+    if (mOutfitMenu && is_tab_header_clicked(tab, y) && cat_id.notNull())
+    {
+        // Focus tab header to trigger tab selection change.
+        LLUICtrl* header = tab->findChild<LLUICtrl>("dd_header");
+        if (header)
+        {
+            header->setFocus(TRUE);
+        }
+
+        uuid_vec_t selected_uuids;
+        selected_uuids.push_back(cat_id);
+        mOutfitMenu->show(ctrl, selected_uuids, x, y);
+    }
+}
+
+LLOutfitListGearMenuBase* LLOutfitsList::createGearMenu()
+{
+    return new LLOutfitListGearMenu(this);
+}
+
+
 bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)
 {
 	if(!tab || !tab->getHeaderVisible()) return false;
@@ -1140,4 +996,490 @@ bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)
 	return y >= header_bottom;
 }
 
+LLOutfitListBase::LLOutfitListBase()
+    :   LLPanelAppearanceTab()
+    ,   mIsInitialized(false)
+{
+    mCategoriesObserver = new LLInventoryCategoriesObserver();
+    mOutfitMenu = new LLOutfitContextMenu(this);
+    //mGearMenu = createGearMenu();
+}
+
+LLOutfitListBase::~LLOutfitListBase()
+{
+    delete mOutfitMenu;
+    delete mGearMenu;
+
+    if (gInventory.containsObserver(mCategoriesObserver))
+    {
+        gInventory.removeObserver(mCategoriesObserver);
+    }
+    delete mCategoriesObserver;
+}
+
+void LLOutfitListBase::onOpen(const LLSD& info)
+{
+    if (!mIsInitialized)
+    {
+        // *TODO: I'm not sure is this check necessary but it never match while developing.
+        if (!gInventory.isInventoryUsable())
+            return;
+
+        const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+
+        // *TODO: I'm not sure is this check necessary but it never match while developing.
+        LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
+        if (!category)
+            return;
+
+        gInventory.addObserver(mCategoriesObserver);
+
+        // Start observing changes in "My Outfits" category.
+        mCategoriesObserver->addCategory(outfits,
+            boost::bind(&LLOutfitListBase::refreshList, this, outfits));
+
+        const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+
+        // Start observing changes in Current Outfit category.
+        //mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
+
+        LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitListBase::highlightBaseOutfit, this));
+        LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitListBase::highlightBaseOutfit, this));
+
+        // Fetch "My Outfits" contents and refresh the list to display
+        // initially fetched items. If not all items are fetched now
+        // the observer will refresh the list as soon as the new items
+        // arrive.
+        category->fetch();
+        refreshList(outfits);
+        highlightBaseOutfit();
+
+        mIsInitialized = true;
+    }
+
+    //LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
+    //if (!selected_tab) return;
+
+    //// Pass focus to the selected outfit tab.
+    //selected_tab->showAndFocusHeader();
+}
+
+void LLOutfitListBase::refreshList(const LLUUID& category_id)
+{
+    LLInventoryModel::cat_array_t cat_array;
+    LLInventoryModel::item_array_t item_array;
+
+    // Collect all sub-categories of a given category.
+    LLIsType is_category(LLAssetType::AT_CATEGORY);
+    gInventory.collectDescendentsIf(
+        category_id,
+        cat_array,
+        item_array,
+        LLInventoryModel::EXCLUDE_TRASH,
+        is_category);
+
+    uuid_vec_t vadded;
+    uuid_vec_t vremoved;
+
+    // Create added and removed items vectors.
+    computeDifference(cat_array, vadded, vremoved);
+
+    // Handle added tabs.
+    for (uuid_vec_t::const_iterator iter = vadded.begin();
+        iter != vadded.end();
+        ++iter)
+    {
+        const LLUUID cat_id = (*iter);
+        updateAddedCategory(cat_id);
+    }
+
+    // Handle removed tabs.
+    for (uuid_vec_t::const_iterator iter = vremoved.begin(); iter != vremoved.end(); ++iter)
+    {
+        const LLUUID cat_id = (*iter);
+        updateRemovedCategory(cat_id);
+    }
+
+    // Get changed items from inventory model and update outfit tabs
+    // which might have been renamed.
+    const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
+    for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
+        items_iter != changed_items.end();
+        ++items_iter)
+    {
+        LLViewerInventoryCategory *cat = gInventory.getCategory(*items_iter);
+        if (!cat) return;
+
+        std::string name = cat->getName();
+
+        updateChangedCategoryName(cat, name);
+    }
+
+    sortOutfits();
+}
+
+void LLOutfitListBase::computeDifference(
+    const LLInventoryModel::cat_array_t& vcats,
+    uuid_vec_t& vadded,
+    uuid_vec_t& vremoved)
+{
+    uuid_vec_t vnew;
+    // Creating a vector of newly collected sub-categories UUIDs.
+    for (LLInventoryModel::cat_array_t::const_iterator iter = vcats.begin();
+        iter != vcats.end();
+        iter++)
+    {
+        vnew.push_back((*iter)->getUUID());
+    }
+
+    uuid_vec_t vcur;
+    //// Creating a vector of currently displayed sub-categories UUIDs.
+    //for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
+    //    iter != mOutfitsMap.end();
+    //    iter++)
+    //{
+    //    vcur.push_back((*iter).first);
+    //}
+    getCurrentCategories(vcur);
+
+    LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
+}
+
+void LLOutfitListBase::sortOutfits()
+{
+}
+
+void LLOutfitListBase::highlightBaseOutfit()
+{
+    // id of base outfit
+    LLUUID base_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
+    if (base_id != mHighlightedOutfitUUID)
+    {
+        LLUUID prev_id = mHighlightedOutfitUUID;
+        mHighlightedOutfitUUID = base_id;
+        onHighlightBaseOutfit(base_id, prev_id);
+    }
+
+}
+
+void LLOutfitListBase::removeSelected()
+{
+    LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitListBase::onOutfitsRemovalConfirmation, this, _1, _2));
+}
+
+void LLOutfitListBase::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (option != 0) return; // canceled
+
+    if (mSelectedOutfitUUID.notNull())
+    {
+        gInventory.removeCategory(mSelectedOutfitUUID);
+    }
+}
+
+void LLOutfitListBase::setSelectedOutfitByUUID(const LLUUID& outfit_uuid)
+{
+    onSetSelectedOutfitByUUID(outfit_uuid);
+}
+
+boost::signals2::connection LLOutfitListBase::setSelectionChangeCallback(selection_change_callback_t cb)
+{
+    return mSelectionChangeSignal.connect(cb);
+}
+
+void LLOutfitListBase::signalSelectionOutfitUUID(const LLUUID& category_id)
+{
+    mSelectionChangeSignal(category_id);
+}
+
+void LLOutfitListBase::outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
+{
+    onOutfitRightClick(ctrl, x, y, cat_id);
+}
+
+void LLOutfitListBase::�hangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
+{
+    onChangeOutfitSelection(list, category_id);
+    mSelectedOutfitUUID = category_id;
+    signalSelectionOutfitUUID(category_id);
+}
+
+BOOL LLOutfitListBase::postBuild()
+{
+    mGearMenu = createGearMenu();
+
+    LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
+
+    menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenuBase::updateItemsVisibility, mGearMenu));
+    menu_gear_btn->setMenu(mGearMenu->getMenu());
+    return TRUE;
+}
+
+void LLOutfitListBase::collapseAllFolders()
+{
+    onCollapseAllFolders();
+}
+
+void LLOutfitListBase::expandAllFolders()
+{
+    onExpandAllFolders();
+}
+
+LLContextMenu* LLOutfitContextMenu::createMenu()
+{
+    LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+    LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+    LLUUID selected_id = mUUIDs.front();
+
+    registrar.add("Outfit.WearReplace",
+        boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.WearAdd",
+        boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.TakeOff",
+        boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.Edit", boost::bind(editOutfit));
+    registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
+    registrar.add("Outfit.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList));
+
+    enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2));
+    enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2));
+
+    return createFromFile("menu_outfit_tab.xml");
+
+}
+
+bool LLOutfitContextMenu::onEnable(LLSD::String param)
+{
+    LLUUID outfit_cat_id = mUUIDs.back();
+
+    if ("rename" == param)
+    {
+        return get_is_category_renameable(&gInventory, outfit_cat_id);
+    }
+    else if ("wear_replace" == param)
+    {
+        return LLAppearanceMgr::instance().getCanReplaceCOF(outfit_cat_id);
+    }
+    else if ("wear_add" == param)
+    {
+        return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id);
+    }
+    else if ("take_off" == param)
+    {
+        return LLAppearanceMgr::getCanRemoveFromCOF(outfit_cat_id);
+    }
+
+    return true;
+}
+
+bool LLOutfitContextMenu::onVisible(LLSD::String param)
+{
+    LLUUID outfit_cat_id = mUUIDs.back();
+    bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id;
+
+    if ("edit" == param)
+    {
+        return is_worn;
+    }
+    else if ("wear_replace" == param)
+    {
+        return !is_worn;
+    }
+    else if ("delete" == param)
+    {
+        return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id);
+    }
+
+    return true;
+}
+
+//static
+void LLOutfitContextMenu::editOutfit()
+{
+    LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+}
+
+void LLOutfitContextMenu::renameOutfit(const LLUUID& outfit_cat_id)
+{
+    LLAppearanceMgr::instance().renameOutfit(outfit_cat_id);
+}
+
+LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
+    :   mOutfitList(olist),
+        mMenu(NULL)
+{
+    llassert_always(mOutfitList);
+
+    LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+    LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+    registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenuBase::onWear, this));
+    registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenuBase::onTakeOff, this));
+    registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenuBase::onRename, this));
+    registrar.add("Gear.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList));
+    registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenuBase::onCreate, this, _2));
+    registrar.add("Gear.Collapse", boost::bind(&LLOutfitListBase::onCollapseAllFolders, mOutfitList));
+    registrar.add("Gear.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, mOutfitList));
+
+    registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
+
+    registrar.add("Gear.UploadFoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
+    registrar.add("Gear.LoadAssets", boost::bind(&LLOutfitListGearMenuBase::onLoadAssets, this));
+    
+    enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
+    enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
+
+    mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+        "menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+    llassert(mMenu);
+}
+
+void LLOutfitListGearMenuBase::updateItemsVisibility()
+{
+    onUpdateItemsVisibility();
+}
+
+void LLOutfitListGearMenuBase::onUpdateItemsVisibility()
+{
+    if (!mMenu) return;
+
+    bool have_selection = getSelectedOutfitID().notNull();
+    mMenu->setItemVisible("sepatator1", have_selection);
+    mMenu->setItemVisible("sepatator2", have_selection);
+    //mMenu->setItemVisible("expand", mOutfitList->getHasExpandableFolders());
+    //mMenu->setItemVisible("collapse", mOutfitList->getHasExpandableFolders());
+    mMenu->arrangeAndClear(); // update menu height
+}
+
+LLToggleableMenu* LLOutfitListGearMenuBase::getMenu()
+{
+    return mMenu;
+}
+const LLUUID& LLOutfitListGearMenuBase::getSelectedOutfitID()
+{
+    return mOutfitList->getSelectedOutfitUUID();
+}
+
+LLViewerInventoryCategory* LLOutfitListGearMenuBase::getSelectedOutfit()
+{
+    const LLUUID& selected_outfit_id = getSelectedOutfitID();
+    if (selected_outfit_id.isNull())
+    {
+        return NULL;
+    }
+
+    LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
+    return cat;
+}
+
+void LLOutfitListGearMenuBase::onWear()
+{
+    LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
+    if (selected_outfit)
+    {
+        LLAppearanceMgr::instance().wearInventoryCategory(
+            selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
+    }
+}
+
+void LLOutfitListGearMenuBase::onAdd()
+{
+    const LLUUID& selected_id = getSelectedOutfitID();
+
+    if (selected_id.notNull())
+    {
+        LLAppearanceMgr::getInstance()->addCategoryToCurrentOutfit(selected_id);
+    }
+}
+
+void LLOutfitListGearMenuBase::onTakeOff()
+{
+    // Take off selected outfit.
+    const LLUUID& selected_outfit_id = getSelectedOutfitID();
+    if (selected_outfit_id.notNull())
+    {
+        LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
+    }
+}
+
+void LLOutfitListGearMenuBase::onRename()
+{
+    const LLUUID& selected_outfit_id = getSelectedOutfitID();
+    if (selected_outfit_id.notNull())
+    {
+        LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
+    }
+}
+
+void LLOutfitListGearMenuBase::onCreate(const LLSD& data)
+{
+    LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
+    if (type == LLWearableType::WT_NONE)
+    {
+        LL_WARNS() << "Invalid wearable type" << LL_ENDL;
+        return;
+    }
+
+    LLAgentWearables::createWearable(type, true);
+}
+
+bool LLOutfitListGearMenuBase::onEnable(LLSD::String param)
+{
+    // Handle the "Wear - Replace Current Outfit" menu option specially
+    // because LLOutfitList::isActionEnabled() checks whether it's allowed
+    // to wear selected outfit OR selected items, while we're only
+    // interested in the outfit (STORM-183).
+    if ("wear" == param)
+    {
+        return LLAppearanceMgr::instance().getCanReplaceCOF(mOutfitList->getSelectedOutfitUUID());
+    }
+
+    return mOutfitList->isActionEnabled(param);
+}
+
+bool LLOutfitListGearMenuBase::onVisible(LLSD::String param)
+{
+    const LLUUID& selected_outfit_id = getSelectedOutfitID();
+    if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
+    {
+        return false;
+    }
+
+    // *TODO This condition leads to menu item behavior inconsistent with
+    // "Wear" button behavior and should be modified or removed.
+    bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
+
+    if ("wear" == param)
+    {
+        return !is_worn;
+    }
+
+    return true;
+}
+
+void LLOutfitListGearMenuBase::onUploadFoto()
+{
+
+}
+
+void LLOutfitListGearMenuBase::onLoadAssets()
+{
+
+}
+
+LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
+    : LLOutfitListGearMenuBase(olist)
+{}
+
+void LLOutfitListGearMenu::onUpdateItemsVisibility()
+{
+    if (!mMenu) return;
+    mMenu->setItemVisible("expand", TRUE);
+    mMenu->setItemVisible("collapse", TRUE);
+    mMenu->setItemVisible("upload_foto", FALSE);
+    mMenu->setItemVisible("load_assets", TRUE);
+    LLOutfitListGearMenuBase::onUpdateItemsVisibility();
+}
+
 // EOF
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 2e3fb3f488..f4b02991e5 100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -32,11 +32,14 @@
 
 // newview
 #include "llinventorymodel.h"
+#include "lllistcontextmenu.h"
 #include "llpanelappearancetab.h"
+#include "lltoggleablemenu.h"
+#include "llviewermenu.h"
 
 class LLAccordionCtrlTab;
 class LLInventoryCategoriesObserver;
-class LLOutfitListGearMenu;
+class LLOutfitListGearMenuBase;
 class LLWearableItemsList;
 class LLListContextMenu;
 
@@ -57,6 +60,134 @@ public:
 	/*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const;
 };
 
+class LLOutfitListBase : public LLPanelAppearanceTab
+{
+public:
+    typedef boost::function<void(const LLUUID&)> selection_change_callback_t;
+    typedef boost::signals2::signal<void(const LLUUID&)> selection_change_signal_t;
+
+    LLOutfitListBase();
+    virtual ~LLOutfitListBase();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& info);
+
+    void refreshList(const LLUUID& category_id);
+    void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+    // highlights currently worn outfit in list and unhighlights previously worn
+    void highlightBaseOutfit();
+    void �hangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
+
+
+    virtual void getCurrentCategories(uuid_vec_t& vcur) = 0;
+    virtual void updateAddedCategory(LLUUID cat_id) = 0;
+    virtual void updateRemovedCategory(LLUUID cat_id) = 0;
+    virtual void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name) = 0;
+    virtual void sortOutfits();
+
+    void removeSelected();
+    void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
+    const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
+    boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
+    void outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
+
+    virtual bool isActionEnabled(const LLSD& userdata);
+    virtual void performAction(std::string action);
+    virtual bool hasItemSelected() = 0;
+    virtual bool canWearSelected() = 0;
+
+    void signalSelectionOutfitUUID(const LLUUID& category_id);
+
+    void collapseAllFolders();
+    virtual void onCollapseAllFolders() = 0;
+
+    void expandAllFolders();
+    virtual void onExpandAllFolders() = 0;
+
+    virtual bool getHasExpandableFolders() = 0;
+
+protected:
+    virtual LLOutfitListGearMenuBase* createGearMenu() = 0;
+    virtual void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) = 0;
+    virtual void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) = 0;
+    virtual void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id) = 0;
+    void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
+    virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0;
+
+    bool                            mIsInitialized;
+    LLInventoryCategoriesObserver* 	mCategoriesObserver;    
+    LLUUID							mSelectedOutfitUUID;
+    // id of currently highlited outfit
+    LLUUID							mHighlightedOutfitUUID;
+    selection_change_signal_t		mSelectionChangeSignal;
+    LLListContextMenu*				mOutfitMenu;
+    LLOutfitListGearMenuBase*		mGearMenu;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+class LLOutfitContextMenu : public LLListContextMenu
+{
+public:
+
+    LLOutfitContextMenu(LLOutfitListBase* outfit_list)
+        : LLListContextMenu(),
+        mOutfitList(outfit_list)
+    {}
+protected:
+    /* virtual */ LLContextMenu* createMenu();
+
+    bool onEnable(LLSD::String param);
+
+    bool onVisible(LLSD::String param);
+
+    static void editOutfit();
+
+    static void renameOutfit(const LLUUID& outfit_cat_id);
+
+private:
+    LLOutfitListBase*	mOutfitList;
+};
+
+class LLOutfitListGearMenuBase
+{
+public:
+    LLOutfitListGearMenuBase(LLOutfitListBase* olist);
+
+    void updateItemsVisibility();
+
+    LLToggleableMenu* getMenu();
+
+protected:
+    virtual void onUpdateItemsVisibility();
+    virtual void onUploadFoto();
+    virtual void onLoadAssets();
+    const LLUUID& getSelectedOutfitID();
+
+    LLOutfitListBase*		mOutfitList;
+    LLToggleableMenu*		mMenu;
+private:
+
+    LLViewerInventoryCategory* getSelectedOutfit();
+
+    void onWear();
+    void onAdd();
+    void onTakeOff();
+    void onRename();
+    void onCreate(const LLSD& data);
+    bool onEnable(LLSD::String param);
+    bool onVisible(LLSD::String param);
+};
+
+class LLOutfitListGearMenu : public LLOutfitListGearMenuBase
+{
+public:
+    LLOutfitListGearMenu(LLOutfitListBase* olist);
+
+protected:
+    /*virtual*/ void onUpdateItemsVisibility();
+};
+
 /**
  * @class LLOutfitsList
  *
@@ -66,11 +197,9 @@ public:
  *
  * Starts fetching necessary inventory content on first opening.
  */
-class LLOutfitsList : public LLPanelAppearanceTab
+class LLOutfitsList : public LLOutfitListBase
 {
 public:
-	typedef boost::function<void (const LLUUID&)> selection_change_callback_t;
-	typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t;
 
 	LLOutfitsList();
 	virtual ~LLOutfitsList();
@@ -79,74 +208,72 @@ public:
 
 	/*virtual*/ void onOpen(const LLSD& info);
 
-	void refreshList(const LLUUID& category_id);
-
-	// highlits currently worn outfit tab text and unhighlights previously worn
-	void highlightBaseOutfit();
 
-	void performAction(std::string action);
+    //virtual void refreshList(const LLUUID& category_id);
 
-	void removeSelected();
+    /*virtual*/ void updateAddedCategory(LLUUID cat_id);
+    /*virtual*/ void updateRemovedCategory(LLUUID cat_id);
 
-	void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
+	// highlits currently worn outfit tab text and unhighlights previously worn
+    /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
 
-	/*virtual*/ void setFilterSubString(const std::string& string);
+	//void performAction(std::string action);
 
-	/*virtual*/ bool isActionEnabled(const LLSD& userdata);
 
-	const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
+	/*virtual*/ void setFilterSubString(const std::string& string);
 
 	/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
 
-	boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
-
-	// Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
+    // Collects selected items from all selected lists and wears them(if possible- adds, else replaces)
 	void wearSelectedItems();
 
 	/**
 	 * Returns true if there is a selection inside currently selected outfit
 	 */
-	bool hasItemSelected();
+    /*virtual*/ bool hasItemSelected();
 
 	/**
 	Collapses all outfit accordions.
 	*/
-	void collapse_all_folders();
+	/*virtual*/ void onCollapseAllFolders();
 	/**
 	Expands all outfit accordions.
 	*/
-	void expand_all_folders();
+	void onExpandAllFolders();
 
+    /*virtual*/ bool getHasExpandableFolders() { return TRUE; }
 
-private:
+protected:
+    LLOutfitListGearMenuBase* createGearMenu();
 
-	void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
+private:
 
 	/**
 	 * Wrapper for LLCommonUtils::computeDifference. @see LLCommonUtils::computeDifference
 	 */
-	void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+	//void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
+
+    void getCurrentCategories(uuid_vec_t& vcur);
 
 	/**
 	 * Updates tab displaying outfit identified by category_id.
 	 */
-	void updateOutfitTab(const LLUUID& category_id);
+    /*virtual*/ void updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name);
+
+    /*virtual*/ void sortOutfits();
+
+    /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
 
 	/**
 	 * Resets previous selection and stores newly selected list and outfit id.
 	 */
-	void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
+    /*virtual*/ void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
 
 	/**
 	 *Resets items selection inside outfit
 	 */
 	void resetItemSelection(LLWearableItemsList* list, const LLUUID& category_id);
 
-	/**
-	 * Saves newly selected outfit ID.
-	 */
-	void setSelectedOutfitUUID(const LLUUID& category_id);
-
 	/**
 	 * Removes the outfit from selection.
 	 */
@@ -182,15 +309,16 @@ private:
 	 */
 	bool canWearSelected();
 
-	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
 	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
 	void onCOFChanged();
 
-	void onSelectionChange(LLUICtrl* ctrl);
+	void onListSelectionChange(LLUICtrl* ctrl);
+
+    /*virtual*/ void onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
 
 	static void onOutfitRename(const LLSD& notification, const LLSD& response);
 
-	LLInventoryCategoriesObserver* 	mCategoriesObserver;
+	//LLInventoryCategoriesObserver* 	mCategoriesObserver;
 
 	LLAccordionCtrl*				mAccordion;
 	LLPanel*						mListCommands;
@@ -199,11 +327,6 @@ private:
 	typedef wearables_lists_map_t::value_type			wearables_lists_map_value_t;
 	wearables_lists_map_t			mSelectedListsMap;
 
-	LLUUID							mSelectedOutfitUUID;
-	// id of currently highlited outfit
-	LLUUID							mHighlightedOutfitUUID;
-	selection_change_signal_t		mSelectionChangeSignal;
-
 	typedef	std::map<LLUUID, LLAccordionCtrlTab*>		outfits_map_t;
 	typedef outfits_map_t::value_type					outfits_map_value_t;
 	outfits_map_t					mOutfitsMap;
@@ -212,10 +335,9 @@ private:
 	// Used to monitor COF changes for updating items worn state. See EXT-8636.
 	uuid_vec_t						mCOFLinkedItems;
 
-	LLOutfitListGearMenu*			mGearMenu;
-	LLListContextMenu*				mOutfitMenu;
+	//LLOutfitListGearMenu*			mGearMenu;
 
-	bool							mIsInitialized;
+	//bool							mIsInitialized;
 	/**
 	 * True if there is a selection inside currently selected outfit
 	 */
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 1e1f59055f..eb88abb2bf 100755
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -37,6 +37,7 @@
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "lloutfitobserver.h"
+#include "lloutfitgallery.h"
 #include "lloutfitslist.h"
 #include "llpanelwearing.h"
 #include "llsaveoutfitcombobtn.h"
@@ -44,6 +45,7 @@
 #include "llviewerfoldertype.h"
 
 static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
+static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";
 static const std::string COF_TAB_NAME = "cof_tab";
 
 static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
@@ -268,12 +270,16 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
 
 void LLPanelOutfitsInventory::initTabPanels()
 {
+    //TODO: Add LLOutfitGallery change callback
 	mCurrentOutfitPanel = findChild<LLPanelWearing>(COF_TAB_NAME);
 	mCurrentOutfitPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
 
 	mMyOutfitsPanel = findChild<LLOutfitsList>(OUTFITS_TAB_NAME);
 	mMyOutfitsPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
 
+    mOutfitGalleryPanel = findChild<LLOutfitGallery>(OUTFIT_GALLERY_TAB_NAME);
+    mOutfitGalleryPanel->setSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));
+
 	mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
 	mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
 }
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index a7917b457c..8c873df038 100755
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -30,8 +30,9 @@
 
 #include "llpanel.h"
 
+class LLOutfitGallery;
 class LLOutfitsList;
-class LLOutfitListGearMenu;
+class LLOutfitListGearMenuBase;
 class LLPanelAppearanceTab;
 class LLPanelWearing;
 class LLMenuGL;
@@ -76,6 +77,7 @@ protected:
 private:
 	LLPanelAppearanceTab*	mActivePanel;
 	LLOutfitsList*			mMyOutfitsPanel;
+    LLOutfitGallery*        mOutfitGalleryPanel;
 	LLPanelWearing*			mCurrentOutfitPanel;
 
 	// tab panels                                                                   //
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 980810835e..1e9d0f912f 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -71,6 +71,7 @@
 #include "llradiogroup.h"
 #include "llfloaterreg.h"
 #include "lllocalbitmaps.h"
+#include "llerror.h"
 
 static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
 static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
@@ -573,6 +574,7 @@ void LLFloaterTexturePicker::draw()
 		mTexturep = NULL;
 		if(mImageAssetID.notNull())
 		{
+            LL_WARNS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
 			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
 			mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a5f2ce1f84..56def93ffe 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -804,4 +804,5 @@ with the same filename but different name
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
 
+  <texture name="Outfit_Default_Foto" fileName="icons/pop_up_caution.png"/>
 </textures>
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 76adaad57c..420aced6a2 100755
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -406,7 +406,7 @@
 	width="400"
 	height="400"
     follows="top|left"/>
-  <view_border 
+  <!--view_border 
    bevel_style="in" 
    height="21"
    layout="topleft"
@@ -414,7 +414,7 @@
    top_pad="0"
    right="-10"
    follows="left|top|right"
-   left_delta="0"/>
+   left_delta="0"/>-->
    <text
     type="string"
     font="SansSerifSmall"
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index 3b8ace6308..c970efbc03 100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -39,8 +39,22 @@
          function="Gear.OnVisible"
          parameter="take_off" />
     </menu_item_call>
+    <menu_item_call
+     label="Upload foto"
+     layout="topleft"
+     name="upload_foto">
+        <on_click
+         function="Gear.UploadFoto" />
+    </menu_item_call>
+    <menu_item_call
+     label="Load assets"
+     layout="topleft"
+     name="load_assets">
+        <on_click
+         function="Gear.LoadAssets" />
+    </menu_item_call>
 
-            <menu_item_separator name="sepatator1" />
+  <menu_item_separator name="sepatator1" />
             <!-- copied (with minor modifications) from menu_inventory_add.xml -->
             <!--  *TODO: generate dynamically? -->
             <menu
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
new file mode 100644
index 0000000000..6146514f98
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+   background_visible="true"
+   bg_alpha_color="DkGray"
+   border="false"
+   follows="all"
+   height="430"
+   name="Outfit Gallery"
+   layout="topleft"
+   left="0"
+   top="0"
+   width="312">
+  <string name="outfit_foto_string">
+    Foto of "[OUTFIT_NAME]" outfit
+  </string>
+  <scroll_container
+   border="true"
+   bevel_style="none"
+   follows="all"
+   height="400"
+   width="312"
+   min_width="312"
+   layout="topleft"
+   left="4"
+   top="0"
+   name="gallery_scroll_panel"
+   opaque="false"
+   top_pad="0">
+   <panel
+   background_visible="true"
+   border="true"
+   bevel_style="none"
+	 follows="all"
+   height="560"
+   width="312"
+   layout="topleft"
+   top="0"
+   left="4"
+   top_pad="0"
+   visible="true"
+   name="gallery_panel">
+   <!--outfit_gallery_item
+    layout="topleft"
+    left="10"
+    name="preview_outfit1"
+    height="175"
+    width="150"
+    follows="left|top"/-->
+     <!--layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="0" name="top_gallery_stack" orientation="horizontal">
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+    </layout_stack>
+    <layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="190" name="top_gallery_stack" orientation="horizontal">
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+      <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+        <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+      </layout_panel>
+    </layout_stack>
+     <layout_stack follows="left|right" height="180" width="498" layout="topleft" left="0" animate="false" top="380" name="top_gallery_stack" orientation="horizontal">
+       <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top_gallery_panel">
+         <outfit_gallery_item layout="topleft" left="10" name="preview_outfit1" height="175" width="150" follows="left|top"/>
+       </layout_panel>
+       <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+         <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+       </layout_panel>
+       <layout_panel follows="left|top" height="175" width="166" layout="topleft" left="0" top="0" auto_resize="false" visible="true" name="top panel">
+         <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
+       </layout_panel>
+     </layout_stack-->
+   </panel>
+  </scroll_container>
+  <panel
+     background_visible="true"
+	 follows="bottom|left|right"
+	 height="28"
+	 layout="topleft"
+	 left="4"
+	 top_pad="0"
+	 visible="true"
+	 name="bottom_panel"
+	 width="312">
+     <menu_button
+       follows="bottom|left"
+       tool_tip="Show additional options"
+       height="25"
+       image_hover_unselected="Toolbar_Left_Over"
+       image_overlay="OptionsMenu_Off"
+       image_selected="Toolbar_Left_Selected"
+       image_unselected="Toolbar_Left_Off"
+       layout="topleft"
+       left="0"
+       name="options_gear_btn"
+       top="1"
+       width="31" />
+     <icon
+       follows="bottom|left|right"
+       height="25"
+       image_name="Toolbar_Middle_Off"
+       layout="topleft"
+       left_pad="1"
+       name="dummy_icon"
+       width="243"/>
+      <button
+       follows="bottom|right"
+       height="25"
+       image_hover_unselected="Toolbar_Right_Over"
+       image_overlay="TrashItem_Off"
+       image_selected="Toolbar_Right_Selected"
+       image_unselected="Toolbar_Right_Off"
+       layout="topleft"
+       left_pad="1"
+       name="trash_btn"
+       tool_tip="Delete selected outfit"
+       width="31"/>
+    </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
new file mode 100644
index 0000000000..acb72402cc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+   background_visible="true"
+   bg_alpha_color="DkGray"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="169"
+   width="149"
+   name="Outfit Gallery Item"
+   layout="topleft"
+   left="0"
+   top="0"
+   >
+  <icon
+      left="0"
+      top="0"
+      layout="topleft"
+      name="preview_outfit"
+      height="149"
+      width="149"
+      follows="left|top"
+      visible="true"
+      image_name="Popup_Caution"
+    />
+  <text
+    length="1"
+    follows="left|top"
+    left="1"
+    height="10"
+    layout="topleft"
+    name="outfit_name"
+    top="150"
+    width="150">
+    Summer hipster, Pierce
+  </text>
+  <text
+    length="1"
+    follows="left|top"
+    left="1"
+    height="10"
+    layout="topleft"
+    name="outfit_worn_text"
+    top="160"
+    width="150">
+    (worn)
+  </text>
+
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 405d9513db..ff0714adbb 100755
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -32,6 +32,17 @@
      halign="center"
      top="8"
      width="315">
+         <panel
+           class="outfit_gallery"
+           filename="panel_outfit_gallery.xml"
+           height="520"
+           name="outfit_gallery_tab"
+           background_visible="true"
+           help_topic="outfit_gallery_tab"
+           follows="all"
+           label="OUTFIT GALLERY"
+           layout="topleft"
+           width="315" />
          <panel
            class="outfits_list"
            filename="panel_outfits_list.xml"
-- 
cgit v1.2.3


From 749bb57cd19d51090d64cd2261048b9a0654807b Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 18 Dec 2015 19:20:32 +0200
Subject: MAINT-5194 Visual Outfit Browser Visual selection of outfit
 implemented

---
 indra/newview/lloutfitgallery.cpp                  | 48 ++++++--------
 indra/newview/lloutfitgallery.h                    |  3 +
 .../default/xui/en/panel_outfit_gallery_item.xml   | 77 ++++++++++++++--------
 3 files changed, 72 insertions(+), 56 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 2d8085e128..ec86e608f2 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -327,7 +327,8 @@ static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_i
 
 LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
     : LLPanel(p),
-    mTexturep(NULL)
+    mTexturep(NULL),
+    mSelected(false)
 {
     buildFromFile("panel_outfit_gallery_item.xml");
 }
@@ -343,6 +344,8 @@ BOOL LLOutfitGalleryItem::postBuild()
 
     mOutfitNameText = getChild<LLTextBox>("outfit_name");
     mOutfitWornText = getChild<LLTextBox>("outfit_worn_text");
+    mFotoBgPanel = getChild<LLPanel>("foto_bg_panel");
+    mTextBgPanel = getChild<LLPanel>("text_bg_panel");
     setOutfitWorn(false);
     return TRUE;
 }
@@ -351,35 +354,32 @@ void LLOutfitGalleryItem::draw()
 {
     LLPanel::draw();
 
-    // In case texture is not set, don't draw it over default image
-    if (!mTexturep)
-    {
-        return;
-    }
-
-    // Border
+    
+    // Draw border
+    LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "FrogGreen" : "MouseGray", LLColor4::white);
     LLRect border = getChildView("preview_outfit")->getRect();
-    //gl_rect_2d(border, LLColor4::black, FALSE);
-
-
-    // Interior
-    LLRect interior = border;
-    //interior.stretch(-1);
+    border.mRight = border.mRight + 1;
+    gl_rect_2d(border, border_color.get(), FALSE);
 
     // If the floater is focused, don't apply its alpha to the texture (STORM-677).
     const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
     if (mTexturep)
     {
-        if (mTexturep->getComponents() == 4)
-        {
-            gl_rect_2d_checkerboard(interior, alpha);
-        }
+        //if (mTexturep->getComponents() == 4)
+        //{
+        //    gl_rect_2d_checkerboard(interior, alpha);
+        //}
 
-        gl_draw_scaled_image(interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
+        // Interior
+        LLRect interior = border;
+        interior.stretch(-1);
+
+        gl_draw_scaled_image(interior.mLeft - 1, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
 
         // Pump the priority
         mTexturep->addTextureStats((F32)(interior.getWidth() * interior.getHeight()));
     }
+    
 }
 
 void LLOutfitGalleryItem::setOutfitName(std::string name)
@@ -404,14 +404,8 @@ void LLOutfitGalleryItem::setOutfitWorn(bool value)
 
 void LLOutfitGalleryItem::setSelected(bool value)
 {
-    if (value)
-    {
-        mOutfitWornText->setValue("(selected)");
-    }
-    else
-    {
-        mOutfitWornText->setValue("");
-    }
+    mSelected = value;
+    mTextBgPanel->setBackgroundVisible(value);
 }
 
 BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 93b9ba1e3f..61a2981a29 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -147,6 +147,9 @@ private:
     LLPointer<LLViewerTexture> mTexturep;
     LLTextBox* mOutfitNameText;
     LLTextBox* mOutfitWornText;
+    LLPanel* mTextBgPanel;
+    LLPanel* mFotoBgPanel;
+    bool     mSelected;
 };
 
 #endif  // LL_LLOUTFITGALLERYCTRL_H
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index acb72402cc..535960502e 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -1,49 +1,68 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
-   background_visible="true"
-   bg_alpha_color="DkGray"
-   border="true"
+   background_visible="false"
+   background_opaque="false"
+   bg_alpha_color="FrogGreen"
+   bg_opaque_color="FrogGreen"
+   border_color="Red"
+   border="false"
    bevel_style="none"
    follows="left|top"
    height="169"
-   width="149"
-   name="Outfit Gallery Item"
+   width="150"
+   name="gallery_item_panel"
    layout="topleft"
    left="0"
    top="0"
    >
   <icon
-      left="0"
+      left="1"
       top="0"
       layout="topleft"
       name="preview_outfit"
       height="149"
-      width="149"
+      width="147"
       follows="left|top"
       visible="true"
       image_name="Popup_Caution"
     />
-  <text
-    length="1"
-    follows="left|top"
-    left="1"
-    height="10"
-    layout="topleft"
-    name="outfit_name"
-    top="150"
-    width="150">
-    Summer hipster, Pierce
-  </text>
-  <text
-    length="1"
-    follows="left|top"
-    left="1"
-    height="10"
-    layout="topleft"
-    name="outfit_worn_text"
-    top="160"
-    width="150">
-    (worn)
-  </text>
+  <panel
+   background_visible="false"
+   background_opaque="true"
+   bg_opaque_color="FrogGreen"
+   border="false"
+   bevel_style="none"
+   follows="left|top"
+   left="0"
+   top="149"
+   height="25"
+   width="148"
+   name="text_bg_panel"
+   >
+    <text
+      read_only="true"
+      length="1"
+      follows="left|top"
+      left="1"
+      height="10"
+      layout="topleft"
+      name="outfit_name"
+      top="0"
+      width="150">
+      Summer hipster, Pierce
+    </text>
+    <text
+      read_only="true"
+      length="1"
+      follows="left|top"
+      left="1"
+      height="10"
+      layout="topleft"
+      name="outfit_worn_text"
+      top="10"
+      width="150">
+      (worn)
+    </text>
+  </panel>
 
 </panel>
-- 
cgit v1.2.3


From 5d576df19047ec45070f6571ebcada26e5c20756 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 22 Dec 2015 20:27:19 +0200
Subject: MAINT-5194 Visual Outfit Browser 1)Added visual hilighting of worn
 outfit 2)Fixed colors  of selection borders to fit initial design

---
 indra/newview/lloutfitgallery.cpp                  | 22 +++++++++++-----------
 indra/newview/lloutfitgallery.h                    |  1 +
 indra/newview/skins/default/colors.xml             |  9 +++++++++
 .../default/xui/en/panel_outfit_gallery_item.xml   |  5 ++++-
 4 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index ec86e608f2..dc6db3307f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -328,7 +328,8 @@ static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_i
 LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
     : LLPanel(p),
     mTexturep(NULL),
-    mSelected(false)
+    mSelected(false),
+    mWorn(false)
 {
     buildFromFile("panel_outfit_gallery_item.xml");
 }
@@ -356,7 +357,7 @@ void LLOutfitGalleryItem::draw()
 
     
     // Draw border
-    LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "FrogGreen" : "MouseGray", LLColor4::white);
+    LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "OutfitGalleryItemSelected" : "OutfitGalleryItemUnselected", LLColor4::white);
     LLRect border = getChildView("preview_outfit")->getRect();
     border.mRight = border.mRight + 1;
     gl_rect_2d(border, border_color.get(), FALSE);
@@ -389,23 +390,22 @@ void LLOutfitGalleryItem::setOutfitName(std::string name)
 
 void LLOutfitGalleryItem::setOutfitWorn(bool value)
 {
+    mWorn = value;
     //LLStringUtil::format_map_t string_args;
     //std::string worn_text = getString("worn_text", string_args);
-
-    if (value)
-    {
-        mOutfitWornText->setValue("(worn)");
-    }
-    else
-    {
-        mOutfitWornText->setValue("");
-    }
+    LLStringUtil::format_map_t worn_string_args;
+    std::string worn_string = getString("worn_string", worn_string_args);
+    LLUIColor text_color = LLUIColorTable::instance().getColor(mSelected ? "White" : (mWorn ? "OutfitGalleryItemWorn" : "White"), LLColor4::white);
+    mOutfitWornText->setReadOnlyColor(text_color.get());
+    mOutfitNameText->setReadOnlyColor(text_color.get());
+    mOutfitWornText->setValue(value ? worn_string : "");
 }
 
 void LLOutfitGalleryItem::setSelected(bool value)
 {
     mSelected = value;
     mTextBgPanel->setBackgroundVisible(value);
+    setOutfitWorn(mWorn);
 }
 
 BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 61a2981a29..81a019f416 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -150,6 +150,7 @@ private:
     LLPanel* mTextBgPanel;
     LLPanel* mFotoBgPanel;
     bool     mSelected;
+    bool     mWorn;
 };
 
 #endif  // LL_LLOUTFITGALLERYCTRL_H
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index bdc884885f..1ee3d0ec0c 100755
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -945,4 +945,13 @@
   <color
     name="SyntaxLslStringLiteral"
     value="1 0.14 0 1" />
+  <color
+    name="OutfitGalleryItemSelected"
+    value="0.22 0.45 0.35 1" />
+  <color
+    name="OutfitGalleryItemWorn"
+    value="0.33 0.58 0.47 1" />
+  <color
+    name="OutfitGalleryItemUnselected"
+    value="0.4 0.4 0.4 1" />
 </colors>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index 535960502e..7c3e93fdae 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -15,6 +15,9 @@
    left="0"
    top="0"
    >
+  <string name="worn_string">
+    (worn)
+  </string>
   <icon
       left="1"
       top="0"
@@ -29,7 +32,7 @@
   <panel
    background_visible="false"
    background_opaque="true"
-   bg_opaque_color="FrogGreen"
+   bg_opaque_color="OutfitGalleryItemSelected"
    border="false"
    bevel_style="none"
    follows="left|top"
-- 
cgit v1.2.3


From 81ecf0c0f304aef72f8b558c732b5ed62acfb946 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Wed, 27 Jan 2016 17:21:25 +0200
Subject: MAINT-5194 Visual Outfit Browser 1) Changed algorithm for building
 gallery, which fixed item cropping when switching between tabs in Appearance
 floater 2) Fixed gap between items in partially fille row

---
 indra/newview/lloutfitgallery.cpp                  | 232 +++++++++++++++------
 indra/newview/lloutfitgallery.h                    |  45 ++--
 .../skins/default/xui/en/panel_outfit_gallery.xml  |  15 +-
 3 files changed, 202 insertions(+), 90 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index dc6db3307f..92827a7b6f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -51,22 +51,40 @@ static LLOutfitGallery* gOutfitGallery = NULL;
 
 LLOutfitGallery::LLOutfitGallery()
     : LLOutfitListBase(),
-      mTexturesObserver(NULL)
+      mTexturesObserver(NULL),
+      mScrollPanel(NULL),
+      mGalleryPanel(NULL),
+      galleryCreated(false),
+      mRowCount(0),
+      mItemsAddedCount(0)
 {
-//    mGearMenu = new LLOutfitGalleryGearMenu(this);
 }
 
 BOOL LLOutfitGallery::postBuild()
 {
     BOOL rv = LLOutfitListBase::postBuild();
+    mScrollPanel = getChild<LLScrollContainer>("gallery_scroll_panel");
+    mGalleryPanel = getChild<LLPanel>("gallery_panel");
     return rv;
 }
 
 void LLOutfitGallery::onOpen(const LLSD& info)
 {
     LLOutfitListBase::onOpen(info);
-    rebuildGallery();
-    loadPhotos();
+    if (!galleryCreated)
+    {
+        loadPhotos();
+        uuid_vec_t cats;
+        getCurrentCategories(cats);
+        int n = cats.size();
+        buildGalleryPanel(n);
+        mScrollPanel->addChild(mGalleryPanel);
+        for (int i = 0; i < n; i++)
+        {
+            addToGallery(mOutfitMap[cats[i]]);
+        }
+        galleryCreated = true;
+    }
 }
 
 #define LAYOUT_STACK_HEIGHT 180
@@ -79,67 +97,126 @@ void LLOutfitGallery::onOpen(const LLSD& info)
 #define LAYOUT_STACK_WIDTH 166 * ITEMS_IN_ROW//498
 #define GALLERY_WIDTH 163 * ITEMS_IN_ROW//485//290
 
-void LLOutfitGallery::rebuildGallery()
+LLPanel* LLOutfitGallery::addLastRow()
 {
-    LLView::child_list_t child_list(*getChild<LLPanel>("gallery_panel")->getChildList());
-    BOOST_FOREACH(LLView* view, child_list)
+    mRowCount++;
+    int row = 0;
+    int vgap = GALLERY_VERTICAL_GAP * row;
+    LLPanel* result = buildLayoutStak(0, row * LAYOUT_STACK_HEIGHT + vgap);
+    mGalleryPanel->addChild(result);
+    return result;
+}
+
+void LLOutfitGallery::moveRowUp(int row)
+{
+    moveRow(row, mRowCount - 1 - row + 1);
+}
+
+void LLOutfitGallery::moveRowDown(int row)
+{
+    moveRow(row, mRowCount - 1 - row - 1);
+}
+
+void LLOutfitGallery::moveRow(int row, int pos)
+{
+    int vgap = GALLERY_VERTICAL_GAP * pos;
+    moveLayoutStak(mStacks[row], 0, pos * LAYOUT_STACK_HEIGHT + vgap);
+}
+
+void LLOutfitGallery::removeLastRow()
+{
+    mRowCount--;
+    mGalleryPanel->removeChild(mLastRowStack);
+    mStacks.pop_back();
+    mLastRowStack = mStacks.back();
+}
+
+LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap)
+{
+    LLPanel* lpanel = buildLayoutPanel(pos * GALLERY_ITEM_WIDTH + hgap);
+    lpanel->addChild(item);
+    row_stack->addChild(lpanel);
+    mPanels.push_back(lpanel);
+    return lpanel;
+}
+
+void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item)
+{
+    mItemsAddedCount++;
+    mItemIndexMap[item] = mItemsAddedCount - 1;
+    int n = mItemsAddedCount;
+    int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
+    int n_prev = n - 1;
+    int row_count_prev = (n_prev % ITEMS_IN_ROW) == 0 ? n_prev / ITEMS_IN_ROW : n_prev / ITEMS_IN_ROW + 1;
+
+    bool add_row = row_count != row_count_prev;
+    int pos = 0;
+    if (add_row)
     {
-        LLLayoutStack* lstack = dynamic_cast<LLLayoutStack*>(view);
-        if (lstack != NULL)
+        for (int i = 0; i < row_count_prev; i++)
         {
-            LLView::child_list_t panel_list(*lstack->getChildList());
-            BOOST_FOREACH(LLView* panel, panel_list)
-            {
-                //LLLayoutPanel* lpanel = dynamic_cast<LLLayoutPanel*>(panel);
-                //if (!lpanel)
-                //    continue;
-                LLView::child_list_t panel_children(*panel->getChildList());
-                if (panel_children.size() > 0)
-                {
-                    //Assume OutfitGalleryItem is the only one child of layout panel
-                    LLView* view_item = panel_children.back();
-                    LLOutfitGalleryItem* gallery_item = dynamic_cast<LLOutfitGalleryItem*>(view_item);
-                    if (gallery_item != NULL)
-                        panel->removeChild(gallery_item);
-                }
-                lstack->removeChild(panel);
-                //delete panel;
-            }
-            getChild<LLPanel>("gallery_panel")->removeChild(lstack);
-            delete lstack;
-        }
-        else
-        {
-            getChild<LLPanel>("gallery_panel")->removeChild(view);
+            moveRowUp(i);
         }
+        mLastRowStack = addLastRow();
+        mStacks.push_back(mLastRowStack);
     }
-    uuid_vec_t cats;
-    getCurrentCategories(cats);
-    int n = cats.size();
+    pos = (n - 1) % ITEMS_IN_ROW;
+    mItems.push_back(item);
+    addToRow(mLastRowStack, item, pos, GALLERY_HORIZONTAL_GAP * pos);
+    reshapeGalleryPanel(row_count);
+}
+
+
+void LLOutfitGallery::removeFromGalleryLast(LLOutfitGalleryItem* item)
+{
+    int n_prev = mItemsAddedCount;
+    int n = mItemsAddedCount - 1;
     int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
-    getChild<LLPanel>("gallery_panel")->reshape(
-        GALLERY_WIDTH, row_count * (LAYOUT_STACK_HEIGHT + GALLERY_VERTICAL_GAP));
-    int vgap = 0;
-    uuid_vec_t::reverse_iterator rit = cats.rbegin();
-    for (int i = row_count - 1; i >= 0; i--)
+    int row_count_prev = (n_prev % ITEMS_IN_ROW) == 0 ? n_prev / ITEMS_IN_ROW : n_prev / ITEMS_IN_ROW + 1;
+    mItemsAddedCount--;
+
+    bool remove_row = row_count != row_count_prev;
+    //int pos = (n_prev - 1) % ITEMS_IN_ROW;
+    removeFromLastRow(mItems[mItemsAddedCount]);
+    mItems.pop_back();
+    if (remove_row)
     {
-        LLLayoutStack* stack = buildLayoutStak(0, (row_count - 1 - i) * LAYOUT_STACK_HEIGHT + vgap);
-        getChild<LLPanel>("gallery_panel")->addChild(stack);
-        int items_in_cur_row = (n % ITEMS_IN_ROW) == 0 ? ITEMS_IN_ROW : (i == row_count - 1 ? n % ITEMS_IN_ROW : ITEMS_IN_ROW);
-        int hgap = 0;
-        for (int j = 0; j < items_in_cur_row && rit != cats.rend(); j++)
+        for (int i = 0; i < row_count_prev - 1; i++)
         {
-            LLLayoutPanel* lpanel = buildLayoutPanel(j * GALLERY_ITEM_WIDTH + hgap);
-            LLOutfitGalleryItem* item = mOutfitMap[*rit];
-            lpanel->addChild(item);
-            stack->addChild(lpanel);
-            rit++;
-            hgap += GALLERY_HORIZONTAL_GAP;
+            moveRowDown(i);
         }
-        vgap += GALLERY_VERTICAL_GAP;
+        removeLastRow();
+    }
+    reshapeGalleryPanel(row_count);
+}
+
+
+void LLOutfitGallery::removeFromGalleryMiddle(LLOutfitGalleryItem* item)
+{
+    int n = mItemIndexMap[item];
+    mItemIndexMap.erase(item);
+    std::vector<LLOutfitGalleryItem*> saved;
+    for (int i = mItemsAddedCount - 1; i > n; i--)
+    {
+        saved.push_back(mItems[i]);
+        removeFromGalleryLast(mItems[i]);
+    }
+    removeFromGalleryLast(mItems[n]);
+    int saved_count = saved.size();
+    for (int i = 0; i < saved_count; i++)
+    {
+        addToGallery(saved.back());
+        saved.pop_back();
     }
 }
 
+void LLOutfitGallery::removeFromLastRow(LLOutfitGalleryItem* item)
+{
+    mPanels.back()->removeChild(item);
+    mLastRowStack->removeChild(mPanels.back());
+    mPanels.pop_back();
+}
+
 LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
 {
     LLOutfitGalleryItem::Params giparams;
@@ -155,11 +232,31 @@ LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
     return gitem;
 }
 
-LLLayoutPanel* LLOutfitGallery::buildLayoutPanel(int left)
+void LLOutfitGallery::buildGalleryPanel(int row_count)
+{
+    LLPanel::Params params;
+    mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params);
+    reshapeGalleryPanel(row_count);
+}
+
+void LLOutfitGallery::reshapeGalleryPanel(int row_count)
 {
-    LLLayoutPanel::Params lpparams;
+    int bottom = 0;
+    int left = 0;
+    int height = row_count * (LAYOUT_STACK_HEIGHT + GALLERY_VERTICAL_GAP);
+    LLRect rect = LLRect(left, bottom + height, left + GALLERY_WIDTH, bottom);
+    mGalleryPanel->setRect(rect);
+    mGalleryPanel->reshape(GALLERY_WIDTH, height);
+    mGalleryPanel->setVisible(true);
+    mGalleryPanel->setFollowsLeft();
+    mGalleryPanel->setFollowsTop();
+}
+
+LLPanel* LLOutfitGallery::buildLayoutPanel(int left)
+{
+    LLPanel::Params lpparams;
     int top = 0;
-    LLLayoutPanel* lpanel = LLUICtrlFactory::create<LLLayoutPanel>(lpparams);
+    LLPanel* lpanel = LLUICtrlFactory::create<LLPanel>(lpparams);
     LLRect rect = LLRect(left, top + GALLERY_ITEM_HEIGHT, left + GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, top);
     lpanel->setRect(rect);
     lpanel->reshape(GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, GALLERY_ITEM_HEIGHT);
@@ -169,20 +266,24 @@ LLLayoutPanel* LLOutfitGallery::buildLayoutPanel(int left)
     return lpanel;
 }
 
-LLLayoutStack* LLOutfitGallery::buildLayoutStak(int left, int top)
+LLPanel* LLOutfitGallery::buildLayoutStak(int left, int bottom)
+{
+    LLPanel::Params sparams;
+    LLPanel* stack = LLUICtrlFactory::create<LLPanel>(sparams);
+    moveLayoutStak(stack, left, bottom);
+    return stack;
+}
+
+void LLOutfitGallery::moveLayoutStak(LLPanel* stack, int left, int bottom)
 {
-    LLLayoutStack::Params sparams;
-    LLLayoutStack* stack = LLUICtrlFactory::create<LLLayoutStack>(sparams);
-    LLRect rect = LLRect(left, top + LAYOUT_STACK_HEIGHT, left + LAYOUT_STACK_WIDTH, top);
+    LLRect rect = LLRect(left, bottom + LAYOUT_STACK_HEIGHT, left + LAYOUT_STACK_WIDTH, bottom);
     stack->setRect(rect);
     stack->reshape(LAYOUT_STACK_WIDTH, LAYOUT_STACK_HEIGHT);
     stack->setVisible(true);
     stack->setFollowsLeft();
     stack->setFollowsTop();
-    return stack;
 }
 
-
 LLOutfitGallery::~LLOutfitGallery()
 {
     if (gInventory.containsObserver(mTexturesObserver))
@@ -240,7 +341,10 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
         _1, _2, _3, cat_id));
     LLWearableItemsList* list = NULL;
     item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::�hangeOutfitSelection, this, list, cat_id));
-
+    if (galleryCreated)
+    {
+        addToGallery(item);
+    }
 }
 
 void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
@@ -259,7 +363,7 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
         mOutfitMap.erase(outfits_iter);
 
         // 4. Remove outfit from gallery.
-        rebuildGallery();
+        removeFromGalleryMiddle(item);
 
         // kill removed item
         if (item != NULL)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 81a019f416..01d56d917f 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -78,11 +78,20 @@ protected:
     /*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
 
 private:
-    void rebuildGallery();
     void loadPhotos();
     void uploadPhoto(LLUUID outfit_id);
     bool checkRemovePhoto(LLUUID outfit_id);
     void setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id);
+    void addToGallery(LLOutfitGalleryItem* item);
+    void removeFromGalleryLast(LLOutfitGalleryItem* item);
+    void removeFromGalleryMiddle(LLOutfitGalleryItem* item);
+    LLPanel* addLastRow();
+    void removeLastRow();
+    void moveRowUp(int row);
+    void moveRowDown(int row);
+    void moveRow(int row, int pos);
+    LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap);
+    void removeFromLastRow(LLOutfitGalleryItem* item);
 
     static void onLoadComplete(LLVFS *vfs,
         const LLUUID& asset_uuid,
@@ -90,20 +99,32 @@ private:
         void* user_data, S32 status, LLExtStat ext_status);
 
     LLOutfitGalleryItem* buildGalleryItem(std::string name);
-    LLLayoutPanel* buildLayoutPanel(int left);
-    LLLayoutStack* buildLayoutStak(int left, int top);
-
+    void buildGalleryPanel(int row_count);
+    void reshapeGalleryPanel(int row_count);
+    LLPanel* buildLayoutPanel(int left);
+    LLPanel* buildLayoutStak(int left, int bottom);
+    void moveLayoutStak(LLPanel* stack, int left, int bottom);
     LLView* mView;
-    std::vector<LLLayoutStack*> mLayouts;
-    std::vector<LLLayoutPanel*> mPanels;
+    std::vector<LLPanel*> mStacks;
+    std::vector<LLPanel*> mPanels;
     std::vector<LLOutfitGalleryItem*> mItems;
+    LLScrollContainer* mScrollPanel;
+    LLPanel* mGalleryPanel;
+    LLPanel* mLastRowStack;
+    bool galleryCreated;
+    int mRowCount;
+    int mItemsAddedCount;
+
+    typedef std::map<LLUUID, LLOutfitGalleryItem*>      outfit_map_t;
+    typedef outfit_map_t::value_type                    outfit_map_value_t;
+    outfit_map_t                                        mOutfitMap;
+    typedef std::map<LLUUID, LLViewerInventoryItem*>    texture_map_t;
+    typedef texture_map_t::value_type                   texture_map_value_t;
+    texture_map_t                                       mTextureMap;
+    typedef std::map<LLOutfitGalleryItem*, int>         item_num_map_t;
+    typedef item_num_map_t::value_type                  item_numb_map_value_t;
+    item_num_map_t                                      mItemIndexMap;
 
-    typedef	std::map<LLUUID, LLOutfitGalleryItem*>		outfit_map_t;
-    typedef outfit_map_t::value_type					outfit_map_value_t;
-    outfit_map_t					mOutfitMap;
-    typedef	std::map<LLUUID, LLViewerInventoryItem*>    texture_map_t;
-    typedef texture_map_t::value_type	                texture_map_value_t;
-    texture_map_t                    mTextureMap;
 
     LLInventoryCategoriesObserver* 	mTexturesObserver;
 
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index 6146514f98..2a06b35942 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -26,19 +26,6 @@
    name="gallery_scroll_panel"
    opaque="false"
    top_pad="0">
-   <panel
-   background_visible="true"
-   border="true"
-   bevel_style="none"
-	 follows="all"
-   height="560"
-   width="312"
-   layout="topleft"
-   top="0"
-   left="4"
-   top_pad="0"
-   visible="true"
-   name="gallery_panel">
    <!--outfit_gallery_item
     layout="topleft"
     left="10"
@@ -79,7 +66,7 @@
          <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
        </layout_panel>
      </layout_stack-->
-   </panel>
+    <!--</panel>-->
   </scroll_container>
   <panel
      background_visible="true"
-- 
cgit v1.2.3


From 5b76576a5a4bde9ae21c080bd612e84d6130ac99 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <none@none>
Date: Thu, 4 Feb 2016 18:56:04 +0200
Subject: MAINT-5194 Visual Outfit Browser Fixed Mac specific build issues

---
 indra/newview/lloutfitgallery.cpp |  5 +----
 indra/newview/lloutfitgallery.h   |  1 -
 indra/newview/lloutfitslist.cpp   | 14 ++++++++++----
 indra/newview/lloutfitslist.h     |  6 ++++--
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 92827a7b6f..e50c35f29f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -221,9 +221,6 @@ LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
 {
     LLOutfitGalleryItem::Params giparams;
     LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams);
-    LLRect girect = LLRect(0, GALLERY_ITEM_HEIGHT - GALLERY_ITEM_HEIGHT,
-        GALLERY_ITEM_WIDTH, 0);
-    //gitem->setRect(girect);
     gitem->reshape(GALLERY_ITEM_WIDTH, GALLERY_ITEM_HEIGHT);
     gitem->setVisible(true);
     gitem->setFollowsLeft();
@@ -340,7 +337,7 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
     item->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this,
         _1, _2, _3, cat_id));
     LLWearableItemsList* list = NULL;
-    item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::�hangeOutfitSelection, this, list, cat_id));
+    item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ChangeOutfitSelection, this, list, cat_id));
     if (galleryCreated)
     {
         addToGallery(item);
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 01d56d917f..323e2580f6 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -104,7 +104,6 @@ private:
     LLPanel* buildLayoutPanel(int left);
     LLPanel* buildLayoutStak(int left, int bottom);
     void moveLayoutStak(LLPanel* stack, int left, int bottom);
-    LLView* mView;
     std::vector<LLPanel*> mStacks;
     std::vector<LLPanel*> mPanels;
     std::vector<LLOutfitGalleryItem*> mItems;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 736da5d411..2b99391dc8 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -227,7 +227,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
         _1, _2, _3, cat_id));
 
     // Setting tab focus callback to monitor currently selected outfit.
-    tab->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::�hangeOutfitSelection, this, list, cat_id));
+    tab->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ChangeOutfitSelection, this, list, cat_id));
 
     // Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
     tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
@@ -469,7 +469,7 @@ void LLOutfitsList::onListSelectionChange(LLUICtrl* ctrl)
 	LLViewerInventoryItem *item = gInventory.getItem(list->getSelectedUUID());
 	if (!item) return;
 
-	�hangeOutfitSelection(list, item->getParentUUID());
+	ChangeOutfitSelection(list, item->getParentUUID());
 }
 
 void LLOutfitListBase::performAction(std::string action)
@@ -508,7 +508,7 @@ void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
 			if (!list) continue;
 
 			tab->setFocus(TRUE);
-			�hangeOutfitSelection(list, outfit_uuid);
+			ChangeOutfitSelection(list, outfit_uuid);
 
 			tab->setDisplayChildren(true);
 		}
@@ -1198,7 +1198,7 @@ void LLOutfitListBase::outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, co
     onOutfitRightClick(ctrl, x, y, cat_id);
 }
 
-void LLOutfitListBase::�hangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
+void LLOutfitListBase::ChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id)
 {
     onChangeOutfitSelection(list, category_id);
     mSelectedOutfitUUID = category_id;
@@ -1335,6 +1335,9 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
     llassert(mMenu);
 }
 
+LLOutfitListGearMenuBase::~LLOutfitListGearMenuBase()
+{}
+
 void LLOutfitListGearMenuBase::updateItemsVisibility()
 {
     onUpdateItemsVisibility();
@@ -1472,6 +1475,9 @@ LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
 
+LLOutfitListGearMenu::~LLOutfitListGearMenu()
+{}
+
 void LLOutfitListGearMenu::onUpdateItemsVisibility()
 {
     if (!mMenu) return;
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index f4b02991e5..9495866d73 100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -76,7 +76,7 @@ public:
     void computeDifference(const LLInventoryModel::cat_array_t& vcats, uuid_vec_t& vadded, uuid_vec_t& vremoved);
     // highlights currently worn outfit in list and unhighlights previously worn
     void highlightBaseOutfit();
-    void �hangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
+    void ChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);
 
 
     virtual void getCurrentCategories(uuid_vec_t& vcur) = 0;
@@ -153,7 +153,8 @@ class LLOutfitListGearMenuBase
 {
 public:
     LLOutfitListGearMenuBase(LLOutfitListBase* olist);
-
+    virtual ~LLOutfitListGearMenuBase();
+    
     void updateItemsVisibility();
 
     LLToggleableMenu* getMenu();
@@ -183,6 +184,7 @@ class LLOutfitListGearMenu : public LLOutfitListGearMenuBase
 {
 public:
     LLOutfitListGearMenu(LLOutfitListBase* olist);
+    virtual ~LLOutfitListGearMenu();
 
 protected:
     /*virtual*/ void onUpdateItemsVisibility();
-- 
cgit v1.2.3


From 12608244387c3247adb759f221da99eb823f53c4 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 5 Feb 2016 18:11:36 +0200
Subject: MAINT-5194 Visual Outfit Browser Corrected typo "foto" to "photo"

---
 indra/newview/lloutfitgallery.cpp                           | 8 ++++----
 indra/newview/lloutfitslist.cpp                             | 4 ++--
 indra/newview/skins/default/xui/en/menu_outfit_gear.xml     | 6 +++---
 indra/newview/skins/default/xui/en/panel_outfit_gallery.xml | 4 ++--
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 92827a7b6f..c1017d4cc0 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -544,7 +544,7 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
     if (!mMenu) return;
     mMenu->setItemVisible("expand", FALSE);
     mMenu->setItemVisible("collapse", FALSE);
-    mMenu->setItemVisible("upload_foto", TRUE);
+    mMenu->setItemVisible("upload_photo", TRUE);
     mMenu->setItemVisible("load_assets", TRUE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
@@ -736,9 +736,9 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 
             checkRemovePhoto(outfit_id);
 
-            LLStringUtil::format_map_t foto_string_args;
-            foto_string_args["OUTFIT_NAME"] = outfit_cat->getName();
-            std::string display_name = getString("outfit_foto_string", foto_string_args);
+            LLStringUtil::format_map_t photo_string_args;
+            photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
+            std::string display_name = getString("outfit_photo_string", photo_string_args);
 
             upload_new_resource(filename, // file
                 display_name,
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 736da5d411..00fa439e8f 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1324,7 +1324,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
 
     registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
 
-    registrar.add("Gear.UploadFoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
+    registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
     registrar.add("Gear.LoadAssets", boost::bind(&LLOutfitListGearMenuBase::onLoadAssets, this));
     
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
@@ -1477,7 +1477,7 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
     if (!mMenu) return;
     mMenu->setItemVisible("expand", TRUE);
     mMenu->setItemVisible("collapse", TRUE);
-    mMenu->setItemVisible("upload_foto", FALSE);
+    mMenu->setItemVisible("upload_photo", FALSE);
     mMenu->setItemVisible("load_assets", TRUE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index c970efbc03..3132c4db8b 100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -40,11 +40,11 @@
          parameter="take_off" />
     </menu_item_call>
     <menu_item_call
-     label="Upload foto"
+     label="Upload Photo (L$10)"
      layout="topleft"
-     name="upload_foto">
+     name="upload_photo">
         <on_click
-         function="Gear.UploadFoto" />
+         function="Gear.UploadPhoto" />
     </menu_item_call>
     <menu_item_call
      label="Load assets"
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index 2a06b35942..c06c6a86c3 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -10,8 +10,8 @@
    left="0"
    top="0"
    width="312">
-  <string name="outfit_foto_string">
-    Foto of "[OUTFIT_NAME]" outfit
+  <string name="outfit_photo_string">
+    Photo of "[OUTFIT_NAME]" outfit
   </string>
   <scroll_container
    border="true"
-- 
cgit v1.2.3


From d52f05dc82c1849f07fd69be5e5fba2cbd1fa47a Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 18 Feb 2016 18:39:53 +0200
Subject: MAINT-5194 Visual Outfit Browser Changed to store uploaded photos as
 links in outfit folders

---
 indra/newview/lloutfitgallery.cpp                  | 191 ++++++++++++---------
 indra/newview/lloutfitgallery.h                    |  16 +-
 .../skins/default/xui/en/panel_outfit_gallery.xml  |   3 +
 3 files changed, 128 insertions(+), 82 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index e5ab736a96..4ee2175286 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -52,11 +52,14 @@ static LLOutfitGallery* gOutfitGallery = NULL;
 LLOutfitGallery::LLOutfitGallery()
     : LLOutfitListBase(),
       mTexturesObserver(NULL),
+      mOutfitsObserver(NULL),
       mScrollPanel(NULL),
       mGalleryPanel(NULL),
       galleryCreated(false),
       mRowCount(0),
-      mItemsAddedCount(0)
+      mItemsAddedCount(0),
+      mPhotoLinkPending(NULL),
+      mOutfitLinkPending(NULL)
 {
 }
 
@@ -342,6 +345,23 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
     {
         addToGallery(item);
     }
+
+    LLViewerInventoryCategory* outfit_category = gInventory.getCategory(cat_id);
+    if (!outfit_category)
+        return;
+
+    if (mOutfitsObserver == NULL)
+    {
+        mOutfitsObserver = new LLInventoryCategoriesObserver();
+        gInventory.addObserver(mOutfitsObserver);
+    }
+
+    // Start observing changes in "My Outits" category.
+    mOutfitsObserver->addCategory(cat_id,
+        boost::bind(&LLOutfitGallery::refreshOutfit, this, cat_id));
+
+    outfit_category->fetch();
+    refreshOutfit(cat_id);
 }
 
 void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
@@ -349,6 +369,9 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
     outfit_map_t::iterator outfits_iter = mOutfitMap.find(cat_id);
     if (outfits_iter != mOutfitMap.end())
     {
+        // 0. Remove category from observer.
+        mOutfitsObserver->removeCategory(cat_id);
+
         //const LLUUID& outfit_id = outfits_iter->first;
         LLOutfitGalleryItem* item = outfits_iter->second;
 
@@ -362,6 +385,8 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
         // 4. Remove outfit from gallery.
         removeFromGalleryMiddle(item);
 
+
+
         // kill removed item
         if (item != NULL)
         {
@@ -573,22 +598,55 @@ void LLOutfitGallery::loadPhotos()
 {
     //Iterate over inventory
     LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::EType::FT_TEXTURE);
-    LLViewerInventoryCategory* category = gInventory.getCategory(textures);
-    if (!category)
+    LLViewerInventoryCategory* textures_category = gInventory.getCategory(textures);
+    if (!textures_category)
         return;
-
     if (mTexturesObserver == NULL)
     {
         mTexturesObserver = new LLInventoryCategoriesObserver();
         gInventory.addObserver(mTexturesObserver);
     }
 
-    // Start observing changes in "My Outfits" category.
+    // Start observing changes in "Textures" category.
     mTexturesObserver->addCategory(textures,
         boost::bind(&LLOutfitGallery::refreshTextures, this, textures));
+    
+    textures_category->fetch();
+}
 
-    category->fetch();
-    refreshTextures(textures);
+void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
+{
+    LLViewerInventoryCategory* category = gInventory.getCategory(category_id);
+    {
+        std::string outfit_name = category->getName();
+        bool photo_loaded = false;
+        LL_WARNS() << "Outfit name:" << outfit_name << LL_ENDL;
+        LLInventoryModel::cat_array_t sub_cat_array;
+        LLInventoryModel::item_array_t outfit_item_array;
+        // Collect all sub-categories of a given category.
+        gInventory.collectDescendents(
+            category->getUUID(),
+            sub_cat_array,
+            outfit_item_array,
+            LLInventoryModel::EXCLUDE_TRASH);
+        BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
+        {
+            LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
+            if (linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+            {
+                std::string texture_name = linked_item->getName();
+                LL_WARNS() << "Texture name:" << texture_name << LL_ENDL;
+                LLUUID asset_id = linked_item->getAssetUUID();
+                mOutfitMap[category_id]->setImageAssetId(asset_id);
+                photo_loaded = true;
+                break;
+            }
+            if (!photo_loaded)
+            {
+                mOutfitMap[category_id]->setDefaultImage();
+            }
+        }
+    }
 }
 
 void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
@@ -607,85 +665,44 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
 
     //Find textures which contain outfit UUID string in description
     LLInventoryModel::item_array_t uploaded_item_array;
+    LLViewerInventoryItem* photo_upload_item = NULL;
     BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
     {
         std::string desc = item->getDescription();
+        std::string name = item->getName();
 
-        LLUUID outfit_id(desc);
-
-        //Check whether description contains correct UUID of outfit
-        if (outfit_id.isNull())
-            continue;
-
-        outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
-        if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
+        if (name == getString("photo_upload_pending_string"))
         {
-            uploaded_item_array.push_back(item);
+            photo_upload_item = item;
+            break;
         }
     }
 
-    uuid_vec_t vadded;
-    uuid_vec_t vremoved;
-
-    // Create added and removed items vectors.
-    computeDifferenceOfTextures(uploaded_item_array, vadded, vremoved);
-
-    BOOST_FOREACH(LLUUID item_id, vadded)
-    {
-        LLViewerInventoryItem* added_item = gInventory.getItem(item_id);
-        LLUUID asset_id = added_item->getAssetUUID();
-        std::string desc = added_item->getDescription();
-        LLUUID outfit_id(desc);
-        mOutfitMap[outfit_id]->setImageAssetId(asset_id);
-        mTextureMap[outfit_id] = added_item;
-    }
-
-    BOOST_FOREACH(LLUUID item_id, vremoved)
+    if (!mPhotoLinkPending.isNull() && photo_upload_item != NULL)
     {
-        LLViewerInventoryItem* rm_item = gInventory.getItem(item_id);
-        std::string desc = rm_item->getDescription();
-        LLUUID outfit_id(desc);
-        mOutfitMap[outfit_id]->setDefaultImage();
-        mTextureMap.erase(outfit_id);
-    }
-
-    /*
-    LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
-    for ( ; it != item_array.end(); it++)
-    {
-        LLViewerInventoryItem* item = (*it);
-        LLUUID asset_id = item->getAssetUUID();
-
-        std::string desc = item->getDescription();
+        LLUUID upload_pending_id = photo_upload_item->getUUID();
+        LLInventoryObject* upload_object = gInventory.getObject(upload_pending_id);
+        if (!upload_object)
+        {
+            LL_WARNS() << "LLOutfitGallery::refreshTextures added_object is null!" << LL_ENDL;
+        }
+        else
+        {
+            LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitLinkPending);
+            linkPhotoToOutfit(upload_pending_id, mOutfitLinkPending);
 
-        LLUUID outfit_id(desc);
+            LLStringUtil::format_map_t photo_string_args;
+            photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
+            std::string new_name = getString("outfit_photo_string", photo_string_args);
 
-        //Check whether description contains correct UUID of outfit
-        if (outfit_id.isNull())
-            continue;
+            LLSD updates;
+            updates["name"] = new_name;
+            update_inventory_item(upload_pending_id, updates, NULL);
 
-        outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
-        if (outfit_it != mOutfitMap.end() && !outfit_it->first.isNull())
-        {
-            outfit_it->second->setImageAssetId(asset_id);
-            mTextureMap[outfit_id] = item;
         }
-
-        
-        //LLUUID* item_idp = new LLUUID();
-
-        //gOutfitGallery = this;
-        //const BOOL high_priority = TRUE;
-        //gAssetStorage->getAssetData(asset_id,
-        //    LLAssetType::AT_TEXTURE,
-        //    onLoadComplete,
-        //    (void**)item_idp,
-        //    high_priority);
-        //
-        ////mAssetStatus = PREVIEW_ASSET_LOADING;
-        
+        mPhotoLinkPending.setNull();
+        mOutfitLinkPending.setNull();
     }
-    */
 }
 
 void LLOutfitGallery::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
@@ -703,6 +720,11 @@ void LLOutfitGallery::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAss
     }
 }
 
+void LLGalleryPhotoStoreCallback(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)
+{
+    LL_WARNS() << "Photo stored as asset. UUID:" << asset_id.asString() << LL_ENDL;
+}
+
 void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 {
     outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
@@ -720,7 +742,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
         if (unit->getValid())
         {
             add_successful = true;
-            LLAssetStorage::LLStoreAssetCallback callback = NULL;
+            //LLAssetStorage::LLStoreAssetCallback callback = &LLGalleryPhotoStoreCallback;
             S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
             void *nruserdata = NULL;
             nruserdata = (void *)&outfit_id;
@@ -732,23 +754,30 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
             if (!outfit_cat) return;
 
             checkRemovePhoto(outfit_id);
+            
+            std::string upload_pending_name = getString("photo_upload_pending_string");
 
-            LLStringUtil::format_map_t photo_string_args;
-            photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
-            std::string display_name = getString("outfit_photo_string", photo_string_args);
-
-            upload_new_resource(filename, // file
-                display_name,
+            LLUUID photo_id = upload_new_resource(filename, // file
+                upload_pending_name,
                 outfit_id.asString(),
                 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
                 LLFloaterPerms::getNextOwnerPerms("Uploads"),
                 LLFloaterPerms::getGroupPerms("Uploads"),
                 LLFloaterPerms::getEveryonePerms("Uploads"),
-                display_name, callback, expected_upload_cost, nruserdata);
+                upload_pending_name, &LLGalleryPhotoStoreCallback, expected_upload_cost, nruserdata);
+
+            mPhotoLinkPending = photo_id;
+            mOutfitLinkPending = outfit_id;
         }
     }
 }
 
+void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
+{
+    LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoUpload();
+    link_inventory_object(outfit_id, photo_id, cb);
+}
+
 bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
 {
     //remove existing photo of outfit from inventory
@@ -771,7 +800,7 @@ void LLOutfitGallery::computeDifferenceOfTextures(
     uuid_vec_t& vremoved)
 {
     uuid_vec_t vnew;
-    // Creating a vector of newly collected sub-categories UUIDs.
+    // Creating a vector of newly collected texture UUIDs.
     for (LLInventoryModel::item_array_t::const_iterator iter = vtextures.begin();
         iter != vtextures.end();
         iter++)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 323e2580f6..47ab85f4e1 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -42,6 +42,16 @@ class LLOutfitGalleryItem;
 class LLOutfitListGearMenuBase;
 class LLOutfitGalleryGearMenu;
 
+class LLUpdateGalleryOnPhotoUpload : public LLInventoryCallback
+{
+public:
+    LLUpdateGalleryOnPhotoUpload(){}
+    virtual ~LLUpdateGalleryOnPhotoUpload(){}
+    /* virtual */ void fire(const LLUUID& inv_item){}
+private:
+};
+
+
 class LLOutfitGallery : public LLOutfitListBase
 {
 public:
@@ -65,6 +75,7 @@ public:
     /*virtual*/ bool getHasExpandableFolders() { return FALSE; }
 
     void refreshTextures(const LLUUID& category_id);
+    void refreshOutfit(const LLUUID& category_id);
     void computeDifferenceOfTextures(const LLInventoryModel::item_array_t& vtextures, uuid_vec_t& vadded, uuid_vec_t& vremoved);
 
 protected:
@@ -80,6 +91,7 @@ protected:
 private:
     void loadPhotos();
     void uploadPhoto(LLUUID outfit_id);
+    void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id);
     bool checkRemovePhoto(LLUUID outfit_id);
     void setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id);
     void addToGallery(LLOutfitGalleryItem* item);
@@ -110,6 +122,8 @@ private:
     LLScrollContainer* mScrollPanel;
     LLPanel* mGalleryPanel;
     LLPanel* mLastRowStack;
+    LLUUID mPhotoLinkPending;
+    LLUUID mOutfitLinkPending;
     bool galleryCreated;
     int mRowCount;
     int mItemsAddedCount;
@@ -126,7 +140,7 @@ private:
 
 
     LLInventoryCategoriesObserver* 	mTexturesObserver;
-
+    LLInventoryCategoriesObserver* 	mOutfitsObserver;
 };
 
 //static LLOutfitGallery* gOutfitGallery;
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index c06c6a86c3..682d2d0730 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -10,6 +10,9 @@
    left="0"
    top="0"
    width="312">
+  <string name="photo_upload_pending_string">
+    Photo upload pending...
+  </string>
   <string name="outfit_photo_string">
     Photo of "[OUTFIT_NAME]" outfit
   </string>
-- 
cgit v1.2.3


From c2bbd1fedd28df3283f087d391f52971e8139327 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 19 Feb 2016 20:47:57 +0200
Subject: MAINT-5194 Visual Outfit Browser Added creating links to photos via
 DragnDrop

---
 indra/newview/llinventorybridge.cpp                |  5 ++--
 indra/newview/lloutfitgallery.cpp                  | 27 ++++------------------
 indra/newview/lloutfitgallery.h                    |  1 -
 .../skins/default/xui/en/panel_outfit_gallery.xml  |  3 ---
 4 files changed, 7 insertions(+), 29 deletions(-)

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 9782c792c9..6e51c08d9c 100755
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4483,8 +4483,9 @@ static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_curr
 	if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
 		(inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
 		(inv_item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) &&
-		(inv_item->getInventoryType() != LLInventoryType::IT_OBJECT))
-	{
+        (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT) &&
+        (inv_item->getInventoryType() != LLInventoryType::IT_TEXTURE))
+    {
 		return FALSE;
 	}
 
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4ee2175286..51d8bea3ad 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -58,7 +58,6 @@ LLOutfitGallery::LLOutfitGallery()
       galleryCreated(false),
       mRowCount(0),
       mItemsAddedCount(0),
-      mPhotoLinkPending(NULL),
       mOutfitLinkPending(NULL)
 {
 }
@@ -618,9 +617,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
 {
     LLViewerInventoryCategory* category = gInventory.getCategory(category_id);
     {
-        std::string outfit_name = category->getName();
         bool photo_loaded = false;
-        LL_WARNS() << "Outfit name:" << outfit_name << LL_ENDL;
         LLInventoryModel::cat_array_t sub_cat_array;
         LLInventoryModel::item_array_t outfit_item_array;
         // Collect all sub-categories of a given category.
@@ -634,8 +631,6 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
             LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
             if (linked_item->getActualType() == LLAssetType::AT_TEXTURE)
             {
-                std::string texture_name = linked_item->getName();
-                LL_WARNS() << "Texture name:" << texture_name << LL_ENDL;
                 LLUUID asset_id = linked_item->getAssetUUID();
                 mOutfitMap[category_id]->setImageAssetId(asset_id);
                 photo_loaded = true;
@@ -663,22 +658,19 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
         LLInventoryModel::EXCLUDE_TRASH,
         is_texture);
 
-    //Find textures which contain outfit UUID string in description
-    LLInventoryModel::item_array_t uploaded_item_array;
+    //Find texture which contain outfit ID string in name
     LLViewerInventoryItem* photo_upload_item = NULL;
     BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
     {
-        std::string desc = item->getDescription();
         std::string name = item->getName();
-
-        if (name == getString("photo_upload_pending_string"))
+        if (!mOutfitLinkPending.isNull() && name == mOutfitLinkPending.asString())
         {
             photo_upload_item = item;
             break;
         }
     }
 
-    if (!mPhotoLinkPending.isNull() && photo_upload_item != NULL)
+    if (photo_upload_item != NULL)
     {
         LLUUID upload_pending_id = photo_upload_item->getUUID();
         LLInventoryObject* upload_object = gInventory.getObject(upload_pending_id);
@@ -700,7 +692,6 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
             update_inventory_item(upload_pending_id, updates, NULL);
 
         }
-        mPhotoLinkPending.setNull();
         mOutfitLinkPending.setNull();
     }
 }
@@ -733,7 +724,6 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
         return;
     }
 
-    bool add_successful = false;
     LLFilePicker& picker = LLFilePicker::instance();
     if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
     {
@@ -741,22 +731,15 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
         LLLocalBitmap* unit = new LLLocalBitmap(filename);
         if (unit->getValid())
         {
-            add_successful = true;
-            //LLAssetStorage::LLStoreAssetCallback callback = &LLGalleryPhotoStoreCallback;
             S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
             void *nruserdata = NULL;
             nruserdata = (void *)&outfit_id;
 
-            LL_WARNS() << "selected_outfit_id: " << outfit_id.asString() << LL_ENDL;
-
-            //LLViewerInventoryItem *outfit = gInventory.getItem(selected_outfit_id);
             LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
             if (!outfit_cat) return;
 
             checkRemovePhoto(outfit_id);
-            
-            std::string upload_pending_name = getString("photo_upload_pending_string");
-
+            std::string upload_pending_name = outfit_id.asString();
             LLUUID photo_id = upload_new_resource(filename, // file
                 upload_pending_name,
                 outfit_id.asString(),
@@ -765,8 +748,6 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
                 LLFloaterPerms::getGroupPerms("Uploads"),
                 LLFloaterPerms::getEveryonePerms("Uploads"),
                 upload_pending_name, &LLGalleryPhotoStoreCallback, expected_upload_cost, nruserdata);
-
-            mPhotoLinkPending = photo_id;
             mOutfitLinkPending = outfit_id;
         }
     }
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 47ab85f4e1..a2bba62157 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -122,7 +122,6 @@ private:
     LLScrollContainer* mScrollPanel;
     LLPanel* mGalleryPanel;
     LLPanel* mLastRowStack;
-    LLUUID mPhotoLinkPending;
     LLUUID mOutfitLinkPending;
     bool galleryCreated;
     int mRowCount;
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index 682d2d0730..c06c6a86c3 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -10,9 +10,6 @@
    left="0"
    top="0"
    width="312">
-  <string name="photo_upload_pending_string">
-    Photo upload pending...
-  </string>
   <string name="outfit_photo_string">
     Photo of "[OUTFIT_NAME]" outfit
   </string>
-- 
cgit v1.2.3


From 5ca5d9f43b56981d0e237566732f16104aaa99db Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 23 Feb 2016 19:12:43 +0200
Subject: MAINT-5194 Visual Outfit Browser Fixed build issues under Linux

---
 indra/newview/lloutfitgallery.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 51d8bea3ad..9a7aa5e277 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -596,7 +596,7 @@ void LLOutfitGalleryGearMenu::onLoadAssets()
 void LLOutfitGallery::loadPhotos()
 {
     //Iterate over inventory
-    LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::EType::FT_TEXTURE);
+    LLUUID textures = gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE);
     LLViewerInventoryCategory* textures_category = gInventory.getCategory(textures);
     if (!textures_category)
         return;
-- 
cgit v1.2.3


From 42008625df1ffba699ee31413ac4c1893528a9dc Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 23 Feb 2016 19:13:33 +0200
Subject: MAINT-5194 Visual Outfit Browser Added ellipsis when outfit name is
 truncated to one line

---
 indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index 7c3e93fdae..d8b0ecaf59 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -51,8 +51,9 @@
       layout="topleft"
       name="outfit_name"
       top="0"
-      width="150">
-      Summer hipster, Pierce
+      width="150"
+      use_ellipses="true">
+      Summer hipster, Pierce Pierce Pierce Pierce
     </text>
     <text
       read_only="true"
-- 
cgit v1.2.3


From 51945162d2f3cde29d698bfad47a2eeafcd86c76 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 25 Feb 2016 20:28:04 +0200
Subject: =?UTF-8?q?MAINT-5194=20Visual=20Outfit=20Browser=20=D0=A1hanging?=
 =?UTF-8?q?=20default=20photo=20for=20outfit?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 indra/newview/lloutfitgallery.cpp                       |   4 ----
 .../default/textures/icons/Default_Outfit_Photo.jpg     | Bin 0 -> 26604 bytes
 indra/newview/skins/default/textures/textures.xml       |   2 +-
 .../skins/default/xui/en/panel_outfit_gallery_item.xml  |   2 +-
 4 files changed, 2 insertions(+), 6 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 9a7aa5e277..9f0c7cbbe3 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -578,10 +578,6 @@ void LLOutfitGalleryGearMenu::onUploadFoto()
     {
         gallery->uploadPhoto(selected_outfit_id);
     }
-    if (selected_outfit_id.notNull())
-    {
-
-    }
 }
 
 void LLOutfitGalleryGearMenu::onLoadAssets()
diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg
new file mode 100644
index 0000000000..c019174fd7
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 1b7b76e3b8..b1b82669a9 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -804,7 +804,7 @@ with the same filename but different name
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
 
-  <texture name="Outfit_Default_Foto" fileName="icons/pop_up_caution.png"/>
+  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.jpg" preload="true"/>
   <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
   <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index d8b0ecaf59..eede209e91 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -27,7 +27,7 @@
       width="147"
       follows="left|top"
       visible="true"
-      image_name="Popup_Caution"
+      image_name="Default_Outfit_Photo"
     />
   <panel
    background_visible="false"
-- 
cgit v1.2.3


From 7ca8e984be40e68c01d2b54092629d41b4df4e46 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 4 Mar 2016 19:41:01 +0200
Subject: MAINT-5194 Visual Outfit Browser 1) Made code clean-up 2) Removed
 constants in code via #define and introduced parametres which can ne set in
 XML instead 3) Made refactoring of some methods 4) Removed non-functional
 item "Load assets" from outfit gear-menu

---
 indra/newview/lloutfitgallery.cpp                  | 181 ++++++--------
 indra/newview/lloutfitgallery.h                    |  66 ++++--
 indra/newview/lloutfitslist.cpp                    | 264 +--------------------
 indra/newview/lloutfitslist.h                      |   5 +-
 .../skins/default/xui/en/menu_outfit_gear.xml      |   7 -
 5 files changed, 141 insertions(+), 382 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 9f0c7cbbe3..48e78b62af 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -45,21 +45,48 @@
 #include "llviewermenufile.h"
 #include "llwearableitemslist.h"
 
-
 static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
 static LLOutfitGallery* gOutfitGallery = NULL;
 
-LLOutfitGallery::LLOutfitGallery()
+LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
     : LLOutfitListBase(),
       mTexturesObserver(NULL),
       mOutfitsObserver(NULL),
       mScrollPanel(NULL),
       mGalleryPanel(NULL),
-      galleryCreated(false),
+      mGalleryCreated(false),
       mRowCount(0),
       mItemsAddedCount(0),
-      mOutfitLinkPending(NULL)
+      mOutfitLinkPending(NULL),
+      mRowPanelHeight(p.row_panel_height),
+      mVerticalGap(p.vertical_gap),
+      mHorizontalGap(p.horizontal_gap),
+      mItemWidth(p.item_width),
+      mItemHeight(p.item_height),
+      mItemHorizontalGap(p.item_horizontal_gap),
+      mItemsInRow(p.items_in_row)
+{
+    mRowPanelWidth = p.row_panel_width_factor * mItemsInRow;
+    mGalleryWidth = p.gallery_width_factor * mItemsInRow;
+}
+
+LLOutfitGallery::Params::Params()
+    : row_panel_height("row_panel_height", 180),
+      vertical_gap("vertical_gap", 10),
+      horizontal_gap("horizontal_gap", 10),
+      item_width("item_width", 150),
+      item_height("item_height", 175),
+      item_horizontal_gap("item_horizontal_gap", 16),
+      items_in_row("items_in_row", 3),
+      row_panel_width_factor("row_panel_width_factor", 166),
+      gallery_width_factor("gallery_width_factor", 163)
+{
+    addSynonym(row_panel_height, "row_height");
+}
+
+const LLOutfitGallery::Params& LLOutfitGallery::getDefaultParams()
 {
+    return LLUICtrlFactory::getDefaultParams<LLOutfitGallery>();
 }
 
 BOOL LLOutfitGallery::postBuild()
@@ -73,7 +100,7 @@ BOOL LLOutfitGallery::postBuild()
 void LLOutfitGallery::onOpen(const LLSD& info)
 {
     LLOutfitListBase::onOpen(info);
-    if (!galleryCreated)
+    if (!mGalleryCreated)
     {
         loadPhotos();
         uuid_vec_t cats;
@@ -85,26 +112,16 @@ void LLOutfitGallery::onOpen(const LLSD& info)
         {
             addToGallery(mOutfitMap[cats[i]]);
         }
-        galleryCreated = true;
+        mGalleryCreated = true;
     }
 }
 
-#define LAYOUT_STACK_HEIGHT 180
-#define GALLERY_VERTICAL_GAP 10
-#define GALLERY_HORIZONTAL_GAP 10
-#define GALLERY_ITEM_WIDTH 150
-#define GALLERY_ITEM_HEIGHT 175
-#define GALLERY_ITEM_HGAP 16 
-#define ITEMS_IN_ROW 3
-#define LAYOUT_STACK_WIDTH 166 * ITEMS_IN_ROW//498
-#define GALLERY_WIDTH 163 * ITEMS_IN_ROW//485//290
-
 LLPanel* LLOutfitGallery::addLastRow()
 {
     mRowCount++;
     int row = 0;
-    int vgap = GALLERY_VERTICAL_GAP * row;
-    LLPanel* result = buildLayoutStak(0, row * LAYOUT_STACK_HEIGHT + vgap);
+    int vgap = mVerticalGap * row;
+    LLPanel* result = buildRowPanel(0, row * mRowPanelHeight + vgap);
     mGalleryPanel->addChild(result);
     return result;
 }
@@ -121,24 +138,24 @@ void LLOutfitGallery::moveRowDown(int row)
 
 void LLOutfitGallery::moveRow(int row, int pos)
 {
-    int vgap = GALLERY_VERTICAL_GAP * pos;
-    moveLayoutStak(mStacks[row], 0, pos * LAYOUT_STACK_HEIGHT + vgap);
+    int vgap = mVerticalGap * pos;
+    moveRowPanel(mRowPanels[row], 0, pos * mRowPanelHeight + vgap);
 }
 
 void LLOutfitGallery::removeLastRow()
 {
     mRowCount--;
-    mGalleryPanel->removeChild(mLastRowStack);
-    mStacks.pop_back();
-    mLastRowStack = mStacks.back();
+    mGalleryPanel->removeChild(mLastRowPanel);
+    mRowPanels.pop_back();
+    mLastRowPanel = mRowPanels.back();
 }
 
 LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap)
 {
-    LLPanel* lpanel = buildLayoutPanel(pos * GALLERY_ITEM_WIDTH + hgap);
+    LLPanel* lpanel = buildItemPanel(pos * mItemWidth + hgap);
     lpanel->addChild(item);
     row_stack->addChild(lpanel);
-    mPanels.push_back(lpanel);
+    mItemPanels.push_back(lpanel);
     return lpanel;
 }
 
@@ -147,9 +164,9 @@ void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item)
     mItemsAddedCount++;
     mItemIndexMap[item] = mItemsAddedCount - 1;
     int n = mItemsAddedCount;
-    int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
+    int row_count = (n % mItemsInRow) == 0 ? n / mItemsInRow : n / mItemsInRow + 1;
     int n_prev = n - 1;
-    int row_count_prev = (n_prev % ITEMS_IN_ROW) == 0 ? n_prev / ITEMS_IN_ROW : n_prev / ITEMS_IN_ROW + 1;
+    int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1;
 
     bool add_row = row_count != row_count_prev;
     int pos = 0;
@@ -159,12 +176,12 @@ void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item)
         {
             moveRowUp(i);
         }
-        mLastRowStack = addLastRow();
-        mStacks.push_back(mLastRowStack);
+        mLastRowPanel = addLastRow();
+        mRowPanels.push_back(mLastRowPanel);
     }
-    pos = (n - 1) % ITEMS_IN_ROW;
+    pos = (n - 1) % mItemsInRow;
     mItems.push_back(item);
-    addToRow(mLastRowStack, item, pos, GALLERY_HORIZONTAL_GAP * pos);
+    addToRow(mLastRowPanel, item, pos, mHorizontalGap * pos);
     reshapeGalleryPanel(row_count);
 }
 
@@ -173,12 +190,11 @@ void LLOutfitGallery::removeFromGalleryLast(LLOutfitGalleryItem* item)
 {
     int n_prev = mItemsAddedCount;
     int n = mItemsAddedCount - 1;
-    int row_count = (n % ITEMS_IN_ROW) == 0 ? n / ITEMS_IN_ROW : n / ITEMS_IN_ROW + 1;
-    int row_count_prev = (n_prev % ITEMS_IN_ROW) == 0 ? n_prev / ITEMS_IN_ROW : n_prev / ITEMS_IN_ROW + 1;
+    int row_count = (n % mItemsInRow) == 0 ? n / mItemsInRow : n / mItemsInRow + 1;
+    int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1;
     mItemsAddedCount--;
 
     bool remove_row = row_count != row_count_prev;
-    //int pos = (n_prev - 1) % ITEMS_IN_ROW;
     removeFromLastRow(mItems[mItemsAddedCount]);
     mItems.pop_back();
     if (remove_row)
@@ -214,16 +230,16 @@ void LLOutfitGallery::removeFromGalleryMiddle(LLOutfitGalleryItem* item)
 
 void LLOutfitGallery::removeFromLastRow(LLOutfitGalleryItem* item)
 {
-    mPanels.back()->removeChild(item);
-    mLastRowStack->removeChild(mPanels.back());
-    mPanels.pop_back();
+    mItemPanels.back()->removeChild(item);
+    mLastRowPanel->removeChild(mItemPanels.back());
+    mItemPanels.pop_back();
 }
 
 LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name)
 {
     LLOutfitGalleryItem::Params giparams;
     LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams);
-    gitem->reshape(GALLERY_ITEM_WIDTH, GALLERY_ITEM_HEIGHT);
+    gitem->reshape(mItemWidth, mItemHeight);
     gitem->setVisible(true);
     gitem->setFollowsLeft();
     gitem->setFollowsTop();
@@ -242,42 +258,42 @@ void LLOutfitGallery::reshapeGalleryPanel(int row_count)
 {
     int bottom = 0;
     int left = 0;
-    int height = row_count * (LAYOUT_STACK_HEIGHT + GALLERY_VERTICAL_GAP);
-    LLRect rect = LLRect(left, bottom + height, left + GALLERY_WIDTH, bottom);
+    int height = row_count * (mRowPanelHeight + mVerticalGap);
+    LLRect rect = LLRect(left, bottom + height, left + mGalleryWidth, bottom);
     mGalleryPanel->setRect(rect);
-    mGalleryPanel->reshape(GALLERY_WIDTH, height);
+    mGalleryPanel->reshape(mGalleryWidth, height);
     mGalleryPanel->setVisible(true);
     mGalleryPanel->setFollowsLeft();
     mGalleryPanel->setFollowsTop();
 }
 
-LLPanel* LLOutfitGallery::buildLayoutPanel(int left)
+LLPanel* LLOutfitGallery::buildItemPanel(int left)
 {
     LLPanel::Params lpparams;
     int top = 0;
     LLPanel* lpanel = LLUICtrlFactory::create<LLPanel>(lpparams);
-    LLRect rect = LLRect(left, top + GALLERY_ITEM_HEIGHT, left + GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, top);
+    LLRect rect = LLRect(left, top + mItemHeight, left + mItemWidth + mItemHorizontalGap, top);
     lpanel->setRect(rect);
-    lpanel->reshape(GALLERY_ITEM_WIDTH + GALLERY_ITEM_HGAP, GALLERY_ITEM_HEIGHT);
+    lpanel->reshape(mItemWidth + mItemHorizontalGap, mItemHeight);
     lpanel->setVisible(true);
     lpanel->setFollowsLeft();
     lpanel->setFollowsTop();
     return lpanel;
 }
 
-LLPanel* LLOutfitGallery::buildLayoutStak(int left, int bottom)
+LLPanel* LLOutfitGallery::buildRowPanel(int left, int bottom)
 {
     LLPanel::Params sparams;
     LLPanel* stack = LLUICtrlFactory::create<LLPanel>(sparams);
-    moveLayoutStak(stack, left, bottom);
+    moveRowPanel(stack, left, bottom);
     return stack;
 }
 
-void LLOutfitGallery::moveLayoutStak(LLPanel* stack, int left, int bottom)
+void LLOutfitGallery::moveRowPanel(LLPanel* stack, int left, int bottom)
 {
-    LLRect rect = LLRect(left, bottom + LAYOUT_STACK_HEIGHT, left + LAYOUT_STACK_WIDTH, bottom);
+    LLRect rect = LLRect(left, bottom + mRowPanelHeight, left + mRowPanelWidth, bottom);
     stack->setRect(rect);
-    stack->reshape(LAYOUT_STACK_WIDTH, LAYOUT_STACK_HEIGHT);
+    stack->reshape(mRowPanelWidth, mRowPanelHeight);
     stack->setVisible(true);
     stack->setFollowsLeft();
     stack->setFollowsTop();
@@ -290,6 +306,12 @@ LLOutfitGallery::~LLOutfitGallery()
         gInventory.removeObserver(mTexturesObserver);
     }
     delete mTexturesObserver;
+
+    if (gInventory.containsObserver(mOutfitsObserver))
+    {
+        gInventory.removeObserver(mOutfitsObserver);
+    }
+    delete mOutfitsObserver;
 }
 
 void LLOutfitGallery::setFilterSubString(const std::string& string)
@@ -340,7 +362,7 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
         _1, _2, _3, cat_id));
     LLWearableItemsList* list = NULL;
     item->setFocusReceivedCallback(boost::bind(&LLOutfitListBase::ChangeOutfitSelection, this, list, cat_id));
-    if (galleryCreated)
+    if (mGalleryCreated)
     {
         addToGallery(item);
     }
@@ -355,7 +377,7 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id)
         gInventory.addObserver(mOutfitsObserver);
     }
 
-    // Start observing changes in "My Outits" category.
+    // Start observing changes in "My Outfits" category.
     mOutfitsObserver->addCategory(cat_id,
         boost::bind(&LLOutfitGallery::refreshOutfit, this, cat_id));
 
@@ -376,7 +398,7 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
 
         // An outfit is removed from the list. Do the following:
         // 2. Remove the outfit from selection.
-        //deselectOutfit(outfit_id);
+        deselectOutfit(cat_id);
 
         // 3. Remove category UUID to accordion tab mapping.
         mOutfitMap.erase(outfits_iter);
@@ -384,8 +406,6 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id)
         // 4. Remove outfit from gallery.
         removeFromGalleryMiddle(item);
 
-
-
         // kill removed item
         if (item != NULL)
         {
@@ -479,7 +499,6 @@ BOOL LLOutfitGalleryItem::postBuild()
 void LLOutfitGalleryItem::draw()
 {
     LLPanel::draw();
-
     
     // Draw border
     LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "OutfitGalleryItemSelected" : "OutfitGalleryItemUnselected", LLColor4::white);
@@ -491,12 +510,6 @@ void LLOutfitGalleryItem::draw()
     const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
     if (mTexturep)
     {
-        //if (mTexturep->getComponents() == 4)
-        //{
-        //    gl_rect_2d_checkerboard(interior, alpha);
-        //}
-
-        // Interior
         LLRect interior = border;
         interior.stretch(-1);
 
@@ -516,8 +529,6 @@ void LLOutfitGalleryItem::setOutfitName(std::string name)
 void LLOutfitGalleryItem::setOutfitWorn(bool value)
 {
     mWorn = value;
-    //LLStringUtil::format_map_t string_args;
-    //std::string worn_text = getString("worn_text", string_args);
     LLStringUtil::format_map_t worn_string_args;
     std::string worn_string = getString("worn_string", worn_string_args);
     LLUIColor text_color = LLUIColorTable::instance().getColor(mSelected ? "White" : (mWorn ? "OutfitGalleryItemWorn" : "White"), LLColor4::white);
@@ -547,11 +558,6 @@ void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
 
 void LLOutfitGalleryItem::setDefaultImage()
 {
-    /*
-    LLUUID imageAssetID("e417f443-a199-bac1-86b0-0530e177fb54");
-    mTexturep = LLViewerTextureManager::getFetchedTexture(imageAssetID);
-    mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
-    */
     mTexturep = NULL;
 }
 
@@ -580,15 +586,6 @@ void LLOutfitGalleryGearMenu::onUploadFoto()
     }
 }
 
-void LLOutfitGalleryGearMenu::onLoadAssets()
-{
-    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
-    if (gallery != NULL)
-    {
-        gallery->loadPhotos();
-    }
-}
-
 void LLOutfitGallery::loadPhotos()
 {
     //Iterate over inventory
@@ -692,26 +689,6 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
     }
 }
 
-void LLOutfitGallery::onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
-{
-    LL_WARNS() << "asset_uuid: " << asset_uuid.asString() << LL_ENDL;
-
-    LLUUID* outfit_id = (LLUUID*)user_data;
-        if (!user_data)
-        return;
-    LL_WARNS() << "outfit_id: " << outfit_id->asString() << LL_ENDL;
-
-    outfit_map_t::iterator it = gOutfitGallery->mOutfitMap.find(*outfit_id);
-    if (it != gOutfitGallery->mOutfitMap.end() && !it->first.isNull())
-    {
-    }
-}
-
-void LLGalleryPhotoStoreCallback(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)
-{
-    LL_WARNS() << "Photo stored as asset. UUID:" << asset_id.asString() << LL_ENDL;
-}
-
 void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 {
     outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
@@ -736,6 +713,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 
             checkRemovePhoto(outfit_id);
             std::string upload_pending_name = outfit_id.asString();
+            LLAssetStorage::LLStoreAssetCallback callback = NULL;
             LLUUID photo_id = upload_new_resource(filename, // file
                 upload_pending_name,
                 outfit_id.asString(),
@@ -743,7 +721,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
                 LLFloaterPerms::getNextOwnerPerms("Uploads"),
                 LLFloaterPerms::getGroupPerms("Uploads"),
                 LLFloaterPerms::getEveryonePerms("Uploads"),
-                upload_pending_name, &LLGalleryPhotoStoreCallback, expected_upload_cost, nruserdata);
+                upload_pending_name, callback, expected_upload_cost, nruserdata);
             mOutfitLinkPending = outfit_id;
         }
     }
@@ -766,11 +744,6 @@ bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
     return false;
 }
 
-void LLOutfitGallery::setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id)
-{
-
-}
-
 void LLOutfitGallery::computeDifferenceOfTextures(
     const LLInventoryModel::item_array_t& vtextures,
     uuid_vec_t& vadded,
@@ -793,8 +766,6 @@ void LLOutfitGallery::computeDifferenceOfTextures(
     {
         vcur.push_back((*iter).second->getUUID());
     }
-//    getCurrentCategories(vcur);
 
     LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
-
 }
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index a2bba62157..dfb100bd43 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -56,7 +56,28 @@ class LLOutfitGallery : public LLOutfitListBase
 {
 public:
     friend class LLOutfitGalleryGearMenu;
-    LLOutfitGallery();
+
+    struct Params
+        : public LLInitParam::Block<Params, LLPanel::Params>
+    {
+        Optional<S32>   row_panel_height;
+        Optional<S32>   row_panel_width_factor;
+        Optional<S32>   gallery_width_factor;
+        Optional<S32>   vertical_gap;
+        Optional<S32>   horizontal_gap;
+        Optional<S32>   item_width;
+        Optional<S32>   item_height;
+        Optional<S32>   item_horizontal_gap;
+        Optional<S32>   items_in_row;
+
+        Params();
+    };
+
+    static const LLOutfitGallery::Params& getDefaultParams();
+
+    LLOutfitGallery(const LLOutfitGallery::Params& params = getDefaultParams());
+
+//    LLOutfitGallery();
     virtual ~LLOutfitGallery();
 
     /*virtual*/ BOOL postBuild();
@@ -93,7 +114,6 @@ private:
     void uploadPhoto(LLUUID outfit_id);
     void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id);
     bool checkRemovePhoto(LLUUID outfit_id);
-    void setUploadedPhoto(LLUUID outfit_id, LLUUID asset_id);
     void addToGallery(LLOutfitGalleryItem* item);
     void removeFromGalleryLast(LLOutfitGalleryItem* item);
     void removeFromGalleryMiddle(LLOutfitGalleryItem* item);
@@ -105,27 +125,44 @@ private:
     LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap);
     void removeFromLastRow(LLOutfitGalleryItem* item);
 
-    static void onLoadComplete(LLVFS *vfs,
-        const LLUUID& asset_uuid,
-        LLAssetType::EType type,
-        void* user_data, S32 status, LLExtStat ext_status);
-
     LLOutfitGalleryItem* buildGalleryItem(std::string name);
     void buildGalleryPanel(int row_count);
     void reshapeGalleryPanel(int row_count);
-    LLPanel* buildLayoutPanel(int left);
-    LLPanel* buildLayoutStak(int left, int bottom);
-    void moveLayoutStak(LLPanel* stack, int left, int bottom);
-    std::vector<LLPanel*> mStacks;
-    std::vector<LLPanel*> mPanels;
+    LLPanel* buildItemPanel(int left);
+    LLPanel* buildRowPanel(int left, int bottom);
+    void moveRowPanel(LLPanel* stack, int left, int bottom);
+    std::vector<LLPanel*> mRowPanels;
+    std::vector<LLPanel*> mItemPanels;
     std::vector<LLOutfitGalleryItem*> mItems;
     LLScrollContainer* mScrollPanel;
     LLPanel* mGalleryPanel;
-    LLPanel* mLastRowStack;
+    LLPanel* mLastRowPanel;
     LLUUID mOutfitLinkPending;
-    bool galleryCreated;
+    bool mGalleryCreated;
     int mRowCount;
     int mItemsAddedCount;
+    /* Params */
+    int mRowPanelHeight;
+    int mVerticalGap;
+    int mHorizontalGap;
+    int mItemWidth;
+    int mItemHeight;
+    int mItemHorizontalGap;
+    int mItemsInRow;
+    int mRowPanelWidth;
+    int mGalleryWidth;
+
+    /*
+    #define LAYOUT_STACK_WIDTH_FACTOR 166
+    #define LAYOUT_STACK_WIDTH LAYOUT_STACK_WIDTH_FACTOR * ITEMS_IN_ROW//498
+    #define GALLERY_WIDTH_FACTOR 163
+    #define GALLERY_WIDTH GALLERY_WIDTH_FACTOR * ITEMS_IN_ROW//485//290
+    */
+
+    /*
+    #define GALLERY_ITEM_HGAP 16 
+    #define ITEMS_IN_ROW 3
+    */
 
     typedef std::map<LLUUID, LLOutfitGalleryItem*>      outfit_map_t;
     typedef outfit_map_t::value_type                    outfit_map_value_t;
@@ -155,7 +192,6 @@ protected:
 
 private:
     /*virtual*/ void onUploadFoto();
-    /*virtual*/ void onLoadAssets();
 };
 
 class LLOutfitGalleryItem : public LLPanel
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 945a8325f8..a7636fc368 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -38,7 +38,6 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
-//#include "lllistcontextmenu.h"
 #include "llmenubutton.h"
 #include "llnotificationsutil.h"
 #include "lloutfitobserver.h"
@@ -106,14 +105,10 @@ LLOutfitsList::LLOutfitsList()
 	,	mListCommands(NULL)
 	,	mItemSelected(false)
 {
-//	mCategoriesObserver = new LLInventoryCategoriesObserver();
-
-//	mGearMenu = new LLOutfitListGearMenu(this);
 }
 
 LLOutfitsList::~LLOutfitsList()
 {
-//	delete mGearMenu;
 }
 
 BOOL LLOutfitsList::postBuild()
@@ -121,11 +116,6 @@ BOOL LLOutfitsList::postBuild()
 	mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
 	mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
 
-	//LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
-
-	//menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenu::updateItemsVisibility, mGearMenu));
-	//menu_gear_btn->setMenu(mGearMenu->getMenu());
-
     return LLOutfitListBase::postBuild();
 }
 
@@ -141,44 +131,6 @@ void LLOutfitsList::onOpen(const LLSD& info)
 
     LLOutfitListBase::onOpen(info);
 
- //   if (!mIsInitialized)
-	//{
-	//	// *TODO: I'm not sure is this check necessary but it never match while developing.
-	//	if (!gInventory.isInventoryUsable())
-	//		return;
-
-	//	const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
-
-	//	// *TODO: I'm not sure is this check necessary but it never match while developing.
-	//	LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
-	//	if (!category)
-	//		return;
-
-	//	gInventory.addObserver(mCategoriesObserver);
-
-	//	// Start observing changes in "My Outfits" category.
-	//	mCategoriesObserver->addCategory(outfits,
-	//		boost::bind(&LLOutfitsList::refreshList, this, outfits));
-
-	//	const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
-
-	//	// Start observing changes in Current Outfit category.
-	//	mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
-
-	//	LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
-	//	LLOutfitObserver::instance().addBOFReplacedCallback(boost::bind(&LLOutfitsList::highlightBaseOutfit, this));
-
-	//	// Fetch "My Outfits" contents and refresh the list to display
-	//	// initially fetched items. If not all items are fetched now
-	//	// the observer will refresh the list as soon as the new items
-	//	// arrive.
-	//	category->fetch();
-	//	refreshList(outfits);
-	//	highlightBaseOutfit();
-
-	//	mIsInitialized = true;
-	//}
-
 	LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
 	if (!selected_tab) return;
 
@@ -295,157 +247,6 @@ void LLOutfitsList::updateRemovedCategory(LLUUID cat_id)
     }
 }
 
-/*
-void LLOutfitsList::refreshList(const LLUUID& category_id)
-{
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-
-	// Collect all sub-categories of a given category.
-	LLIsType is_category(LLAssetType::AT_CATEGORY);
-	gInventory.collectDescendentsIf(
-		category_id,
-		cat_array,
-		item_array,
-		LLInventoryModel::EXCLUDE_TRASH,
-		is_category);
-
-	uuid_vec_t vadded;
-	uuid_vec_t vremoved;
-
-	// Create added and removed items vectors.
-	computeDifference(cat_array, vadded, vremoved);
-
-	// Handle added tabs.
-	for (uuid_vec_t::const_iterator iter = vadded.begin();
-		 iter != vadded.end();
-		 ++iter)
-	{
-		const LLUUID cat_id = (*iter);
-        updateAddedCategory(cat_id);
-		//LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
-		//if (!cat) continue;
-
-		//std::string name = cat->getName();
-
-		//outfit_accordion_tab_params tab_params(get_accordion_tab_params());
-		//LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(tab_params);
-		//if (!tab) continue;
-		//LLWearableItemsList* wearable_list = LLUICtrlFactory::create<LLWearableItemsList>(tab_params.wearable_list);
-		//wearable_list->setShape(tab->getLocalRect());
-		//tab->addChild(wearable_list);
-
-		//tab->setName(name);
-		//tab->setTitle(name);
-
-		//// *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated.
-		//tab->setDisplayChildren(false);
-		//mAccordion->addCollapsibleCtrl(tab);
-
-		//// Start observing the new outfit category.
-		//LLWearableItemsList* list  = tab->getChild<LLWearableItemsList>("wearable_items_list");
-		//if (!mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id)))
-		//{
-		//	// Remove accordion tab if category could not be added to observer.
-		//	mAccordion->removeCollapsibleCtrl(tab);
-
-		//	// kill removed tab
-		//		tab->die();
-		//	continue;
-		//}
-
-		//// Map the new tab with outfit category UUID.
-		//mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
-
-		//tab->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onAccordionTabRightClick, this,
-		//	_1, _2, _3, cat_id));
-
-		//// Setting tab focus callback to monitor currently selected outfit.
-		//tab->setFocusReceivedCallback(boost::bind(&LLOutfitsList::changeOutfitSelection, this, list, cat_id));
-
-		//// Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
-		//tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
-
-		//// force showing list items that don't match current filter(EXT-7158)
-		//list->setForceShowingUnmatchedItems(true);
-
-		//// Setting list commit callback to monitor currently selected wearable item.
-		//list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
-
-		//// Setting list refresh callback to apply filter on list change.
-		//list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
-
-		//list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
-
-		//// Fetch the new outfit contents.
-		//cat->fetch();
-
-		//// Refresh the list of outfit items after fetch().
-		//// Further list updates will be triggered by the category observer.
-		//list->updateList(cat_id);
-
-		//// If filter is currently applied we store the initial tab state and
-		//// open it to show matched items if any.
-		//if (!sFilterSubString.empty())
-		//{
-		//	tab->notifyChildren(LLSD().with("action","store_state"));
-		//	tab->setDisplayChildren(true);
-
-		//	// Setting mForceRefresh flag will make the list refresh its contents
-		//	// even if it is not currently visible. This is required to apply the
-		//	// filter to the newly added list.
-		//	list->setForceRefresh(true);
-
-		//	list->setFilterSubString(sFilterSubString);
-		//}
-	}
-
-	// Handle removed tabs.
-	for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); ++iter)
-	{
-        const LLUUID cat_id = (*iter);
-        updateRemovedCategory(cat_id);
-        //outfits_map_t::iterator outfits_iter = mOutfitsMap.find(cat_id);
-		//if (outfits_iter != mOutfitsMap.end())
-		//{
-		//	const LLUUID& outfit_id = outfits_iter->first;
-		//	LLAccordionCtrlTab* tab = outfits_iter->second;
-
-		//	// An outfit is removed from the list. Do the following:
-		//	// 1. Remove outfit category from observer to stop monitoring its changes.
-		//	mCategoriesObserver->removeCategory(outfit_id);
-
-		//	// 2. Remove the outfit from selection.
-		//	deselectOutfit(outfit_id);
-
-		//	// 3. Remove category UUID to accordion tab mapping.
-		//	mOutfitsMap.erase(outfits_iter);
-
-		//	// 4. Remove outfit tab from accordion.
-		//	mAccordion->removeCollapsibleCtrl(tab);
-
-		//	// kill removed tab
-		//	if (tab != NULL)
-		//	{
-		//		tab->die();
-		//	}
-		//}
-	}
-
-	// Get changed items from inventory model and update outfit tabs
-	// which might have been renamed.
-	const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
-	for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
-		 items_iter != changed_items.end();
-		 ++items_iter)
-	{
-		updateChangedCategoryName(*items_iter);
-	}
-
-	mAccordion->sort();
-}
-*/
-
 //virtual
 void LLOutfitsList::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
 {
@@ -628,33 +429,6 @@ bool LLOutfitsList::hasItemSelected()
 //////////////////////////////////////////////////////////////////////////
 // Private methods
 //////////////////////////////////////////////////////////////////////////
-/*
-void LLOutfitsList::computeDifference(
-	const LLInventoryModel::cat_array_t& vcats, 
-	uuid_vec_t& vadded, 
-	uuid_vec_t& vremoved)
-{
-	uuid_vec_t vnew;
-	// Creating a vector of newly collected sub-categories UUIDs.
-	for (LLInventoryModel::cat_array_t::const_iterator iter = vcats.begin();
-		iter != vcats.end();
-		iter++)
-	{
-		vnew.push_back((*iter)->getUUID());
-	}
-
-	uuid_vec_t vcur;
-	// Creating a vector of currently displayed sub-categories UUIDs.
-	for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
-		iter != mOutfitsMap.end();
-		iter++)
-	{
-		vcur.push_back((*iter).first);
-	}
-
-	LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
-}
-*/
 
 void LLOutfitsList::updateChangedCategoryName(LLViewerInventoryCategory *cat, std::string name)
 {
@@ -710,12 +484,8 @@ void LLOutfitsList::deselectOutfit(const LLUUID& category_id)
 {
 	// Remove selected lists map entry.
 	mSelectedListsMap.erase(category_id);
-
-	// Reset selection if the outfit is selected.
-	if (category_id == mSelectedOutfitUUID)
-	{
-		signalSelectionOutfitUUID(LLUUID::null);
-	}
+    
+    LLOutfitListBase::deselectOutfit(category_id);
 }
 
 void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID& category_id)
@@ -1056,12 +826,6 @@ void LLOutfitListBase::onOpen(const LLSD& info)
 
         mIsInitialized = true;
     }
-
-    //LLAccordionCtrlTab* selected_tab = mAccordion->getSelectedTab();
-    //if (!selected_tab) return;
-
-    //// Pass focus to the selected outfit tab.
-    //selected_tab->showAndFocusHeader();
 }
 
 void LLOutfitListBase::refreshList(const LLUUID& category_id)
@@ -1133,13 +897,6 @@ void LLOutfitListBase::computeDifference(
     }
 
     uuid_vec_t vcur;
-    //// Creating a vector of currently displayed sub-categories UUIDs.
-    //for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
-    //    iter != mOutfitsMap.end();
-    //    iter++)
-    //{
-    //    vcur.push_back((*iter).first);
-    //}
     getCurrentCategories(vcur);
 
     LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
@@ -1226,6 +983,15 @@ void LLOutfitListBase::expandAllFolders()
     onExpandAllFolders();
 }
 
+void LLOutfitListBase::deselectOutfit(const LLUUID& category_id)
+{
+    // Reset selection if the outfit is selected.
+    if (category_id == mSelectedOutfitUUID)
+    {
+        signalSelectionOutfitUUID(LLUUID::null);
+    }
+}
+
 LLContextMenu* LLOutfitContextMenu::createMenu()
 {
     LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -1325,7 +1091,6 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
     registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
 
     registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
-    registrar.add("Gear.LoadAssets", boost::bind(&LLOutfitListGearMenuBase::onLoadAssets, this));
     
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
     enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
@@ -1350,8 +1115,6 @@ void LLOutfitListGearMenuBase::onUpdateItemsVisibility()
     bool have_selection = getSelectedOutfitID().notNull();
     mMenu->setItemVisible("sepatator1", have_selection);
     mMenu->setItemVisible("sepatator2", have_selection);
-    //mMenu->setItemVisible("expand", mOutfitList->getHasExpandableFolders());
-    //mMenu->setItemVisible("collapse", mOutfitList->getHasExpandableFolders());
     mMenu->arrangeAndClear(); // update menu height
 }
 
@@ -1466,11 +1229,6 @@ void LLOutfitListGearMenuBase::onUploadFoto()
 
 }
 
-void LLOutfitListGearMenuBase::onLoadAssets()
-{
-
-}
-
 LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 9495866d73..6db3efa70d 100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -96,6 +96,8 @@ public:
     virtual bool hasItemSelected() = 0;
     virtual bool canWearSelected() = 0;
 
+    virtual void deselectOutfit(const LLUUID& category_id);
+
     void signalSelectionOutfitUUID(const LLUUID& category_id);
 
     void collapseAllFolders();
@@ -162,7 +164,6 @@ public:
 protected:
     virtual void onUpdateItemsVisibility();
     virtual void onUploadFoto();
-    virtual void onLoadAssets();
     const LLUUID& getSelectedOutfitID();
 
     LLOutfitListBase*		mOutfitList;
@@ -279,7 +280,7 @@ private:
 	/**
 	 * Removes the outfit from selection.
 	 */
-	void deselectOutfit(const LLUUID& category_id);
+	/*virtual*/ void deselectOutfit(const LLUUID& category_id);
 
 	/**
 	 * Try restoring selection for a temporary hidden tab.
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index 3132c4db8b..e31ff2a6e2 100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -46,13 +46,6 @@
         <on_click
          function="Gear.UploadPhoto" />
     </menu_item_call>
-    <menu_item_call
-     label="Load assets"
-     layout="topleft"
-     name="load_assets">
-        <on_click
-         function="Gear.LoadAssets" />
-    </menu_item_call>
 
   <menu_item_separator name="sepatator1" />
             <!-- copied (with minor modifications) from menu_inventory_add.xml -->
-- 
cgit v1.2.3


From ff0f2d2f9746b991c01bdbc8c685cb35c711cf2d Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 11 Mar 2016 18:25:25 +0200
Subject: MAINT-5194 Visual Outfit Browser Fixed Mac build issue

---
 indra/newview/lloutfitgallery.cpp | 1 -
 indra/newview/lloutfitgallery.h   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 48e78b62af..c301f5d570 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -46,7 +46,6 @@
 #include "llwearableitemslist.h"
 
 static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
-static LLOutfitGallery* gOutfitGallery = NULL;
 
 LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
     : LLOutfitListBase(),
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index dfb100bd43..97b80acd19 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -179,8 +179,6 @@ private:
     LLInventoryCategoriesObserver* 	mOutfitsObserver;
 };
 
-//static LLOutfitGallery* gOutfitGallery;
-
 class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase
 {
 public:
-- 
cgit v1.2.3


From cb45000b837a1e04db91865c516b4b1c2b141d2f Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 15 Mar 2016 18:20:41 +0200
Subject: MAINT-5194 Visual Outfit Browser Changed default outfit icon

---
 .../default/textures/icons/Default_Outfit_Photo.PNG     | Bin 0 -> 15058 bytes
 .../default/textures/icons/Default_Outfit_Photo.jpg     | Bin 26604 -> 0 bytes
 indra/newview/skins/default/textures/textures.xml       |   2 +-
 3 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG
 delete mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg

diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG
new file mode 100644
index 0000000000..781454880a
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG differ
diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg
deleted file mode 100644
index c019174fd7..0000000000
Binary files a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.jpg and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b1b82669a9..be23cbfeb7 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -804,7 +804,7 @@ with the same filename but different name
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
 
-  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.jpg" preload="true"/>
+  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/>
   <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
   <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
-- 
cgit v1.2.3


From 7a49c07fcb914430cbe4905071b0b901033dd75a Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Wed, 16 Mar 2016 17:13:53 +0200
Subject: MAINT-5194 Visual Outfit Browser Attempt to fix issue with default
 outfit icon on Mac

---
 .../default/textures/icons/Default_Outfit_Photo.PNG     | Bin 15058 -> 0 bytes
 .../textures/icons/Default_Outfit_Photo_renamed.png     | Bin 0 -> 15058 bytes
 indra/newview/skins/default/textures/textures.xml       |   2 +-
 3 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG
 create mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png

diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG
deleted file mode 100644
index 781454880a..0000000000
Binary files a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.PNG and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png
new file mode 100644
index 0000000000..781454880a
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index be23cbfeb7..56a15fff42 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -804,7 +804,7 @@ with the same filename but different name
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
 
-  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/>
+  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo_renamed.png" preload="true"/>
   <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
   <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
-- 
cgit v1.2.3


From 824deea265614b649e074d4702e8f4bf071cef68 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 17 Mar 2016 19:25:23 +0200
Subject: MAINT-5194 Visual Outfit Browser Changed default outfit icon

---
 .../default/textures/icons/Default_Outfit_Photo.png     | Bin 0 -> 19459 bytes
 .../textures/icons/Default_Outfit_Photo_renamed.png     | Bin 15058 -> 0 bytes
 indra/newview/skins/default/textures/textures.xml       |   2 +-
 3 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png
 delete mode 100644 indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png

diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png
new file mode 100644
index 0000000000..bacddcbb68
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo.png differ
diff --git a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png b/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png
deleted file mode 100644
index 781454880a..0000000000
Binary files a/indra/newview/skins/default/textures/icons/Default_Outfit_Photo_renamed.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 56a15fff42..be23cbfeb7 100755
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -804,7 +804,7 @@ with the same filename but different name
   <texture name="Camera_Drag_Dot" file_name="world/CameraDragDot.png"/>
   <texture name="NavBar Separator" file_name="navbar/separator.png"/>
 
-  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo_renamed.png" preload="true"/>
+  <texture name="Default_Outfit_Photo" file_name="icons/Default_Outfit_Photo.png" preload="true"/>
   <texture name="Notification_Condense" file_name="icons/Icon_Notification_Condense.png" preload="true"/>
   <texture name="Notification_Expand" file_name="icons/Icon_Notification_Expand.png" preload="true"/>
   <texture name="System_Notification" file_name="icons/SL_Logo.png" preload="true"/>
-- 
cgit v1.2.3


From 30569854448e52e085366390a078054e1aa53ed9 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Wed, 30 Mar 2016 20:33:52 +0300
Subject: MAINT-6243 Photo upload for Visual Outfit Browser on the latest Mac
 build doesn't update Fixed photo update on upload over existing photo

---
 indra/newview/lloutfitgallery.cpp | 84 ++++++++++++++++++---------------------
 indra/newview/lloutfitgallery.h   | 28 ++++---------
 2 files changed, 46 insertions(+), 66 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index c301f5d570..8af05173e6 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -57,6 +57,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
       mRowCount(0),
       mItemsAddedCount(0),
       mOutfitLinkPending(NULL),
+      mOutfitRenamePending(NULL),
       mRowPanelHeight(p.row_panel_height),
       mVerticalGap(p.vertical_gap),
       mHorizontalGap(p.horizontal_gap),
@@ -621,11 +622,23 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
         BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
         {
             LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
-            if (linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+            if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
             {
                 LLUUID asset_id = linked_item->getAssetUUID();
                 mOutfitMap[category_id]->setImageAssetId(asset_id);
                 photo_loaded = true;
+                std::string linked_item_name = linked_item->getName();
+                if (!mOutfitRenamePending.isNull() && mOutfitRenamePending.asString() == linked_item_name)
+                {
+                    LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitRenamePending);
+                    LLStringUtil::format_map_t photo_string_args;
+                    photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
+                    std::string new_name = getString("outfit_photo_string", photo_string_args);
+                    LLSD updates;
+                    updates["name"] = new_name;
+                    update_inventory_item(linked_item->getUUID(), updates, NULL);
+                    mOutfitRenamePending.setNull();
+                }
                 break;
             }
             if (!photo_loaded)
@@ -650,7 +663,7 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
         LLInventoryModel::EXCLUDE_TRASH,
         is_texture);
 
-    //Find texture which contain outfit ID string in name
+    //Find texture which contain pending outfit ID string in name
     LLViewerInventoryItem* photo_upload_item = NULL;
     BOOST_FOREACH(LLViewerInventoryItem* item, item_array)
     {
@@ -664,27 +677,18 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
 
     if (photo_upload_item != NULL)
     {
-        LLUUID upload_pending_id = photo_upload_item->getUUID();
-        LLInventoryObject* upload_object = gInventory.getObject(upload_pending_id);
+        LLUUID photo_item_id = photo_upload_item->getUUID();
+        LLInventoryObject* upload_object = gInventory.getObject(photo_item_id);
         if (!upload_object)
         {
             LL_WARNS() << "LLOutfitGallery::refreshTextures added_object is null!" << LL_ENDL;
         }
         else
         {
-            LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(mOutfitLinkPending);
-            linkPhotoToOutfit(upload_pending_id, mOutfitLinkPending);
-
-            LLStringUtil::format_map_t photo_string_args;
-            photo_string_args["OUTFIT_NAME"] = outfit_cat->getName();
-            std::string new_name = getString("outfit_photo_string", photo_string_args);
-
-            LLSD updates;
-            updates["name"] = new_name;
-            update_inventory_item(upload_pending_id, updates, NULL);
-
+            linkPhotoToOutfit(photo_item_id, mOutfitLinkPending);
+            mOutfitRenamePending = mOutfitLinkPending;
+            mOutfitLinkPending.setNull();
         }
-        mOutfitLinkPending.setNull();
     }
 }
 
@@ -728,43 +732,31 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 
 void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
 {
-    LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoUpload();
+    LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked(this);
     link_inventory_object(outfit_id, photo_id, cb);
 }
 
 bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
 {
-    //remove existing photo of outfit from inventory
-    texture_map_t::iterator texture_it = mTextureMap.find(outfit_id);
-    if (texture_it != mTextureMap.end()) {
-        gInventory.removeItem(texture_it->second->getUUID());
-        return true;
+    //remove existing photo link from outfit folder
+    LLInventoryModel::cat_array_t sub_cat_array;
+    LLInventoryModel::item_array_t outfit_item_array;
+    gInventory.collectDescendents(
+        outfit_id,
+        sub_cat_array,
+        outfit_item_array,
+        LLInventoryModel::EXCLUDE_TRASH);
+    BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
+    {
+        LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
+        if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+        {
+            gInventory.removeItem(outfit_item->getUUID());
+        }
     }
-    return false;
+    return true;
 }
 
-void LLOutfitGallery::computeDifferenceOfTextures(
-    const LLInventoryModel::item_array_t& vtextures,
-    uuid_vec_t& vadded,
-    uuid_vec_t& vremoved)
+void LLUpdateGalleryOnPhotoLinked::fire(const LLUUID& inv_item_id)
 {
-    uuid_vec_t vnew;
-    // Creating a vector of newly collected texture UUIDs.
-    for (LLInventoryModel::item_array_t::const_iterator iter = vtextures.begin();
-        iter != vtextures.end();
-        iter++)
-    {
-        vnew.push_back((*iter)->getUUID());
-    }
-
-    uuid_vec_t vcur;
-    // Creating a vector of currently uploaded texture UUIDs.
-    for (texture_map_t::const_iterator iter = mTextureMap.begin();
-        iter != mTextureMap.end();
-        iter++)
-    {
-        vcur.push_back((*iter).second->getUUID());
-    }
-
-    LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
 }
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 97b80acd19..ce3964ca1d 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -38,24 +38,26 @@
 #include <vector>
 
 class LLVFS;
+class LLOutfitGallery;
 class LLOutfitGalleryItem;
 class LLOutfitListGearMenuBase;
 class LLOutfitGalleryGearMenu;
 
-class LLUpdateGalleryOnPhotoUpload : public LLInventoryCallback
+class LLUpdateGalleryOnPhotoLinked : public LLInventoryCallback
 {
 public:
-    LLUpdateGalleryOnPhotoUpload(){}
-    virtual ~LLUpdateGalleryOnPhotoUpload(){}
-    /* virtual */ void fire(const LLUUID& inv_item){}
+    LLUpdateGalleryOnPhotoLinked(LLOutfitGallery* gallery) : mGallery(gallery) {}
+    virtual ~LLUpdateGalleryOnPhotoLinked(){}
+    /* virtual */ void fire(const LLUUID& inv_item_id);
 private:
+    LLOutfitGallery* mGallery;
 };
 
-
 class LLOutfitGallery : public LLOutfitListBase
 {
 public:
     friend class LLOutfitGalleryGearMenu;
+    friend class LLUpdateGalleryOnPhotoLinked;
 
     struct Params
         : public LLInitParam::Block<Params, LLPanel::Params>
@@ -76,8 +78,6 @@ public:
     static const LLOutfitGallery::Params& getDefaultParams();
 
     LLOutfitGallery(const LLOutfitGallery::Params& params = getDefaultParams());
-
-//    LLOutfitGallery();
     virtual ~LLOutfitGallery();
 
     /*virtual*/ BOOL postBuild();
@@ -97,7 +97,6 @@ public:
 
     void refreshTextures(const LLUUID& category_id);
     void refreshOutfit(const LLUUID& category_id);
-    void computeDifferenceOfTextures(const LLInventoryModel::item_array_t& vtextures, uuid_vec_t& vadded, uuid_vec_t& vremoved);
 
 protected:
     /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
@@ -138,6 +137,7 @@ private:
     LLPanel* mGalleryPanel;
     LLPanel* mLastRowPanel;
     LLUUID mOutfitLinkPending;
+    LLUUID mOutfitRenamePending;
     bool mGalleryCreated;
     int mRowCount;
     int mItemsAddedCount;
@@ -152,18 +152,6 @@ private:
     int mRowPanelWidth;
     int mGalleryWidth;
 
-    /*
-    #define LAYOUT_STACK_WIDTH_FACTOR 166
-    #define LAYOUT_STACK_WIDTH LAYOUT_STACK_WIDTH_FACTOR * ITEMS_IN_ROW//498
-    #define GALLERY_WIDTH_FACTOR 163
-    #define GALLERY_WIDTH GALLERY_WIDTH_FACTOR * ITEMS_IN_ROW//485//290
-    */
-
-    /*
-    #define GALLERY_ITEM_HGAP 16 
-    #define ITEMS_IN_ROW 3
-    */
-
     typedef std::map<LLUUID, LLOutfitGalleryItem*>      outfit_map_t;
     typedef outfit_map_t::value_type                    outfit_map_value_t;
     outfit_map_t                                        mOutfitMap;
-- 
cgit v1.2.3


From 4f27522175ce2be03cf7ef4673fcc57e29d88554 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 31 Mar 2016 19:13:31 +0300
Subject: Fixed build on Mac

---
 indra/newview/lloutfitgallery.cpp | 2 +-
 indra/newview/lloutfitgallery.h   | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 8af05173e6..5bab133080 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -732,7 +732,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 
 void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
 {
-    LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked(this);
+    LLPointer<LLInventoryCallback> cb = new LLUpdateGalleryOnPhotoLinked();
     link_inventory_object(outfit_id, photo_id, cb);
 }
 
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index ce3964ca1d..e9b0fecae7 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -46,11 +46,10 @@ class LLOutfitGalleryGearMenu;
 class LLUpdateGalleryOnPhotoLinked : public LLInventoryCallback
 {
 public:
-    LLUpdateGalleryOnPhotoLinked(LLOutfitGallery* gallery) : mGallery(gallery) {}
+    LLUpdateGalleryOnPhotoLinked(){}
     virtual ~LLUpdateGalleryOnPhotoLinked(){}
     /* virtual */ void fire(const LLUUID& inv_item_id);
 private:
-    LLOutfitGallery* mGallery;
 };
 
 class LLOutfitGallery : public LLOutfitListBase
-- 
cgit v1.2.3


From 808b8ed01849fc6e2cd5caba68843eebcadc5333 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 5 Apr 2016 17:44:53 +0300
Subject: MAINT-6228 Update Photo/Image Upload feature for Outfit Browser 1)
 Added "Select Photo" to outfit gear menu 2) Incorporated Texture Picker

---
 indra/newview/lloutfitgallery.cpp                  | 108 ++++++++++-
 indra/newview/lloutfitgallery.h                    |  18 +-
 indra/newview/lloutfitslist.cpp                    |  10 +-
 indra/newview/lloutfitslist.h                      |   2 +
 indra/newview/lltexturectrl.cpp                    | 199 +++++++--------------
 indra/newview/lltexturectrl.h                      | 141 ++++++++++++++-
 .../skins/default/xui/en/menu_outfit_gear.xml      |   7 +
 7 files changed, 339 insertions(+), 146 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 5bab133080..81ef8e96ec 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -42,6 +42,7 @@
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
 #include "lllocalbitmaps.h"
+#include "lltexturectrl.h"
 #include "llviewermenufile.h"
 #include "llwearableitemslist.h"
 
@@ -552,13 +553,20 @@ BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
 
 void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
 {
+    mImageAssetId = image_asset_id;
     mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
     mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 }
 
+LLUUID LLOutfitGalleryItem::getImageAssetId()
+{
+    return mImageAssetId;
+}
+
 void LLOutfitGalleryItem::setDefaultImage()
 {
     mTexturep = NULL;
+    mImageAssetId.setNull();
 }
 
 LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
@@ -572,7 +580,7 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("expand", FALSE);
     mMenu->setItemVisible("collapse", FALSE);
     mMenu->setItemVisible("upload_photo", TRUE);
-    mMenu->setItemVisible("load_assets", TRUE);
+    mMenu->setItemVisible("select_photo", TRUE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
@@ -586,6 +594,20 @@ void LLOutfitGalleryGearMenu::onUploadFoto()
     }
 }
 
+void LLOutfitGalleryGearMenu::onSelectPhoto()
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    LLUUID selected_outfit_id = getSelectedOutfitID();
+    if (gallery && !selected_outfit_id.isNull())
+    {
+        gallery->onSelectPhoto(selected_outfit_id);
+    }
+}
+
+void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp)
+{
+}
+
 void LLOutfitGallery::loadPhotos()
 {
     //Iterate over inventory
@@ -760,3 +782,87 @@ bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
 void LLUpdateGalleryOnPhotoLinked::fire(const LLUUID& inv_item_id)
 {
 }
+
+LLUUID LLOutfitGallery::getPhotoAssetId(const LLUUID& outfit_id)
+{
+    outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
+    if (outfit_it != mOutfitMap.end())
+    {
+        return outfit_it->second->getImageAssetId();
+    }
+    return LLUUID();
+}
+
+LLUUID LLOutfitGallery::getDefaultPhoto()
+{
+    return LLUUID();
+}
+
+void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id)
+{
+    LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+
+    if (floaterp && op == LLTextureCtrl::TEXTURE_SELECT)
+    {
+        LLUUID image_item_id;
+        if (id.notNull())
+        {
+            image_item_id = id;
+        }
+        else
+        {
+            image_item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+        }
+        checkRemovePhoto(getSelectedOutfitUUID());
+        linkPhotoToOutfit(image_item_id, getSelectedOutfitUUID());
+    }
+}
+
+void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
+{
+    if (selected_outfit_id.notNull())
+    {
+
+        // show hourglass cursor when loading inventory window
+        // because inventory construction is slooow
+        getWindow()->setCursor(UI_CURSOR_WAIT);
+        LLFloater* floaterp = mFloaterHandle.get();
+
+        // Show the dialog
+        if (floaterp)
+        {
+            floaterp->openFloater();
+        }
+        else
+        {
+            floaterp = new LLFloaterTexturePicker(
+                this,
+                getPhotoAssetId(selected_outfit_id),
+                getPhotoAssetId(selected_outfit_id),
+                getPhotoAssetId(selected_outfit_id),
+                FALSE,
+                TRUE,
+                "SELECT PHOTO",
+                PERM_NONE,
+                PERM_NONE,
+                PERM_NONE,
+                FALSE,
+                NULL);
+
+            mFloaterHandle = floaterp->getHandle();
+
+            LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+            if (texture_floaterp)
+            {
+                texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1));
+            }
+            if (texture_floaterp)
+            {
+                texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
+            }
+
+            floaterp->openFloater();
+        }
+        floaterp->setFocus(TRUE);
+    }
+}
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index e9b0fecae7..e874776e3e 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -33,6 +33,7 @@
 #include "lllayoutstack.h"
 #include "lloutfitslist.h"
 #include "llpanelappearancetab.h"
+#include "lltexturectrl.h"
 #include "llviewertexture.h"
 
 #include <vector>
@@ -81,6 +82,8 @@ public:
 
     /*virtual*/ BOOL postBuild();
     /*virtual*/ void onOpen(const LLSD& info);
+    
+    void onSelectPhoto(LLUUID selected_outfit_id);
 
     /*virtual*/ void setFilterSubString(const std::string& string);
 
@@ -97,6 +100,7 @@ public:
     void refreshTextures(const LLUUID& category_id);
     void refreshOutfit(const LLUUID& category_id);
 
+    void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id);
 protected:
     /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
     /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
@@ -110,6 +114,8 @@ protected:
 private:
     void loadPhotos();
     void uploadPhoto(LLUUID outfit_id);
+    LLUUID getPhotoAssetId(const LLUUID& outfit_id);
+    LLUUID getDefaultPhoto();
     void linkPhotoToOutfit(LLUUID outfit_id, LLUUID photo_id);
     bool checkRemovePhoto(LLUUID outfit_id);
     void addToGallery(LLOutfitGalleryItem* item);
@@ -124,6 +130,9 @@ private:
     void removeFromLastRow(LLOutfitGalleryItem* item);
 
     LLOutfitGalleryItem* buildGalleryItem(std::string name);
+
+    void onTextureSelectionChanged(LLInventoryItem* itemp);
+
     void buildGalleryPanel(int row_count);
     void reshapeGalleryPanel(int row_count);
     LLPanel* buildItemPanel(int left);
@@ -151,12 +160,11 @@ private:
     int mRowPanelWidth;
     int mGalleryWidth;
 
+    LLHandle<LLFloater> mFloaterHandle;
+
     typedef std::map<LLUUID, LLOutfitGalleryItem*>      outfit_map_t;
     typedef outfit_map_t::value_type                    outfit_map_value_t;
     outfit_map_t                                        mOutfitMap;
-    typedef std::map<LLUUID, LLViewerInventoryItem*>    texture_map_t;
-    typedef texture_map_t::value_type                   texture_map_value_t;
-    texture_map_t                                       mTextureMap;
     typedef std::map<LLOutfitGalleryItem*, int>         item_num_map_t;
     typedef item_num_map_t::value_type                  item_numb_map_value_t;
     item_num_map_t                                      mItemIndexMap;
@@ -174,9 +182,9 @@ public:
 
 protected:
     /*virtual*/ void onUpdateItemsVisibility();
-
 private:
     /*virtual*/ void onUploadFoto();
+    /*virtual*/ void onSelectPhoto();
 };
 
 class LLOutfitGalleryItem : public LLPanel
@@ -194,11 +202,13 @@ public:
 
     void setDefaultImage();
     void setImageAssetId(LLUUID asset_id);
+    LLUUID getImageAssetId();
     void setOutfitName(std::string name);
     void setOutfitWorn(bool value);
     void setSelected(bool value);
 private:
     LLPointer<LLViewerTexture> mTexturep;
+    LLUUID mImageAssetId;
     LLTextBox* mOutfitNameText;
     LLTextBox* mOutfitWornText;
     LLPanel* mTextBgPanel;
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index a7636fc368..b657d2e285 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1091,7 +1091,8 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
     registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this));
 
     registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
-    
+    registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this));
+
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
     enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
 
@@ -1229,6 +1230,11 @@ void LLOutfitListGearMenuBase::onUploadFoto()
 
 }
 
+void LLOutfitListGearMenuBase::onSelectPhoto()
+{
+
+}
+
 LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
@@ -1242,7 +1248,7 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("expand", TRUE);
     mMenu->setItemVisible("collapse", TRUE);
     mMenu->setItemVisible("upload_photo", FALSE);
-    mMenu->setItemVisible("load_assets", TRUE);
+    mMenu->setItemVisible("select_photo", FALSE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 6db3efa70d..d7c549c417 100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -164,6 +164,8 @@ public:
 protected:
     virtual void onUpdateItemsVisibility();
     virtual void onUploadFoto();
+    virtual void onSelectPhoto();
+
     const LLUUID& getSelectedOutfitID();
 
     LLOutfitListBase*		mOutfitList;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1e9d0f912f..ee98ad0c4f 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -37,8 +37,6 @@
 #include "llbutton.h"
 #include "lldraghandle.h"
 #include "llfocusmgr.h"
-#include "llviewertexture.h"
-#include "llfolderview.h"
 #include "llfolderviewmodel.h"
 #include "llinventory.h"
 #include "llinventoryfunctions.h"
@@ -83,118 +81,13 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
 //static const char WHITE_IMAGE_NAME[] = "Blank Texture";
 //static const char NO_IMAGE_NAME[] = "None";
 
-//////////////////////////////////////////////////////////////////////////////////////////
-// LLFloaterTexturePicker
-
-class LLFloaterTexturePicker : public LLFloater
-{
-public:
-	LLFloaterTexturePicker(
-		LLTextureCtrl* owner,
-		const std::string& label,
-		PermissionMask immediate_filter_perm_mask,
-		PermissionMask dnd_filter_perm_mask,
-		PermissionMask non_immediate_filter_perm_mask,
-		BOOL can_apply_immediately,
-		LLUIImagePtr fallback_image_name);
-
-	virtual ~LLFloaterTexturePicker();
-
-	// LLView overrides
-	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,
-						BOOL drop, EDragAndDropType cargo_type, void *cargo_data, 
-						EAcceptance *accept,
-						std::string& tooltip_msg);
-	/*virtual*/ void	draw();
-	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask);
-
-	// LLFloater overrides
-	/*virtual*/ BOOL    postBuild();
-	/*virtual*/ void	onClose(bool app_settings);
-	
-	// New functions
-	void setImageID( const LLUUID& image_asset_id, bool set_selection = true);
-	void updateImageStats();
-	const LLUUID& getAssetID() { return mImageAssetID; }
-	const LLUUID& findItemID(const LLUUID& asset_id, BOOL copyable_only);
-	void			setCanApplyImmediately(BOOL b);
-
-	void			setActive( BOOL active );
-
-	LLTextureCtrl*	getOwner() const { return mOwner; }
-	void			setOwner(LLTextureCtrl* owner) { mOwner = owner; }
-	
-	void			stopUsingPipette();
-	PermissionMask 	getFilterPermMask();
-	void updateFilterPermMask();
-	void commitIfImmediateSet();
-	void commitCancel();
-	
-	void onFilterEdit(const std::string& search_string );
-	
-	void setCanApply(bool can_preview, bool can_apply);
-	void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;}
-
-	static void		onBtnSetToDefault( void* userdata );
-	static void		onBtnSelect( void* userdata );
-	static void		onBtnCancel( void* userdata );
-		   void		onBtnPipette( );
-	//static void		onBtnRevert( void* userdata );
-	static void		onBtnBlank( void* userdata );
-	static void		onBtnNone( void* userdata );
-	static void		onBtnClear( void* userdata );
-		   void		onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
-	static void		onShowFolders(LLUICtrl* ctrl, void* userdata);
-	static void		onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
-		   void		onTextureSelect( const LLTextureEntry& te );
-
-	static void		onModeSelect(LLUICtrl* ctrl, void *userdata);
-	static void		onBtnAdd(void* userdata);
-	static void		onBtnRemove(void* userdata);
-	static void		onBtnUpload(void* userdata);
-	static void		onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
-
-protected:
-	LLPointer<LLViewerTexture> mTexturep;
-	LLTextureCtrl*		mOwner;
-
-	LLUUID				mImageAssetID; // Currently selected texture
-	LLUIImagePtr		mFallbackImage; // What to show if currently selected texture is null.
-
-	LLUUID				mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.
-	LLUUID				mOriginalImageAssetID;
-
-	std::string			mLabel;
-
-	LLTextBox*			mTentativeLabel;
-	LLTextBox*			mResolutionLabel;
-
-	std::string			mPendingName;
-	BOOL				mActive;
-
-	LLFilterEditor*		mFilterEdit;
-	LLInventoryPanel*	mInventoryPanel;
-	PermissionMask		mImmediateFilterPermMask;
-	PermissionMask		mDnDFilterPermMask;
-	PermissionMask		mNonImmediateFilterPermMask;
-	BOOL				mCanApplyImmediately;
-	BOOL				mNoCopyTextureSelected;
-	F32					mContextConeOpacity;
-	LLSaveFolderState	mSavedFolderState;
-	BOOL				mSelectedItemPinned;
-
-	LLRadioGroup*		mModeSelector;
-	LLScrollListCtrl*	mLocalScrollCtrl;
-
-private:
-	bool mCanApply;
-	bool mCanPreview;
-	bool mPreviewSettingChanged;
-	texture_selected_callback mTextureSelectedCallback;
-};
-
 LLFloaterTexturePicker::LLFloaterTexturePicker(	
-	LLTextureCtrl* owner,
+	LLView* owner,
+	LLUUID image_asset_id,
+	LLUUID default_image_asset_id,
+	LLUUID blank_image_asset_id,
+	BOOL tentative,
+	BOOL allow_no_texture,
 	const std::string& label,
 	PermissionMask immediate_filter_perm_mask,
 	PermissionMask dnd_filter_perm_mask,
@@ -203,9 +96,13 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	LLUIImagePtr fallback_image)
 :	LLFloater(LLSD()),
 	mOwner( owner ),
-	mImageAssetID( owner->getImageAssetID() ),
-	mFallbackImage( fallback_image ),
-	mOriginalImageAssetID(owner->getImageAssetID()),
+	mImageAssetID( image_asset_id ),
+	mOriginalImageAssetID(image_asset_id),
+	mFallbackImage(fallback_image),
+	mDefaultImageAssetID(default_image_asset_id),
+	mBlankImageAssetID(blank_image_asset_id),
+	mTentative(tentative),
+	mAllowNoTexture(allow_no_texture),
 	mLabel(label),
 	mTentativeLabel(NULL),
 	mResolutionLabel(NULL),
@@ -218,7 +115,10 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	mSelectedItemPinned( FALSE ),
 	mCanApply(true),
 	mCanPreview(true),
-	mPreviewSettingChanged(false)
+	mPreviewSettingChanged(false),
+	mOnFloaterCommitCallback(NULL),
+	mOnFloaterCloseCallback(NULL),
+	mSetImageAssetIDCallback(NULL)
 {
 	buildFromFile("floater_texture_ctrl.xml");
 	mCanApplyImmediately = can_apply_immediately;
@@ -401,9 +301,9 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 
 void LLFloaterTexturePicker::onClose(bool app_quitting)
 {
-	if (mOwner)
+	if (mOnFloaterCloseCallback)
 	{
-		mOwner->onFloaterClose();
+		mOnFloaterCloseCallback();
 	}
 	stopUsingPipette();
 }
@@ -584,9 +484,9 @@ void LLFloaterTexturePicker::draw()
 			mTentativeLabel->setVisible( FALSE  );
 		}
 
-		getChildView("Default")->setEnabled(mImageAssetID != mOwner->getDefaultImageAssetID() || mOwner->getTentative());
-		getChildView("Blank")->setEnabled(mImageAssetID != mOwner->getBlankImageAssetID() || mOwner->getTentative());
-		getChildView("None")->setEnabled(mOwner->getAllowNoTexture() && (!mImageAssetID.isNull() || mOwner->getTentative()));
+		getChildView("Default")->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
+		getChildView("Blank")->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
+		getChildView("None")->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
 
 		LLFloater::draw();
 
@@ -631,7 +531,7 @@ void LLFloaterTexturePicker::draw()
 		}
 
 		// Draw Tentative Label over the image
-		if( mOwner->getTentative() && !mViewModel->isDirty() )
+		if( mTentative && !mViewModel->isDirty() )
 		{
 			mTentativeLabel->setVisible( TRUE );
 			drawChild(mTentativeLabel);
@@ -706,17 +606,17 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()
 
 void LLFloaterTexturePicker::commitIfImmediateSet()
 {
-	if (!mNoCopyTextureSelected && mOwner && mCanApply)
+	if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
 	{
-		mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
+		mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, LLUUID::null);
 	}
 }
 
 void LLFloaterTexturePicker::commitCancel()
 {
-	if (!mNoCopyTextureSelected && mOwner && mCanApply)
+	if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
 	{
-		mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
+		mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
 	}
 }
 
@@ -727,7 +627,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
 	self->setCanApply(true, true);
 	if (self->mOwner)
 	{
-		self->setImageID( self->mOwner->getDefaultImageAssetID() );
+		self->setImageID( self->getDefaultImageAssetID() );
 	}
 	self->commitIfImmediateSet();
 }
@@ -737,7 +637,7 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
 	self->setCanApply(true, true);
-	self->setImageID( self->mOwner->getBlankImageAssetID() );
+	self->setImageID( self->getBlankImageAssetID() );
 	self->commitIfImmediateSet();
 }
 
@@ -767,9 +667,9 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
 	self->setImageID( self->mOriginalImageAssetID );
-	if (self->mOwner)
+	if (self->mOnFloaterCommitCallback)
 	{
-		self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CANCEL);
+		self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, LLUUID::null);
 	}
 	self->mViewModel->resetDirty();
 	self->closeFloater();
@@ -779,17 +679,18 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
 void LLFloaterTexturePicker::onBtnSelect(void* userdata)
 {
 	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+	LLUUID local_id = LLUUID::null;
 	if (self->mOwner)
 	{
-		LLUUID local_id = LLUUID::null;
-
 		if (self->mLocalScrollCtrl->getVisible() && !self->mLocalScrollCtrl->getAllSelected().empty())
 		{
 			LLUUID temp_id = self->mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
 			local_id = LLLocalBitmapMgr::getWorldID(temp_id);
 		}
-
-		self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_SELECT, local_id);
+	}
+	if (self->mOnFloaterCommitCallback)
+	{
+		self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_SELECT, local_id);
 	}
 	self->closeFloater();
 }
@@ -943,11 +844,17 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
 	{
 		LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN); 
 		LLUUID inworld_id = LLLocalBitmapMgr::getWorldID(tracking_id);
-		self->mOwner->setImageAssetID(inworld_id);
+		if (self->mSetImageAssetIDCallback)
+		{
+			self->mSetImageAssetIDCallback(inworld_id);
+		}
 
 		if (self->childGetValue("apply_immediate_check").asBoolean())
 		{
-			self->mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE, inworld_id);
+			if (self->mOnFloaterCommitCallback)
+			{
+				self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, inworld_id);
+			}
 		}
 	}
 }
@@ -1240,13 +1147,17 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 	{
 		floaterp = new LLFloaterTexturePicker(
 			this,
+			getImageAssetID(),
+			getDefaultImageAssetID(),
+			getBlankImageAssetID(),
+			getTentative(),
+			getAllowNoTexture(),
 			mLabel,
 			mImmediateFilterPermMask,
 			mDnDFilterPermMask,
 			mNonImmediateFilterPermMask,
 			mCanApplyImmediately,
 			mFallbackImage);
-
 		mFloaterHandle = floaterp->getHandle();
 
 		LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
@@ -1254,6 +1165,18 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 		{
 			texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
 		}
+		if (texture_floaterp && mOnCloseCallback)
+		{
+			texture_floaterp->setOnFloaterCloseCallback(boost::bind(&LLTextureCtrl::onFloaterClose, this));
+		}
+		if (texture_floaterp)
+		{
+			texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2));
+		}
+		if (texture_floaterp)
+		{
+			texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
+		}
 
 		LLFloater* root_floater = gFloaterView->getParentFloater(this);
 		if (root_floater)
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 15ca7bed92..3ea052ad57 100755
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -29,12 +29,20 @@
 #define LL_LLTEXTURECTRL_H
 
 #include "llcoord.h"
+#include "llfiltereditor.h"
 #include "llfloater.h"
+#include "llfolderview.h"
+#include "lllocalbitmaps.h"
 #include "llstring.h"
 #include "lluictrl.h"
 #include "llpermissionsflags.h"
+#include "llradiogroup.h"
 #include "lltextbox.h" // for params
+#include "llviewerinventory.h"
 #include "llviewborder.h" // for params
+#include "llviewerobject.h"
+#include "llviewertexture.h"
+#include "llwindow.h"
 
 class LLButton;
 class LLFloaterTexturePicker;
@@ -166,7 +174,7 @@ public:
 	void			closeDependentFloater();
 
 	void			onFloaterClose();
-	void			onFloaterCommit(ETexturePickOp op, LLUUID id = LLUUID::null);
+	void			onFloaterCommit(ETexturePickOp op, LLUUID id);
 
 	// This call is returned when a drag is detected. Your callback
 	// should return TRUE if the drag is acceptable.
@@ -227,4 +235,135 @@ private:
 	S32						 	mLabelWidth;
 };
 
+//////////////////////////////////////////////////////////////////////////////////////////
+// LLFloaterTexturePicker
+typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLUUID id)> floater_commit_callback;
+typedef boost::function<void()> floater_close_callback;
+typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
+
+class LLFloaterTexturePicker : public LLFloater
+{
+public:
+	LLFloaterTexturePicker(
+		LLView* owner,
+		LLUUID image_asset_id,
+		LLUUID default_image_asset_id,
+		LLUUID blank_image_asset_id,
+		BOOL tentative,
+		BOOL allow_no_texture,
+		const std::string& label,
+		PermissionMask immediate_filter_perm_mask,
+		PermissionMask dnd_filter_perm_mask,
+		PermissionMask non_immediate_filter_perm_mask,
+		BOOL can_apply_immediately,
+		LLUIImagePtr fallback_image_name
+		);
+
+	virtual ~LLFloaterTexturePicker();
+
+	// LLView overrides
+	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,
+		BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
+		EAcceptance *accept,
+		std::string& tooltip_msg);
+	/*virtual*/ void	draw();
+	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask);
+
+	// LLFloater overrides
+	/*virtual*/ BOOL    postBuild();
+	/*virtual*/ void	onClose(bool app_settings);
+
+	// New functions
+	void setImageID(const LLUUID& image_asset_id, bool set_selection = true);
+	void updateImageStats();
+	const LLUUID&	getAssetID() { return mImageAssetID; }
+	const LLUUID&	findItemID(const LLUUID& asset_id, BOOL copyable_only);
+	void			setCanApplyImmediately(BOOL b);
+
+	void			setActive(BOOL active);
+
+	LLView*			getOwner() const { return mOwner; }
+	void			setOwner(LLView* owner) { mOwner = owner; }
+	void			stopUsingPipette();
+	PermissionMask 	getFilterPermMask();
+
+	void updateFilterPermMask();
+	void commitIfImmediateSet();
+	void commitCancel();
+
+	void onFilterEdit(const std::string& search_string);
+
+	void setCanApply(bool can_preview, bool can_apply);
+	void setTextureSelectedCallback(const texture_selected_callback& cb) { mTextureSelectedCallback = cb; }
+	void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
+	void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
+	void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
+	const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
+	const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
+
+	static void		onBtnSetToDefault(void* userdata);
+	static void		onBtnSelect(void* userdata);
+	static void		onBtnCancel(void* userdata);
+	void			onBtnPipette();
+	//static void		onBtnRevert( void* userdata );
+	static void		onBtnBlank(void* userdata);
+	static void		onBtnNone(void* userdata);
+	static void		onBtnClear(void* userdata);
+	void			onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
+	static void		onShowFolders(LLUICtrl* ctrl, void* userdata);
+	static void		onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
+	void			onTextureSelect(const LLTextureEntry& te);
+
+	static void		onModeSelect(LLUICtrl* ctrl, void *userdata);
+	static void		onBtnAdd(void* userdata);
+	static void		onBtnRemove(void* userdata);
+	static void		onBtnUpload(void* userdata);
+	static void		onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
+
+protected:
+	LLPointer<LLViewerTexture> mTexturep;
+	LLView*				mOwner;
+
+	LLUUID				mImageAssetID; // Currently selected texture
+	LLUIImagePtr		mFallbackImage; // What to show if currently selected texture is null.
+	LLUUID				mDefaultImageAssetID;
+	LLUUID				mBlankImageAssetID;
+	BOOL				mTentative;
+	BOOL				mAllowNoTexture;
+	LLUUID				mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.
+	LLUUID				mOriginalImageAssetID;
+
+	std::string			mLabel;
+
+	LLTextBox*			mTentativeLabel;
+	LLTextBox*			mResolutionLabel;
+
+	std::string			mPendingName;
+	BOOL				mActive;
+
+	LLFilterEditor*		mFilterEdit;
+	LLInventoryPanel*	mInventoryPanel;
+	PermissionMask		mImmediateFilterPermMask;
+	PermissionMask		mDnDFilterPermMask;
+	PermissionMask		mNonImmediateFilterPermMask;
+	BOOL				mCanApplyImmediately;
+	BOOL				mNoCopyTextureSelected;
+	F32					mContextConeOpacity;
+	LLSaveFolderState	mSavedFolderState;
+	BOOL				mSelectedItemPinned;
+
+	LLRadioGroup*		mModeSelector;
+	LLScrollListCtrl*	mLocalScrollCtrl;
+
+private:
+	bool mCanApply;
+	bool mCanPreview;
+	bool mPreviewSettingChanged;
+
+	texture_selected_callback mTextureSelectedCallback;
+	floater_close_callback mOnFloaterCloseCallback;
+	floater_commit_callback mOnFloaterCommitCallback;
+	set_image_asset_id_callback mSetImageAssetIDCallback;
+};
+
 #endif  // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index e31ff2a6e2..23133d4f7c 100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -46,6 +46,13 @@
         <on_click
          function="Gear.UploadPhoto" />
     </menu_item_call>
+    <menu_item_call
+     label="Select Photo"
+     layout="topleft"
+     name="select_photo">
+        <on_click
+         function="Gear.SelectPhoto" />
+  </menu_item_call>
 
   <menu_item_separator name="sepatator1" />
             <!-- copied (with minor modifications) from menu_inventory_add.xml -->
-- 
cgit v1.2.3


From bb06bcb1eae78ce3811761f057c8060e7575192d Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 14 Apr 2016 16:36:30 +0300
Subject: MAINT-6254 FIXED Default gallery thumbnail shows thru the outfit
 gallery image

---
 indra/newview/lloutfitgallery.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 81ef8e96ec..175fd652c5 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -556,6 +556,7 @@ void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
     mImageAssetId = image_asset_id;
     mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
     mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+    getChildView("preview_outfit")->setVisible(FALSE);
 }
 
 LLUUID LLOutfitGalleryItem::getImageAssetId()
@@ -567,6 +568,7 @@ void LLOutfitGalleryItem::setDefaultImage()
 {
     mTexturep = NULL;
     mImageAssetId.setNull();
+    getChildView("preview_outfit")->setVisible(TRUE);
 }
 
 LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
-- 
cgit v1.2.3


From 8c98c8e1cb3a040bef7b2c93111034358099bca2 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 19 Apr 2016 19:08:25 +0300
Subject: MAINT-6303 Outfit browser should add columns after window is resized

---
 indra/newview/lloutfitgallery.cpp | 46 ++++++++++++++++++++++++++++++++++++---
 indra/newview/lloutfitgallery.h   |  5 +++++
 2 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 175fd652c5..dfb5a3d5a8 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -65,10 +65,12 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
       mItemWidth(p.item_width),
       mItemHeight(p.item_height),
       mItemHorizontalGap(p.item_horizontal_gap),
-      mItemsInRow(p.items_in_row)
+      mItemsInRow(p.items_in_row),
+      mRowPanWidthFactor(p.row_panel_width_factor),
+      mGalleryWidthFactor(p.gallery_width_factor)
 {
-    mRowPanelWidth = p.row_panel_width_factor * mItemsInRow;
-    mGalleryWidth = p.gallery_width_factor * mItemsInRow;
+    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
+    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
 }
 
 LLOutfitGallery::Params::Params()
@@ -117,6 +119,44 @@ void LLOutfitGallery::onOpen(const LLSD& info)
     }
 }
 
+void LLOutfitGallery::draw()
+{
+    LLPanel::draw();
+    updateRowsIfNeeded();
+}
+
+void LLOutfitGallery::updateRowsIfNeeded()
+{
+    if(((getRect().getWidth() - mRowPanelWidth) > mItemWidth) && mRowCount > 1)
+    {
+        reArrangeRows(1);
+    }
+    else if((mRowPanelWidth > (getRect().getWidth() + mItemHorizontalGap)) && mItemsInRow > 3)
+    {
+        reArrangeRows(-1);
+    }
+}
+
+void LLOutfitGallery::reArrangeRows(S32 row_diff)
+{
+ 
+    std::vector<LLOutfitGalleryItem*> buf_items = mItems;
+    for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = buf_items.rbegin(); it != buf_items.rend(); ++it)
+    {
+        removeFromGalleryLast(*it);
+    }
+    
+    mItemsInRow+= row_diff;
+    
+    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
+    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
+
+    for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
+    {
+        addToGallery(*it);
+    }
+}
+
 LLPanel* LLOutfitGallery::addLastRow()
 {
     mRowCount++;
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index e874776e3e..1b6878bce3 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -82,6 +82,7 @@ public:
 
     /*virtual*/ BOOL postBuild();
     /*virtual*/ void onOpen(const LLSD& info);
+    /*virtual*/ void draw();	
     
     void onSelectPhoto(LLUUID selected_outfit_id);
 
@@ -128,6 +129,8 @@ private:
     void moveRow(int row, int pos);
     LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap);
     void removeFromLastRow(LLOutfitGalleryItem* item);
+    void reArrangeRows(S32 row_diff);
+    void updateRowsIfNeeded();
 
     LLOutfitGalleryItem* buildGalleryItem(std::string name);
 
@@ -159,6 +162,8 @@ private:
     int mItemsInRow;
     int mRowPanelWidth;
     int mGalleryWidth;
+    int mRowPanWidthFactor;
+    int mGalleryWidthFactor;
 
     LLHandle<LLFloater> mFloaterHandle;
 
-- 
cgit v1.2.3


From 8d265cd59f0c141ae5fb5eadc0ef5e9007a38e29 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 22 Apr 2016 17:01:56 +0300
Subject: MAINT-6229 Organize Outfit Browser thumbnails

---
 indra/newview/lloutfitgallery.cpp | 32 +++++++++++++++++++++++++-------
 indra/newview/lloutfitgallery.h   | 24 +++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index dfb5a3d5a8..9a9993f58c 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -69,8 +69,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
       mRowPanWidthFactor(p.row_panel_width_factor),
       mGalleryWidthFactor(p.gallery_width_factor)
 {
-    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
-    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
+    updateGalleryWidth();
 }
 
 LLOutfitGallery::Params::Params()
@@ -115,6 +114,7 @@ void LLOutfitGallery::onOpen(const LLSD& info)
         {
             addToGallery(mOutfitMap[cats[i]]);
         }
+        reArrangeRows();
         mGalleryCreated = true;
     }
 }
@@ -122,7 +122,10 @@ void LLOutfitGallery::onOpen(const LLSD& info)
 void LLOutfitGallery::draw()
 {
     LLPanel::draw();
-    updateRowsIfNeeded();
+    if (mGalleryCreated)
+    {
+        updateRowsIfNeeded();
+    }
 }
 
 void LLOutfitGallery::updateRowsIfNeeded()
@@ -147,16 +150,21 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
     }
     
     mItemsInRow+= row_diff;
+    updateGalleryWidth();
+    std::sort(buf_items.begin(), buf_items.end(), LLOutfitGalleryItem::compareGalleryItem());
     
-    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
-    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
-
     for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
     {
         addToGallery(*it);
     }
 }
 
+void LLOutfitGallery::updateGalleryWidth()
+{
+    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
+    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
+}
+
 LLPanel* LLOutfitGallery::addLastRow()
 {
     mRowCount++;
@@ -515,7 +523,9 @@ LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p)
     : LLPanel(p),
     mTexturep(NULL),
     mSelected(false),
-    mWorn(false)
+    mWorn(false),
+    mDefaultImage(true),
+    mOutfitName("")
 {
     buildFromFile("panel_outfit_gallery_item.xml");
 }
@@ -565,6 +575,7 @@ void LLOutfitGalleryItem::draw()
 void LLOutfitGalleryItem::setOutfitName(std::string name)
 {
     mOutfitNameText->setText(name);
+    mOutfitName = name;
 }
 
 void LLOutfitGalleryItem::setOutfitWorn(bool value)
@@ -597,6 +608,7 @@ void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
     mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
     mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
     getChildView("preview_outfit")->setVisible(FALSE);
+    mDefaultImage = false;
 }
 
 LLUUID LLOutfitGalleryItem::getImageAssetId()
@@ -609,6 +621,7 @@ void LLOutfitGalleryItem::setDefaultImage()
     mTexturep = NULL;
     mImageAssetId.setNull();
     getChildView("preview_outfit")->setVisible(TRUE);
+    mDefaultImage = true;
 }
 
 LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
@@ -711,6 +724,11 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
             }
         }
     }
+    
+    if (mGalleryCreated)
+    {
+        reArrangeRows();
+    }
 }
 
 void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 1b6878bce3..285c8baf59 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -129,8 +129,9 @@ private:
     void moveRow(int row, int pos);
     LLPanel* addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap);
     void removeFromLastRow(LLOutfitGalleryItem* item);
-    void reArrangeRows(S32 row_diff);
+    void reArrangeRows(S32 row_diff = 0);
     void updateRowsIfNeeded();
+    void updateGalleryWidth();
 
     LLOutfitGalleryItem* buildGalleryItem(std::string name);
 
@@ -211,6 +212,25 @@ public:
     void setOutfitName(std::string name);
     void setOutfitWorn(bool value);
     void setSelected(bool value);
+    
+    std::string getItemName() {return mOutfitName;}
+    bool mIsDefaultImage() {return mDefaultImage;}
+    
+    struct compareGalleryItem
+    {
+        bool operator()(LLOutfitGalleryItem* a, LLOutfitGalleryItem* b)
+        {
+            if((a->mIsDefaultImage() && b->mIsDefaultImage()) || (!a->mIsDefaultImage() && !b->mIsDefaultImage()))
+            {
+                return a->getItemName().compare(b->getItemName()) < 0;
+            }
+            else
+            {
+                return b->mIsDefaultImage();
+            }
+        }
+    };
+    
 private:
     LLPointer<LLViewerTexture> mTexturep;
     LLUUID mImageAssetId;
@@ -220,6 +240,8 @@ private:
     LLPanel* mFotoBgPanel;
     bool     mSelected;
     bool     mWorn;
+    bool     mDefaultImage;
+    std::string mOutfitName;
 };
 
 #endif  // LL_LLOUTFITGALLERYCTRL_H
-- 
cgit v1.2.3


From f70be72ad614f2e7b2b2773c413249137662f570 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 22 Apr 2016 18:21:18 +0300
Subject: MAINT-6303 Width was changed to appropriate value

---
 indra/newview/lloutfitgallery.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 9a9993f58c..c553d3d338 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -161,8 +161,8 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
 
 void LLOutfitGallery::updateGalleryWidth()
 {
-    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow;
-    mGalleryWidth = mGalleryWidthFactor * mItemsInRow;
+    mRowPanelWidth = mRowPanWidthFactor * mItemsInRow - mItemHorizontalGap;
+    mGalleryWidth = mGalleryWidthFactor * mItemsInRow - mItemHorizontalGap;
 }
 
 LLPanel* LLOutfitGallery::addLastRow()
-- 
cgit v1.2.3


From 4125bebce7116e074aef664026b9ed33ffa9ca19 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Fri, 29 Apr 2016 20:28:11 +0300
Subject: MAINT-6226 Incorporate a customized Snapshot feature to Outfit
 Browser flow Initial version, further refactoring pending

---
 indra/newview/CMakeLists.txt                       |    2 +
 indra/newview/llappviewer.cpp                      |    3 +
 indra/newview/llassetuploadresponders.cpp          |   11 +-
 indra/newview/llfloaterfacebook.cpp                |    2 +-
 indra/newview/llfloaterflickr.cpp                  |    2 +-
 indra/newview/llfloateroutfitsnapshot.cpp          | 1586 ++++++++++++++++++++
 indra/newview/llfloateroutfitsnapshot.h            |  110 ++
 indra/newview/llfloatersnapshot.cpp                |  110 +-
 indra/newview/llfloatersnapshot.h                  |   49 +-
 indra/newview/llfloatertwitter.cpp                 |    2 +-
 indra/newview/lloutfitgallery.cpp                  |   51 +-
 indra/newview/lloutfitgallery.h                    |    5 +
 indra/newview/lloutfitslist.cpp                    |    7 +
 indra/newview/lloutfitslist.h                      |    1 +
 indra/newview/llpanelsnapshot.cpp                  |   18 +-
 indra/newview/llpanelsnapshot.h                    |   11 +-
 indra/newview/llpanelsnapshotinventory.cpp         |  112 +-
 indra/newview/llpanelsnapshotlocal.cpp             |   19 +-
 indra/newview/llpanelsnapshotpostcard.cpp          |   11 +-
 indra/newview/llpanelsnapshotprofile.cpp           |    2 +-
 indra/newview/llsnapshotlivepreview.cpp            |   36 +-
 indra/newview/llsnapshotlivepreview.h              |   22 +-
 indra/newview/llviewerfloaterreg.cpp               |    4 +-
 indra/newview/llviewermenufile.cpp                 |    2 +-
 .../default/xui/en/floater_outfit_snapshot.xml     |  462 ++++++
 .../skins/default/xui/en/menu_outfit_gear.xml      |    9 +-
 .../xui/en/panel_outfit_snapshot_inventory.xml     |  147 ++
 27 files changed, 2688 insertions(+), 108 deletions(-)
 create mode 100644 indra/newview/llfloateroutfitsnapshot.cpp
 create mode 100644 indra/newview/llfloateroutfitsnapshot.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 6567654a9d..595a9a5e21 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -271,6 +271,7 @@ set(viewer_SOURCE_FILES
     llfloaternamedesc.cpp
     llfloaternotificationsconsole.cpp
     llfloaternotificationstabbed.cpp 
+    llfloateroutfitsnapshot.cpp
     llfloaterobjectweights.cpp
     llfloateropenobject.cpp
     llfloateroutbox.cpp
@@ -894,6 +895,7 @@ set(viewer_HEADER_FILES
     llfloaternamedesc.h
     llfloaternotificationsconsole.h
     llfloaternotificationstabbed.h 
+    llfloateroutfitsnapshot.h
     llfloaterobjectweights.h
     llfloateropenobject.h
     llfloateroutbox.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 2898d8ca31..1887adc97e 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -203,6 +203,7 @@
 #include "llcommandlineparser.h"
 #include "llfloatermemleak.h"
 #include "llfloaterreg.h"
+#include "llfloateroutfitsnapshot.h"
 #include "llfloatersnapshot.h"
 #include "llfloaterinventory.h"
 
@@ -1471,6 +1472,8 @@ bool LLAppViewer::mainLoop()
 					display();
 					pingMainloopTimeout("Main:Snapshot");
 					LLFloaterSnapshot::update(); // take snapshots
+                    //TODO: Make one call by moving LLFloaterOutfitSnapshot::update() to LLFloaterSnapshotBase class
+                    LLFloaterOutfitSnapshot::update();
 					gGLActive = FALSE;
 				}
 			}
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 121ce647a6..86576538ec 100755
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -178,9 +178,14 @@ void on_new_single_inventory_upload_complete(
 
 	// Let the Snapshot floater know we have finished uploading a snapshot to inventory.
 	LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
-	if (asset_type == LLAssetType::AT_TEXTURE && floater_snapshot)
-	{
-		floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+    if (asset_type == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
+    {
+        floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+    }
+    LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
+    if (asset_type == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
+    {
+        floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
 	}
 }
 
diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp
index da85d378b2..ff6e342d62 100644
--- a/indra/newview/llfloaterfacebook.cpp
+++ b/indra/newview/llfloaterfacebook.cpp
@@ -488,7 +488,7 @@ void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible)
             mQuality = MAX_QUALITY;
 
             previewp->setContainer(this);
-			previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
+            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
 			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
 			previewp->setSnapshotQuality(mQuality, false);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
index cd132b843d..131df22956 100644
--- a/indra/newview/llfloaterflickr.cpp
+++ b/indra/newview/llfloaterflickr.cpp
@@ -238,7 +238,7 @@ void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible)
 			mPreviewHandle = previewp->getHandle();
 
             previewp->setContainer(this);
-			previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
+            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
 			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
             previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
new file mode 100644
index 0000000000..8fa54e7f94
--- /dev/null
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -0,0 +1,1586 @@
+/** 
+ * @file llfloatersnapshot.cpp
+ * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2016, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersnapshot.h"
+#include "llfloateroutfitsnapshot.h"
+
+#include "llagent.h"
+#include "llfacebookconnect.h"
+#include "llfloaterreg.h"
+#include "llfloaterfacebook.h"
+#include "llfloaterflickr.h"
+#include "llfloatertwitter.h"
+#include "llimagefiltersmanager.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llpostcard.h"
+#include "llresmgr.h"		// LLLocale
+#include "llsdserialize.h"
+#include "llsidetraypanelcontainer.h"
+#include "llsnapshotlivepreview.h"
+#include "llspinctrl.h"
+#include "llviewercontrol.h"
+#include "lltoolfocus.h"
+#include "lltoolmgr.h"
+#include "llwebprofile.h"
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+LLUICtrl* LLFloaterOutfitSnapshot::sThumbnailPlaceholder = NULL;
+LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
+
+const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
+
+const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
+const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
+
+static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
+
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSnapshot::Impl
+///----------------------------------------------------------------------------
+
+
+class LLFloaterOutfitSnapshot::Impl
+{
+	LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
+public:
+	typedef enum e_status
+	{
+		STATUS_READY,
+		STATUS_WORKING,
+		STATUS_FINISHED
+	} EStatus;
+
+	Impl()
+	:	mAvatarPauseHandles(),
+		mLastToolset(NULL),
+		mAspectRatioCheckOff(false),
+		mNeedRefresh(false),
+		mStatus(STATUS_READY)
+	{
+	}
+	~Impl()
+	{
+		//unpause avatars
+		mAvatarPauseHandles.clear();
+
+	}
+	static void onClickNewSnapshot(void* data);
+	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
+	static void onClickFilter(LLUICtrl *ctrl, void* data);
+	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
+	static void onClickUICheck(LLUICtrl *ctrl, void* data);
+	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
+	static void applyKeepAspectCheck(LLFloaterOutfitSnapshot* view, BOOL checked);
+	static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
+	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
+	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
+	static void onImageQualityChange(LLFloaterOutfitSnapshot* view, S32 quality_val);
+	static void onImageFormatChange(LLFloaterOutfitSnapshot* view);
+	static void applyCustomResolution(LLFloaterOutfitSnapshot* view, S32 w, S32 h);
+	static void onSnapshotUploadFinished(bool status);
+	static void onSendingPostcardFinished(bool status);
+	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
+	static void setImageSizeSpinnersValues(LLFloaterOutfitSnapshot *view, S32 width, S32 height) ;
+	static void updateSpinners(LLFloaterOutfitSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
+
+	static LLPanelSnapshot* getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found = true);
+    static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterOutfitSnapshot* floater);
+	static LLFloaterOutfitSnapshot::ESnapshotFormat getImageFormat(LLFloaterOutfitSnapshot* floater);
+	static LLSpinCtrl* getWidthSpinner(LLFloaterOutfitSnapshot* floater);
+	static LLSpinCtrl* getHeightSpinner(LLFloaterOutfitSnapshot* floater);
+	static void enableAspectRatioCheckbox(LLFloaterOutfitSnapshot* floater, BOOL enable);
+	static void setAspectRatioCheckboxValue(LLFloaterOutfitSnapshot* floater, BOOL checked);
+
+	static LLSnapshotLivePreview* getPreviewView(LLFloaterOutfitSnapshot *floater);
+	static void setResolution(LLFloaterOutfitSnapshot* floater, const std::string& comboname);
+	static void updateControls(LLFloaterOutfitSnapshot* floater);
+	static void updateLayout(LLFloaterOutfitSnapshot* floater);
+	static void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
+	EStatus getStatus() const { return mStatus; }
+	static void setNeedRefresh(LLFloaterOutfitSnapshot* floater, bool need);
+
+private:
+	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterOutfitSnapshot* floater);
+	static void comboSetCustom(LLFloaterOutfitSnapshot *floater, const std::string& comboname);
+	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
+	static void checkAspectRatio(LLFloaterOutfitSnapshot *view, S32 index) ;
+	static void setWorking(LLFloaterOutfitSnapshot* floater, bool working);
+	static void setFinished(LLFloaterOutfitSnapshot* floater, bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
+
+
+public:
+	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+
+	LLToolset*	mLastToolset;
+	LLHandle<LLView> mPreviewHandle;
+	bool mAspectRatioCheckOff ;
+	bool mNeedRefresh;
+	EStatus mStatus;
+};
+
+
+
+// static
+LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found)
+{
+    LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
+    //LLPanel* panel = panel_container->getCurrentPanel();
+    LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
+	if (!ok_if_not_found)
+	{
+		llassert_always(active_panel != NULL);
+	}
+	return active_panel;
+}
+
+// static
+LLPanelSnapshot::ESnapshotType LLFloaterOutfitSnapshot::Impl::getActiveSnapshotType(LLFloaterOutfitSnapshot* floater)
+{
+	//LLSnapshotLivePreview::ESnapshotType type = LLSnapshotLivePreview::SNAPSHOT_WEB;
+	//std::string name;
+	LLPanelSnapshot* spanel = getActivePanel(floater);
+
+	//if (spanel)
+	//{
+	//	name = spanel->getName();
+	//}
+
+    //if (name == "panel_snapshot_postcard")
+	//{
+	//	type = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
+	//}
+	//else if (name == "panel_snapshot_inventory")
+	//{
+	//	type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
+	//}
+	//else if (name == "panel_snapshot_local")
+	//{
+	//	type = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
+	//}
+
+	//return type;
+    if (spanel)
+    {
+        return spanel->getSnapshotType();
+    }
+    return LLPanelSnapshot::SNAPSHOT_WEB;
+}
+
+// static
+LLFloaterOutfitSnapshot::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterOutfitSnapshot* floater)
+{
+	//LLPanelSnapshot* active_panel = getActivePanel(floater);
+	// FIXME: if the default is not PNG, profile uploads may fail.
+	//return active_panel ? active_panel->getImageFormat() : LLFloaterOutfitSnapshot::SNAPSHOT_FORMAT_PNG;
+    return LLFloaterOutfitSnapshot::SNAPSHOT_FORMAT_PNG;
+}
+
+// static
+LLSpinCtrl* LLFloaterOutfitSnapshot::Impl::getWidthSpinner(LLFloaterOutfitSnapshot* floater)
+{
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	return active_panel ? active_panel->getWidthSpinner() : floater->getChild<LLSpinCtrl>("snapshot_width");
+}
+
+// static
+LLSpinCtrl* LLFloaterOutfitSnapshot::Impl::getHeightSpinner(LLFloaterOutfitSnapshot* floater)
+{
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	return active_panel ? active_panel->getHeightSpinner() : floater->getChild<LLSpinCtrl>("snapshot_height");
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterOutfitSnapshot* floater, BOOL enable)
+{
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	if (active_panel)
+	{
+		active_panel->enableAspectRatioCheckbox(enable);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterOutfitSnapshot* floater, BOOL checked)
+{
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	if (active_panel)
+	{
+		active_panel->getChild<LLUICtrl>(active_panel->getAspectRatioCBName())->setValue(checked);
+	}
+}
+
+// static
+LLSnapshotLivePreview* LLFloaterOutfitSnapshot::Impl::getPreviewView(LLFloaterOutfitSnapshot *floater)
+{
+	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get();
+	return previewp;
+}
+
+// static
+LLViewerWindow::ESnapshotType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterOutfitSnapshot* floater)
+{
+	LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	LLSD value = floater->getChild<LLUICtrl>("layer_types")->getValue();
+	const std::string id = value.asString();
+	if (id == "colors")
+		type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	else if (id == "depth")
+		type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH;
+	return type;
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::setResolution(LLFloaterOutfitSnapshot* floater, const std::string& comboname)
+{
+	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
+		combo->setVisible(TRUE);
+	updateResolution(combo, floater, FALSE); // to sync spinners with combo
+}
+
+//static 
+void LLFloaterOutfitSnapshot::Impl::updateLayout(LLFloaterOutfitSnapshot* floaterp)
+{
+	LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
+
+	BOOL advanced = gSavedSettings.getBOOL("AdvanceSnapshot");
+
+	//BD - Automatically calculate the size of our snapshot window to enlarge
+	//     the snapshot preview to its maximum size, this is especially helpfull
+	//     for pretty much every aspect ratio other than 1:1.
+	F32 panel_width = 400.f * gViewerWindow->getWorldViewAspectRatio();
+
+	//BD - Make sure we clamp at 700 here because 700 would be for 16:9 which we
+	//     consider the maximum. Everything bigger will be clamped and will have
+	//     a slightly smaller preview window which most likely won't fill up the
+	//     whole snapshot floater as it should.
+	if(panel_width > 700.f)
+	{
+		panel_width = 700.f;
+	}
+
+	S32 floater_width = 224.f;
+	if(advanced)
+	{
+		floater_width = floater_width + panel_width;
+	}
+
+	LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
+	thumbnail_placeholder->setVisible(advanced);
+	thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
+	floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(advanced);
+	floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(advanced);
+	if(!floaterp->isMinimized())
+	{
+		floaterp->reshape(floater_width, floaterp->getRect().getHeight());
+	}
+
+	bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean();
+
+	if (use_freeze_frame)
+	{
+		// stop all mouse events at fullscreen preview layer
+		floaterp->getParent()->setMouseOpaque(TRUE);
+		
+		// shrink to smaller layout
+		// *TODO: unneeded?
+		floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getRect().getHeight());
+
+		// can see and interact with fullscreen preview now
+		if (previewp)
+		{
+			previewp->setVisible(TRUE);
+			previewp->setEnabled(TRUE);
+		}
+
+		//RN: freeze all avatars
+		LLCharacter* avatarp;
+		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+			iter != LLCharacter::sInstances.end(); ++iter)
+		{
+			avatarp = *iter;
+			floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
+		}
+
+		// freeze everything else
+		gSavedSettings.setBOOL("FreezeTime", TRUE);
+
+		if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
+		{
+			floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
+			LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
+		}
+	}
+	else // turning off freeze frame mode
+	{
+		floaterp->getParent()->setMouseOpaque(FALSE);
+		// *TODO: unneeded?
+		floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getRect().getHeight());
+		if (previewp)
+		{
+			previewp->setVisible(FALSE);
+			previewp->setEnabled(FALSE);
+		}
+
+		//RN: thaw all avatars
+		floaterp->impl.mAvatarPauseHandles.clear();
+
+		// thaw everything else
+		gSavedSettings.setBOOL("FreezeTime", FALSE);
+
+		// restore last tool (e.g. pie menu, etc)
+		if (floaterp->impl.mLastToolset)
+		{
+			LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset);
+		}
+	}
+}
+
+// This is the main function that keeps all the GUI controls in sync with the saved settings.
+// It should be called anytime a setting is changed that could affect the controls.
+// No other methods should be changing any of the controls directly except for helpers called by this method.
+// The basic pattern for programmatically changing the GUI settings is to first set the
+// appropriate saved settings and then call this method to sync the GUI with them.
+// FIXME: The above comment seems obsolete now.
+// static
+void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterOutfitSnapshot* floater)
+{
+    LLPanelSnapshot::ESnapshotType shot_type = getActiveSnapshotType(floater);
+    LLFloaterSnapshotBase::ESnapshotFormat shot_format = (LLFloaterSnapshotBase::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
+	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
+
+	floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
+    floater->getChildView("layer_types")->setEnabled(shot_type == LLPanelSnapshot::SNAPSHOT_LOCAL);
+
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	if (active_panel)
+	{
+		LLSpinCtrl* width_ctrl = getWidthSpinner(floater);
+		LLSpinCtrl* height_ctrl = getHeightSpinner(floater);
+
+		// Initialize spinners.
+		if (width_ctrl->getValue().asInteger() == 0)
+		{
+			S32 w = gViewerWindow->getWindowWidthRaw();
+			LL_DEBUGS() << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << LL_ENDL;
+			width_ctrl->setValue(w);
+            if (getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			{
+				width_ctrl->setIncrement(w >> 1);
+			}
+		}
+		if (height_ctrl->getValue().asInteger() == 0)
+		{
+			S32 h = gViewerWindow->getWindowHeightRaw();
+			LL_DEBUGS() << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << LL_ENDL;
+			height_ctrl->setValue(h);
+            if (getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			{
+				height_ctrl->setIncrement(h >> 1);
+			}
+		}
+
+		// Clamp snapshot resolution to window size when showing UI or HUD in snapshot.
+		if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
+		{
+			S32 width = gViewerWindow->getWindowWidthRaw();
+			S32 height = gViewerWindow->getWindowHeightRaw();
+
+			width_ctrl->setMaxValue(width);
+
+			height_ctrl->setMaxValue(height);
+
+			if (width_ctrl->getValue().asInteger() > width)
+			{
+				width_ctrl->forceSetValue(width);
+			}
+			if (height_ctrl->getValue().asInteger() > height)
+			{
+				height_ctrl->forceSetValue(height);
+			}
+		}
+		else
+		{
+			width_ctrl->setMaxValue(6016);
+			height_ctrl->setMaxValue(6016);
+		}
+	}
+		
+	LLSnapshotLivePreview* previewp = getPreviewView(floater);
+	BOOL got_bytes = previewp && previewp->getDataSize() > 0;
+	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
+
+	// *TODO: Separate maximum size for Web images from postcards
+	LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
+
+	LLLocale locale(LLLocale::USER_LOCALE);
+	std::string bytes_string;
+	if (got_snap)
+	{
+		LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
+	}
+
+	// Update displayed image resolution.
+	LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
+	image_res_tb->setVisible(got_snap);
+	if (got_snap)
+	{
+		image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
+		image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
+	}
+
+	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
+	floater->getChild<LLUICtrl>("file_size_label")->setColor(
+        shot_type == LLPanelSnapshot::SNAPSHOT_POSTCARD
+			&& got_bytes
+			&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
+
+	// Update the width and height spinners based on the corresponding resolution combos. (?)
+	switch(shot_type)
+	{
+      case LLPanelSnapshot::SNAPSHOT_WEB:
+		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
+		setResolution(floater, "profile_size_combo");
+		break;
+      case LLPanelSnapshot::SNAPSHOT_POSTCARD:
+		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
+		setResolution(floater, "postcard_size_combo");
+		break;
+      case LLPanelSnapshot::SNAPSHOT_TEXTURE:
+		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
+		setResolution(floater, "texture_size_combo");
+		break;
+      case  LLPanelSnapshot::SNAPSHOT_LOCAL:
+		setResolution(floater, "local_size_combo");
+		break;
+	  default:
+		break;
+	}
+	setAspectRatioCheckboxValue(floater, !floater->impl.mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot"));
+
+	if (previewp)
+	{
+		previewp->setSnapshotType(shot_type);
+		previewp->setSnapshotFormat(shot_format);
+		previewp->setSnapshotBufferType(layer_type);
+	}
+
+	LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
+	if (current_panel)
+	{
+		LLSD info;
+		info["have-snapshot"] = got_snap;
+		current_panel->updateControls(info);
+	}
+	LL_DEBUGS() << "finished updating controls" << LL_ENDL;
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
+{
+	LLFloaterOutfitSnapshot* floater = LLFloaterOutfitSnapshot::getInstance();
+	switch (status)
+	{
+	case STATUS_READY:
+		setWorking(floater, false);
+		setFinished(floater, false);
+		break;
+	case STATUS_WORKING:
+		setWorking(floater, true);
+		setFinished(floater, false);
+		break;
+	case STATUS_FINISHED:
+		setWorking(floater, false);
+		setFinished(floater, true, ok, msg);
+		break;
+	}
+
+	floater->impl.mStatus = status;
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::setNeedRefresh(LLFloaterOutfitSnapshot* floater, bool need)
+{
+	if (!floater) return;
+
+	// Don't display the "Refresh to save" message if we're in auto-refresh mode.
+	if (gSavedSettings.getBOOL("AutoSnapshot"))
+	{
+		need = false;
+	}
+
+	floater->mRefreshLabel->setVisible(need);
+	floater->impl.mNeedRefresh = need;
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
+{
+	if (previewp)
+	{
+		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
+		LL_DEBUGS() << "updating " << (autosnap ? "snapshot" : "thumbnail") << LL_ENDL;
+		previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onClickNewSnapshot(void* data)
+{
+	LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterOutfitSnapshot *)data);
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+	if (previewp && view)
+	{
+		view->impl.setStatus(Impl::STATUS_READY);
+		LL_DEBUGS() << "updating snapshot" << LL_ENDL;
+		previewp->mForceUpdateSnapshot = TRUE;
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
+{
+	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
+	gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
+	
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;		
+	if (view)
+	{
+		checkAutoSnapshot(getPreviewView(view));
+		updateControls(view);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data)
+{
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+	if (view)
+	{
+		updateControls(view);
+        LLSnapshotLivePreview* previewp = getPreviewView(view);
+        if (previewp)
+        {
+            checkAutoSnapshot(previewp);
+            // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
+            LLComboBox* filterbox = static_cast<LLComboBox *>(view->getChild<LLComboBox>("filters_combobox"));
+            std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
+            previewp->setFilter(filter_name);
+            previewp->updateSnapshot(TRUE);
+        }
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
+{
+	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
+	gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() );
+	
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+	if (view)
+	{
+		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		if(previewp)
+		{
+			previewp->updateSnapshot(TRUE, TRUE);
+		}
+		updateControls(view);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
+{
+	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
+	gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() );
+	
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+	if (view)
+	{
+		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		if(previewp)
+		{
+			previewp->updateSnapshot(TRUE, TRUE);
+		}
+		updateControls(view);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::applyKeepAspectCheck(LLFloaterOutfitSnapshot* view, BOOL checked)
+{
+	gSavedSettings.setBOOL("KeepAspectForSnapshot", checked);
+
+	if (view)
+	{
+		LLPanelSnapshot* active_panel = getActivePanel(view);
+		if (checked && active_panel)
+		{
+			LLComboBox* combo = view->getChild<LLComboBox>(active_panel->getImageSizeComboName());
+			combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
+		}
+
+		LLSnapshotLivePreview* previewp = getPreviewView(view) ;
+		if(previewp)
+		{
+			previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
+
+			S32 w, h ;
+			previewp->getSize(w, h) ;
+			updateSpinners(view, previewp, w, h, TRUE); // may change w and h
+
+			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
+			previewp->setSize(w, h) ;
+			previewp->updateSnapshot(TRUE);
+			checkAutoSnapshot(previewp, TRUE);
+		}
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
+{
+	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+	LLSnapshotLivePreview* previewp = getPreviewView(view);
+		
+	if (!view || !check_box || !previewp)
+	{
+		return;
+	}
+
+	gSavedSettings.setBOOL("UseFreezeFrame", check_box->get());
+
+	if (check_box->get())
+	{
+		previewp->prepareFreezeFrame();
+	}
+
+	updateLayout(view);
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::checkAspectRatio(LLFloaterOutfitSnapshot *view, S32 index)
+{
+	LLSnapshotLivePreview *previewp = getPreviewView(view) ;
+
+	// Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
+	if(LLPanelSnapshot::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
+	{
+		previewp->mKeepAspectRatio = FALSE ;
+		return ;
+	}
+
+	BOOL keep_aspect = FALSE, enable_cb = FALSE;
+
+	if (0 == index) // current window size
+	{
+		enable_cb = FALSE;
+		keep_aspect = TRUE;
+	}
+	else if (-1 == index) // custom
+	{
+		enable_cb = TRUE;
+		keep_aspect = gSavedSettings.getBOOL("KeepAspectForSnapshot");
+	}
+	else // predefined resolution
+	{
+		enable_cb = FALSE;
+		keep_aspect = FALSE;
+	}
+
+	view->impl.mAspectRatioCheckOff = !enable_cb;
+
+	if (previewp)
+	{
+		previewp->mKeepAspectRatio = keep_aspect;
+	}
+}
+
+// Show/hide upload progress indicators.
+// static
+void LLFloaterOutfitSnapshot::Impl::setWorking(LLFloaterOutfitSnapshot* floater, bool working)
+{
+	LLUICtrl* working_lbl = floater->getChild<LLUICtrl>("working_lbl");
+	working_lbl->setVisible(working);
+	floater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
+
+	if (working)
+	{
+		const std::string panel_name = getActivePanel(floater, false)->getName();
+		const std::string prefix = panel_name.substr(std::string("panel_outfit_snapshot_").size());
+		std::string progress_text = floater->getString(prefix + "_" + "progress_str");
+		working_lbl->setValue(progress_text);
+	}
+
+	// All controls should be disabled while posting.
+	floater->setCtrlsEnabled(!working);
+	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	if (active_panel)
+	{
+		active_panel->enableControls(!working);
+	}
+}
+
+// Show/hide upload status message.
+// static
+void LLFloaterOutfitSnapshot::Impl::setFinished(LLFloaterOutfitSnapshot* floater, bool finished, bool ok, const std::string& msg)
+{
+	floater->mSucceessLblPanel->setVisible(finished && ok);
+	floater->mFailureLblPanel->setVisible(finished && !ok);
+
+	if (finished)
+	{
+		LLUICtrl* finished_lbl = floater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
+		std::string result_text = floater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
+		finished_lbl->setValue(result_text);
+
+		//LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
+		//panel_container->openPreviousPanel();
+		//panel_container->getCurrentPanel()->onOpen(LLSD());
+        LLPanel* snapshot_panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
+        snapshot_panel->onOpen(LLSD());
+	}
+}
+
+// Apply a new resolution selected from the given combobox.
+// static
+void LLFloaterOutfitSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update)
+{
+	LLComboBox* combobox = (LLComboBox*)ctrl;
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+		
+	if (!view || !combobox)
+	{
+		llassert(view && combobox);
+		return;
+	}
+
+	std::string sdstring = combobox->getSelectedValue();
+	LLSD sdres;
+	std::stringstream sstream(sdstring);
+	LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
+		
+	S32 width = sdres[0];
+	S32 height = sdres[1];
+	
+	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	if (previewp && combobox->getCurrentIndex() >= 0)
+	{
+		S32 original_width = 0 , original_height = 0 ;
+		previewp->getSize(original_width, original_height) ;
+		
+		if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
+		{ //clamp snapshot resolution to window size when showing UI or HUD in snapshot
+			width = llmin(width, gViewerWindow->getWindowWidthRaw());
+			height = llmin(height, gViewerWindow->getWindowHeightRaw());
+		}
+
+		if (width == 0 || height == 0)
+		{
+			// take resolution from current window size
+			LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
+			previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+		}
+		else if (width == -1 || height == -1)
+		{
+			// load last custom value
+			S32 new_width = 0, new_height = 0;
+			LLPanelSnapshot* spanel = getActivePanel(view);
+			if (spanel)
+			{
+				LL_DEBUGS() << "Loading typed res from panel " << spanel->getName() << LL_ENDL;
+				new_width = spanel->getTypedPreviewWidth();
+				new_height = spanel->getTypedPreviewHeight();
+
+				// Limit custom size for inventory snapshots to 512x512 px.
+				if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+				{
+					new_width = llmin(new_width, MAX_TEXTURE_SIZE);
+					new_height = llmin(new_height, MAX_TEXTURE_SIZE);
+				}
+			}
+			else
+			{
+				LL_DEBUGS() << "No custom res chosen, setting preview res from window: "
+					<< gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
+				new_width = gViewerWindow->getWindowWidthRaw();
+				new_height = gViewerWindow->getWindowHeightRaw();
+			}
+
+			llassert(new_width > 0 && new_height > 0);
+			previewp->setSize(new_width, new_height);
+		}
+		else
+		{
+			// use the resolution from the selected pre-canned drop-down choice
+			LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
+			previewp->setSize(width, height);
+		}
+
+		checkAspectRatio(view, width) ;
+
+		previewp->getSize(width, height);
+
+		// We use the height spinner here because we come here via the aspect ratio
+		// checkbox as well and we want height always changing to width by default.
+		// If we use the width spinner we would change width according to height by
+		// default, that is not what we want.
+		updateSpinners(view, previewp, width, height, !getHeightSpinner(view)->isDirty()); // may change width and height
+		
+		if(getWidthSpinner(view)->getValue().asInteger() != width || getHeightSpinner(view)->getValue().asInteger() != height)
+		{
+			getWidthSpinner(view)->setValue(width);
+			getHeightSpinner(view)->setValue(height);
+			if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			{
+				getWidthSpinner(view)->setIncrement(width >> 1);
+				getHeightSpinner(view)->setIncrement(height >> 1);
+			}
+		}
+
+		if(original_width != width || original_height != height)
+		{
+			previewp->setSize(width, height);
+
+			// hide old preview as the aspect ratio could be wrong
+			checkAutoSnapshot(previewp, FALSE);
+			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
+			getPreviewView(view)->updateSnapshot(TRUE);
+			if(do_update)
+			{
+				LL_DEBUGS() << "Will update controls" << LL_ENDL;
+				updateControls(view);
+			}
+		}
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
+{
+	LLComboBox* combobox = (LLComboBox*)ctrl;
+
+	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
+		
+	if (view)
+	{
+		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		if (previewp)
+		{
+			previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex());
+		}
+		checkAutoSnapshot(previewp, TRUE);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onImageQualityChange(LLFloaterOutfitSnapshot* view, S32 quality_val)
+{
+	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	if (previewp)
+	{
+		previewp->setSnapshotQuality(quality_val);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onImageFormatChange(LLFloaterOutfitSnapshot* view)
+{
+	if (view)
+	{
+		gSavedSettings.setS32("SnapshotFormat", getImageFormat(view));
+		LL_DEBUGS() << "image format changed, updating snapshot" << LL_ENDL;
+		getPreviewView(view)->updateSnapshot(TRUE);
+		updateControls(view);
+	}
+}
+
+// Sets the named size combo to "custom" mode.
+// static
+void LLFloaterOutfitSnapshot::Impl::comboSetCustom(LLFloaterOutfitSnapshot* floater, const std::string& comboname)
+{
+	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
+	combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
+	checkAspectRatio(floater, -1); // -1 means custom
+}
+
+// Update supplied width and height according to the constrain proportions flag; limit them by max_val.
+//static
+BOOL LLFloaterOutfitSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
+{
+	S32 w = width ;
+	S32 h = height ;
+
+	if(previewp && previewp->mKeepAspectRatio)
+	{
+		if(gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1)
+		{
+			return FALSE ;
+		}
+
+		//aspect ratio of the current window
+		F32 aspect_ratio = (F32)gViewerWindow->getWindowWidthRaw() / gViewerWindow->getWindowHeightRaw() ;
+
+		//change another value proportionally
+		if(isWidthChanged)
+		{
+			height = ll_round(width / aspect_ratio) ;
+		}
+		else
+		{
+			width = ll_round(height * aspect_ratio) ;
+		}
+
+		//bound w/h by the max_value
+		if(width > max_value || height > max_value)
+		{
+			if(width > height)
+			{
+				width = max_value ;
+				height = (S32)(width / aspect_ratio) ;
+			}
+			else
+			{
+				height = max_value ;
+				width = (S32)(height * aspect_ratio) ;
+			}
+		}
+	}
+
+	return (w != width || h != height) ;
+}
+
+//static
+void LLFloaterOutfitSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterOutfitSnapshot *view, S32 width, S32 height)
+{
+	getWidthSpinner(view)->forceSetValue(width);
+	getHeightSpinner(view)->forceSetValue(height);
+	if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+	{
+		getWidthSpinner(view)->setIncrement(width >> 1);
+		getHeightSpinner(view)->setIncrement(height >> 1);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::updateSpinners(LLFloaterOutfitSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed)
+{
+	getWidthSpinner(view)->resetDirty();
+	getHeightSpinner(view)->resetDirty();
+	if (checkImageSize(previewp, width, height, is_width_changed, previewp->getMaxImageSize()))
+	{
+		setImageSizeSpinnersValues(view, width, height);
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::applyCustomResolution(LLFloaterOutfitSnapshot* view, S32 w, S32 h)
+{
+	LL_DEBUGS() << "applyCustomResolution(" << w << ", " << h << ")" << LL_ENDL;
+	if (!view) return;
+
+	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	if (previewp)
+	{
+		S32 curw,curh;
+		previewp->getSize(curw, curh);
+
+		if (w != curw || h != curh)
+		{
+			//if to upload a snapshot, process spinner input in a special way.
+			previewp->setMaxImageSize((S32) getWidthSpinner(view)->getMaxValue()) ;
+
+			previewp->setSize(w,h);
+			checkAutoSnapshot(previewp, FALSE);
+			comboSetCustom(view, "profile_size_combo");
+			comboSetCustom(view, "postcard_size_combo");
+			comboSetCustom(view, "texture_size_combo");
+			comboSetCustom(view, "local_size_combo");
+			LL_DEBUGS() << "applied custom resolution, updating thumbnail" << LL_ENDL;
+			previewp->updateSnapshot(TRUE);
+		}
+	}
+}
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished(bool status)
+{
+	setStatus(STATUS_FINISHED, status, "profile");
+}
+
+
+// static
+void LLFloaterOutfitSnapshot::Impl::onSendingPostcardFinished(bool status)
+{
+	setStatus(STATUS_FINISHED, status, "postcard");
+}
+
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterSnapshot
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
+    : LLFloaterSnapshotBase(key),
+	  mRefreshBtn(NULL),
+	  mRefreshLabel(NULL),
+	  mSucceessLblPanel(NULL),
+	  mFailureLblPanel(NULL),
+      mOutfitGallery(NULL),
+	  impl (*(new Impl))
+{
+}
+
+// Destroys the object
+LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
+{
+	if (impl.mPreviewHandle.get()) impl.mPreviewHandle.get()->die();
+
+	//unfreeze everything else
+	gSavedSettings.setBOOL("FreezeTime", FALSE);
+
+	if (impl.mLastToolset)
+	{
+		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
+	}
+
+	delete &impl;
+}
+
+
+BOOL LLFloaterOutfitSnapshot::postBuild()
+{
+	mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
+	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
+	mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
+	mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
+	mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
+
+	childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
+	getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
+
+	childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
+	getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
+
+	impl.setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot"));
+
+	childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this);
+	getChild<LLUICtrl>("layer_types")->setValue("colors");
+	getChildView("layer_types")->setEnabled(FALSE);
+
+	getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
+	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
+
+	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
+	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
+    
+
+	// Filters
+	LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
+    std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
+    for (U32 i = 0; i < filter_list.size(); i++)
+    {
+        filterbox->add(filter_list[i]);
+    }
+    childSetCommitCallback("filters_combobox", Impl::onClickFilter, this);
+    
+	LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished, _1));
+	LLPostCard::setPostResultCallback(boost::bind(&LLFloaterOutfitSnapshot::Impl::onSendingPostcardFinished, _1));
+
+	sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+
+	// create preview window
+	LLRect full_screen_rect = getRootView()->getRect();
+	LLSnapshotLivePreview::Params p;
+	p.rect(full_screen_rect);
+	LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+	LLView* parent_view = gSnapshotFloaterView->getParent();
+	
+	parent_view->removeChild(gSnapshotFloaterView);
+	// make sure preview is below snapshot floater
+	parent_view->addChild(previewp);
+	parent_view->addChild(gSnapshotFloaterView);
+	
+	//move snapshot floater to special purpose snapshotfloaterview
+	gFloaterView->removeChild(this);
+	gSnapshotFloaterView->addChild(this);
+
+	// Pre-select "Current Window" resolution.
+	getChild<LLComboBox>("profile_size_combo")->selectNthItem(0);
+	getChild<LLComboBox>("postcard_size_combo")->selectNthItem(0);
+	getChild<LLComboBox>("texture_size_combo")->selectNthItem(0);
+	getChild<LLComboBox>("local_size_combo")->selectNthItem(8);
+	getChild<LLComboBox>("local_format_combo")->selectNthItem(0);
+
+	impl.mPreviewHandle = previewp->getHandle();
+    previewp->setContainer(this);
+	impl.updateControls(this);
+	impl.updateLayout(this);
+	
+
+	previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
+
+	return TRUE;
+}
+
+void LLFloaterOutfitSnapshot::draw()
+{
+	LLSnapshotLivePreview* previewp = impl.getPreviewView(this);
+
+	if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
+	{
+		// don't render snapshot window in snapshot, even if "show ui" is turned on
+		return;
+	}
+
+	LLFloater::draw();
+
+	if (previewp && !isMinimized() && sThumbnailPlaceholder->getVisible())
+	{		
+		if(previewp->getThumbnailImage())
+		{
+			bool working = impl.getStatus() == Impl::STATUS_WORKING;
+			const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
+			const S32 thumbnail_w = previewp->getThumbnailWidth();
+			const S32 thumbnail_h = previewp->getThumbnailHeight();
+
+			// calc preview offset within the preview rect
+			const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
+			const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ; // preview y pos within the preview rect
+
+			// calc preview offset within the floater rect
+			S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
+			S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
+
+			gGL.matrixMode(LLRender::MM_MODELVIEW);
+			// Apply floater transparency to the texture unless the floater is focused.
+			F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+			LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
+			gl_draw_scaled_image(offset_x, offset_y, 
+					thumbnail_w, thumbnail_h,
+					previewp->getThumbnailImage(), color % alpha);
+
+			previewp->drawPreviewRect(offset_x, offset_y) ;
+
+			gGL.pushUIMatrix();
+			LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
+			sThumbnailPlaceholder->draw();
+			gGL.popUIMatrix();
+		}
+	}
+	impl.updateLayout(this);
+}
+
+void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
+{
+	LLSnapshotLivePreview* preview = LLFloaterOutfitSnapshot::Impl::getPreviewView(this);
+	if(preview)
+	{
+		LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
+		preview->updateSnapshot(TRUE);
+	}
+	focusFirstItem(FALSE);
+	gSnapshotFloaterView->setEnabled(TRUE);
+	gSnapshotFloaterView->setVisible(TRUE);
+	gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
+
+	impl.updateControls(this);
+	impl.updateLayout(this);
+
+	// Initialize default tab.
+	//getChild<LLSideTrayPanelContainer>("panel_container")->getCurrentPanel()->onOpen(LLSD());
+    //parent->openPanel(panel_name);
+    LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
+    snapshot_panel->onOpen(LLSD());
+    postPanelSwitch();
+
+}
+
+void LLFloaterOutfitSnapshot::onClose(bool app_quitting)
+{
+	getParent()->setMouseOpaque(FALSE);
+
+	//unfreeze everything, hide fullscreen preview
+	LLSnapshotLivePreview* previewp = LLFloaterOutfitSnapshot::Impl::getPreviewView(this);
+	if (previewp)
+	{
+		previewp->setVisible(FALSE);
+		previewp->setEnabled(FALSE);
+	}
+
+	gSavedSettings.setBOOL("FreezeTime", FALSE);
+	impl.mAvatarPauseHandles.clear();
+
+	if (impl.mLastToolset)
+	{
+		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
+	}
+}
+
+// virtual
+S32 LLFloaterOutfitSnapshot::notify(const LLSD& info)
+{
+	// A child panel wants to change snapshot resolution.
+	if (info.has("combo-res-change"))
+	{
+		std::string combo_name = info["combo-res-change"]["control-name"].asString();
+		impl.updateResolution(getChild<LLUICtrl>(combo_name), this);
+		return 1;
+	}
+
+	if (info.has("custom-res-change"))
+	{
+		LLSD res = info["custom-res-change"];
+		impl.applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger());
+		return 1;
+	}
+
+	if (info.has("keep-aspect-change"))
+	{
+		impl.applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean());
+		return 1;
+	}
+
+	if (info.has("image-quality-change"))
+	{
+		impl.onImageQualityChange(this, info["image-quality-change"].asInteger());
+		return 1;
+	}
+
+	if (info.has("image-format-change"))
+	{
+		impl.onImageFormatChange(this);
+		return 1;
+	}
+
+	if (info.has("set-ready"))
+	{
+		impl.setStatus(Impl::STATUS_READY);
+		return 1;
+	}
+
+	if (info.has("set-working"))
+	{
+		impl.setStatus(Impl::STATUS_WORKING);
+		return 1;
+	}
+
+	if (info.has("set-finished"))
+	{
+		LLSD data = info["set-finished"];
+		impl.setStatus(Impl::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString());
+		return 1;
+	}
+    
+	if (info.has("snapshot-updating"))
+	{
+        // Disable the send/post/save buttons until snapshot is ready.
+        impl.updateControls(this);
+		return 1;
+	}
+
+	if (info.has("snapshot-updated"))
+	{
+        // Enable the send/post/save buttons.
+        impl.updateControls(this);
+        // We've just done refresh.
+        impl.setNeedRefresh(this, false);
+            
+        // The refresh button is initially hidden. We show it after the first update,
+        // i.e. when preview appears.
+        if (!mRefreshBtn->getVisible())
+        {
+            mRefreshBtn->setVisible(true);
+        }
+		return 1;
+	}    
+    
+	return 0;
+}
+
+//static 
+void LLFloaterOutfitSnapshot::update()
+{
+	LLFloaterOutfitSnapshot* inst = findInstance();
+	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); 
+	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); 
+	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); 
+
+	if (!inst && !floater_facebook && !floater_flickr && !floater_twitter)
+		return;
+	
+	BOOL changed = FALSE;
+	LL_DEBUGS() << "npreviews: " << LLSnapshotLivePreview::sList.size() << LL_ENDL;
+	for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
+		 iter != LLSnapshotLivePreview::sList.end(); ++iter)
+	{
+		changed |= LLSnapshotLivePreview::onIdle(*iter);
+	}
+    
+	if (inst && changed)
+	{
+		LL_DEBUGS() << "changed" << LL_ENDL;
+		inst->impl.updateControls(inst);
+	}
+}
+
+// static
+LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
+{
+	return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
+}
+
+// static
+LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
+{
+	return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
+}
+
+// static
+void LLFloaterOutfitSnapshot::saveTexture()
+{
+	LL_DEBUGS() << "saveTexture" << LL_ENDL;
+
+	// FIXME: duplicated code
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (!instance)
+	{
+		llassert(instance != NULL);
+		return;
+	}
+	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	if (!previewp)
+	{
+		llassert(previewp != NULL);
+		return;
+	}
+
+    if (instance->mOutfitGallery)
+    {
+        instance->mOutfitGallery->onBeforeOutfitSnapshotSave();
+    }
+    previewp->saveTexture(TRUE, instance->getOutfitID().asString());
+    if (instance->mOutfitGallery)
+    {
+        instance->mOutfitGallery->onAfterOutfitSnapshotSave();
+    }
+    instance->closeFloater();
+}
+
+// static
+BOOL LLFloaterOutfitSnapshot::saveLocal()
+{
+	LL_DEBUGS() << "saveLocal" << LL_ENDL;
+	// FIXME: duplicated code
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (!instance)
+	{
+		llassert(instance != NULL);
+		return FALSE;
+	}
+	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	if (!previewp)
+	{
+		llassert(previewp != NULL);
+		return FALSE;
+	}
+
+	return previewp->saveLocal();
+}
+
+// static
+void LLFloaterOutfitSnapshot::postSave()
+{
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (!instance)
+	{
+		llassert(instance != NULL);
+		return;
+	}
+
+	instance->impl.updateControls(instance);
+	instance->impl.setStatus(Impl::STATUS_WORKING);
+}
+
+// static
+void LLFloaterOutfitSnapshot::postPanelSwitch()
+{
+	LLFloaterOutfitSnapshot* instance = getInstance();
+	instance->impl.updateControls(instance);
+
+	// Remove the success/failure indicator whenever user presses a snapshot option button.
+	instance->impl.setStatus(Impl::STATUS_READY);
+}
+
+// static
+LLPointer<LLImageFormatted> LLFloaterOutfitSnapshot::getImageData()
+{
+	// FIXME: May not work for textures.
+
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (!instance)
+	{
+		llassert(instance != NULL);
+		return NULL;
+	}
+
+	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	if (!previewp)
+	{
+		llassert(previewp != NULL);
+		return NULL;
+	}
+
+	LLPointer<LLImageFormatted> img = previewp->getFormattedImage();
+	if (!img.get())
+	{
+		LL_WARNS() << "Empty snapshot image data" << LL_ENDL;
+		llassert(img.get() != NULL);
+	}
+
+	return img;
+}
+
+// static
+const LLVector3d& LLFloaterOutfitSnapshot::getPosTakenGlobal()
+{
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (!instance)
+	{
+		llassert(instance != NULL);
+		return LLVector3d::zero;
+	}
+
+	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	if (!previewp)
+	{
+		llassert(previewp != NULL);
+		return LLVector3d::zero;
+	}
+
+	return previewp->getPosTakenGlobal();
+}
+
+// static
+void LLFloaterOutfitSnapshot::setAgentEmail(const std::string& email)
+{
+	LLFloaterOutfitSnapshot* instance = findInstance();
+	if (instance)
+	{
+		LLSideTrayPanelContainer* panel_container = instance->getChild<LLSideTrayPanelContainer>("panel_container");
+		LLPanel* postcard_panel = panel_container->getPanelByName("panel_snapshot_postcard");
+		postcard_panel->notify(LLSD().with("agent-email", email));
+	}
+}
+
+///----------------------------------------------------------------------------
+/// Class LLSnapshotFloaterView
+///----------------------------------------------------------------------------
+
+LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView (const Params& p) : LLFloaterView (p)
+{
+}
+
+LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
+{
+}
+
+BOOL LLOutfitSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
+{
+	// use default handler when not in freeze-frame mode
+	if(!gSavedSettings.getBOOL("FreezeTime"))
+	{
+		return LLFloaterView::handleKey(key, mask, called_from_parent);
+	}
+
+	if (called_from_parent)
+	{
+		// pass all keystrokes down
+		LLFloaterView::handleKey(key, mask, called_from_parent);
+	}
+	else
+	{
+		// bounce keystrokes back down
+		LLFloaterView::handleKey(key, mask, TRUE);
+	}
+	return TRUE;
+}
+
+BOOL LLOutfitSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	// use default handler when not in freeze-frame mode
+	if(!gSavedSettings.getBOOL("FreezeTime"))
+	{
+		return LLFloaterView::handleMouseDown(x, y, mask);
+	}
+	// give floater a change to handle mouse, else camera tool
+	if (childrenHandleMouseDown(x, y, mask) == NULL)
+	{
+		LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask );
+	}
+	return TRUE;
+}
+
+BOOL LLOutfitSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+	// use default handler when not in freeze-frame mode
+	if(!gSavedSettings.getBOOL("FreezeTime"))
+	{
+		return LLFloaterView::handleMouseUp(x, y, mask);
+	}
+	// give floater a change to handle mouse, else camera tool
+	if (childrenHandleMouseUp(x, y, mask) == NULL)
+	{
+		LLToolMgr::getInstance()->getCurrentTool()->handleMouseUp( x, y, mask );
+	}
+	return TRUE;
+}
+
+BOOL LLOutfitSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)
+{
+	// use default handler when not in freeze-frame mode
+	if(!gSavedSettings.getBOOL("FreezeTime"))
+	{
+		return LLFloaterView::handleHover(x, y, mask);
+	}	
+	// give floater a change to handle mouse, else camera tool
+	if (childrenHandleHover(x, y, mask) == NULL)
+	{
+		LLToolMgr::getInstance()->getCurrentTool()->handleHover( x, y, mask );
+	}
+	return TRUE;
+}
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
new file mode 100644
index 0000000000..176a9520c2
--- /dev/null
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -0,0 +1,110 @@
+/** 
+ * @file llfloateroutfitsnapshot.h
+ * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2016, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATEROUTFITSNAPSHOT_H
+#define LL_LLFLOATEROUTFITSNAPSHOT_H
+
+#include "llfloater.h"
+#include "llfloatersnapshot.h"
+#include "lloutfitgallery.h"
+
+class LLSpinCtrl;
+
+class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
+{
+	LOG_CLASS(LLFloaterOutfitSnapshot);
+
+public:
+	//typedef enum e_snapshot_format
+	//{
+	//	SNAPSHOT_FORMAT_PNG,
+	//	SNAPSHOT_FORMAT_JPEG,
+	//	SNAPSHOT_FORMAT_BMP
+	//} ESnapshotFormat;
+
+	LLFloaterOutfitSnapshot(const LLSD& key);
+	virtual ~LLFloaterOutfitSnapshot();
+    
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
+	/*virtual*/ S32 notify(const LLSD& info);
+	
+	static void update();
+
+	// TODO: create a snapshot model instead
+	static LLFloaterOutfitSnapshot* getInstance();
+	static LLFloaterOutfitSnapshot* findInstance();
+	static void saveTexture();
+	static BOOL saveLocal();
+	static void postSave();
+	static void postPanelSwitch();
+	static LLPointer<LLImageFormatted> getImageData();
+	static const LLVector3d& getPosTakenGlobal();
+	static void setAgentEmail(const std::string& email);
+
+	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
+
+    void setOutfitID(LLUUID id) { mOutfitID = id; }
+    LLUUID getOutfitID() { return mOutfitID; }
+    void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
+private:
+	static LLUICtrl* sThumbnailPlaceholder;
+	LLUICtrl *mRefreshBtn, *mRefreshLabel;
+	LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
+
+	class Impl;
+	Impl& impl;
+
+    LLUUID mOutfitID;
+    LLOutfitGallery* mOutfitGallery;
+};
+
+class LLOutfitSnapshotFloaterView : public LLFloaterView
+{
+public:
+	struct Params 
+	:	public LLInitParam::Block<Params, LLFloaterView::Params>
+	{
+	};
+
+protected:
+	LLOutfitSnapshotFloaterView (const Params& p);
+	friend class LLUICtrlFactory;
+
+public:
+	virtual ~LLOutfitSnapshotFloaterView();
+
+	/*virtual*/	BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+	/*virtual*/	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/	BOOL handleHover(S32 x, S32 y, MASK mask);
+};
+
+extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
+
+#endif // LL_LLFLOATEROUTFITSNAPSHOT_H
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index afec981d56..e5a2bd03cd 100755
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -62,11 +62,20 @@ const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
 static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
 
 
+LLFloaterSnapshotBase::ImplBase::ImplBase()
+{
+}
+
+LLFloaterSnapshotBase::ImplBase::~ImplBase()
+{
+}
+
+
 ///----------------------------------------------------------------------------
 /// Class LLFloaterSnapshot::Impl
 ///----------------------------------------------------------------------------
 
-class LLFloaterSnapshot::Impl
+class LLFloaterSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
 {
 	LOG_CLASS(LLFloaterSnapshot::Impl);
 public:
@@ -111,8 +120,8 @@ public:
 	static void updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
 
 	static LLPanelSnapshot* getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found = true);
-	static LLSnapshotLivePreview::ESnapshotType getActiveSnapshotType(LLFloaterSnapshot* floater);
-	static LLFloaterSnapshot::ESnapshotFormat getImageFormat(LLFloaterSnapshot* floater);
+    static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterSnapshot* floater);
+    static LLFloaterSnapshotBase::ESnapshotFormat getImageFormat(LLFloaterSnapshot* floater);
 	static LLSpinCtrl* getWidthSpinner(LLFloaterSnapshot* floater);
 	static LLSpinCtrl* getHeightSpinner(LLFloaterSnapshot* floater);
 	static void enableAspectRatioCheckbox(LLFloaterSnapshot* floater, BOOL enable);
@@ -158,35 +167,40 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshot* floa
 }
 
 // static
-LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getActiveSnapshotType(LLFloaterSnapshot* floater)
+LLPanelSnapshot::ESnapshotType LLFloaterSnapshot::Impl::getActiveSnapshotType(LLFloaterSnapshot* floater)
 {
-	LLSnapshotLivePreview::ESnapshotType type = LLSnapshotLivePreview::SNAPSHOT_WEB;
-	std::string name;
+ //   LLPanelSnapshot::ESnapshotType type = LLPanelSnapshot::SNAPSHOT_WEB;
+	//std::string name;
 	LLPanelSnapshot* spanel = getActivePanel(floater);
 
-	if (spanel)
-	{
-		name = spanel->getName();
-	}
-
-	if (name == "panel_snapshot_postcard")
-	{
-		type = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
-	}
-	else if (name == "panel_snapshot_inventory")
-	{
-		type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
-	}
-	else if (name == "panel_snapshot_local")
-	{
-		type = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
-	}
-
-	return type;
+	//if (spanel)
+	//{
+	//	name = spanel->getName();
+	//}
+
+	//if (name == "panel_snapshot_postcard")
+	//{
+	//	type = LLPanelSnapshot::SNAPSHOT_POSTCARD;
+	//}
+	//else if (name == "panel_snapshot_inventory")
+	//{
+	//	type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
+	//}
+	//else if (name == "panel_snapshot_local")
+	//{
+	//	type = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
+	//}
+
+	//return type;
+    if (spanel)
+    {
+        return spanel->getSnapshotType();
+    }
+    return LLPanelSnapshot::SNAPSHOT_WEB;
 }
 
 // static
-LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshot* floater)
+LLFloaterSnapshotBase::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshot* floater)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	// FIXME: if the default is not PNG, profile uploads may fail.
@@ -362,12 +376,12 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 // static
 void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 {
-	LLSnapshotLivePreview::ESnapshotType shot_type = getActiveSnapshotType(floater);
+	LLPanelSnapshot::ESnapshotType shot_type = getActiveSnapshotType(floater);
 	ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
 	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
 
 	floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
-	floater->getChildView("layer_types")->setEnabled(shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
+	floater->getChildView("layer_types")->setEnabled(shot_type == LLPanelSnapshot::SNAPSHOT_LOCAL);
 
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	if (active_panel)
@@ -381,7 +395,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 			S32 w = gViewerWindow->getWindowWidthRaw();
 			LL_DEBUGS() << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << LL_ENDL;
 			width_ctrl->setValue(w);
-			if(getActiveSnapshotType(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+			if(getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 			{
 				width_ctrl->setIncrement(w >> 1);
 			}
@@ -391,7 +405,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 			S32 h = gViewerWindow->getWindowHeightRaw();
 			LL_DEBUGS() << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << LL_ENDL;
 			height_ctrl->setValue(h);
-			if(getActiveSnapshotType(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+			if(getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 			{
 				height_ctrl->setIncrement(h >> 1);
 			}
@@ -448,29 +462,29 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 
 	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
 	floater->getChild<LLUICtrl>("file_size_label")->setColor(
-			shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
+			shot_type == LLPanelSnapshot::SNAPSHOT_POSTCARD
 			&& got_bytes
 			&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
 
 	// Update the width and height spinners based on the corresponding resolution combos. (?)
 	switch(shot_type)
 	{
-	  case LLSnapshotLivePreview::SNAPSHOT_WEB:
+	  case LLPanelSnapshot::SNAPSHOT_WEB:
 		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "profile_size_combo");
 		break;
-	  case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
+	  case LLPanelSnapshot::SNAPSHOT_POSTCARD:
 		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "postcard_size_combo");
 		break;
-	  case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
+	  case LLPanelSnapshot::SNAPSHOT_TEXTURE:
 		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "texture_size_combo");
 		break;
-	  case  LLSnapshotLivePreview::SNAPSHOT_LOCAL:
+	  case  LLPanelSnapshot::SNAPSHOT_LOCAL:
 		setResolution(floater, "local_size_combo");
 		break;
 	  default:
@@ -686,7 +700,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
 	LLSnapshotLivePreview *previewp = getPreviewView(view) ;
 
 	// Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
-	if(LLSnapshotLivePreview::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
+	if(LLPanelSnapshot::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
 	{
 		previewp->mKeepAspectRatio = FALSE ;
 		return ;
@@ -813,7 +827,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 				new_height = spanel->getTypedPreviewHeight();
 
 				// Limit custom size for inventory snapshots to 512x512 px.
-				if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+				if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 				{
 					new_width = llmin(new_width, MAX_TEXTURE_SIZE);
 					new_height = llmin(new_height, MAX_TEXTURE_SIZE);
@@ -851,7 +865,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 		{
 			getWidthSpinner(view)->setValue(width);
 			getHeightSpinner(view)->setValue(height);
-			if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+			if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 			{
 				getWidthSpinner(view)->setIncrement(width >> 1);
 				getHeightSpinner(view)->setIncrement(height >> 1);
@@ -975,7 +989,7 @@ void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshot *view
 {
 	getWidthSpinner(view)->forceSetValue(width);
 	getHeightSpinner(view)->forceSetValue(height);
-	if (getActiveSnapshotType(view) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+	if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 	{
 		getWidthSpinner(view)->setIncrement(width >> 1);
 		getHeightSpinner(view)->setIncrement(height >> 1);
@@ -1035,13 +1049,27 @@ void LLFloaterSnapshot::Impl::onSendingPostcardFinished(bool status)
 	setStatus(STATUS_FINISHED, status, "postcard");
 }
 
+///----------------------------------------------------------------------------
+/// Class LLFloaterSnapshotBase
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLFloaterSnapshotBase::LLFloaterSnapshotBase(const LLSD& key)
+    : LLFloater(key)
+{
+}
+
+LLFloaterSnapshotBase::~LLFloaterSnapshotBase()
+{
+}
+
 ///----------------------------------------------------------------------------
 /// Class LLFloaterSnapshot
 ///----------------------------------------------------------------------------
 
 // Default constructor
 LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)
-	: LLFloater(key),
+    : LLFloaterSnapshotBase(key),
 	  mRefreshBtn(NULL),
 	  mRefreshLabel(NULL),
 	  mSucceessLblPanel(NULL),
@@ -1377,7 +1405,7 @@ BOOL LLFloaterSnapshot::saveLocal()
 {
 	LL_DEBUGS() << "saveLocal" << LL_ENDL;
 	// FIXME: duplicated code
-	LLFloaterSnapshot* instance = findInstance();
+    LLFloaterSnapshot* instance = findInstance();
 	if (!instance)
 	{
 		llassert(instance != NULL);
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 0bb9474bb5..5f9857c8c5 100755
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -31,17 +31,45 @@
 
 class LLSpinCtrl;
 
-class LLFloaterSnapshot : public LLFloater
+class LLFloaterSnapshotBase : public LLFloater
+{
+    LOG_CLASS(LLFloaterSnapshotBase);
+
+public:
+    typedef enum e_snapshot_format
+    {
+        SNAPSHOT_FORMAT_PNG,
+        SNAPSHOT_FORMAT_JPEG,
+        SNAPSHOT_FORMAT_BMP
+    } ESnapshotFormat;
+
+    LLFloaterSnapshotBase(const LLSD& key);
+    virtual ~LLFloaterSnapshotBase();
+
+    ///*virtual*/ S32 notify(const LLSD& info);
+
+    //static LLFloaterSnapshotBase* getInstance();
+    //static LLFloaterSnapshotBase* findInstance();
+    //static void saveTexture();
+    //static BOOL saveLocal();
+    //static void postSave();
+
+protected:
+    class ImplBase;
+    //ImplBase& impl;
+};
+
+class LLFloaterSnapshot : public LLFloaterSnapshotBase
 {
 	LOG_CLASS(LLFloaterSnapshot);
 
 public:
-	typedef enum e_snapshot_format
-	{
-		SNAPSHOT_FORMAT_PNG,
-		SNAPSHOT_FORMAT_JPEG,
-		SNAPSHOT_FORMAT_BMP
-	} ESnapshotFormat;
+	//typedef enum e_snapshot_format
+	//{
+	//	SNAPSHOT_FORMAT_PNG,
+	//	SNAPSHOT_FORMAT_JPEG,
+	//	SNAPSHOT_FORMAT_BMP
+	//} ESnapshotFormat;
 
 	LLFloaterSnapshot(const LLSD& key);
 	virtual ~LLFloaterSnapshot();
@@ -76,6 +104,13 @@ private:
 	Impl& impl;
 };
 
+class LLFloaterSnapshotBase::ImplBase
+{
+public:
+    ImplBase();
+    ~ImplBase();
+};
+
 class LLSnapshotFloaterView : public LLFloaterView
 {
 public:
diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
index c48b1a3325..984ba587ed 100644
--- a/indra/newview/llfloatertwitter.cpp
+++ b/indra/newview/llfloatertwitter.cpp
@@ -241,7 +241,7 @@ void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible)
 			mPreviewHandle = previewp->getHandle();
 
             previewp->setContainer(this);
-			previewp->setSnapshotType(previewp->SNAPSHOT_WEB);
+            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
 			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
             previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index c553d3d338..b351be8de9 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -39,6 +39,8 @@
 #include "llerror.h"
 #include "llfilepicker.h"
 #include "llfloaterperms.h"
+#include "llfloaterreg.h"
+#include "llfloateroutfitsnapshot.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
 #include "lllocalbitmaps.h"
@@ -636,6 +638,7 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("collapse", FALSE);
     mMenu->setItemVisible("upload_photo", TRUE);
     mMenu->setItemVisible("select_photo", TRUE);
+    mMenu->setItemVisible("take_snapshot", TRUE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
@@ -659,6 +662,16 @@ void LLOutfitGalleryGearMenu::onSelectPhoto()
     }
 }
 
+void LLOutfitGalleryGearMenu::onTakeSnapshot()
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    LLUUID selected_outfit_id = getSelectedOutfitID();
+    if (gallery && !selected_outfit_id.isNull())
+    {
+        gallery->onTakeSnapshot(selected_outfit_id);
+    }
+}
+
 void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp)
 {
 }
@@ -715,6 +728,16 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
                     updates["name"] = new_name;
                     update_inventory_item(linked_item->getUUID(), updates, NULL);
                     mOutfitRenamePending.setNull();
+                    LLFloater* inv_floater = LLFloaterReg::getInstance("inventory");
+                    if (inv_floater)
+                    {
+                        inv_floater->closeFloater();
+                    }
+                    LLFloater* appearance_floater = LLFloaterReg::getInstance("appearance");
+                    if (appearance_floater)
+                    {
+                        appearance_floater->setFocus(TRUE);
+                    }
                 }
                 break;
             }
@@ -798,10 +821,11 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
 
             checkRemovePhoto(outfit_id);
             std::string upload_pending_name = outfit_id.asString();
+            std::string upload_pending_desc = "";
             LLAssetStorage::LLStoreAssetCallback callback = NULL;
             LLUUID photo_id = upload_new_resource(filename, // file
                 upload_pending_name,
-                outfit_id.asString(),
+                upload_pending_desc,
                 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
                 LLFloaterPerms::getNextOwnerPerms("Uploads"),
                 LLFloaterPerms::getGroupPerms("Uploads"),
@@ -926,3 +950,28 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
         floaterp->setFocus(TRUE);
     }
 }
+
+void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
+{
+    LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot");
+    LLFloaterOutfitSnapshot::getInstance()->setOutfitID(selected_outfit_id);
+    LLFloaterOutfitSnapshot::getInstance()->setGallery(this);
+}
+
+void LLOutfitGallery::onBeforeOutfitSnapshotSave()
+{
+    LLUUID selected_outfit_id = getSelectedOutfitUUID();
+    if (!selected_outfit_id.isNull())
+    {
+        checkRemovePhoto(selected_outfit_id);
+    }
+}
+
+void LLOutfitGallery::onAfterOutfitSnapshotSave()
+{
+    LLUUID selected_outfit_id = getSelectedOutfitUUID();
+    if (!selected_outfit_id.isNull())
+    {
+        mOutfitLinkPending = selected_outfit_id;
+    }
+}
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 285c8baf59..dbf891142d 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -85,6 +85,8 @@ public:
     /*virtual*/ void draw();	
     
     void onSelectPhoto(LLUUID selected_outfit_id);
+    void onTakeSnapshot(LLUUID selected_outfit_id);
+
 
     /*virtual*/ void setFilterSubString(const std::string& string);
 
@@ -102,6 +104,8 @@ public:
     void refreshOutfit(const LLUUID& category_id);
 
     void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id);
+    void onBeforeOutfitSnapshotSave();
+    void onAfterOutfitSnapshotSave();
 protected:
     /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id);
     /*virtual*/ void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid);
@@ -191,6 +195,7 @@ protected:
 private:
     /*virtual*/ void onUploadFoto();
     /*virtual*/ void onSelectPhoto();
+    /*virtual*/ void onTakeSnapshot();
 };
 
 class LLOutfitGalleryItem : public LLPanel
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index b657d2e285..31fe6839f3 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1092,6 +1092,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
 
     registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
     registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this));
+    registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this));
 
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
     enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
@@ -1235,6 +1236,11 @@ void LLOutfitListGearMenuBase::onSelectPhoto()
 
 }
 
+void LLOutfitListGearMenuBase::onTakeSnapshot()
+{
+
+}
+
 LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
@@ -1249,6 +1255,7 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("collapse", TRUE);
     mMenu->setItemVisible("upload_photo", FALSE);
     mMenu->setItemVisible("select_photo", FALSE);
+    mMenu->setItemVisible("take_snapshot", FALSE);    
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index d7c549c417..696a18a36a 100755
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -165,6 +165,7 @@ protected:
     virtual void onUpdateItemsVisibility();
     virtual void onUploadFoto();
     virtual void onSelectPhoto();
+    virtual void onTakeSnapshot();
 
     const LLUUID& getSelectedOutfitID();
 
diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index 106fb4997e..ca62f2bdf5 100755
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
@@ -76,11 +76,11 @@ void LLPanelSnapshot::onOpen(const LLSD& key)
 	// e.g. attempt to send a large BMP image by email.
 	if (old_format != new_format)
 	{
-		LLFloaterSnapshot::getInstance()->notify(LLSD().with("image-format-change", true));
+        getParentByType<LLFloater>()->notify(LLSD().with("image-format-change", true));
 	}
 }
 
-LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
+LLFloaterSnapshotBase::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
 {
 	return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
 }
@@ -171,7 +171,7 @@ void LLPanelSnapshot::goBack()
 void LLPanelSnapshot::cancel()
 {
 	goBack();
-	LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-ready", true));
+    getParentByType<LLFloater>()->notify(LLSD().with("set-ready", true));
 }
 
 void LLPanelSnapshot::onCustomResolutionCommit()
@@ -179,6 +179,7 @@ void LLPanelSnapshot::onCustomResolutionCommit()
 	LLSD info;
 	LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(getWidthSpinnerName());
 	LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(getHeightSpinnerName());
+    //TODO: Refactoring - move this code into some virtual method of LLPanelSnapshotInventory
 	if (getName() == "panel_snapshot_inventory")
 	{
 		S32 width = widthSpinner->getValue().asInteger();
@@ -197,17 +198,22 @@ void LLPanelSnapshot::onCustomResolutionCommit()
 		info["w"] = widthSpinner->getValue().asInteger();
 		info["h"] = heightSpinner->getValue().asInteger();
 	}
-	LLFloaterSnapshot::getInstance()->notify(LLSD().with("custom-res-change", info));
+    getParentByType<LLFloater>()->notify(LLSD().with("custom-res-change", info));
 }
 
 void LLPanelSnapshot::onResolutionComboCommit(LLUICtrl* ctrl)
 {
 	LLSD info;
 	info["combo-res-change"]["control-name"] = ctrl->getName();
-	LLFloaterSnapshot::getInstance()->notify(info);
+    getParentByType<LLFloater>()->notify(info);
 }
 
 void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl)
 {
-	LLFloaterSnapshot::getInstance()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
+    getParentByType<LLFloater>()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
+}
+
+LLPanelSnapshot::ESnapshotType LLPanelSnapshot::getSnapshotType()
+{
+    return ESnapshotType::SNAPSHOT_WEB;
 }
diff --git a/indra/newview/llpanelsnapshot.h b/indra/newview/llpanelsnapshot.h
index 42ad798d60..d64ef3b75a 100755
--- a/indra/newview/llpanelsnapshot.h
+++ b/indra/newview/llpanelsnapshot.h
@@ -37,6 +37,14 @@ class LLSideTrayPanelContainer;
 class LLPanelSnapshot: public LLPanel
 {
 public:
+    enum ESnapshotType
+    {
+        SNAPSHOT_POSTCARD,
+        SNAPSHOT_TEXTURE,
+        SNAPSHOT_LOCAL,
+        SNAPSHOT_WEB
+    };
+
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
@@ -51,7 +59,8 @@ public:
 	virtual LLSpinCtrl* getWidthSpinner();
 	virtual LLSpinCtrl* getHeightSpinner();
 	virtual void enableAspectRatioCheckbox(BOOL enable);
-	virtual LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
+    virtual LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const;
+    virtual ESnapshotType getSnapshotType();
 	virtual void updateControls(const LLSD& info) = 0; ///< Update controls from saved settings
 	void enableControls(BOOL enable);
 
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index c55e230b5e..013a564908 100755
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -32,14 +32,43 @@
 #include "llspinctrl.h"
 
 #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
+#include "llfloateroutfitsnapshot.h"
 #include "llpanelsnapshot.h"
+#include "llsnapshotlivepreview.h"
 #include "llviewercontrol.h" // gSavedSettings
 
 /**
  * The panel provides UI for saving snapshot as an inventory texture.
  */
+class LLPanelSnapshotInventoryBase
+    : public LLPanelSnapshot
+{
+    LOG_CLASS(LLPanelSnapshotInventoryBase);
+
+public:
+    LLPanelSnapshotInventoryBase();
+//
+//    /*virtual*/ BOOL postBuild();
+//    /*virtual*/ void onOpen(const LLSD& key);
+//
+//    void onResolutionCommit(LLUICtrl* ctrl);
+//
+//private:
+//    /*virtual*/ std::string getWidthSpinnerName() const		{ return "inventory_snapshot_width"; }
+//    /*virtual*/ std::string getHeightSpinnerName() const	{ return "inventory_snapshot_height"; }
+//    /*virtual*/ std::string getAspectRatioCBName() const	{ return "inventory_keep_aspect_check"; }
+//    /*virtual*/ std::string getImageSizeComboName() const	{ return "texture_size_combo"; }
+//    /*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
+//    /*virtual*/ void updateControls(const LLSD& info);
+
+protected:
+    virtual void onSend() = 0;
+    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
+
+};
+
 class LLPanelSnapshotInventory
-:	public LLPanelSnapshot
+    : public LLPanelSnapshotInventoryBase
 {
 	LOG_CLASS(LLPanelSnapshotInventory);
 
@@ -58,10 +87,44 @@ private:
 	/*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
 	/*virtual*/ void updateControls(const LLSD& info);
 
-	void onSend();
+    /*virtual*/ void onSend();
+};
+
+class LLPanelOutfitSnapshotInventory
+    : public LLPanelSnapshotInventoryBase
+{
+    LOG_CLASS(LLPanelOutfitSnapshotInventory);
+
+public:
+    LLPanelOutfitSnapshotInventory();
+    	/*virtual*/ BOOL postBuild();
+    	/*virtual*/ void onOpen(const LLSD& key);
+    
+    	void onResolutionCommit(LLUICtrl* ctrl);
+    
+    private:
+    	/*virtual*/ std::string getWidthSpinnerName() const		{ return "inventory_snapshot_width"; }
+    	/*virtual*/ std::string getHeightSpinnerName() const	{ return "inventory_snapshot_height"; }
+    	/*virtual*/ std::string getAspectRatioCBName() const	{ return "inventory_keep_aspect_check"; }
+    	/*virtual*/ std::string getImageSizeComboName() const	{ return "texture_size_combo"; }
+    	/*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
+    	/*virtual*/ void updateControls(const LLSD& info);
+
+    /*virtual*/ void onSend();
 };
 
-static LLPanelInjector<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory");
+static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory");
+
+static LLPanelInjector<LLPanelOutfitSnapshotInventory> panel_class2("llpaneloutfitsnapshotinventory");
+
+LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase()
+{
+}
+
+LLPanelSnapshot::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType()
+{
+    return LLPanelSnapshot::SNAPSHOT_TEXTURE;
+}
 
 LLPanelSnapshotInventory::LLPanelSnapshotInventory()
 {
@@ -105,3 +168,46 @@ void LLPanelSnapshotInventory::onSend()
 	LLFloaterSnapshot::saveTexture();
 	LLFloaterSnapshot::postSave();
 }
+
+LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory()
+{
+    mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this));
+    mCommitCallbackRegistrar.add("Inventory.Cancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this));
+}
+
+// virtual
+BOOL LLPanelOutfitSnapshotInventory::postBuild()
+{
+    getChild<LLSpinCtrl>(getWidthSpinnerName())->setAllowEdit(FALSE);
+    getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE);
+
+    getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelOutfitSnapshotInventory::onResolutionCommit, this, _1));
+    return LLPanelSnapshot::postBuild();
+}
+
+// virtual
+void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key)
+{
+    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()));
+    LLPanelSnapshot::onOpen(key);
+}
+
+// virtual
+void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info)
+{
+    const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true;
+    getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
+}
+
+void LLPanelOutfitSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
+{
+    BOOL current_window_selected = (getChild<LLComboBox>(getImageSizeComboName())->getCurrentIndex() == 3);
+    getChild<LLSpinCtrl>(getWidthSpinnerName())->setVisible(!current_window_selected);
+    getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected);
+}
+
+void LLPanelOutfitSnapshotInventory::onSend()
+{
+    LLFloaterOutfitSnapshot::saveTexture();
+    LLFloaterOutfitSnapshot::postSave();
+}
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 01dfdc4ece..954eb63a28 100755
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -33,6 +33,7 @@
 
 #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
 #include "llpanelsnapshot.h"
+#include "llsnapshotlivepreview.h"
 #include "llviewercontrol.h" // gSavedSettings
 #include "llviewerwindow.h"
 
@@ -55,8 +56,9 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "local_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "local_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "local_image_size_lp"; }
-	/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
-	/*virtual*/ void updateControls(const LLSD& info);
+    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const;
+    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
+    /*virtual*/ void updateControls(const LLSD& info);
 
 	S32 mLocalFormat;
 
@@ -94,9 +96,9 @@ void LLPanelSnapshotLocal::onOpen(const LLSD& key)
 }
 
 // virtual
-LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
+LLFloaterSnapshotBase::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
 {
-	LLFloaterSnapshot::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
+    LLFloaterSnapshotBase::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
 
 	LLComboBox* local_format_combo = getChild<LLComboBox>("local_format_combo");
 	const std::string id  = local_format_combo->getValue().asString();
@@ -119,8 +121,8 @@ LLFloaterSnapshot::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
 // virtual
 void LLPanelSnapshotLocal::updateControls(const LLSD& info)
 {
-	LLFloaterSnapshot::ESnapshotFormat fmt =
-		(LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
+    LLFloaterSnapshotBase::ESnapshotFormat fmt =
+        (LLFloaterSnapshotBase::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
 	getChild<LLComboBox>("local_format_combo")->selectNthItem((S32) fmt);
 
 	const bool show_quality_ctrls = (fmt == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
@@ -174,3 +176,8 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
 		cancel();
 	}
 }
+
+LLPanelSnapshot::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
+{
+    return LLPanelSnapshot::SNAPSHOT_LOCAL;
+}
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index 8e37b1418c..2884313f60 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -38,6 +38,7 @@
 #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
 #include "llpanelsnapshot.h"
 #include "llpostcard.h"
+#include "llsnapshotlivepreview.h"
 #include "llviewercontrol.h" // gSavedSettings
 #include "llviewerwindow.h"
 
@@ -63,8 +64,9 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "postcard_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "postcard_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "postcard_image_size_lp"; }
-	/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG; }
-	/*virtual*/ void updateControls(const LLSD& info);
+    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshotBase::SNAPSHOT_FORMAT_JPEG; }
+    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
+    /*virtual*/ void updateControls(const LLSD& info);
 
 	bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
 	void sendPostcard();
@@ -242,3 +244,8 @@ void LLPanelSnapshotPostcard::onSend()
 	// Send postcard.
 	sendPostcard();
 }
+
+LLPanelSnapshot::ESnapshotType LLPanelSnapshotPostcard::getSnapshotType()
+{
+    return LLPanelSnapshot::SNAPSHOT_POSTCARD;
+}
diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp
index 8949eb73eb..b6fc45fb63 100755
--- a/indra/newview/llpanelsnapshotprofile.cpp
+++ b/indra/newview/llpanelsnapshotprofile.cpp
@@ -58,7 +58,7 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "profile_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "profile_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "profile_image_size_lp"; }
-	/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG; }
+    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshotBase::SNAPSHOT_FORMAT_PNG; }
 	/*virtual*/ void updateControls(const LLSD& info);
 
 	void onSend();
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 8561a89ae5..d40694f2f4 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -86,8 +86,8 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param
 	mNeedsFlash(TRUE),
 	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
 	mDataSize(0),
-	mSnapshotType(SNAPSHOT_POSTCARD),
-	mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
+    mSnapshotType(LLPanelSnapshot::ESnapshotType::SNAPSHOT_POSTCARD),
+    mSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
 	mSnapshotUpToDate(FALSE),
 	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
 	mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
@@ -737,7 +737,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
                 previewp->getWidth(),
                 previewp->getHeight(),
                 previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
-                previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
+                previewp->getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE,
                 previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                 FALSE,
                 previewp->mSnapshotBufferType,
@@ -813,7 +813,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
         mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
         LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex];
         gGL.getTexUnit(0)->bind(curr_preview_image);
-        curr_preview_image->setFilteringOption(getSnapshotType() == SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
+        curr_preview_image->setFilteringOption(getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
         curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
 
 
@@ -827,7 +827,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
 S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 {
     S32 width = getWidth();
-    if (getSnapshotType() == SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
     {
         width = LLImageRaw::biasedDimToPowerOfTwo(width,MAX_TEXTURE_SIZE);
     }
@@ -836,7 +836,7 @@ S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 S32 LLSnapshotLivePreview::getEncodedImageHeight() const
 {
     S32 height = getHeight();
-    if (getSnapshotType() == SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
     {
         height = LLImageRaw::biasedDimToPowerOfTwo(height,MAX_TEXTURE_SIZE);
     }
@@ -854,7 +854,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
             mPreviewImage->getHeight(),
             mPreviewImage->getComponents());
         
-		if (getSnapshotType() == SNAPSHOT_TEXTURE)
+        if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
 		{
             // We don't store the intermediate formatted image in mFormattedImage in the J2C case 
 			LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
@@ -903,13 +903,13 @@ void LLSnapshotLivePreview::estimateDataSize()
     // Compression ratio
     F32 ratio = 1.0;
     
-    if (getSnapshotType() == SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
     {
         ratio = 8.0;    // This is what we shoot for when compressing to J2C
     }
     else
     {
-        LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat();
+        LLFloaterSnapshotBase::ESnapshotFormat format = getSnapshotFormat();
         switch (format)
         {
             case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
@@ -947,7 +947,7 @@ LLPointer<LLImageFormatted>	LLSnapshotLivePreview::getFormattedImage()
         }
         
         // Create the new formatted image of the appropriate format.
-        LLFloaterSnapshot::ESnapshotFormat format = getSnapshotFormat();
+        LLFloaterSnapshotBase::ESnapshotFormat format = getSnapshotFormat();
         LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL;
             
         switch (format)
@@ -978,7 +978,7 @@ void LLSnapshotLivePreview::setSize(S32 w, S32 h)
 	setHeight(h);
 }
 
-void LLSnapshotLivePreview::setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format)
+void LLSnapshotLivePreview::setSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat format)
 {
     if (mSnapshotFormat != format)
     {
@@ -993,7 +993,7 @@ void LLSnapshotLivePreview::getSize(S32& w, S32& h) const
 	h = getHeight();
 }
 
-void LLSnapshotLivePreview::saveTexture()
+void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
 {
 	LL_DEBUGS() << "saving texture: " << mPreviewImage->getWidth() << "x" << mPreviewImage->getHeight() << LL_ENDL;
 	// gen a new uuid for this asset
@@ -1035,13 +1035,17 @@ void LLSnapshotLivePreview::saveTexture()
 		LLAssetStorage::LLStoreAssetCallback callback = NULL;
 		S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
 		void *userdata = NULL;
+        std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;
+        std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;
+        LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY;
+        LLInventoryType::EType inv_type = outfit_snapshot ? LLInventoryType::IT_NONE : LLInventoryType::IT_SNAPSHOT;
 		upload_new_resource(tid,	// tid
 			LLAssetType::AT_TEXTURE,
-			"Snapshot : " + pos_string,
-			"Taken by " + who_took_it + " at " + pos_string,
+            res_name,
+			res_desc,
 			0,
-			LLFolderType::FT_SNAPSHOT_CATEGORY,
-			LLInventoryType::IT_SNAPSHOT,
+            folder_type,
+            inv_type,
 			PERM_ALL,  // Note: Snapshots to inventory is a special case of content upload
 			LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads
 			LLFloaterPerms::getEveryonePerms("Uploads"),
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index 57e5d83f8e..b822707d29 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -40,14 +40,6 @@ class LLSnapshotLivePreview : public LLView
 {
 	LOG_CLASS(LLSnapshotLivePreview);
 public:
-	enum ESnapshotType
-	{
-		SNAPSHOT_POSTCARD,
-		SNAPSHOT_TEXTURE,
-		SNAPSHOT_LOCAL,
-		SNAPSHOT_WEB
-	};
-
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
@@ -80,8 +72,8 @@ public:
 	void setMaxImageSize(S32 size) ;
 	S32  getMaxImageSize() {return mMaxImageSize ;}
 
-	ESnapshotType getSnapshotType() const { return mSnapshotType; }
-	LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
+    LLPanelSnapshot::ESnapshotType getSnapshotType() const { return mSnapshotType; }
+    LLFloaterSnapshotBase::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
 	BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
 	BOOL isSnapshotActive() { return mSnapshotActive; }
 	LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
@@ -98,8 +90,8 @@ public:
 	void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
 	const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
 
-	void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
-	void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat format);
+    void setSnapshotType(LLPanelSnapshot::ESnapshotType type) { mSnapshotType = type; }
+    void setSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat format);
 	bool setSnapshotQuality(S32 quality, bool set_by_user = true);
 	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
     void setAllowRenderUI(BOOL allow) { mAllowRenderUI = allow; }
@@ -107,7 +99,7 @@ public:
     void setFilter(std::string filter_name) { mFilterName = filter_name; }
     std::string  getFilter() const { return mFilterName; }
 	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
-	void saveTexture();
+    void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = "");
 	BOOL saveLocal();
 
 	LLPointer<LLImageFormatted>	getFormattedImage();
@@ -169,8 +161,8 @@ private:
 	LLVector3d					mPosTakenGlobal;
 	S32							mSnapshotQuality;
 	S32							mDataSize;
-	ESnapshotType				mSnapshotType;
-	LLFloaterSnapshot::ESnapshotFormat	mSnapshotFormat;
+    LLPanelSnapshot::ESnapshotType				mSnapshotType;
+    LLFloaterSnapshotBase::ESnapshotFormat	mSnapshotFormat;
 	BOOL						mSnapshotUpToDate;
 	LLFrameTimer				mFallAnimTimer;
 	LLVector3					mCameraPos;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 14a2627f27..fd48598925 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -94,6 +94,7 @@
 #include "llfloaterobjectweights.h"
 #include "llfloateropenobject.h"
 #include "llfloateroutbox.h"
+#include "llfloateroutfitsnapshot.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindingconsole.h"
 #include "llfloaterpathfindinglinksets.h"
@@ -332,7 +333,8 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>);
 	LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
 	LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
-	LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
+    LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
+    LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
 	LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
 	LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
 	LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index f8e50ba463..7b87d210c0 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -556,7 +556,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 		{
 			gViewerWindow->playSnapshotAnimAndSound();
 			LLPointer<LLImageFormatted> formatted;
-			LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
+            LLFloaterSnapshotBase::ESnapshotFormat fmt = (LLFloaterSnapshotBase::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
 			switch (fmt)
 			{
 			case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
new file mode 100644
index 0000000000..7b88b07ca6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ positioning="cascading"
+ legacy_header_height="18"
+ can_minimize="true"
+ can_resize="false"
+ can_close="true"
+ height="455"
+ layout="topleft"
+ name="outfit_snapshot"
+ single_instance="true"
+ help_topic="snapshot"
+ save_rect="true"
+ save_visibility="false"
+ title="OUTFIT SNAPSHOT"
+ width="624"
+ min_height="455">
+  <floater.string
+   name="unknown">
+    unknown
+  </floater.string>
+  <string
+   name="postcard_progress_str">
+    Sending Email
+  </string>
+  <string
+      name="facebook_progress_str">
+    Posting to Facebook
+  </string>
+  <string
+      name="profile_progress_str">
+    Posting
+  </string>
+  <string
+   name="inventory_progress_str">
+    Saving to Inventory
+  </string>
+  <string
+   name="local_progress_str">
+    Saving to Computer
+  </string>
+  <string
+        name="facebook_succeeded_str">
+    Image uploaded
+  </string>
+  <string
+        name="profile_succeeded_str">
+    Image uploaded
+  </string>
+  <string
+ 	 name="postcard_succeeded_str">
+    Email Sent!
+  </string>
+  <string
+ 	 name="inventory_succeeded_str">
+    Saved to Inventory!
+  </string>
+  <string
+ 	 name="local_succeeded_str">
+    Saved to Computer!
+  </string>
+  <string
+     name="facebook_failed_str">
+    Failed to upload image to your Facebook timeline.
+  </string>
+  <string
+     name="profile_failed_str">
+    Failed to upload image to your Profile Feed.
+  </string>
+  <string
+ 	 name="postcard_failed_str">
+    Failed to send email.
+  </string>
+  <string
+ 	 name="inventory_failed_str">
+    Failed to save to inventory.
+  </string>
+  <string
+ 	 name="local_failed_str">
+    Failed to save to computer.
+  </string>
+  <button
+     follows="left|top"
+     height="25"
+     image_overlay="Refresh_Off"
+	 image_hover_unselected="Toolbar_Middle_Over"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     image_overlay_alignment="left"
+     imgoverlay_label_space="5"
+	 pad_bottom="0"
+	 halign="left"
+     layout="topleft"
+     left="10"
+	 label="REFRESH"
+     name="new_snapshot_btn"
+     top_pad="26"
+     width="167" />
+	<button
+       follows="left|top"
+	   control_name="AdvanceSnapshot"
+	   invisibility_control="AdvanceSnapshot"
+       height="25"
+	   is_toggle="true"
+       layout="topleft"
+	   image_hover_unselected="Toolbar_Middle_Over"
+	   image_selected="Toolbar_Middle_Off"
+	   image_unselected="Toolbar_Middle_Off"
+	   image_overlay="Conv_toolbar_expand"
+       name="retract_btn"
+       left_pad="1"
+	   top_delta="0"
+       width="31" />
+   <button
+       follows="left|top"
+	   control_name="AdvanceSnapshot"
+	   visibility_control="AdvanceSnapshot"
+       height="25"
+	   is_toggle="true"
+       layout="topleft"
+	   image_overlay="Conv_toolbar_collapse"
+	   image_hover_unselected="Toolbar_Middle_Over"
+	   image_selected="Toolbar_Middle_Off"
+	   image_unselected="Toolbar_Middle_Off"
+       name="extend_btn"
+       left_delta="0"
+	   top_delta="0"
+       width="31" />
+	<panel
+     height="154"
+     layout="topleft"
+	 follows="top|left"
+     left="0"
+     name="advanced_options_panel"
+     top_pad="-6"
+     width="210">
+        <view_border 
+         bevel_style="in"
+         follows="left|top|right" 
+         height="1"
+         left="10"
+         layout="topleft"
+         name="advanced_options_hr"
+         right="-1"
+         top_pad="5"
+         />
+        <text
+         type="string"
+         length="1"
+         follows="left|top"
+         height="13"
+         layout="topleft"
+         left="10"
+         name="layer_type_label"
+         top_pad="10"
+         width="100">
+            Capture:
+        </text>
+        <combo_box
+         follows="left|top|right"
+         height="23"
+         label="Image Layers"
+         layout="topleft"
+         left="30"
+         name="layer_types"
+         right="-2">
+            <combo_box.item
+             label="Colors"
+             name="Colors"
+             value="colors" />
+            <combo_box.item
+             label="Depth"
+             name="Depth"
+             value="depth" />
+        </combo_box>
+        <check_box
+         label="Interface"
+         layout="topleft"
+         left="30"
+		 height="16"
+         top_pad="8"
+         width="180"
+         name="ui_check" />
+        <check_box
+         label="HUDs"
+         layout="topleft"
+		 height="16"
+         left="30"
+         top_pad="1"
+         width="180"
+         name="hud_check" />
+        <check_box
+         label="Freeze frame (fullscreen)"
+         layout="topleft"
+		 height="16"
+         left="10"
+         top_pad="1"
+         width="180"
+         name="freeze_frame_check" />
+        <check_box
+         label="Auto-refresh"
+         layout="topleft"
+		 height="16"
+         left="10"
+         top_pad="1"
+         width="180"
+         name="auto_snapshot_check" />
+        <text
+         type="string"
+         length="1"
+         follows="left|top"
+         height="13"
+         layout="topleft"
+         left="10"
+         name="filter_list_label"
+         top_pad="10"
+         width="50">
+            Filter:
+        </text>
+        <combo_box
+            control_name="PhotoFilters"
+            follows="left|right|top"
+            name="filters_combobox"
+            tool_tip="Image filters"
+            top_delta="-3"
+            left="50"
+			right="-1"
+            height="21"
+            width="135">
+            <combo_box.item
+            label="No Filter"
+            name="NoFilter"
+            value="NoFilter" />
+        </combo_box>
+		 <view_border 
+         bevel_style="in"
+         follows="left|top|right" 
+         height="1"
+         left="10"
+         layout="topleft"
+         name="advanced_options_hr"
+         right="-1"
+         top_pad="7"
+         />
+    </panel>
+ <!--
+	<panel_container
+     follows="left|top"
+     height="230"
+     layout="topleft"
+     left="0"
+     name="panel_container"
+     default_panel_name="panel_snapshot_options"
+     top_pad="10"
+     width="215">
+      <panel
+       class="llpanelsnapshotoptions"
+       filename="panel_snapshot_options.xml"
+       follows="all"
+       layout="topleft"
+       left="0"
+       name="panel_snapshot_options"
+       top="0" />
+      <panel
+       class="llpanelsnapshotprofile"
+       follows="all"
+       layout="topleft"
+       name="panel_snapshot_profile"
+       filename="panel_snapshot_profile.xml" />
+      <panel
+       class="llpanelsnapshotpostcard"
+       follows="all"
+       layout="topleft"
+       name="panel_snapshot_postcard"
+       filename="panel_snapshot_postcard.xml" />
+      -->
+  <!--panel
+       class="llpaneloutfitsnapshotinventory"
+       follows="all"
+       layout="topleft"
+       name="panel_outfit_snapshot_inventory"
+       filename="panel_snapshot_inventory.xml"-->
+      <panel
+        class="llpaneloutfitsnapshotinventory"
+        follows="left|top"
+        height="230"
+        layout="topleft"
+        left="0"
+        name="panel_outfit_snapshot_inventory"
+        filename="panel_outfit_snapshot_inventory.xml"
+        top_pad="10"
+        width="215"
+      />
+      <!--
+      <panel
+       class="llpanelsnapshotlocal"
+       follows="all"
+       layout="topleft"
+       name="panel_snapshot_local"
+       filename="panel_snapshot_local.xml" />
+      </panel_container>
+-->
+	<view_border 
+         bevel_style="in"
+         follows="left|top" 
+         height="1"
+         left="10"
+         layout="topleft"
+         name="status_hr"
+         width="199"
+         top_pad="-16"/>
+	<panel
+       background_visible="false"
+       follows="left|top"
+       font="SansSerifLarge"
+       halign="center"
+       height="20"
+       layout="topleft"
+       left="10"
+       length="1"
+       name="succeeded_panel"
+	   width="198"
+       top_pad="1"
+       type="string"
+       visible="false">
+          <text
+           follows="all"
+           font="SansSerif"
+           halign="center"
+           height="18"
+           layout="topleft"
+           left="1"
+           length="1"
+           name="succeeded_lbl"
+           right="-1"
+           text_color="0.2 0.85 0.2 1"
+           top="4"
+           translate="false"
+           type="string">
+              Succeeded
+          </text>
+      </panel>
+      <panel
+       background_visible="false"
+       follows="left|top"
+       font="SansSerifLarge"
+       halign="center"
+       height="20"
+       layout="topleft"
+       left="10"
+       length="1"
+       name="failed_panel"
+	   width="198"
+       top_delta="0"
+       type="string"
+       visible="false">
+          <text
+           follows="all"
+           font="SansSerif"
+           halign="center"
+           height="18"
+           layout="topleft"
+           left="1"
+           length="1"
+           name="failed_lbl"
+           right="-1"
+           text_color="0.95 0.4 0.4 1"
+           top="4"
+           translate="false"
+           type="string">
+              Failed
+          </text>
+      </panel>
+      <loading_indicator
+       follows="left|top"
+       height="24"
+       layout="topleft"
+       name="working_indicator"
+       left="10"
+       top_delta="0"
+       visible="false"
+       width="24" />
+      <text
+       follows="left|top"
+       font="SansSerifBold"
+       height="14"
+       layout="topleft"
+       left_pad="3"
+       length="1"
+       halign="left"
+       name="working_lbl"
+       top_delta="5"
+       translate="false"
+       type="string"
+       visible="false"
+       width="162">
+          Working
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerifBold"
+       halign="left"
+       height="18"
+       layout="topleft"
+       left="10"
+       length="1"
+       name="refresh_lbl"
+       text_color="0.95 0.4 0.4 1"
+       top_delta="0"
+       translate="false"
+       type="string"
+       visible="false"
+       width="130">
+          Refresh to save.
+      </text>
+  <ui_ctrl 
+    layout="topleft"
+    name="thumbnail_placeholder"
+    top="23"
+	left="215"
+	width="400"
+	height="400"
+    follows="top|left"/>
+  <!--view_border 
+   bevel_style="in" 
+   height="21"
+   layout="topleft"
+   name="img_info_border"
+   top_pad="0"
+   right="-10"
+   follows="left|top|right"
+   left_delta="0"/>-->
+   <text
+    type="string"
+    font="SansSerifSmall"
+    length="1"
+    follows="left|top|right"
+    height="14"
+    layout="topleft"
+    left="220"
+	right="-20"
+    halign="left"
+    name="image_res_text"
+    top_delta="5"
+    width="200">
+       [WIDTH]px (width) x [HEIGHT]px (height)
+   </text>
+   <text
+    follows="right|top"
+    font="SansSerifSmall"
+    height="14"
+    layout="topleft"
+    left="-65"
+    length="1"
+    halign="right"
+    name="file_size_label"
+    top_delta="0"
+    type="string"
+    width="50">
+       [SIZE] KB
+   </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index 23133d4f7c..e527e1f901 100755
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -52,7 +52,14 @@
      name="select_photo">
         <on_click
          function="Gear.SelectPhoto" />
-  </menu_item_call>
+    </menu_item_call>
+    <menu_item_call
+     label="Take a Snapshot"
+     layout="topleft"
+     name="take_snapshot">
+        <on_click
+         function="Gear.TakeSnapshot" />
+    </menu_item_call>
 
   <menu_item_separator name="sepatator1" />
             <!-- copied (with minor modifications) from menu_inventory_add.xml -->
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
new file mode 100644
index 0000000000..ce6309e2ed
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ height="380"
+ layout="topleft"
+ name="panel_outfit_snapshot_inventory"
+ width="490">
+    <icon
+     follows="top|left"
+     height="18"
+     image_name="Snapshot_Inventory"
+     layout="topleft"
+     left="12"
+     mouse_opaque="true"
+     name="title_icon"
+     top="6"
+     width="18" />
+    <text
+     follows="top|left|right"
+     font="SansSerifBold"
+     height="14"
+     layout="topleft"
+     left_pad="12"
+     length="1"
+     name="title"
+     right="-10"
+     text_color="white"
+     type="string"
+     top_delta="3">
+        Inventory
+    </text>
+    <view_border 
+     bevel_style="in"
+     follows="left|top|right" 
+     height="1"
+     left="9"
+     layout="topleft"
+     name="hr"
+     right="-5"
+     top_pad="5"
+     />
+    <combo_box
+     follows="top|left|right"
+     height="20"
+     label="Resolution"
+     layout="topleft"
+     left_delta="0"
+     name="texture_size_combo"
+     right="-5"
+     top_pad="5">
+        <combo_box.item
+         label="Small (128x128)"
+         name="Small(128x128)"
+         value="[i128,i128]" />
+        <combo_box.item
+         label="Medium (256x256)"
+         name="Medium(256x256)"
+         value="[i256,i256]" />
+        <combo_box.item
+         label="Large (512x512)"
+         name="Large(512x512)"
+         value="[i512,i512]" />
+        <combo_box.item
+         label="Current Window(512x512)"
+         name="CurrentWindow"
+         value="[i0,i0]" />
+        <combo_box.item
+         label="Custom"
+         name="Custom"
+         value="[i-1,i-1]" />
+    </combo_box>
+    <spinner
+     allow_text_entry="false"
+     decimal_digits="0"
+     follows="left|top"
+     height="20"
+     increment="32"
+     label="Width x Height"
+     label_width="90"
+     layout="topleft"
+     left="10"
+     max_val="6016"
+     min_val="32"
+     name="inventory_snapshot_width"
+     top_pad="7"
+     width="144" />
+    <spinner
+     allow_text_entry="false"
+     decimal_digits="0"
+     follows="left|top"
+     height="20"
+     increment="32"
+     label=""
+     label_width="0"
+     layout="topleft"
+     left_pad="0"
+     max_val="6016"
+     min_val="32"
+     name="inventory_snapshot_height"
+     top_delta="0"
+     width="54" />
+    <check_box
+     top_pad="12"
+     follows="left|top"
+     label="Constrain proportions"
+     layout="topleft"
+     left="10"
+     name="inventory_keep_aspect_check"
+     visible="false" />
+    <text
+     follows="top|left"
+     font="SansSerif"
+     height="56"
+     layout="topleft"
+     left="10"
+     length="1"
+     name="hint_lbl"
+     top_pad="6"
+     width="200"
+     type="string"
+     word_wrap="true">
+        Saving an image to your inventory costs L$[UPLOAD_COST]. To save your image as a texture select one of the square formats.
+    </text>
+    <button
+     follows="right|bottom"
+     height="23"
+     label="Cancel"
+     layout="topleft"
+     name="cancel_btn"
+     right="-5"
+     top="337"
+     width="97">
+      <button.commit_callback
+       function="Inventory.Cancel" />
+    </button>
+    <button
+     follows="left|bottom"
+     height="23"
+     label="Save"
+     layout="topleft"
+     left="10"
+     name="save_btn"
+     top_delta="0"
+     width="97">
+      <button.commit_callback
+       function="Inventory.SaveOutfitPhoto" />
+    </button>
+</panel>
\ No newline at end of file
-- 
cgit v1.2.3


From 0a73840dd8e350cd936b681c0cc5131905eb3b09 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 5 May 2016 16:30:41 +0300
Subject: MAINT-6381 Right click on Outfit Folder behavior

---
 indra/newview/lloutfitgallery.cpp                  | 103 ++++++++++++++++++++-
 indra/newview/lloutfitgallery.h                    |  27 ++++++
 .../default/xui/en/panel_outfit_gallery_item.xml   |   3 +-
 3 files changed, 130 insertions(+), 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index b351be8de9..a36728e6ac 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -44,6 +44,7 @@
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
 #include "lllocalbitmaps.h"
+#include "llnotificationsutil.h"
 #include "lltexturectrl.h"
 #include "llviewermenufile.h"
 #include "llwearableitemslist.h"
@@ -98,6 +99,7 @@ BOOL LLOutfitGallery::postBuild()
     BOOL rv = LLOutfitListBase::postBuild();
     mScrollPanel = getChild<LLScrollContainer>("gallery_scroll_panel");
     mGalleryPanel = getChild<LLPanel>("gallery_panel");
+    mOutfitGalleryMenu = new LLOutfitGalleryContextMenu(this);
     return rv;
 }
 
@@ -352,6 +354,8 @@ void LLOutfitGallery::moveRowPanel(LLPanel* stack, int left, int bottom)
 
 LLOutfitGallery::~LLOutfitGallery()
 {
+    delete mOutfitGalleryMenu;
+    
     if (gInventory.containsObserver(mTexturesObserver))
     {
         gInventory.removeObserver(mTexturesObserver);
@@ -486,7 +490,7 @@ void LLOutfitGallery::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLU
     {
         uuid_vec_t selected_uuids;
         selected_uuids.push_back(cat_id);
-        mOutfitMenu->show(ctrl, selected_uuids, x, y);
+        mOutfitGalleryMenu->show(ctrl, selected_uuids, x, y);
     }
 }
 
@@ -604,6 +608,12 @@ BOOL LLOutfitGalleryItem::handleMouseDown(S32 x, S32 y, MASK mask)
     return LLUICtrl::handleMouseDown(x, y, mask);
 }
 
+BOOL LLOutfitGalleryItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+    setFocus(TRUE);
+    return LLUICtrl::handleRightMouseDown(x, y, mask);
+}
+
 void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
 {
     mImageAssetId = image_asset_id;
@@ -626,6 +636,97 @@ void LLOutfitGalleryItem::setDefaultImage()
     mDefaultImage = true;
 }
 
+LLContextMenu* LLOutfitGalleryContextMenu::createMenu()
+{
+    LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+    LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+    LLUUID selected_id = mUUIDs.front();
+    
+    registrar.add("Outfit.WearReplace",
+                  boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.WearAdd",
+                  boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.TakeOff",
+                  boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id));
+    registrar.add("Outfit.Edit", boost::bind(editOutfit));
+    registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
+    registrar.add("Outfit.Delete", boost::bind(&LLOutfitGalleryContextMenu::onRemoveOutfit, this, selected_id));
+    registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2));
+    registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id));
+    registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id));
+    registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id));
+    
+    enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2));
+    enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2));
+    
+    return createFromFile("menu_gallery_outfit_tab.xml");
+}
+
+void LLOutfitGalleryContextMenu::onUploadPhoto(const LLUUID& outfit_cat_id)
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery && outfit_cat_id.notNull())
+    {
+        gallery->uploadPhoto(outfit_cat_id);
+    }
+}
+
+void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id)
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery && outfit_cat_id.notNull())
+    {
+        gallery->onSelectPhoto(outfit_cat_id);
+    }
+}
+
+void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id)
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery && outfit_cat_id.notNull())
+    {
+        gallery->onTakeSnapshot(outfit_cat_id);
+    }
+}
+
+void LLOutfitGalleryContextMenu::onRemoveOutfit(const LLUUID& outfit_cat_id)
+{
+    LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation, this, _1, _2, outfit_cat_id));
+}
+
+void LLOutfitGalleryContextMenu::onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (option != 0) return; // canceled
+    
+    if (outfit_cat_id.notNull())
+    {
+        gInventory.removeCategory(outfit_cat_id);
+    }
+}
+
+void LLOutfitGalleryContextMenu::onCreate(const LLSD& data)
+{
+    LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
+    if (type == LLWearableType::WT_NONE)
+    {
+        LL_WARNS() << "Invalid wearable type" << LL_ENDL;
+        return;
+    }
+    
+    LLAgentWearables::createWearable(type, true);
+}
+
+bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param)
+{
+    return LLOutfitContextMenu::onEnable(param);
+}
+
+bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param)
+{
+    return LLOutfitContextMenu::onVisible(param);
+}
+
 LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index dbf891142d..b8c7d66406 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -43,6 +43,7 @@ class LLOutfitGallery;
 class LLOutfitGalleryItem;
 class LLOutfitListGearMenuBase;
 class LLOutfitGalleryGearMenu;
+class LLOutfitGalleryContextMenu;
 
 class LLUpdateGalleryOnPhotoLinked : public LLInventoryCallback
 {
@@ -57,6 +58,7 @@ class LLOutfitGallery : public LLOutfitListBase
 {
 public:
     friend class LLOutfitGalleryGearMenu;
+    friend class LLOutfitGalleryContextMenu;
     friend class LLUpdateGalleryOnPhotoLinked;
 
     struct Params
@@ -169,6 +171,8 @@ private:
     int mGalleryWidth;
     int mRowPanWidthFactor;
     int mGalleryWidthFactor;
+    
+    LLListContextMenu* mOutfitGalleryMenu;
 
     LLHandle<LLFloater> mFloaterHandle;
 
@@ -183,6 +187,28 @@ private:
     LLInventoryCategoriesObserver* 	mTexturesObserver;
     LLInventoryCategoriesObserver* 	mOutfitsObserver;
 };
+class LLOutfitGalleryContextMenu : public LLOutfitContextMenu
+{
+public:
+    
+    friend class LLOutfitGallery;
+    LLOutfitGalleryContextMenu(LLOutfitListBase* outfit_list)
+    : LLOutfitContextMenu(outfit_list),
+    mOutfitList(outfit_list){}
+protected:
+    /* virtual */ LLContextMenu* createMenu();
+    bool onEnable(LLSD::String param);
+    bool onVisible(LLSD::String param);
+    void onUploadPhoto(const LLUUID& outfit_cat_id);
+    void onSelectPhoto(const LLUUID& outfit_cat_id);
+    void onTakeSnapshot(const LLUUID& outfit_cat_id);
+    void onCreate(const LLSD& data);
+    void onRemoveOutfit(const LLUUID& outfit_cat_id);
+    void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response, const LLUUID& outfit_cat_id);
+private:
+    LLOutfitListBase*	mOutfitList;
+};
+
 
 class LLOutfitGalleryGearMenu : public LLOutfitListGearMenuBase
 {
@@ -210,6 +236,7 @@ public:
     /*virtual*/ BOOL postBuild();
     /*virtual*/ void draw();
     /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+    /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
 
     void setDefaultImage();
     void setImageAssetId(LLUUID asset_id);
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index eede209e91..77c546c6e7 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -3,8 +3,7 @@
    background_visible="false"
    background_opaque="false"
    bg_alpha_color="FrogGreen"
-   bg_opaque_color="FrogGreen"
-   border_color="Red"
+   bg_opaque_color="FrogGreen"   
    border="false"
    bevel_style="none"
    follows="left|top"
-- 
cgit v1.2.3


From bdeeb6451fcfaabb826a6a8babe9f580643bc873 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 5 May 2016 16:32:12 +0300
Subject: MAINT-6381 Right click on Outfit Folder behavior

---
 .../default/xui/en/menu_gallery_outfit_tab.xml     | 246 +++++++++++++++++++++
 1 file changed, 246 insertions(+)
 create mode 100755 indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml

diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
new file mode 100755
index 0000000000..b9e29788dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+    layout="topleft"
+    name="Outfit">
+    <menu_item_call
+        label="Wear - Replace Current Outfit"
+        layout="topleft"
+        name="wear_replace">
+        <on_click
+        function="Outfit.WearReplace" />
+        <on_enable
+        function="Outfit.OnEnable"
+        parameter="wear_replace" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="wear_replace" />
+    </menu_item_call>
+    <menu_item_call
+        label="Wear - Add to Current Outfit"
+        layout="topleft"
+        name="wear_add">
+        <on_click
+        function="Outfit.WearAdd" />
+        <on_enable
+        function="Outfit.OnEnable"
+        parameter="wear_add" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="wear_add" />
+    </menu_item_call>
+    <menu_item_call
+        label="Take Off - Remove from Current Outfit"
+        layout="topleft"
+        name="take_off">
+        <on_click
+        function="Outfit.TakeOff" />
+        <on_enable
+        function="Outfit.OnEnable"
+        parameter="take_off" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="take_off" />
+    </menu_item_call>
+    <menu_item_call
+        label="Upload Photo (L$10)"
+        layout="topleft"
+        name="upload_photo">
+        <on_click
+        function="Outfit.UploadPhoto" />
+    </menu_item_call>
+    <menu_item_call
+        label="Select Photo"
+        layout="topleft"
+        name="select_photo">
+        <on_click
+        function="Outfit.SelectPhoto" />
+    </menu_item_call>
+    <menu_item_call
+        label="Take a Snapshot"
+        layout="topleft"
+        name="take_snapshot">
+        <on_click
+        function="Outfit.TakeSnapshot" />
+    </menu_item_call>
+    
+    <menu_item_separator name="sepatator1" />
+    <menu
+        height="175"
+        label="New Clothes"
+        layout="topleft"
+        left_delta="0"
+        mouse_opaque="false"
+        name="New Clothes"
+        top_pad="514"
+        width="125">
+        <menu_item_call
+            label="New Shirt"
+            layout="topleft"
+            name="New Shirt">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="shirt" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Pants"
+            layout="topleft"
+            name="New Pants">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="pants" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Shoes"
+            layout="topleft"
+            name="New Shoes">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="shoes" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Socks"
+            layout="topleft"
+            name="New Socks">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="socks" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Jacket"
+            layout="topleft"
+            name="New Jacket">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="jacket" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Skirt"
+            layout="topleft"
+            name="New Skirt">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="skirt" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Gloves"
+            layout="topleft"
+            name="New Gloves">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="gloves" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Undershirt"
+            layout="topleft"
+            name="New Undershirt">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="undershirt" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Underpants"
+            layout="topleft"
+            name="New Underpants">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="underpants" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Alpha"
+            layout="topleft"
+            name="New Alpha">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="alpha" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Physics"
+            layout="topleft"
+            name="New Physics">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="physics" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Tattoo"
+            layout="topleft"
+            name="New Tattoo">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="tattoo" />
+        </menu_item_call>
+    </menu>
+    <menu
+        height="85"
+        label="New Body Parts"
+        layout="topleft"
+        left_delta="0"
+        mouse_opaque="false"
+        name="New Body Parts"
+        top_pad="514"
+        width="118">
+        <menu_item_call
+            label="New Shape"
+            layout="topleft"
+            name="New Shape">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="shape" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Skin"
+            layout="topleft"
+            name="New Skin">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="skin" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Hair"
+            layout="topleft"
+            name="New Hair">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="hair" />
+        </menu_item_call>
+        <menu_item_call
+            label="New Eyes"
+            layout="topleft"
+            name="New Eyes">
+            <menu_item_call.on_click
+            function="Outfit.Create"
+            parameter="eyes" />
+        </menu_item_call>
+    </menu>
+    <menu_item_separator name="sepatator2" />
+    <menu_item_call
+        label="Edit Outfit"
+        layout="topleft"
+        name="edit">
+        <on_click
+        function="Outfit.Edit" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="edit" />
+    </menu_item_call>
+    <menu_item_call
+        label="Rename Outfit"
+        layout="topleft"
+        name="rename">
+        <on_click
+        function="Outfit.Rename" />
+        <on_enable
+        function="Outfit.OnEnable"
+        parameter="rename" />
+    </menu_item_call>
+    <menu_item_call
+        label="Delete Outfit"
+        layout="topleft"
+        name="delete">
+        <on_click
+        function="Outfit.Delete" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="delete" />
+    </menu_item_call>
+</context_menu>
-- 
cgit v1.2.3


From 8b3f4ec5f58c1488ac7b3403a1a510a4977cebf6 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 5 May 2016 19:43:02 +0300
Subject: MAINT-6226 Incorporate a customized Snapshot feature to Outfit
 Browser flow Removed odd controls like custom resolution spinners etc

---
 indra/newview/llfloateroutfitsnapshot.cpp          | 382 +--------------------
 indra/newview/llfloateroutfitsnapshot.h            |   6 -
 indra/newview/llpanelsnapshot.cpp                  |  33 +-
 indra/newview/llpanelsnapshot.h                    |   2 +-
 indra/newview/llpanelsnapshotinventory.cpp         |  50 +--
 .../default/xui/en/floater_outfit_snapshot.xml     |  63 ----
 .../xui/en/panel_outfit_snapshot_inventory.xml     |  52 +--
 7 files changed, 58 insertions(+), 530 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 8fa54e7f94..cea0e48aa6 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -105,20 +105,13 @@ public:
 	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
 	static void onImageQualityChange(LLFloaterOutfitSnapshot* view, S32 quality_val);
 	static void onImageFormatChange(LLFloaterOutfitSnapshot* view);
-	static void applyCustomResolution(LLFloaterOutfitSnapshot* view, S32 w, S32 h);
 	static void onSnapshotUploadFinished(bool status);
 	static void onSendingPostcardFinished(bool status);
 	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
-	static void setImageSizeSpinnersValues(LLFloaterOutfitSnapshot *view, S32 width, S32 height) ;
-	static void updateSpinners(LLFloaterOutfitSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
 
 	static LLPanelSnapshot* getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found = true);
     static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterOutfitSnapshot* floater);
 	static LLFloaterOutfitSnapshot::ESnapshotFormat getImageFormat(LLFloaterOutfitSnapshot* floater);
-	static LLSpinCtrl* getWidthSpinner(LLFloaterOutfitSnapshot* floater);
-	static LLSpinCtrl* getHeightSpinner(LLFloaterOutfitSnapshot* floater);
-	static void enableAspectRatioCheckbox(LLFloaterOutfitSnapshot* floater, BOOL enable);
-	static void setAspectRatioCheckboxValue(LLFloaterOutfitSnapshot* floater, BOOL checked);
 
 	static LLSnapshotLivePreview* getPreviewView(LLFloaterOutfitSnapshot *floater);
 	static void setResolution(LLFloaterOutfitSnapshot* floater, const std::string& comboname);
@@ -130,9 +123,7 @@ public:
 
 private:
 	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterOutfitSnapshot* floater);
-	static void comboSetCustom(LLFloaterOutfitSnapshot *floater, const std::string& comboname);
 	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
-	static void checkAspectRatio(LLFloaterOutfitSnapshot *view, S32 index) ;
 	static void setWorking(LLFloaterOutfitSnapshot* floater, bool working);
 	static void setFinished(LLFloaterOutfitSnapshot* floater, bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
 
@@ -165,79 +156,15 @@ LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterOutfitSn
 // static
 LLPanelSnapshot::ESnapshotType LLFloaterOutfitSnapshot::Impl::getActiveSnapshotType(LLFloaterOutfitSnapshot* floater)
 {
-	//LLSnapshotLivePreview::ESnapshotType type = LLSnapshotLivePreview::SNAPSHOT_WEB;
-	//std::string name;
-	LLPanelSnapshot* spanel = getActivePanel(floater);
-
-	//if (spanel)
-	//{
-	//	name = spanel->getName();
-	//}
-
-    //if (name == "panel_snapshot_postcard")
-	//{
-	//	type = LLSnapshotLivePreview::SNAPSHOT_POSTCARD;
-	//}
-	//else if (name == "panel_snapshot_inventory")
-	//{
-	//	type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
-	//}
-	//else if (name == "panel_snapshot_local")
-	//{
-	//	type = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
-	//}
-
-	//return type;
-    if (spanel)
-    {
-        return spanel->getSnapshotType();
-    }
-    return LLPanelSnapshot::SNAPSHOT_WEB;
+    return LLPanelSnapshot::SNAPSHOT_TEXTURE;
 }
 
 // static
 LLFloaterOutfitSnapshot::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterOutfitSnapshot* floater)
 {
-	//LLPanelSnapshot* active_panel = getActivePanel(floater);
-	// FIXME: if the default is not PNG, profile uploads may fail.
-	//return active_panel ? active_panel->getImageFormat() : LLFloaterOutfitSnapshot::SNAPSHOT_FORMAT_PNG;
     return LLFloaterOutfitSnapshot::SNAPSHOT_FORMAT_PNG;
 }
 
-// static
-LLSpinCtrl* LLFloaterOutfitSnapshot::Impl::getWidthSpinner(LLFloaterOutfitSnapshot* floater)
-{
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	return active_panel ? active_panel->getWidthSpinner() : floater->getChild<LLSpinCtrl>("snapshot_width");
-}
-
-// static
-LLSpinCtrl* LLFloaterOutfitSnapshot::Impl::getHeightSpinner(LLFloaterOutfitSnapshot* floater)
-{
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	return active_panel ? active_panel->getHeightSpinner() : floater->getChild<LLSpinCtrl>("snapshot_height");
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterOutfitSnapshot* floater, BOOL enable)
-{
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	if (active_panel)
-	{
-		active_panel->enableAspectRatioCheckbox(enable);
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterOutfitSnapshot* floater, BOOL checked)
-{
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	if (active_panel)
-	{
-		active_panel->getChild<LLUICtrl>(active_panel->getAspectRatioCBName())->setValue(checked);
-	}
-}
-
 // static
 LLSnapshotLivePreview* LLFloaterOutfitSnapshot::Impl::getPreviewView(LLFloaterOutfitSnapshot *floater)
 {
@@ -248,14 +175,7 @@ LLSnapshotLivePreview* LLFloaterOutfitSnapshot::Impl::getPreviewView(LLFloaterOu
 // static
 LLViewerWindow::ESnapshotType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterOutfitSnapshot* floater)
 {
-	LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
-	LLSD value = floater->getChild<LLUICtrl>("layer_types")->getValue();
-	const std::string id = value.asString();
-	if (id == "colors")
-		type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
-	else if (id == "depth")
-		type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH;
-	return type;
+    return LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 }
 
 // static
@@ -375,67 +295,9 @@ void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterOutfitSnapshot* floa
 {
     LLPanelSnapshot::ESnapshotType shot_type = getActiveSnapshotType(floater);
     LLFloaterSnapshotBase::ESnapshotFormat shot_format = (LLFloaterSnapshotBase::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
-	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
-
-	floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
-    floater->getChildView("layer_types")->setEnabled(shot_type == LLPanelSnapshot::SNAPSHOT_LOCAL);
-
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	if (active_panel)
-	{
-		LLSpinCtrl* width_ctrl = getWidthSpinner(floater);
-		LLSpinCtrl* height_ctrl = getHeightSpinner(floater);
-
-		// Initialize spinners.
-		if (width_ctrl->getValue().asInteger() == 0)
-		{
-			S32 w = gViewerWindow->getWindowWidthRaw();
-			LL_DEBUGS() << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << LL_ENDL;
-			width_ctrl->setValue(w);
-            if (getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
-			{
-				width_ctrl->setIncrement(w >> 1);
-			}
-		}
-		if (height_ctrl->getValue().asInteger() == 0)
-		{
-			S32 h = gViewerWindow->getWindowHeightRaw();
-			LL_DEBUGS() << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << LL_ENDL;
-			height_ctrl->setValue(h);
-            if (getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
-			{
-				height_ctrl->setIncrement(h >> 1);
-			}
-		}
-
-		// Clamp snapshot resolution to window size when showing UI or HUD in snapshot.
-		if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
-		{
-			S32 width = gViewerWindow->getWindowWidthRaw();
-			S32 height = gViewerWindow->getWindowHeightRaw();
-
-			width_ctrl->setMaxValue(width);
-
-			height_ctrl->setMaxValue(height);
-
-			if (width_ctrl->getValue().asInteger() > width)
-			{
-				width_ctrl->forceSetValue(width);
-			}
-			if (height_ctrl->getValue().asInteger() > height)
-			{
-				height_ctrl->forceSetValue(height);
-			}
-		}
-		else
-		{
-			width_ctrl->setMaxValue(6016);
-			height_ctrl->setMaxValue(6016);
-		}
-	}
+    LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
 		
 	LLSnapshotLivePreview* previewp = getPreviewView(floater);
-	BOOL got_bytes = previewp && previewp->getDataSize() > 0;
 	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
 
 	// *TODO: Separate maximum size for Web images from postcards
@@ -458,36 +320,9 @@ void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterOutfitSnapshot* floa
 	}
 
 	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
-	floater->getChild<LLUICtrl>("file_size_label")->setColor(
-        shot_type == LLPanelSnapshot::SNAPSHOT_POSTCARD
-			&& got_bytes
-			&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
-
-	// Update the width and height spinners based on the corresponding resolution combos. (?)
-	switch(shot_type)
-	{
-      case LLPanelSnapshot::SNAPSHOT_WEB:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
-		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
-		setResolution(floater, "profile_size_combo");
-		break;
-      case LLPanelSnapshot::SNAPSHOT_POSTCARD:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
-		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
-		setResolution(floater, "postcard_size_combo");
-		break;
-      case LLPanelSnapshot::SNAPSHOT_TEXTURE:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
-		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
-		setResolution(floater, "texture_size_combo");
-		break;
-      case  LLPanelSnapshot::SNAPSHOT_LOCAL:
-		setResolution(floater, "local_size_combo");
-		break;
-	  default:
-		break;
-	}
-	setAspectRatioCheckboxValue(floater, !floater->impl.mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot"));
+	floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor( "LabelTextColor" ));
+
+    setResolution(floater, "texture_size_combo");
 
 	if (previewp)
 	{
@@ -641,32 +476,6 @@ void LLFloaterOutfitSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
 // static
 void LLFloaterOutfitSnapshot::Impl::applyKeepAspectCheck(LLFloaterOutfitSnapshot* view, BOOL checked)
 {
-	gSavedSettings.setBOOL("KeepAspectForSnapshot", checked);
-
-	if (view)
-	{
-		LLPanelSnapshot* active_panel = getActivePanel(view);
-		if (checked && active_panel)
-		{
-			LLComboBox* combo = view->getChild<LLComboBox>(active_panel->getImageSizeComboName());
-			combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
-		}
-
-		LLSnapshotLivePreview* previewp = getPreviewView(view) ;
-		if(previewp)
-		{
-			previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
-
-			S32 w, h ;
-			previewp->getSize(w, h) ;
-			updateSpinners(view, previewp, w, h, TRUE); // may change w and h
-
-			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
-			previewp->setSize(w, h) ;
-			previewp->updateSnapshot(TRUE);
-			checkAutoSnapshot(previewp, TRUE);
-		}
-	}
 }
 
 // static
@@ -691,44 +500,6 @@ void LLFloaterOutfitSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* da
 	updateLayout(view);
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::checkAspectRatio(LLFloaterOutfitSnapshot *view, S32 index)
-{
-	LLSnapshotLivePreview *previewp = getPreviewView(view) ;
-
-	// Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
-	if(LLPanelSnapshot::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
-	{
-		previewp->mKeepAspectRatio = FALSE ;
-		return ;
-	}
-
-	BOOL keep_aspect = FALSE, enable_cb = FALSE;
-
-	if (0 == index) // current window size
-	{
-		enable_cb = FALSE;
-		keep_aspect = TRUE;
-	}
-	else if (-1 == index) // custom
-	{
-		enable_cb = TRUE;
-		keep_aspect = gSavedSettings.getBOOL("KeepAspectForSnapshot");
-	}
-	else // predefined resolution
-	{
-		enable_cb = FALSE;
-		keep_aspect = FALSE;
-	}
-
-	view->impl.mAspectRatioCheckOff = !enable_cb;
-
-	if (previewp)
-	{
-		previewp->mKeepAspectRatio = keep_aspect;
-	}
-}
-
 // Show/hide upload progress indicators.
 // static
 void LLFloaterOutfitSnapshot::Impl::setWorking(LLFloaterOutfitSnapshot* floater, bool working)
@@ -807,78 +578,22 @@ void LLFloaterOutfitSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data,
 			width = llmin(width, gViewerWindow->getWindowWidthRaw());
 			height = llmin(height, gViewerWindow->getWindowHeightRaw());
 		}
+        
 
-		if (width == 0 || height == 0)
-		{
-			// take resolution from current window size
-			LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
-			previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
-		}
-		else if (width == -1 || height == -1)
-		{
-			// load last custom value
-			S32 new_width = 0, new_height = 0;
-			LLPanelSnapshot* spanel = getActivePanel(view);
-			if (spanel)
-			{
-				LL_DEBUGS() << "Loading typed res from panel " << spanel->getName() << LL_ENDL;
-				new_width = spanel->getTypedPreviewWidth();
-				new_height = spanel->getTypedPreviewHeight();
-
-				// Limit custom size for inventory snapshots to 512x512 px.
-				if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
-				{
-					new_width = llmin(new_width, MAX_TEXTURE_SIZE);
-					new_height = llmin(new_height, MAX_TEXTURE_SIZE);
-				}
-			}
-			else
-			{
-				LL_DEBUGS() << "No custom res chosen, setting preview res from window: "
-					<< gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
-				new_width = gViewerWindow->getWindowWidthRaw();
-				new_height = gViewerWindow->getWindowHeightRaw();
-			}
+        llassert(width > 0 && height > 0);
 
-			llassert(new_width > 0 && new_height > 0);
-			previewp->setSize(new_width, new_height);
-		}
-		else
-		{
-			// use the resolution from the selected pre-canned drop-down choice
-			LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
-			previewp->setSize(width, height);
-		}
-
-		checkAspectRatio(view, width) ;
-
-		previewp->getSize(width, height);
-
-		// We use the height spinner here because we come here via the aspect ratio
-		// checkbox as well and we want height always changing to width by default.
-		// If we use the width spinner we would change width according to height by
-		// default, that is not what we want.
-		updateSpinners(view, previewp, width, height, !getHeightSpinner(view)->isDirty()); // may change width and height
+        // use the resolution from the selected pre-canned drop-down choice
+        LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
+        previewp->setSize(width, height);
 		
-		if(getWidthSpinner(view)->getValue().asInteger() != width || getHeightSpinner(view)->getValue().asInteger() != height)
-		{
-			getWidthSpinner(view)->setValue(width);
-			getHeightSpinner(view)->setValue(height);
-			if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
-			{
-				getWidthSpinner(view)->setIncrement(width >> 1);
-				getHeightSpinner(view)->setIncrement(height >> 1);
-			}
-		}
-
 		if(original_width != width || original_height != height)
 		{
-			previewp->setSize(width, height);
+			//previewp->setSize(width, height);
 
 			// hide old preview as the aspect ratio could be wrong
 			checkAutoSnapshot(previewp, FALSE);
 			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
-			getPreviewView(view)->updateSnapshot(TRUE);
+            previewp->updateSnapshot(TRUE);
 			if(do_update)
 			{
 				LL_DEBUGS() << "Will update controls" << LL_ENDL;
@@ -928,15 +643,6 @@ void LLFloaterOutfitSnapshot::Impl::onImageFormatChange(LLFloaterOutfitSnapshot*
 	}
 }
 
-// Sets the named size combo to "custom" mode.
-// static
-void LLFloaterOutfitSnapshot::Impl::comboSetCustom(LLFloaterOutfitSnapshot* floater, const std::string& comboname)
-{
-	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
-	combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
-	checkAspectRatio(floater, -1); // -1 means custom
-}
-
 // Update supplied width and height according to the constrain proportions flag; limit them by max_val.
 //static
 BOOL LLFloaterOutfitSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
@@ -983,58 +689,6 @@ BOOL LLFloaterOutfitSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previe
 	return (w != width || h != height) ;
 }
 
-//static
-void LLFloaterOutfitSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterOutfitSnapshot *view, S32 width, S32 height)
-{
-	getWidthSpinner(view)->forceSetValue(width);
-	getHeightSpinner(view)->forceSetValue(height);
-	if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
-	{
-		getWidthSpinner(view)->setIncrement(width >> 1);
-		getHeightSpinner(view)->setIncrement(height >> 1);
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::updateSpinners(LLFloaterOutfitSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed)
-{
-	getWidthSpinner(view)->resetDirty();
-	getHeightSpinner(view)->resetDirty();
-	if (checkImageSize(previewp, width, height, is_width_changed, previewp->getMaxImageSize()))
-	{
-		setImageSizeSpinnersValues(view, width, height);
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::applyCustomResolution(LLFloaterOutfitSnapshot* view, S32 w, S32 h)
-{
-	LL_DEBUGS() << "applyCustomResolution(" << w << ", " << h << ")" << LL_ENDL;
-	if (!view) return;
-
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
-	if (previewp)
-	{
-		S32 curw,curh;
-		previewp->getSize(curw, curh);
-
-		if (w != curw || h != curh)
-		{
-			//if to upload a snapshot, process spinner input in a special way.
-			previewp->setMaxImageSize((S32) getWidthSpinner(view)->getMaxValue()) ;
-
-			previewp->setSize(w,h);
-			checkAutoSnapshot(previewp, FALSE);
-			comboSetCustom(view, "profile_size_combo");
-			comboSetCustom(view, "postcard_size_combo");
-			comboSetCustom(view, "texture_size_combo");
-			comboSetCustom(view, "local_size_combo");
-			LL_DEBUGS() << "applied custom resolution, updating thumbnail" << LL_ENDL;
-			previewp->updateSnapshot(TRUE);
-		}
-	}
-}
-
 // static
 void LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished(bool status)
 {
@@ -1096,12 +750,6 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
 	childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
 	getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
 
-	impl.setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot"));
-
-	childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this);
-	getChild<LLUICtrl>("layer_types")->setValue("colors");
-	getChildView("layer_types")->setEnabled(FALSE);
-
 	getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
 	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
 
@@ -1261,7 +909,7 @@ S32 LLFloaterOutfitSnapshot::notify(const LLSD& info)
 		impl.updateResolution(getChild<LLUICtrl>(combo_name), this);
 		return 1;
 	}
-
+    /*
 	if (info.has("custom-res-change"))
 	{
 		LLSD res = info["custom-res-change"];
@@ -1274,7 +922,7 @@ S32 LLFloaterOutfitSnapshot::notify(const LLSD& info)
 		impl.applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean());
 		return 1;
 	}
-
+    */
 	if (info.has("image-quality-change"))
 	{
 		impl.onImageQualityChange(this, info["image-quality-change"].asInteger());
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 176a9520c2..9982676bea 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -38,12 +38,6 @@ class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
 	LOG_CLASS(LLFloaterOutfitSnapshot);
 
 public:
-	//typedef enum e_snapshot_format
-	//{
-	//	SNAPSHOT_FORMAT_PNG,
-	//	SNAPSHOT_FORMAT_JPEG,
-	//	SNAPSHOT_FORMAT_BMP
-	//} ESnapshotFormat;
 
 	LLFloaterOutfitSnapshot(const LLSD& key);
 	virtual ~LLFloaterOutfitSnapshot();
diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index ca62f2bdf5..284f7aad3f 100755
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
@@ -54,10 +54,18 @@ S32 power_of_two(S32 sz, S32 upper)
 BOOL LLPanelSnapshot::postBuild()
 {
 	getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onResolutionComboCommit, this, _1));
-	getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
-	getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
-	getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
-
+    if (!getWidthSpinnerName().empty())
+    {
+        getChild<LLUICtrl>(getWidthSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
+    }
+    if (!getHeightSpinnerName().empty())
+    {
+        getChild<LLUICtrl>(getHeightSpinnerName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onCustomResolutionCommit, this));
+    }
+    if (!getAspectRatioCBName().empty())
+    {
+        getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
+    }
 	updateControls(LLSD());
 	return TRUE;
 }
@@ -92,27 +100,32 @@ void LLPanelSnapshot::enableControls(BOOL enable)
 
 LLSpinCtrl* LLPanelSnapshot::getWidthSpinner()
 {
+    llassert(!getWidthSpinnerName().empty());
 	return getChild<LLSpinCtrl>(getWidthSpinnerName());
 }
 
 LLSpinCtrl* LLPanelSnapshot::getHeightSpinner()
 {
+    llassert(!getHeightSpinnerName().empty());
 	return getChild<LLSpinCtrl>(getHeightSpinnerName());
 }
 
 S32 LLPanelSnapshot::getTypedPreviewWidth() const
 {
+    llassert(!getWidthSpinnerName().empty());
 	return getChild<LLUICtrl>(getWidthSpinnerName())->getValue().asInteger();
 }
 
 S32 LLPanelSnapshot::getTypedPreviewHeight() const
 {
-	return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
+    llassert(!getHeightSpinnerName().empty());
+    return getChild<LLUICtrl>(getHeightSpinnerName())->getValue().asInteger();
 }
 
 void LLPanelSnapshot::enableAspectRatioCheckbox(BOOL enable)
 {
-	getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable);
+    llassert(!getAspectRatioCBName().empty());
+    getChild<LLUICtrl>(getAspectRatioCBName())->setEnabled(enable);
 }
 
 LLSideTrayPanelContainer* LLPanelSnapshot::getParentContainer()
@@ -177,9 +190,11 @@ void LLPanelSnapshot::cancel()
 void LLPanelSnapshot::onCustomResolutionCommit()
 {
 	LLSD info;
-	LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(getWidthSpinnerName());
-	LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(getHeightSpinnerName());
-    //TODO: Refactoring - move this code into some virtual method of LLPanelSnapshotInventory
+    std::string widthSpinnerName = getWidthSpinnerName();
+    std::string heightSpinnerName = getHeightSpinnerName();
+    llassert(!widthSpinnerName.empty() && !heightSpinnerName.empty());
+    LLSpinCtrl *widthSpinner = getChild<LLSpinCtrl>(widthSpinnerName);
+    LLSpinCtrl *heightSpinner = getChild<LLSpinCtrl>(heightSpinnerName);
 	if (getName() == "panel_snapshot_inventory")
 	{
 		S32 width = widthSpinner->getValue().asInteger();
diff --git a/indra/newview/llpanelsnapshot.h b/indra/newview/llpanelsnapshot.h
index d64ef3b75a..3868020cdf 100755
--- a/indra/newview/llpanelsnapshot.h
+++ b/indra/newview/llpanelsnapshot.h
@@ -68,7 +68,7 @@ protected:
 	LLSideTrayPanelContainer* getParentContainer();
 	void updateImageQualityLevel();
 	void goBack(); ///< Switch to the default (Snapshot Options) panel
-	void cancel();
+	virtual void cancel();
 
 	// common UI callbacks
 	void onCustomResolutionCommit();
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index 013a564908..057e046e30 100755
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -47,19 +47,6 @@ class LLPanelSnapshotInventoryBase
 
 public:
     LLPanelSnapshotInventoryBase();
-//
-//    /*virtual*/ BOOL postBuild();
-//    /*virtual*/ void onOpen(const LLSD& key);
-//
-//    void onResolutionCommit(LLUICtrl* ctrl);
-//
-//private:
-//    /*virtual*/ std::string getWidthSpinnerName() const		{ return "inventory_snapshot_width"; }
-//    /*virtual*/ std::string getHeightSpinnerName() const	{ return "inventory_snapshot_height"; }
-//    /*virtual*/ std::string getAspectRatioCBName() const	{ return "inventory_keep_aspect_check"; }
-//    /*virtual*/ std::string getImageSizeComboName() const	{ return "texture_size_combo"; }
-//    /*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
-//    /*virtual*/ void updateControls(const LLSD& info);
 
 protected:
     virtual void onSend() = 0;
@@ -99,18 +86,17 @@ public:
     LLPanelOutfitSnapshotInventory();
     	/*virtual*/ BOOL postBuild();
     	/*virtual*/ void onOpen(const LLSD& key);
-    
-    	void onResolutionCommit(LLUICtrl* ctrl);
-    
-    private:
-    	/*virtual*/ std::string getWidthSpinnerName() const		{ return "inventory_snapshot_width"; }
-    	/*virtual*/ std::string getHeightSpinnerName() const	{ return "inventory_snapshot_height"; }
-    	/*virtual*/ std::string getAspectRatioCBName() const	{ return "inventory_keep_aspect_check"; }
-    	/*virtual*/ std::string getImageSizeComboName() const	{ return "texture_size_combo"; }
-    	/*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
-    	/*virtual*/ void updateControls(const LLSD& info);
+        
+private:
+    /*virtual*/ std::string getWidthSpinnerName() const		{ return ""; }
+    /*virtual*/ std::string getHeightSpinnerName() const	{ return ""; }
+    /*virtual*/ std::string getAspectRatioCBName() const	{ return ""; }
+    /*virtual*/ std::string getImageSizeComboName() const	{ return "texture_size_combo"; }
+    /*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
+    /*virtual*/ void updateControls(const LLSD& info);
 
     /*virtual*/ void onSend();
+    /*virtual*/ void cancel();
 };
 
 static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory");
@@ -172,16 +158,12 @@ void LLPanelSnapshotInventory::onSend()
 LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory()
 {
     mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this));
-    mCommitCallbackRegistrar.add("Inventory.Cancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this));
+    mCommitCallbackRegistrar.add("Inventory.SaveOutfitCancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this));
 }
 
 // virtual
 BOOL LLPanelOutfitSnapshotInventory::postBuild()
 {
-    getChild<LLSpinCtrl>(getWidthSpinnerName())->setAllowEdit(FALSE);
-    getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE);
-
-    getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelOutfitSnapshotInventory::onResolutionCommit, this, _1));
     return LLPanelSnapshot::postBuild();
 }
 
@@ -199,15 +181,13 @@ void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info)
     getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
 }
 
-void LLPanelOutfitSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
-{
-    BOOL current_window_selected = (getChild<LLComboBox>(getImageSizeComboName())->getCurrentIndex() == 3);
-    getChild<LLSpinCtrl>(getWidthSpinnerName())->setVisible(!current_window_selected);
-    getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected);
-}
-
 void LLPanelOutfitSnapshotInventory::onSend()
 {
     LLFloaterOutfitSnapshot::saveTexture();
     LLFloaterOutfitSnapshot::postSave();
 }
+
+void LLPanelOutfitSnapshotInventory::cancel()
+{
+    getParentByType<LLFloater>()->closeFloater();
+}
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
index 7b88b07ca6..34f02e535f 100644
--- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
@@ -156,23 +156,6 @@
          width="100">
             Capture:
         </text>
-        <combo_box
-         follows="left|top|right"
-         height="23"
-         label="Image Layers"
-         layout="topleft"
-         left="30"
-         name="layer_types"
-         right="-2">
-            <combo_box.item
-             label="Colors"
-             name="Colors"
-             value="colors" />
-            <combo_box.item
-             label="Depth"
-             name="Depth"
-             value="depth" />
-        </combo_box>
         <check_box
          label="Interface"
          layout="topleft"
@@ -243,43 +226,6 @@
          top_pad="7"
          />
     </panel>
- <!--
-	<panel_container
-     follows="left|top"
-     height="230"
-     layout="topleft"
-     left="0"
-     name="panel_container"
-     default_panel_name="panel_snapshot_options"
-     top_pad="10"
-     width="215">
-      <panel
-       class="llpanelsnapshotoptions"
-       filename="panel_snapshot_options.xml"
-       follows="all"
-       layout="topleft"
-       left="0"
-       name="panel_snapshot_options"
-       top="0" />
-      <panel
-       class="llpanelsnapshotprofile"
-       follows="all"
-       layout="topleft"
-       name="panel_snapshot_profile"
-       filename="panel_snapshot_profile.xml" />
-      <panel
-       class="llpanelsnapshotpostcard"
-       follows="all"
-       layout="topleft"
-       name="panel_snapshot_postcard"
-       filename="panel_snapshot_postcard.xml" />
-      -->
-  <!--panel
-       class="llpaneloutfitsnapshotinventory"
-       follows="all"
-       layout="topleft"
-       name="panel_outfit_snapshot_inventory"
-       filename="panel_snapshot_inventory.xml"-->
       <panel
         class="llpaneloutfitsnapshotinventory"
         follows="left|top"
@@ -291,15 +237,6 @@
         top_pad="10"
         width="215"
       />
-      <!--
-      <panel
-       class="llpanelsnapshotlocal"
-       follows="all"
-       layout="topleft"
-       name="panel_snapshot_local"
-       filename="panel_snapshot_local.xml" />
-      </panel_container>
--->
 	<view_border 
          bevel_style="in"
          follows="left|top" 
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
index ce6309e2ed..7261d429ba 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
@@ -59,53 +59,7 @@
          label="Large (512x512)"
          name="Large(512x512)"
          value="[i512,i512]" />
-        <combo_box.item
-         label="Current Window(512x512)"
-         name="CurrentWindow"
-         value="[i0,i0]" />
-        <combo_box.item
-         label="Custom"
-         name="Custom"
-         value="[i-1,i-1]" />
     </combo_box>
-    <spinner
-     allow_text_entry="false"
-     decimal_digits="0"
-     follows="left|top"
-     height="20"
-     increment="32"
-     label="Width x Height"
-     label_width="90"
-     layout="topleft"
-     left="10"
-     max_val="6016"
-     min_val="32"
-     name="inventory_snapshot_width"
-     top_pad="7"
-     width="144" />
-    <spinner
-     allow_text_entry="false"
-     decimal_digits="0"
-     follows="left|top"
-     height="20"
-     increment="32"
-     label=""
-     label_width="0"
-     layout="topleft"
-     left_pad="0"
-     max_val="6016"
-     min_val="32"
-     name="inventory_snapshot_height"
-     top_delta="0"
-     width="54" />
-    <check_box
-     top_pad="12"
-     follows="left|top"
-     label="Constrain proportions"
-     layout="topleft"
-     left="10"
-     name="inventory_keep_aspect_check"
-     visible="false" />
     <text
      follows="top|left"
      font="SansSerif"
@@ -118,7 +72,7 @@
      width="200"
      type="string"
      word_wrap="true">
-        Saving an image to your inventory costs L$[UPLOAD_COST]. To save your image as a texture select one of the square formats.
+        Uploading an image to your inventory costs L$[UPLOAD_COST].
     </text>
     <button
      follows="right|bottom"
@@ -130,12 +84,12 @@
      top="337"
      width="97">
       <button.commit_callback
-       function="Inventory.Cancel" />
+       function="Inventory.SaveOutfitCancel" />
     </button>
     <button
      follows="left|bottom"
      height="23"
-     label="Save"
+     label="UPLOAD L$10"
      layout="topleft"
      left="10"
      name="save_btn"
-- 
cgit v1.2.3


From cec81209b7c3163135cca138cca920b364ae82df Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 6 May 2016 11:09:46 +0300
Subject: mac build fix

---
 indra/newview/llfloateroutfitsnapshot.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index cea0e48aa6..66bb4df4ba 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -57,9 +57,6 @@ LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
 
 const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
 
-const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
-const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
-
 static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
 
 
-- 
cgit v1.2.3


From 042930b59a82f706f16e4b67a683697aed65112f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 6 May 2016 12:43:48 +0300
Subject: linux build fix

---
 indra/newview/llpanelsnapshot.cpp       |  2 +-
 indra/newview/llsnapshotlivepreview.cpp | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index 284f7aad3f..e320c4ce8b 100755
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
@@ -230,5 +230,5 @@ void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl)
 
 LLPanelSnapshot::ESnapshotType LLPanelSnapshot::getSnapshotType()
 {
-    return ESnapshotType::SNAPSHOT_WEB;
+    return LLPanelSnapshot::SNAPSHOT_WEB;
 }
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index d40694f2f4..31a2895b9d 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -86,7 +86,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param
 	mNeedsFlash(TRUE),
 	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
 	mDataSize(0),
-    mSnapshotType(LLPanelSnapshot::ESnapshotType::SNAPSHOT_POSTCARD),
+    mSnapshotType(LLPanelSnapshot::SNAPSHOT_POSTCARD),
     mSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
 	mSnapshotUpToDate(FALSE),
 	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
@@ -813,7 +813,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
         mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
         LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex];
         gGL.getTexUnit(0)->bind(curr_preview_image);
-        curr_preview_image->setFilteringOption(getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
+        curr_preview_image->setFilteringOption(getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
         curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
 
 
@@ -827,7 +827,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
 S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 {
     S32 width = getWidth();
-    if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
     {
         width = LLImageRaw::biasedDimToPowerOfTwo(width,MAX_TEXTURE_SIZE);
     }
@@ -836,7 +836,7 @@ S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 S32 LLSnapshotLivePreview::getEncodedImageHeight() const
 {
     S32 height = getHeight();
-    if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
     {
         height = LLImageRaw::biasedDimToPowerOfTwo(height,MAX_TEXTURE_SIZE);
     }
@@ -854,7 +854,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
             mPreviewImage->getHeight(),
             mPreviewImage->getComponents());
         
-        if (getSnapshotType() == LLPanelSnapshot::ESnapshotType::SNAPSHOT_TEXTURE)
+        if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
 		{
             // We don't store the intermediate formatted image in mFormattedImage in the J2C case 
 			LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
-- 
cgit v1.2.3


From b601b92e1fb8de7e82b0729b3b70342afde6f3d6 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 10 May 2016 18:05:23 +0300
Subject: build fix

---
 indra/newview/llsnapshotlivepreview.cpp | 2 +-
 indra/newview/llviewerfloaterreg.cpp    | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 88eb64f130..15aa62f5d3 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -1039,7 +1039,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
         LLInventoryType::EType inv_type = outfit_snapshot ? LLInventoryType::IT_NONE : LLInventoryType::IT_SNAPSHOT;
 
         LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
-            tid, LLAssetType::AT_TEXTURE, name, desc, 0,
+            tid, LLAssetType::AT_TEXTURE, res_name, res_desc, 0,
             folder_type, inv_type,
             PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
             expected_upload_cost));
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c5ae0fecaa..5b6a23c785 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -92,6 +92,7 @@
 #include "llfloaternotificationstabbed.h"
 #include "llfloaterobjectweights.h"
 #include "llfloateropenobject.h"
+#include "llfloateroutfitsnapshot.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindingconsole.h"
 #include "llfloaterpathfindinglinksets.h"
-- 
cgit v1.2.3


From 6d4d58738c8f1703d4e821308f749a3ae577268c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 13 May 2016 18:17:29 +0300
Subject: MAINT-6395 Visual outfit browser snapshot window needs image size
 fixes

---
 indra/newview/llfloateroutfitsnapshot.cpp          | 191 ++-------------------
 indra/newview/llfloateroutfitsnapshot.h            |   2 -
 .../xui/en/panel_outfit_snapshot_inventory.xml     |  22 ---
 3 files changed, 12 insertions(+), 203 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 66bb4df4ba..6d641613ff 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -57,6 +57,9 @@ LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
 
 const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
 
+const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
+const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
+
 static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
 
 
@@ -96,22 +99,17 @@ public:
 	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
 	static void onClickUICheck(LLUICtrl *ctrl, void* data);
 	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
-	static void applyKeepAspectCheck(LLFloaterOutfitSnapshot* view, BOOL checked);
-	static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
+	static void updateResolution(void* data);
 	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
 	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
-	static void onImageQualityChange(LLFloaterOutfitSnapshot* view, S32 quality_val);
-	static void onImageFormatChange(LLFloaterOutfitSnapshot* view);
 	static void onSnapshotUploadFinished(bool status);
 	static void onSendingPostcardFinished(bool status);
-	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
 
 	static LLPanelSnapshot* getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found = true);
     static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterOutfitSnapshot* floater);
 	static LLFloaterOutfitSnapshot::ESnapshotFormat getImageFormat(LLFloaterOutfitSnapshot* floater);
 
 	static LLSnapshotLivePreview* getPreviewView(LLFloaterOutfitSnapshot *floater);
-	static void setResolution(LLFloaterOutfitSnapshot* floater, const std::string& comboname);
 	static void updateControls(LLFloaterOutfitSnapshot* floater);
 	static void updateLayout(LLFloaterOutfitSnapshot* floater);
 	static void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
@@ -175,14 +173,6 @@ LLViewerWindow::ESnapshotType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloa
     return LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::setResolution(LLFloaterOutfitSnapshot* floater, const std::string& comboname)
-{
-	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
-		combo->setVisible(TRUE);
-	updateResolution(combo, floater, FALSE); // to sync spinners with combo
-}
-
 //static 
 void LLFloaterOutfitSnapshot::Impl::updateLayout(LLFloaterOutfitSnapshot* floaterp)
 {
@@ -319,7 +309,7 @@ void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterOutfitSnapshot* floa
 	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
 	floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor( "LabelTextColor" ));
 
-    setResolution(floater, "texture_size_combo");
+	updateResolution(floater);
 
 	if (previewp)
 	{
@@ -470,11 +460,6 @@ void LLFloaterOutfitSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
 	}
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::applyKeepAspectCheck(LLFloaterOutfitSnapshot* view, BOOL checked)
-{
-}
-
 // static
 void LLFloaterOutfitSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
 {
@@ -545,27 +530,21 @@ void LLFloaterOutfitSnapshot::Impl::setFinished(LLFloaterOutfitSnapshot* floater
 
 // Apply a new resolution selected from the given combobox.
 // static
-void LLFloaterOutfitSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update)
+void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
 {
-	LLComboBox* combobox = (LLComboBox*)ctrl;
 	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
 		
-	if (!view || !combobox)
+	if (!view)
 	{
-		llassert(view && combobox);
+		llassert(view);
 		return;
 	}
-
-	std::string sdstring = combobox->getSelectedValue();
-	LLSD sdres;
-	std::stringstream sstream(sdstring);
-	LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
 		
-	S32 width = sdres[0];
-	S32 height = sdres[1];
+	S32 width = OUTFIT_SNAPSHOT_WIDTH;
+	S32 height = OUTFIT_SNAPSHOT_HEIGHT;
 	
 	LLSnapshotLivePreview* previewp = getPreviewView(view);
-	if (previewp && combobox->getCurrentIndex() >= 0)
+	if (previewp)
 	{
 		S32 original_width = 0 , original_height = 0 ;
 		previewp->getSize(original_width, original_height) ;
@@ -591,11 +570,6 @@ void LLFloaterOutfitSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data,
 			checkAutoSnapshot(previewp, FALSE);
 			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
             previewp->updateSnapshot(TRUE);
-			if(do_update)
-			{
-				LL_DEBUGS() << "Will update controls" << LL_ENDL;
-				updateControls(view);
-			}
 		}
 	}
 }
@@ -618,74 +592,6 @@ void LLFloaterOutfitSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data
 	}
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onImageQualityChange(LLFloaterOutfitSnapshot* view, S32 quality_val)
-{
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
-	if (previewp)
-	{
-		previewp->setSnapshotQuality(quality_val);
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::onImageFormatChange(LLFloaterOutfitSnapshot* view)
-{
-	if (view)
-	{
-		gSavedSettings.setS32("SnapshotFormat", getImageFormat(view));
-		LL_DEBUGS() << "image format changed, updating snapshot" << LL_ENDL;
-		getPreviewView(view)->updateSnapshot(TRUE);
-		updateControls(view);
-	}
-}
-
-// Update supplied width and height according to the constrain proportions flag; limit them by max_val.
-//static
-BOOL LLFloaterOutfitSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
-{
-	S32 w = width ;
-	S32 h = height ;
-
-	if(previewp && previewp->mKeepAspectRatio)
-	{
-		if(gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1)
-		{
-			return FALSE ;
-		}
-
-		//aspect ratio of the current window
-		F32 aspect_ratio = (F32)gViewerWindow->getWindowWidthRaw() / gViewerWindow->getWindowHeightRaw() ;
-
-		//change another value proportionally
-		if(isWidthChanged)
-		{
-			height = ll_round(width / aspect_ratio) ;
-		}
-		else
-		{
-			width = ll_round(height * aspect_ratio) ;
-		}
-
-		//bound w/h by the max_value
-		if(width > max_value || height > max_value)
-		{
-			if(width > height)
-			{
-				width = max_value ;
-				height = (S32)(width / aspect_ratio) ;
-			}
-			else
-			{
-				height = max_value ;
-				width = (S32)(height * aspect_ratio) ;
-			}
-		}
-	}
-
-	return (w != width || h != height) ;
-}
-
 // static
 void LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished(bool status)
 {
@@ -784,19 +690,12 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
 	gFloaterView->removeChild(this);
 	gSnapshotFloaterView->addChild(this);
 
-	// Pre-select "Current Window" resolution.
-	getChild<LLComboBox>("profile_size_combo")->selectNthItem(0);
-	getChild<LLComboBox>("postcard_size_combo")->selectNthItem(0);
-	getChild<LLComboBox>("texture_size_combo")->selectNthItem(0);
-	getChild<LLComboBox>("local_size_combo")->selectNthItem(8);
-	getChild<LLComboBox>("local_format_combo")->selectNthItem(0);
-
 	impl.mPreviewHandle = previewp->getHandle();
     previewp->setContainer(this);
 	impl.updateControls(this);
 	impl.updateLayout(this);
 	
-
+	previewp->mKeepAspectRatio = FALSE;
 	previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
 
 	return TRUE;
@@ -899,39 +798,6 @@ void LLFloaterOutfitSnapshot::onClose(bool app_quitting)
 // virtual
 S32 LLFloaterOutfitSnapshot::notify(const LLSD& info)
 {
-	// A child panel wants to change snapshot resolution.
-	if (info.has("combo-res-change"))
-	{
-		std::string combo_name = info["combo-res-change"]["control-name"].asString();
-		impl.updateResolution(getChild<LLUICtrl>(combo_name), this);
-		return 1;
-	}
-    /*
-	if (info.has("custom-res-change"))
-	{
-		LLSD res = info["custom-res-change"];
-		impl.applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger());
-		return 1;
-	}
-
-	if (info.has("keep-aspect-change"))
-	{
-		impl.applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean());
-		return 1;
-	}
-    */
-	if (info.has("image-quality-change"))
-	{
-		impl.onImageQualityChange(this, info["image-quality-change"].asInteger());
-		return 1;
-	}
-
-	if (info.has("image-format-change"))
-	{
-		impl.onImageFormatChange(this);
-		return 1;
-	}
-
 	if (info.has("set-ready"))
 	{
 		impl.setStatus(Impl::STATUS_READY);
@@ -1046,27 +912,6 @@ void LLFloaterOutfitSnapshot::saveTexture()
     instance->closeFloater();
 }
 
-// static
-BOOL LLFloaterOutfitSnapshot::saveLocal()
-{
-	LL_DEBUGS() << "saveLocal" << LL_ENDL;
-	// FIXME: duplicated code
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return FALSE;
-	}
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
-	if (!previewp)
-	{
-		llassert(previewp != NULL);
-		return FALSE;
-	}
-
-	return previewp->saveLocal();
-}
-
 // static
 void LLFloaterOutfitSnapshot::postSave()
 {
@@ -1140,18 +985,6 @@ const LLVector3d& LLFloaterOutfitSnapshot::getPosTakenGlobal()
 	return previewp->getPosTakenGlobal();
 }
 
-// static
-void LLFloaterOutfitSnapshot::setAgentEmail(const std::string& email)
-{
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (instance)
-	{
-		LLSideTrayPanelContainer* panel_container = instance->getChild<LLSideTrayPanelContainer>("panel_container");
-		LLPanel* postcard_panel = panel_container->getPanelByName("panel_snapshot_postcard");
-		postcard_panel->notify(LLSD().with("agent-email", email));
-	}
-}
-
 ///----------------------------------------------------------------------------
 /// Class LLSnapshotFloaterView
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 9982676bea..9a7b30ebd8 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -54,12 +54,10 @@ public:
 	static LLFloaterOutfitSnapshot* getInstance();
 	static LLFloaterOutfitSnapshot* findInstance();
 	static void saveTexture();
-	static BOOL saveLocal();
 	static void postSave();
 	static void postPanelSwitch();
 	static LLPointer<LLImageFormatted> getImageData();
 	static const LLVector3d& getPosTakenGlobal();
-	static void setAgentEmail(const std::string& email);
 
 	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
 
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
index 7261d429ba..800faabc2a 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_snapshot_inventory.xml
@@ -38,28 +38,6 @@
      right="-5"
      top_pad="5"
      />
-    <combo_box
-     follows="top|left|right"
-     height="20"
-     label="Resolution"
-     layout="topleft"
-     left_delta="0"
-     name="texture_size_combo"
-     right="-5"
-     top_pad="5">
-        <combo_box.item
-         label="Small (128x128)"
-         name="Small(128x128)"
-         value="[i128,i128]" />
-        <combo_box.item
-         label="Medium (256x256)"
-         name="Medium(256x256)"
-         value="[i256,i256]" />
-        <combo_box.item
-         label="Large (512x512)"
-         name="Large(512x512)"
-         value="[i512,i512]" />
-    </combo_box>
     <text
      follows="top|left"
      font="SansSerif"
-- 
cgit v1.2.3


From 5bee6f1e5e5ec9d25283ecf1815b57e5921f2c47 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 18 May 2016 15:02:15 +0300
Subject: MAINT-6421 Inappropriate menu items are presented in gear menu when
 no outfit is selected in Visual Outfit Browser

---
 indra/newview/lloutfitgallery.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index a36728e6ac..e6c41b612f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -735,11 +735,12 @@ LLOutfitGalleryGearMenu::LLOutfitGalleryGearMenu(LLOutfitListBase* olist)
 void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
 {
     if (!mMenu) return;
+    bool have_selection = getSelectedOutfitID().notNull();
     mMenu->setItemVisible("expand", FALSE);
     mMenu->setItemVisible("collapse", FALSE);
-    mMenu->setItemVisible("upload_photo", TRUE);
-    mMenu->setItemVisible("select_photo", TRUE);
-    mMenu->setItemVisible("take_snapshot", TRUE);
+    mMenu->setItemVisible("upload_photo", have_selection);
+    mMenu->setItemVisible("select_photo", have_selection);
+    mMenu->setItemVisible("take_snapshot", have_selection);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
-- 
cgit v1.2.3


From addbfaf1c774011f3e55a1106f0b83153b7b8568 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 23 May 2016 17:07:48 +0300
Subject: MAINT-6431 Trash button is not functional in in Visual Outfit Browser

---
 indra/newview/llpaneloutfitsinventory.cpp | 7 +++++++
 indra/newview/llpaneloutfitsinventory.h   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index eb88abb2bf..c0c1adddf3 100755
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -236,6 +236,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
 	mListCommands = getChild<LLPanel>("bottom_panel");
 	mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
 	mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
+	mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onGalleryTrashButtonClick, this));
 }
 
 void LLPanelOutfitsInventory::updateListCommands()
@@ -247,6 +248,7 @@ void LLPanelOutfitsInventory::updateListCommands()
 
 	LLButton* wear_btn = mListCommands->getChild<LLButton>("wear_btn");
 	mMyOutfitsPanel->childSetEnabled("trash_btn", trash_enabled);
+	mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled);
 	wear_btn->setEnabled(wear_enabled);
 	wear_btn->setVisible(wear_visible);
 	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
@@ -258,6 +260,11 @@ void LLPanelOutfitsInventory::onTrashButtonClick()
 	mMyOutfitsPanel->removeSelected();
 }
 
+void LLPanelOutfitsInventory::onGalleryTrashButtonClick()
+{
+	mOutfitGalleryPanel->removeSelected();
+}
+
 bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
 {
 	return mActivePanel && mActivePanel->isActionEnabled(userdata);
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 8c873df038..efb9524a21 100755
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -91,6 +91,7 @@ protected:
 	void onWearButtonClick();
 	void showGearMenu();
 	void onTrashButtonClick();
+	void onGalleryTrashButtonClick();
 	bool isActionEnabled(const LLSD& userdata);
 	void setWearablesLoading(bool val);
 	void onWearablesLoaded();
-- 
cgit v1.2.3


From 5b49f5c56e0178d1f2f655ee678a9bea58edd5d5 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 25 May 2016 18:52:57 +0300
Subject: MAINT-6440 FIXED Inappropriate outfit is worn after clicking Wear
 button in Visual Outfit Browser

---
 indra/newview/lloutfitgallery.cpp         |  5 ++++
 indra/newview/lloutfitgallery.h           |  2 ++
 indra/newview/llpaneloutfitsinventory.cpp | 50 +++++++++++++++++++++++--------
 indra/newview/llpaneloutfitsinventory.h   |  3 +-
 4 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index e6c41b612f..f29fc53dea 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -508,6 +508,11 @@ void LLOutfitGallery::onChangeOutfitSelection(LLWearableItemsList* list, const L
     }
 }
 
+void LLOutfitGallery::wearSelectedOutfit()
+{
+    LLAppearanceMgr::instance().replaceCurrentOutfit(getSelectedOutfitUUID());
+}
+
 bool LLOutfitGallery::hasItemSelected()
 {
     return false;
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index b8c7d66406..a22e86df83 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -89,6 +89,8 @@ public:
     void onSelectPhoto(LLUUID selected_outfit_id);
     void onTakeSnapshot(LLUUID selected_outfit_id);
 
+    void wearSelectedOutfit();
+
 
     /*virtual*/ void setFilterSubString(const std::string& string);
 
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index c0c1adddf3..3f700496a9 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -167,14 +167,22 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
 
 void LLPanelOutfitsInventory::onWearButtonClick()
 {
-	if (mMyOutfitsPanel->hasItemSelected())
+	if(isOutfitsListPanelActive())
 	{
-		mMyOutfitsPanel->wearSelectedItems();
+		if (mMyOutfitsPanel->hasItemSelected())
+		{
+			mMyOutfitsPanel->wearSelectedItems();
+		}
+		else
+		{
+			mMyOutfitsPanel->performAction("replaceoutfit");
+		}
 	}
-	else
+	else if(isOutfitsGalleryPanelActive())
 	{
-		mMyOutfitsPanel->performAction("replaceoutfit");
+		mOutfitGalleryPanel->wearSelectedOutfit();
 	}
+
 }
 
 bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response)
@@ -236,7 +244,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers()
 	mListCommands = getChild<LLPanel>("bottom_panel");
 	mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
 	mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
-	mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onGalleryTrashButtonClick, this));
+	mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
 }
 
 void LLPanelOutfitsInventory::updateListCommands()
@@ -252,17 +260,19 @@ void LLPanelOutfitsInventory::updateListCommands()
 	wear_btn->setEnabled(wear_enabled);
 	wear_btn->setVisible(wear_visible);
 	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
-	wear_btn->setToolTip(getString(mMyOutfitsPanel->hasItemSelected() ? "wear_items_tooltip" : "wear_outfit_tooltip"));
+	wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip"));
 }
 
 void LLPanelOutfitsInventory::onTrashButtonClick()
 {
-	mMyOutfitsPanel->removeSelected();
-}
-
-void LLPanelOutfitsInventory::onGalleryTrashButtonClick()
-{
-	mOutfitGalleryPanel->removeSelected();
+	if(isOutfitsListPanelActive())
+	{
+		mMyOutfitsPanel->removeSelected();
+	}
+	else if(isOutfitsGalleryPanelActive())
+	{
+		mOutfitGalleryPanel->removeSelected();
+	}
 }
 
 bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
@@ -309,6 +319,22 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const
 	return mActivePanel->getName() == COF_TAB_NAME;
 }
 
+bool LLPanelOutfitsInventory::isOutfitsListPanelActive() const
+{
+	if (!mActivePanel) return false;
+
+	return mActivePanel->getName() == OUTFITS_TAB_NAME;
+}
+
+bool LLPanelOutfitsInventory::isOutfitsGalleryPanelActive() const
+{
+	if (!mActivePanel) return false;
+
+	return mActivePanel->getName() == OUTFIT_GALLERY_TAB_NAME;
+}
+
+
+
 void LLPanelOutfitsInventory::setWearablesLoading(bool val)
 {
 	updateVerbs();
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index efb9524a21..6a0ea04fa6 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -73,6 +73,8 @@ protected:
 	void 					initTabPanels();
 	void 					onTabChange();
 	bool 					isCOFPanelActive() const;
+	bool 					isOutfitsListPanelActive() const;
+	bool 					isOutfitsGalleryPanelActive() const;
 
 private:
 	LLPanelAppearanceTab*	mActivePanel;
@@ -91,7 +93,6 @@ protected:
 	void onWearButtonClick();
 	void showGearMenu();
 	void onTrashButtonClick();
-	void onGalleryTrashButtonClick();
 	bool isActionEnabled(const LLSD& userdata);
 	void setWearablesLoading(bool val);
 	void onWearablesLoaded();
-- 
cgit v1.2.3


From 2b9927863ff6826bc448379e2f829b1de5e6c3fb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 30 May 2016 15:03:40 +0300
Subject: MAINT-6444 Outfits filter doesn't work in Outfit gallery

---
 indra/newview/lloutfitgallery.cpp | 42 ++++++++++++++++++++++++++++++++++++---
 indra/newview/lloutfitgallery.h   |  7 +++++++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index f29fc53dea..6a8256d41c 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -152,6 +152,11 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
     {
         removeFromGalleryLast(*it);
     }
+    for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = mHiddenItems.rbegin(); it != mHiddenItems.rend(); ++it)
+    {
+        buf_items.push_back(*it);
+    }
+    mHiddenItems.clear();
     
     mItemsInRow+= row_diff;
     updateGalleryWidth();
@@ -159,7 +164,9 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
     
     for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
     {
-        addToGallery(*it);
+    	(*it)->setHidden(false);
+    	applyFilter(*it,sFilterSubString);
+    	addToGallery(*it);
     }
 }
 
@@ -214,6 +221,11 @@ LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item
 
 void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item)
 {
+    if(item->isHidden())
+    {
+        mHiddenItems.push_back(item);
+        return;
+    }
     mItemsAddedCount++;
     mItemIndexMap[item] = mItemsAddedCount - 1;
     int n = mItemsAddedCount;
@@ -241,6 +253,11 @@ void LLOutfitGallery::addToGallery(LLOutfitGalleryItem* item)
 
 void LLOutfitGallery::removeFromGalleryLast(LLOutfitGalleryItem* item)
 {
+    if(item->isHidden())
+    {
+        mHiddenItems.pop_back();
+        return;
+    }
     int n_prev = mItemsAddedCount;
     int n = mItemsAddedCount - 1;
     int row_count = (n % mItemsInRow) == 0 ? n / mItemsInRow : n / mItemsInRow + 1;
@@ -264,6 +281,11 @@ void LLOutfitGallery::removeFromGalleryLast(LLOutfitGalleryItem* item)
 
 void LLOutfitGallery::removeFromGalleryMiddle(LLOutfitGalleryItem* item)
 {
+    if(item->isHidden())
+    {
+        mHiddenItems.erase(std::remove(mHiddenItems.begin(), mHiddenItems.end(), item), mHiddenItems.end());
+        return;
+    }
     int n = mItemIndexMap[item];
     mItemIndexMap.erase(item);
     std::vector<LLOutfitGalleryItem*> saved;
@@ -371,9 +393,8 @@ LLOutfitGallery::~LLOutfitGallery()
 
 void LLOutfitGallery::setFilterSubString(const std::string& string)
 {
-    //TODO: Implement filtering
-
     sFilterSubString = string;
+    reArrangeRows();
 }
 
 void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
@@ -388,6 +409,20 @@ void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
     }
 }
 
+void LLOutfitGallery::applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring)
+{
+    if (!item) return;
+
+    std::string outfit_name = item->getItemName();
+    LLStringUtil::toUpper(outfit_name);
+
+    std::string cur_filter = filter_substring;
+    LLStringUtil::toUpper(cur_filter);
+
+    bool hidden = (std::string::npos == outfit_name.find(cur_filter));
+    item->setHidden(hidden);
+}
+
 void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
 {
 }
@@ -555,6 +590,7 @@ BOOL LLOutfitGalleryItem::postBuild()
     mFotoBgPanel = getChild<LLPanel>("foto_bg_panel");
     mTextBgPanel = getChild<LLPanel>("text_bg_panel");
     setOutfitWorn(false);
+    mHidden = false;
     return TRUE;
 }
 
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index a22e86df83..b3e699e0e7 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -120,6 +120,8 @@ protected:
     /*virtual*/ void onExpandAllFolders() {}
     /*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
 
+    void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring);
+
 private:
     void loadPhotos();
     void uploadPhoto(LLUUID outfit_id);
@@ -153,6 +155,7 @@ private:
     std::vector<LLPanel*> mRowPanels;
     std::vector<LLPanel*> mItemPanels;
     std::vector<LLOutfitGalleryItem*> mItems;
+    std::vector<LLOutfitGalleryItem*> mHiddenItems;
     LLScrollContainer* mScrollPanel;
     LLPanel* mGalleryPanel;
     LLPanel* mLastRowPanel;
@@ -250,6 +253,9 @@ public:
     std::string getItemName() {return mOutfitName;}
     bool mIsDefaultImage() {return mDefaultImage;}
     
+    bool isHidden() {return mHidden;}
+    void setHidden(bool hidden) {mHidden = hidden;}
+
     struct compareGalleryItem
     {
         bool operator()(LLOutfitGalleryItem* a, LLOutfitGalleryItem* b)
@@ -275,6 +281,7 @@ private:
     bool     mSelected;
     bool     mWorn;
     bool     mDefaultImage;
+    bool	 mHidden;
     std::string mOutfitName;
 };
 
-- 
cgit v1.2.3


From d1b7deda45f778e0fcfb92f38f9f5694ab285d1c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 31 May 2016 18:04:05 +0300
Subject: MAINT-6452 No message is displayed when there is no outfits in
 Gallery

---
 indra/newview/lloutfitgallery.cpp                  | 18 ++++++++++++++++
 indra/newview/lloutfitgallery.h                    |  3 +++
 .../skins/default/xui/en/panel_outfit_gallery.xml  | 24 ++++++++++++++++++++--
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 6a8256d41c..7bd9c0bd94 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -99,6 +99,7 @@ BOOL LLOutfitGallery::postBuild()
     BOOL rv = LLOutfitListBase::postBuild();
     mScrollPanel = getChild<LLScrollContainer>("gallery_scroll_panel");
     mGalleryPanel = getChild<LLPanel>("gallery_panel");
+    mMessageTextBox = getChild<LLTextBox>("no_outfits_txt");
     mOutfitGalleryMenu = new LLOutfitGalleryContextMenu(this);
     return rv;
 }
@@ -168,6 +169,7 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
     	applyFilter(*it,sFilterSubString);
     	addToGallery(*it);
     }
+    updateMessageVisibility();
 }
 
 void LLOutfitGallery::updateGalleryWidth()
@@ -558,6 +560,22 @@ bool LLOutfitGallery::canWearSelected()
     return false;
 }
 
+void LLOutfitGallery::updateMessageVisibility()
+{
+    if(mItems.empty())
+    {
+        mMessageTextBox->setVisible(TRUE);
+        mScrollPanel->setVisible(FALSE);
+        std::string message = sFilterSubString.empty()? getString("no_outfits_msg") : getString("no_matched_outfits_msg");
+        mMessageTextBox->setValue(message);
+    }
+    else
+    {
+        mScrollPanel->setVisible(TRUE);
+        mMessageTextBox->setVisible(FALSE);
+    }
+}
+
 LLOutfitListGearMenuBase* LLOutfitGallery::createGearMenu()
 {
     return new LLOutfitGalleryGearMenu(this);
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index b3e699e0e7..ad3f2a7129 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -104,6 +104,8 @@ public:
 
     /*virtual*/ bool getHasExpandableFolders() { return FALSE; }
 
+    void updateMessageVisibility();
+
     void refreshTextures(const LLUUID& category_id);
     void refreshOutfit(const LLUUID& category_id);
 
@@ -161,6 +163,7 @@ private:
     LLPanel* mLastRowPanel;
     LLUUID mOutfitLinkPending;
     LLUUID mOutfitRenamePending;
+    LLTextBox* mMessageTextBox;
     bool mGalleryCreated;
     int mRowCount;
     int mItemsAddedCount;
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index c06c6a86c3..9a547f615d 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -13,6 +13,26 @@
   <string name="outfit_photo_string">
     Photo of "[OUTFIT_NAME]" outfit
   </string>
+  <string name="no_outfits_msg">
+    You don't have any outfits yet. Try [secondlife:///app/search/all/ Search]
+  </string>
+  <string name="no_matched_outfits_msg">
+    Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].
+  </string>
+  <text
+    type="string"
+    clip_partial="false"
+    follows="left|top"
+    layout="topleft"
+    left="13"
+    name="no_outfits_txt"
+    top="0"
+    height="32"
+    valign="center"
+    parse_urls="true"
+    wrap="true">
+    Searching...
+  </text> 
   <scroll_container
    border="true"
    bevel_style="none"
@@ -66,8 +86,8 @@
          <outfit_gallery_item layout="topleft" left="10" name="preview_outfit2" height="175" width="150" follows="left|top"/>
        </layout_panel>
      </layout_stack-->
-    <!--</panel>-->
-  </scroll_container>
+    <!--</panel>-->  
+  </scroll_container> 
   <panel
      background_visible="true"
 	 follows="bottom|left|right"
-- 
cgit v1.2.3


From 9f789ddfbad656b0a6e1f59b592795ad22bdd061 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 2 Jun 2016 20:23:46 +0300
Subject: MAINT-5194 Visual Outfit browser Made refactoring of
 LLFloaterOutfitSnapshot and LLFloaterSnapshot

---
 indra/newview/CMakeLists.txt               |    1 +
 indra/newview/llappviewer.cpp              |    3 +-
 indra/newview/llfloaterfacebook.cpp        | 1072 ++++++++++++++--------------
 indra/newview/llfloaterflickr.cpp          |    4 +-
 indra/newview/llfloateroutfitsnapshot.cpp  | 1051 +++++----------------------
 indra/newview/llfloateroutfitsnapshot.h    |  108 +--
 indra/newview/llfloatersnapshot.cpp        |  689 +++++++-----------
 indra/newview/llfloatersnapshot.h          |  175 +++--
 indra/newview/llfloatertwitter.cpp         |    4 +-
 indra/newview/lloutfitgallery.cpp          |    8 +-
 indra/newview/llpanelsnapshot.cpp          |   16 +-
 indra/newview/llpanelsnapshot.h            |   20 +-
 indra/newview/llpanelsnapshotinventory.cpp |   42 +-
 indra/newview/llpanelsnapshotlocal.cpp     |   30 +-
 indra/newview/llpanelsnapshotoptions.cpp   |    5 +-
 indra/newview/llpanelsnapshotpostcard.cpp  |   20 +-
 indra/newview/llpanelsnapshotprofile.cpp   |    6 +-
 indra/newview/llsnapshotlivepreview.cpp    |   38 +-
 indra/newview/llsnapshotlivepreview.h      |   18 +-
 indra/newview/llsnapshotmodel.h            |   55 ++
 indra/newview/llviewerassetupload.cpp      |    9 +-
 indra/newview/llviewermenufile.cpp         |   24 +-
 indra/newview/llviewerwindow.cpp           |   10 +-
 indra/newview/llviewerwindow.h             |   13 +-
 indra/newview/llviewerwindowlistener.cpp   |    6 +-
 25 files changed, 1384 insertions(+), 2043 deletions(-)
 create mode 100644 indra/newview/llsnapshotmodel.h

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index de0dff61bb..5d7ab0c985 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1144,6 +1144,7 @@ set(viewer_HEADER_FILES
     llsky.h
     llslurl.h
     llsnapshotlivepreview.h
+    llsnapshotmodel.h
     llspatialpartition.h
     llspeakers.h
     llspeakingindicatormanager.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 86cf1cecf3..a92ad4e41d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1448,8 +1448,7 @@ bool LLAppViewer::mainLoop()
 					display();
 					pingMainloopTimeout("Main:Snapshot");
 					LLFloaterSnapshot::update(); // take snapshots
-                    //TODO: Make one call by moving LLFloaterOutfitSnapshot::update() to LLFloaterSnapshotBase class
-                    LLFloaterOutfitSnapshot::update();
+					LLFloaterOutfitSnapshot::update();
 					gGLActive = FALSE;
 				}
 			}
diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp
index ff6e342d62..b1d6d8be82 100644
--- a/indra/newview/llfloaterfacebook.cpp
+++ b/indra/newview/llfloaterfacebook.cpp
@@ -87,7 +87,7 @@ S32 compute_jpeg_quality(S32 width, S32 height)
 {
     F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE);
     S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio));
-    return llclamp(quality,MIN_QUALITY,MAX_QUALITY);
+    return llclamp(quality, MIN_QUALITY, MAX_QUALITY);
 }
 
 ///////////////////////////
@@ -95,52 +95,52 @@ S32 compute_jpeg_quality(S32 width, S32 height)
 ///////////////////////////
 
 LLFacebookStatusPanel::LLFacebookStatusPanel() :
-	mMessageTextEditor(NULL),
-	mPostButton(NULL),
+    mMessageTextEditor(NULL),
+    mPostButton(NULL),
     mCancelButton(NULL),
-	mAccountCaptionLabel(NULL),
-	mAccountNameLabel(NULL),
-	mPanelButtons(NULL),
-	mConnectButton(NULL),
-	mDisconnectButton(NULL)
+    mAccountCaptionLabel(NULL),
+    mAccountNameLabel(NULL),
+    mPanelButtons(NULL),
+    mConnectButton(NULL),
+    mDisconnectButton(NULL)
 {
-	mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this));
-	mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this));
+    mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this));
+    mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this));
 
-	setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2));
+    setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2));
 
-	mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this));
+    mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this));
 }
 
 BOOL LLFacebookStatusPanel::postBuild()
 {
-	mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
-	mAccountNameLabel = getChild<LLTextBox>("account_name_label");
-	mPanelButtons = getChild<LLUICtrl>("panel_buttons");
-	mConnectButton = getChild<LLUICtrl>("connect_btn");
-	mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
+    mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
+    mAccountNameLabel = getChild<LLTextBox>("account_name_label");
+    mPanelButtons = getChild<LLUICtrl>("panel_buttons");
+    mConnectButton = getChild<LLUICtrl>("connect_btn");
+    mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
 
-	mMessageTextEditor = getChild<LLUICtrl>("status_message");
-	mPostButton = getChild<LLUICtrl>("post_status_btn");
-	mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
+    mMessageTextEditor = getChild<LLUICtrl>("status_message");
+    mPostButton = getChild<LLUICtrl>("post_status_btn");
+    mCancelButton = getChild<LLUICtrl>("cancel_status_btn");
 
-	return LLPanel::postBuild();
+    return LLPanel::postBuild();
 }
 
 void LLFacebookStatusPanel::draw()
 {
-	LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
+    LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
 
-	//Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
-	bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
-	mDisconnectButton->setEnabled(!disconnecting);
+    //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
+    bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING;
+    mDisconnectButton->setEnabled(!disconnecting);
 
-	//Disable the 'connect' button when a connection is in progress
-	bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
-	mConnectButton->setEnabled(!connecting);
+    //Disable the 'connect' button when a connection is in progress
+    bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS;
+    mConnectButton->setEnabled(!connecting);
 
     if (mMessageTextEditor && mPostButton && mCancelButton)
-	{
+    {
         bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
         std::string message = mMessageTextEditor->getValue().asString();
         mMessageTextEditor->setEnabled(no_ongoing_connection);
@@ -148,175 +148,175 @@ void LLFacebookStatusPanel::draw()
         mPostButton->setEnabled(no_ongoing_connection && !message.empty());
     }
 
-	LLPanel::draw();
+    LLPanel::draw();
 }
 
 void LLFacebookStatusPanel::onSend()
 {
-	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening
-	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1));
-	
-	// Connect to Facebook if necessary and then post
-	if (LLFacebookConnect::instance().isConnected())
-	{
-		sendStatus();
-	}
-	else
-	{
-		LLFacebookConnect::instance().checkConnectionToFacebook(true);
-	}
+    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening
+    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1));
+
+    // Connect to Facebook if necessary and then post
+    if (LLFacebookConnect::instance().isConnected())
+    {
+        sendStatus();
+    }
+    else
+    {
+        LLFacebookConnect::instance().checkConnectionToFacebook(true);
+    }
 }
 
 bool LLFacebookStatusPanel::onFacebookConnectStateChange(const LLSD& data)
 {
-	switch (data.get("enum").asInteger())
-	{
-		case LLFacebookConnect::FB_CONNECTED:
-			sendStatus();
-			break;
-
-		case LLFacebookConnect::FB_POSTED:
-			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel");
-			clearAndClose();
-			break;
-	}
-
-	return false;
+    switch (data.get("enum").asInteger())
+    {
+    case LLFacebookConnect::FB_CONNECTED:
+        sendStatus();
+        break;
+
+    case LLFacebookConnect::FB_POSTED:
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel");
+        clearAndClose();
+        break;
+    }
+
+    return false;
 }
 
 bool LLFacebookStatusPanel::onFacebookConnectAccountStateChange(const LLSD& data)
 {
-	if(LLFacebookConnect::instance().isConnected())
-	{
-		//In process of disconnecting so leave the layout as is
-		if(data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
-		{
-			showConnectedLayout();
-		}
-	}
-	else
-	{
-		showDisconnectedLayout();
-	}
-
-	return false;
+    if (LLFacebookConnect::instance().isConnected())
+    {
+        //In process of disconnecting so leave the layout as is
+        if (data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING)
+        {
+            showConnectedLayout();
+        }
+    }
+    else
+    {
+        showDisconnectedLayout();
+    }
+
+    return false;
 }
 
 void LLFacebookStatusPanel::sendStatus()
 {
-	std::string message = mMessageTextEditor->getValue().asString();
-	if (!message.empty())
-	{
-		LLFacebookConnect::instance().updateStatus(message);
-	}
+    std::string message = mMessageTextEditor->getValue().asString();
+    if (!message.empty())
+    {
+        LLFacebookConnect::instance().updateStatus(message);
+    }
 }
 
 void LLFacebookStatusPanel::onVisibilityChange(BOOL visible)
 {
-	if(visible)
-	{
-		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
-		LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1));
-
-		LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
-		LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this));
-
-		//Connected
-		if(LLFacebookConnect::instance().isConnected())
-		{
-			showConnectedLayout();
-		}
-		//Check if connected (show disconnected layout in meantime)
-		else
-		{
-			showDisconnectedLayout();
-		}
+    if (visible)
+    {
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
+        LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1));
+
+        LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
+        LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this));
+
+        //Connected
+        if (LLFacebookConnect::instance().isConnected())
+        {
+            showConnectedLayout();
+        }
+        //Check if connected (show disconnected layout in meantime)
+        else
+        {
+            showDisconnectedLayout();
+        }
         if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
             (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
         {
             LLFacebookConnect::instance().checkConnectionToFacebook();
         }
-	}
-	else
-	{
-		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
-		LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
-	}
+    }
+    else
+    {
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel");
+        LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel");
+    }
 }
 
 bool LLFacebookStatusPanel::onFacebookConnectInfoChange()
 {
-	LLSD info = LLFacebookConnect::instance().getInfo();
-	std::string clickable_name;
+    LLSD info = LLFacebookConnect::instance().getInfo();
+    std::string clickable_name;
 
-	//Strings of format [http://www.somewebsite.com Click Me] become clickable text
-	if(info.has("link") && info.has("name"))
-	{
-		clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
-	}
+    //Strings of format [http://www.somewebsite.com Click Me] become clickable text
+    if (info.has("link") && info.has("name"))
+    {
+        clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
+    }
 
-	mAccountNameLabel->setText(clickable_name);
+    mAccountNameLabel->setText(clickable_name);
 
-	return false;
+    return false;
 }
 
 void LLFacebookStatusPanel::showConnectButton()
 {
-	if(!mConnectButton->getVisible())
-	{
-		mConnectButton->setVisible(TRUE);
-		mDisconnectButton->setVisible(FALSE);
-	}
+    if (!mConnectButton->getVisible())
+    {
+        mConnectButton->setVisible(TRUE);
+        mDisconnectButton->setVisible(FALSE);
+    }
 }
 
 void LLFacebookStatusPanel::hideConnectButton()
 {
-	if(mConnectButton->getVisible())
-	{
-		mConnectButton->setVisible(FALSE);
-		mDisconnectButton->setVisible(TRUE);
-	}
+    if (mConnectButton->getVisible())
+    {
+        mConnectButton->setVisible(FALSE);
+        mDisconnectButton->setVisible(TRUE);
+    }
 }
 
 void LLFacebookStatusPanel::showDisconnectedLayout()
 {
-	mAccountCaptionLabel->setText(getString("facebook_disconnected"));
-	mAccountNameLabel->setText(std::string(""));
-	showConnectButton();
+    mAccountCaptionLabel->setText(getString("facebook_disconnected"));
+    mAccountNameLabel->setText(std::string(""));
+    showConnectButton();
 }
 
 void LLFacebookStatusPanel::showConnectedLayout()
 {
-	LLFacebookConnect::instance().loadFacebookInfo();
+    LLFacebookConnect::instance().loadFacebookInfo();
 
-	mAccountCaptionLabel->setText(getString("facebook_connected"));
-	hideConnectButton();
+    mAccountCaptionLabel->setText(getString("facebook_connected"));
+    hideConnectButton();
 }
 
 void LLFacebookStatusPanel::onConnect()
 {
-	LLFacebookConnect::instance().checkConnectionToFacebook(true);
+    LLFacebookConnect::instance().checkConnectionToFacebook(true);
 
-	//Clear only the facebook browser cookies so that the facebook login screen appears
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); 
+    //Clear only the facebook browser cookies so that the facebook login screen appears
+    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
 }
 
 void LLFacebookStatusPanel::onDisconnect()
 {
-	LLFacebookConnect::instance().disconnectFromFacebook();
+    LLFacebookConnect::instance().disconnectFromFacebook();
 
-	LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com"); 
+    LLViewerMedia::getCookieStore()->removeCookiesByDomain(".facebook.com");
 }
 
 void LLFacebookStatusPanel::clearAndClose()
 {
-	mMessageTextEditor->setValue("");
+    mMessageTextEditor->setValue("");
 
-	LLFloater* floater = getParentByType<LLFloater>();
-	if (floater)
-	{
-		floater->closeFloater();
-	}
+    LLFloater* floater = getParentByType<LLFloater>();
+    if (floater)
+    {
+        floater->closeFloater();
+    }
 }
 
 ///////////////////////////
@@ -324,89 +324,89 @@ void LLFacebookStatusPanel::clearAndClose()
 ///////////////////////////
 
 LLFacebookPhotoPanel::LLFacebookPhotoPanel() :
-mResolutionComboBox(NULL),
-mRefreshBtn(NULL),
-mBtnPreview(NULL),
-mWorkingLabel(NULL),
-mThumbnailPlaceholder(NULL),
-mCaptionTextBox(NULL),
-mPostButton(NULL),
-mBigPreviewFloater(NULL),
-mQuality(MAX_QUALITY)
+    mResolutionComboBox(NULL),
+    mRefreshBtn(NULL),
+    mBtnPreview(NULL),
+    mWorkingLabel(NULL),
+    mThumbnailPlaceholder(NULL),
+    mCaptionTextBox(NULL),
+    mPostButton(NULL),
+    mBigPreviewFloater(NULL),
+    mQuality(MAX_QUALITY)
 {
-	mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this));
-	mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this));
-	mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this));
+    mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this));
+    mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this));
+    mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this));
 }
 
 LLFacebookPhotoPanel::~LLFacebookPhotoPanel()
 {
-	if(mPreviewHandle.get())
-	{
-		mPreviewHandle.get()->die();
-	}
+    if (mPreviewHandle.get())
+    {
+        mPreviewHandle.get()->die();
+    }
 }
 
 BOOL LLFacebookPhotoPanel::postBuild()
 {
-	setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2));
-	
-	mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
-	mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw!
-	mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
-	mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
-	mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
-	mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
-	mBtnPreview = getChild<LLButton>("big_preview_btn");
+    setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2));
+
+    mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
+    mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw!
+    mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
+    mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
+    mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE));
+    mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
+    mBtnPreview = getChild<LLButton>("big_preview_btn");
     mWorkingLabel = getChild<LLUICtrl>("working_lbl");
-	mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
-	mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
-	mPostButton = getChild<LLUICtrl>("post_photo_btn");
-	mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
-	mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
+    mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+    mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
+    mPostButton = getChild<LLUICtrl>("post_photo_btn");
+    mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
+    mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
 
-	// Update filter list
+    // Update filter list
     std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
-	LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
+    LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
     for (U32 i = 0; i < filter_list.size(); i++)
-	{
+    {
         filterbox->add(filter_list[i]);
     }
 
-	return LLPanel::postBuild();
+    return LLPanel::postBuild();
 }
 
 // virtual
 S32 LLFacebookPhotoPanel::notify(const LLSD& info)
 {
-	if (info.has("snapshot-updating"))
-	{
+    if (info.has("snapshot-updating"))
+    {
         // Disable the Post button and whatever else while the snapshot is not updated
         // updateControls();
-		return 1;
-	}
-    
-	if (info.has("snapshot-updated"))
-	{
+        return 1;
+    }
+
+    if (info.has("snapshot-updated"))
+    {
         // Enable the send/post/save buttons.
         updateControls();
-        
-		// The refresh button is initially hidden. We show it after the first update,
-		// i.e. after snapshot is taken
-		LLUICtrl * refresh_button = getRefreshBtn();
-		if (!refresh_button->getVisible())
-		{
-			refresh_button->setVisible(true);
-		}
-		return 1;
-	}
-    
-	return 0;
+
+        // The refresh button is initially hidden. We show it after the first update,
+        // i.e. after snapshot is taken
+        LLUICtrl * refresh_button = getRefreshBtn();
+        if (!refresh_button->getVisible())
+        {
+            refresh_button->setVisible(true);
+        }
+        return 1;
+    }
+
+    return 0;
 }
 
 void LLFacebookPhotoPanel::draw()
-{ 
-	LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+{
+    LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
 
     // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
     bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing());
@@ -416,98 +416,98 @@ void LLFacebookPhotoPanel::draw()
     mFilterComboBox->setEnabled(no_ongoing_connection);
     mRefreshBtn->setEnabled(no_ongoing_connection);
     mBtnPreview->setEnabled(no_ongoing_connection);
-	
+
     // Reassign the preview floater if we have the focus and the preview exists
     if (hasFocus() && isPreviewVisible())
     {
         attachPreview();
     }
-    
+
     // Toggle the button state as appropriate
     bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
-	mBtnPreview->setToggleState(preview_active);
-    
+    mBtnPreview->setToggleState(preview_active);
+
     // Display the thumbnail if one is available
-	if (previewp && previewp->getThumbnailImage())
-	{
-		const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
-		const S32 thumbnail_w = previewp->getThumbnailWidth();
-		const S32 thumbnail_h = previewp->getThumbnailHeight();
-
-		// calc preview offset within the preview rect
-		const S32 local_offset_x = (thumbnail_rect.getWidth()  - thumbnail_w) / 2 ;
-		const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
-		S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
-		S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
-		gGL.matrixMode(LLRender::MM_MODELVIEW);
-		// Apply floater transparency to the texture unless the floater is focused.
-		F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-		LLColor4 color = LLColor4::white;
-		gl_draw_scaled_image(offset_x, offset_y, 
-			thumbnail_w, thumbnail_h,
-			previewp->getThumbnailImage(), color % alpha);
-	}
+    if (previewp && previewp->getThumbnailImage())
+    {
+        const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
+        const S32 thumbnail_w = previewp->getThumbnailWidth();
+        const S32 thumbnail_h = previewp->getThumbnailHeight();
+
+        // calc preview offset within the preview rect
+        const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2;
+        const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2;
+        S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
+        S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
+
+        gGL.matrixMode(LLRender::MM_MODELVIEW);
+        // Apply floater transparency to the texture unless the floater is focused.
+        F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+        LLColor4 color = LLColor4::white;
+        gl_draw_scaled_image(offset_x, offset_y,
+            thumbnail_w, thumbnail_h,
+            previewp->getThumbnailImage(), color % alpha);
+    }
 
     // Update the visibility of the working (computing preview) label
     mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-    
+
     // Enable Post if we have a preview to send and no on going connection being processed
     mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
-    
+
     // Draw the rest of the panel on top of it
-	LLPanel::draw();
+    LLPanel::draw();
 }
 
 LLSnapshotLivePreview* LLFacebookPhotoPanel::getPreviewView()
 {
-	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
-	return previewp;
+    LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
+    return previewp;
 }
 
 void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible)
 {
-	if (visible)
-	{
-		if (mPreviewHandle.get())
-		{
-			LLSnapshotLivePreview* preview = getPreviewView();
-			if(preview)
-			{
-				LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
-				preview->updateSnapshot(TRUE);
-			}
-		}
-		else
-		{
-			LLRect full_screen_rect = getRootView()->getRect();
-			LLSnapshotLivePreview::Params p;
-			p.rect(full_screen_rect);
-			LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
-			mPreviewHandle = previewp->getHandle();	
+    if (visible)
+    {
+        if (mPreviewHandle.get())
+        {
+            LLSnapshotLivePreview* preview = getPreviewView();
+            if (preview)
+            {
+                LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
+                preview->updateSnapshot(TRUE);
+            }
+        }
+        else
+        {
+            LLRect full_screen_rect = getRootView()->getRect();
+            LLSnapshotLivePreview::Params p;
+            p.rect(full_screen_rect);
+            LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+            mPreviewHandle = previewp->getHandle();
             mQuality = MAX_QUALITY;
 
             previewp->setContainer(this);
-            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
-			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
-			previewp->setSnapshotQuality(mQuality, false);
+            previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
+            previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
+            previewp->setSnapshotQuality(mQuality, false);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
             previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
             previewp->setAllowFullScreenPreview(FALSE);  // No full screen preview in SL Share mode
-			previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
+            previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
 
-			updateControls();
-		}
-	}
+            updateControls();
+        }
+    }
 }
 
 void LLFacebookPhotoPanel::onClickNewSnapshot()
 {
-	LLSnapshotLivePreview* previewp = getPreviewView();
-	if (previewp)
-	{
-		previewp->updateSnapshot(TRUE);
-	}
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    if (previewp)
+    {
+        previewp->updateSnapshot(TRUE);
+    }
 }
 
 void LLFacebookPhotoPanel::onClickBigPreview()
@@ -541,167 +541,167 @@ void LLFacebookPhotoPanel::attachPreview()
 
 void LLFacebookPhotoPanel::onSend()
 {
-	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening
-	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1));
-	
-	// Connect to Facebook if necessary and then post
-	if (LLFacebookConnect::instance().isConnected())
-	{
-		sendPhoto();
-	}
-	else
-	{
-		LLFacebookConnect::instance().checkConnectionToFacebook(true);
-	}
+    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening
+    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1));
+
+    // Connect to Facebook if necessary and then post
+    if (LLFacebookConnect::instance().isConnected())
+    {
+        sendPhoto();
+    }
+    else
+    {
+        LLFacebookConnect::instance().checkConnectionToFacebook(true);
+    }
 }
 
 bool LLFacebookPhotoPanel::onFacebookConnectStateChange(const LLSD& data)
 {
-	switch (data.get("enum").asInteger())
-	{
-		case LLFacebookConnect::FB_CONNECTED:
-			sendPhoto();
-			break;
-
-		case LLFacebookConnect::FB_POSTED:
-			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel");
-			clearAndClose();
-			break;
-	}
-
-	return false;
+    switch (data.get("enum").asInteger())
+    {
+    case LLFacebookConnect::FB_CONNECTED:
+        sendPhoto();
+        break;
+
+    case LLFacebookConnect::FB_POSTED:
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel");
+        clearAndClose();
+        break;
+    }
+
+    return false;
 }
 
 void LLFacebookPhotoPanel::sendPhoto()
 {
-	// Get the caption
-	std::string caption = mCaptionTextBox->getValue().asString();
+    // Get the caption
+    std::string caption = mCaptionTextBox->getValue().asString();
 
-	// Get the image
-	LLSnapshotLivePreview* previewp = getPreviewView();
-	
-	// Post to Facebook
-	LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
+    // Get the image
+    LLSnapshotLivePreview* previewp = getPreviewView();
 
-	updateControls();
+    // Post to Facebook
+    LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption);
+
+    updateControls();
 }
 
 void LLFacebookPhotoPanel::clearAndClose()
 {
-	mCaptionTextBox->setValue("");
+    mCaptionTextBox->setValue("");
 
-	LLFloater* floater = getParentByType<LLFloater>();
-	if (floater)
-	{
-		floater->closeFloater();
+    LLFloater* floater = getParentByType<LLFloater>();
+    if (floater)
+    {
+        floater->closeFloater();
         if (mBigPreviewFloater)
         {
             mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
         }
-	}
+    }
 }
 
 void LLFacebookPhotoPanel::updateControls()
 {
-	LLSnapshotLivePreview* previewp = getPreviewView();
-	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-    
-	// *TODO: Separate maximum size for Web images from postcards
-	LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-    
-	updateResolution(FALSE);
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
+
+    // *TODO: Separate maximum size for Web images from postcards
+    LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
+
+    updateResolution(FALSE);
 }
 
 void LLFacebookPhotoPanel::updateResolution(BOOL do_update)
 {
-	LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
-	LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
+    LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
+    LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
 
-	std::string sdstring = combobox->getSelectedValue();
-	LLSD sdres;
-	std::stringstream sstream(sdstring);
-	LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
+    std::string sdstring = combobox->getSelectedValue();
+    LLSD sdres;
+    std::stringstream sstream(sdstring);
+    LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
 
-	S32 width = sdres[0];
-	S32 height = sdres[1];
+    S32 width = sdres[0];
+    S32 height = sdres[1];
 
     // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
     std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
 
-	LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-	if (previewp && combobox->getCurrentIndex() >= 0)
-	{
-		S32 original_width = 0 , original_height = 0 ;
-		previewp->getSize(original_width, original_height) ;
-
-		if (width == 0 || height == 0)
-		{
-			// take resolution from current window size
-			LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
-			previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
-		}
-		else
-		{
-			// use the resolution from the selected pre-canned drop-down choice
-			LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
-			previewp->setSize(width, height);
-		}
-
-		checkAspectRatio(width);
-
-		previewp->getSize(width, height);
-        
+    LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
+    if (previewp && combobox->getCurrentIndex() >= 0)
+    {
+        S32 original_width = 0, original_height = 0;
+        previewp->getSize(original_width, original_height);
+
+        if (width == 0 || height == 0)
+        {
+            // take resolution from current window size
+            LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
+            previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
+        }
+        else
+        {
+            // use the resolution from the selected pre-canned drop-down choice
+            LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
+            previewp->setSize(width, height);
+        }
+
+        checkAspectRatio(width);
+
+        previewp->getSize(width, height);
+
         // Recompute quality setting
         mQuality = compute_jpeg_quality(width, height);
         previewp->setSnapshotQuality(mQuality, false);
-		
-		if (original_width != width || original_height != height)
-		{
-			previewp->setSize(width, height);
-			if (do_update)
-			{
+
+        if (original_width != width || original_height != height)
+        {
+            previewp->setSize(width, height);
+            if (do_update)
+            {
                 previewp->updateSnapshot(TRUE);
-				updateControls();
-			}
-		}
+                updateControls();
+            }
+        }
         // Get the old filter, compare to the current one "filter_name" and set if changed
         std::string original_filter = previewp->getFilter();
-		if (original_filter != filter_name)
-		{
+        if (original_filter != filter_name)
+        {
             previewp->setFilter(filter_name);
-			if (do_update)
-			{
+            if (do_update)
+            {
                 previewp->updateSnapshot(FALSE, TRUE);
-				updateControls();
-			}
-		}
-	}
+                updateControls();
+            }
+        }
+    }
 }
 
 void LLFacebookPhotoPanel::checkAspectRatio(S32 index)
 {
-	LLSnapshotLivePreview *previewp = getPreviewView() ;
-
-	BOOL keep_aspect = FALSE;
-
-	if (0 == index) // current window size
-	{
-		keep_aspect = TRUE;
-	}
-	else // predefined resolution
-	{
-		keep_aspect = FALSE;
-	}
-
-	if (previewp)
-	{
-		previewp->mKeepAspectRatio = keep_aspect;
-	}
+    LLSnapshotLivePreview *previewp = getPreviewView();
+
+    BOOL keep_aspect = FALSE;
+
+    if (0 == index) // current window size
+    {
+        keep_aspect = TRUE;
+    }
+    else // predefined resolution
+    {
+        keep_aspect = FALSE;
+    }
+
+    if (previewp)
+    {
+        previewp->mKeepAspectRatio = keep_aspect;
+    }
 }
 
 LLUICtrl* LLFacebookPhotoPanel::getRefreshBtn()
 {
-	return mRefreshBtn;
+    return mRefreshBtn;
 }
 
 ////////////////////////
@@ -712,21 +712,21 @@ LLFacebookCheckinPanel::LLFacebookCheckinPanel() :
     mMapUrl(""),
     mReloadingMapTexture(false)
 {
-	mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this));
+    mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this));
 }
 
 BOOL LLFacebookCheckinPanel::postBuild()
 {
     // Keep pointers to widgets so we don't traverse the UI hierarchy too often
-	mPostButton = getChild<LLUICtrl>("post_place_btn");
-	mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
-	mMessageTextEditor = getChild<LLUICtrl>("place_caption");
+    mPostButton = getChild<LLUICtrl>("post_place_btn");
+    mCancelButton = getChild<LLUICtrl>("cancel_place_btn");
+    mMessageTextEditor = getChild<LLUICtrl>("place_caption");
     mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator");
     mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder");
     mMapDefault = getChild<LLIconCtrl>("map_default");
     mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb");
-    
-	return LLPanel::postBuild();
+
+    return LLPanel::postBuild();
 }
 
 void LLFacebookCheckinPanel::draw()
@@ -767,101 +767,101 @@ void LLFacebookCheckinPanel::draw()
     // This will hide/show the loading indicator and/or tile underneath
     mMapDefault->setVisible(!(mMapCheckBox->get()));
 
-	LLPanel::draw();
+    LLPanel::draw();
 }
 
 void LLFacebookCheckinPanel::onSend()
 {
-	LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening
-	LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1));
-	
-	// Connect to Facebook if necessary and then post
-	if (LLFacebookConnect::instance().isConnected())
-	{
-		sendCheckin();
-	}
-	else
-	{
-		LLFacebookConnect::instance().checkConnectionToFacebook(true);
-	}
+    LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening
+    LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1));
+
+    // Connect to Facebook if necessary and then post
+    if (LLFacebookConnect::instance().isConnected())
+    {
+        sendCheckin();
+    }
+    else
+    {
+        LLFacebookConnect::instance().checkConnectionToFacebook(true);
+    }
 }
 
 bool LLFacebookCheckinPanel::onFacebookConnectStateChange(const LLSD& data)
 {
-	switch (data.get("enum").asInteger())
-	{
-		case LLFacebookConnect::FB_CONNECTED:
-			sendCheckin();
-			break;
-
-		case LLFacebookConnect::FB_POSTED:
-			LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel");
-			clearAndClose();
-			break;
-	}
-
-	return false;
+    switch (data.get("enum").asInteger())
+    {
+    case LLFacebookConnect::FB_CONNECTED:
+        sendCheckin();
+        break;
+
+    case LLFacebookConnect::FB_POSTED:
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel");
+        clearAndClose();
+        break;
+    }
+
+    return false;
 }
 
 void LLFacebookCheckinPanel::sendCheckin()
 {
-	// Get the location SLURL
-	LLSLURL slurl;
-	LLAgentUI::buildSLURL(slurl);
-	std::string slurl_string = slurl.getSLURLString();
-
-	// Use a valid http:// URL if the scheme is secondlife:// 
-	LLURI slurl_uri(slurl_string);
-	if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
-	{
-		slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
-	}
-
-	// Add query parameters so Google Analytics can track incoming clicks!
-	slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
-    
-	// Get the region name
-	std::string region_name("");
+    // Get the location SLURL
+    LLSLURL slurl;
+    LLAgentUI::buildSLURL(slurl);
+    std::string slurl_string = slurl.getSLURLString();
+
+    // Use a valid http:// URL if the scheme is secondlife:// 
+    LLURI slurl_uri(slurl_string);
+    if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
+    {
+        slurl_string = DEFAULT_CHECKIN_LOCATION_URL;
+    }
+
+    // Add query parameters so Google Analytics can track incoming clicks!
+    slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS;
+
+    // Get the region name
+    std::string region_name("");
     LLViewerRegion *regionp = gAgent.getRegion();
     if (regionp)
     {
         region_name = regionp->getName();
     }
-    
-	// Get the region description
-	std::string description;
-	LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
-    
-	// Optionally add the region map view
-	bool add_map_view = mMapCheckBox->getValue().asBoolean();
+
+    // Get the region description
+    std::string description;
+    LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent());
+
+    // Optionally add the region map view
+    bool add_map_view = mMapCheckBox->getValue().asBoolean();
     std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL);
-    
-	// Get the caption
-	std::string caption = mMessageTextEditor->getValue().asString();
 
-	// Post to Facebook
-	LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
+    // Get the caption
+    std::string caption = mMessageTextEditor->getValue().asString();
+
+    // Post to Facebook
+    LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption);
 }
 
 void LLFacebookCheckinPanel::clearAndClose()
 {
-	mMessageTextEditor->setValue("");
+    mMessageTextEditor->setValue("");
 
-	LLFloater* floater = getParentByType<LLFloater>();
-	if (floater)
-	{
-		floater->closeFloater();
-	}
+    LLFloater* floater = getParentByType<LLFloater>();
+    if (floater)
+    {
+        floater->closeFloater();
+    }
 }
 
 ///////////////////////////
 //LLFacebookFriendsPanel//////
 ///////////////////////////
 
-LLFacebookFriendsPanel::LLFacebookFriendsPanel() : 
-mFriendsStatusCaption(NULL),
-mSecondLifeFriends(NULL),
-mSuggestedFriends(NULL)
+LLFacebookFriendsPanel::LLFacebookFriendsPanel() :
+    mFriendsStatusCaption(NULL),
+    mSecondLifeFriends(NULL),
+    mSuggestedFriends(NULL)
 {
 }
 
@@ -872,55 +872,55 @@ LLFacebookFriendsPanel::~LLFacebookFriendsPanel()
 
 BOOL LLFacebookFriendsPanel::postBuild()
 {
-	mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status");
+    mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status");
+
+    mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends");
+    mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
 
-	mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends");
-	mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
-	
-	mSuggestedFriends = getChild<LLAvatarList>("suggested_friends");
-	mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
-	
-	setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2));
+    mSuggestedFriends = getChild<LLAvatarList>("suggested_friends");
+    mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu);
+
+    setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2));
 
     LLAvatarTracker::instance().addObserver(this);
-    
-	return LLPanel::postBuild();
+
+    return LLPanel::postBuild();
 }
 
 bool LLFacebookFriendsPanel::updateSuggestedFriendList()
 {
-	const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
-	uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs();
-	second_life_friends.clear();
-	uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
-	suggested_friends.clear();
-
-	//Add suggested friends
-	LLSD friends = LLFacebookConnect::instance().getContent();
-	for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
-	{
-		LLUUID agent_id = (*i).asUUID();
-		if (agent_id.notNull())
-		{
-			bool second_life_buddy = av_tracker.isBuddy(agent_id);
-			if (second_life_buddy)
-			{
-				second_life_friends.push_back(agent_id);
-			}
-			else
-			{
-				//FB+SL but not SL friend
-				suggested_friends.push_back(agent_id);
-			}
-		}
-	}
-
-	//Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
-	mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches());
-	mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
-	showFriendsAccordionsIfNeeded();
-
-	return false;
+    const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+    uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs();
+    second_life_friends.clear();
+    uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs();
+    suggested_friends.clear();
+
+    //Add suggested friends
+    LLSD friends = LLFacebookConnect::instance().getContent();
+    for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i)
+    {
+        LLUUID agent_id = (*i).asUUID();
+        if (agent_id.notNull())
+        {
+            bool second_life_buddy = av_tracker.isBuddy(agent_id);
+            if (second_life_buddy)
+            {
+                second_life_friends.push_back(agent_id);
+            }
+            else
+            {
+                //FB+SL but not SL friend
+                suggested_friends.push_back(agent_id);
+            }
+        }
+    }
+
+    //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display)
+    mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches());
+    mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches());
+    showFriendsAccordionsIfNeeded();
+
+    return false;
 }
 
 void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded()
@@ -949,15 +949,15 @@ void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded()
     {
         // We have something in the lists, hide the explanatory text
         mFriendsStatusCaption->setVisible(false);
-        
+
         // Show the lists
         LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
         accordion->setVisible(true);
-        
+
         // Expand and show accordions if needed, else - hide them
         getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(mSecondLifeFriends->filterHasMatches());
         getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(mSuggestedFriends->filterHasMatches());
-        
+
         // Rearrange accordions
         accordion->arrange();
     }
@@ -965,56 +965,56 @@ void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded()
 
 void LLFacebookFriendsPanel::changed(U32 mask)
 {
-	if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
-	{
+    if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+    {
         LLFacebookConnect::instance().loadFacebookFriends();
-		updateFacebookList(true);
-	}
+        updateFacebookList(true);
+    }
 }
 
 
 void LLFacebookFriendsPanel::updateFacebookList(bool visible)
 {
-	if (visible)
-	{
+    if (visible)
+    {
         // We want this to be called to fetch the friends list once a connection is established
-		LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel");
-		LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1));
-        
+        LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel");
+        LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1));
+
         // We then want this to be called to update the displayed lists once the list of friends is received
-		LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening
-		LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this));
-        
-		// Try to connect to Facebook
+        LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening
+        LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this));
+
+        // Try to connect to Facebook
         if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) ||
             (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED))
         {
             LLFacebookConnect::instance().checkConnectionToFacebook();
         }
-		// Loads FB friends
-		if (LLFacebookConnect::instance().isConnected())
-		{
-			LLFacebookConnect::instance().loadFacebookFriends();
-		}
+        // Loads FB friends
+        if (LLFacebookConnect::instance().isConnected())
+        {
+            LLFacebookConnect::instance().loadFacebookFriends();
+        }
         // Sort the FB friends and update the lists
-		updateSuggestedFriendList();
-	}
+        updateSuggestedFriendList();
+    }
 }
 
 bool LLFacebookFriendsPanel::onConnectedToFacebook(const LLSD& data)
 {
-	LLSD::Integer connection_state = data.get("enum").asInteger();
-
-	if (connection_state == LLFacebookConnect::FB_CONNECTED)
-	{
-		LLFacebookConnect::instance().loadFacebookFriends();
-	}
-	else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
-	{
-		updateSuggestedFriendList();
-	}
-
-	return false;
+    LLSD::Integer connection_state = data.get("enum").asInteger();
+
+    if (connection_state == LLFacebookConnect::FB_CONNECTED)
+    {
+        LLFacebookConnect::instance().loadFacebookFriends();
+    }
+    else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED)
+    {
+        updateSuggestedFriendList();
+    }
+
+    return false;
 }
 
 ////////////////////////
@@ -1027,7 +1027,7 @@ LLFloaterFacebook::LLFloaterFacebook(const LLSD& key) : LLFloater(key),
     mStatusLoadingText(NULL),
     mStatusLoadingIndicator(NULL)
 {
-	mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this));
+    mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this));
 }
 
 void LLFloaterFacebook::onClose(bool app_quitting)
@@ -1037,7 +1037,7 @@ void LLFloaterFacebook::onClose(bool app_quitting)
     {
         big_preview_floater->closeOnFloaterOwnerClosing(this);
     }
-	LLFloater::onClose(app_quitting);
+    LLFloater::onClose(app_quitting);
 }
 
 void LLFloaterFacebook::onCancel()
@@ -1053,24 +1053,24 @@ void LLFloaterFacebook::onCancel()
 BOOL LLFloaterFacebook::postBuild()
 {
     // Keep tab of the Photo Panel
-	mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo"));
+    mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo"));
     // Connection status widgets
     mStatusErrorText = getChild<LLTextBox>("connection_error_text");
     mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
     mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
-	return LLFloater::postBuild();
+    return LLFloater::postBuild();
 }
 
 void LLFloaterFacebook::showPhotoPanel()
 {
-	LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent());
-	if (!parent)
-	{
-		LL_WARNS() << "Cannot find panel container" << LL_ENDL;
-		return;
-	}
-
-	parent->selectTabPanel(mFacebookPhotoPanel);
+    LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent());
+    if (!parent)
+    {
+        LL_WARNS() << "Cannot find panel container" << LL_ENDL;
+        return;
+    }
+
+    parent->selectTabPanel(mFacebookPhotoPanel);
 }
 
 void LLFloaterFacebook::draw()
@@ -1082,7 +1082,7 @@ void LLFloaterFacebook::draw()
         mStatusLoadingIndicator->setVisible(false);
         LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState();
         std::string status_text;
-        
+
         switch (connection_state)
         {
         case LLFacebookConnect::FB_NOT_CONNECTED:
@@ -1105,7 +1105,7 @@ void LLFloaterFacebook::draw()
             status_text = LLTrans::getString("SocialFacebookPosting");
             mStatusLoadingText->setValue(status_text);
             mStatusLoadingIndicator->setVisible(true);
-			break;
+            break;
         case LLFacebookConnect::FB_CONNECTION_FAILED:
             // Error connecting to the service
             mStatusErrorText->setVisible(true);
@@ -1118,21 +1118,21 @@ void LLFloaterFacebook::draw()
             status_text = LLTrans::getString("SocialFacebookErrorPosting");
             mStatusErrorText->setValue(status_text);
             break;
-		case LLFacebookConnect::FB_DISCONNECTING:
-			// Disconnecting loading indicator
-			mStatusLoadingText->setVisible(true);
-			status_text = LLTrans::getString("SocialFacebookDisconnecting");
-			mStatusLoadingText->setValue(status_text);
-			mStatusLoadingIndicator->setVisible(true);
-			break;
-		case LLFacebookConnect::FB_DISCONNECT_FAILED:
-			// Error disconnecting from the service
-			mStatusErrorText->setVisible(true);
-			status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
-			mStatusErrorText->setValue(status_text);
-			break;
+        case LLFacebookConnect::FB_DISCONNECTING:
+            // Disconnecting loading indicator
+            mStatusLoadingText->setVisible(true);
+            status_text = LLTrans::getString("SocialFacebookDisconnecting");
+            mStatusLoadingText->setValue(status_text);
+            mStatusLoadingIndicator->setVisible(true);
+            break;
+        case LLFacebookConnect::FB_DISCONNECT_FAILED:
+            // Error disconnecting from the service
+            mStatusErrorText->setVisible(true);
+            status_text = LLTrans::getString("SocialFacebookErrorDisconnecting");
+            mStatusErrorText->setValue(status_text);
+            break;
         }
     }
-	LLFloater::draw();
+    LLFloater::draw();
 }
 
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
index 131df22956..15b7c7fafa 100644
--- a/indra/newview/llfloaterflickr.cpp
+++ b/indra/newview/llfloaterflickr.cpp
@@ -238,8 +238,8 @@ void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible)
 			mPreviewHandle = previewp->getHandle();
 
             previewp->setContainer(this);
-            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
-			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG);
+            previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
+            previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
             previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
             previewp->setAllowFullScreenPreview(FALSE);  // No full screen preview in SL Share mode
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 6d641613ff..4c4e9bcc48 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
 #include "llresmgr.h"		// LLLocale
 #include "llsdserialize.h"
 #include "llsidetraypanelcontainer.h"
-#include "llsnapshotlivepreview.h"
 #include "llspinctrl.h"
 #include "llviewercontrol.h"
 #include "lltoolfocus.h"
@@ -52,7 +51,6 @@
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
-LLUICtrl* LLFloaterOutfitSnapshot::sThumbnailPlaceholder = NULL;
 LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
 
 const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
@@ -62,213 +60,32 @@ const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
 
 static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
 
-
 ///----------------------------------------------------------------------------
-/// Class LLFloaterSnapshot::Impl
+/// Class LLFloaterOutfitSnapshot::Impl
 ///----------------------------------------------------------------------------
 
-
-class LLFloaterOutfitSnapshot::Impl
-{
-	LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
-public:
-	typedef enum e_status
-	{
-		STATUS_READY,
-		STATUS_WORKING,
-		STATUS_FINISHED
-	} EStatus;
-
-	Impl()
-	:	mAvatarPauseHandles(),
-		mLastToolset(NULL),
-		mAspectRatioCheckOff(false),
-		mNeedRefresh(false),
-		mStatus(STATUS_READY)
-	{
-	}
-	~Impl()
-	{
-		//unpause avatars
-		mAvatarPauseHandles.clear();
-
-	}
-	static void onClickNewSnapshot(void* data);
-	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
-	static void onClickFilter(LLUICtrl *ctrl, void* data);
-	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
-	static void onClickUICheck(LLUICtrl *ctrl, void* data);
-	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
-	static void updateResolution(void* data);
-	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
-	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
-	static void onSnapshotUploadFinished(bool status);
-	static void onSendingPostcardFinished(bool status);
-
-	static LLPanelSnapshot* getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found = true);
-    static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterOutfitSnapshot* floater);
-	static LLFloaterOutfitSnapshot::ESnapshotFormat getImageFormat(LLFloaterOutfitSnapshot* floater);
-
-	static LLSnapshotLivePreview* getPreviewView(LLFloaterOutfitSnapshot *floater);
-	static void updateControls(LLFloaterOutfitSnapshot* floater);
-	static void updateLayout(LLFloaterOutfitSnapshot* floater);
-	static void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
-	EStatus getStatus() const { return mStatus; }
-	static void setNeedRefresh(LLFloaterOutfitSnapshot* floater, bool need);
-
-private:
-	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterOutfitSnapshot* floater);
-	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
-	static void setWorking(LLFloaterOutfitSnapshot* floater, bool working);
-	static void setFinished(LLFloaterOutfitSnapshot* floater, bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
-
-
-public:
-	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
-
-	LLToolset*	mLastToolset;
-	LLHandle<LLView> mPreviewHandle;
-	bool mAspectRatioCheckOff ;
-	bool mNeedRefresh;
-	EStatus mStatus;
-};
-
-
-
-// static
-LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterOutfitSnapshot* floater, bool ok_if_not_found)
+// virtual
+LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
 {
     LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
-    //LLPanel* panel = panel_container->getCurrentPanel();
     LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel);
-	if (!ok_if_not_found)
-	{
-		llassert_always(active_panel != NULL);
-	}
-	return active_panel;
-}
-
-// static
-LLPanelSnapshot::ESnapshotType LLFloaterOutfitSnapshot::Impl::getActiveSnapshotType(LLFloaterOutfitSnapshot* floater)
-{
-    return LLPanelSnapshot::SNAPSHOT_TEXTURE;
-}
-
-// static
-LLFloaterOutfitSnapshot::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterOutfitSnapshot* floater)
-{
-    return LLFloaterOutfitSnapshot::SNAPSHOT_FORMAT_PNG;
-}
-
-// static
-LLSnapshotLivePreview* LLFloaterOutfitSnapshot::Impl::getPreviewView(LLFloaterOutfitSnapshot *floater)
-{
-	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get();
-	return previewp;
+    if (!ok_if_not_found)
+    {
+        llassert_always(active_panel != NULL);
+    }
+    return active_panel;
 }
 
-// static
-LLViewerWindow::ESnapshotType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterOutfitSnapshot* floater)
+// virtual
+LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
 {
-    return LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+    return LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
 }
 
-//static 
-void LLFloaterOutfitSnapshot::Impl::updateLayout(LLFloaterOutfitSnapshot* floaterp)
+// virtual
+LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
 {
-	LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
-
-	BOOL advanced = gSavedSettings.getBOOL("AdvanceSnapshot");
-
-	//BD - Automatically calculate the size of our snapshot window to enlarge
-	//     the snapshot preview to its maximum size, this is especially helpfull
-	//     for pretty much every aspect ratio other than 1:1.
-	F32 panel_width = 400.f * gViewerWindow->getWorldViewAspectRatio();
-
-	//BD - Make sure we clamp at 700 here because 700 would be for 16:9 which we
-	//     consider the maximum. Everything bigger will be clamped and will have
-	//     a slightly smaller preview window which most likely won't fill up the
-	//     whole snapshot floater as it should.
-	if(panel_width > 700.f)
-	{
-		panel_width = 700.f;
-	}
-
-	S32 floater_width = 224.f;
-	if(advanced)
-	{
-		floater_width = floater_width + panel_width;
-	}
-
-	LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
-	thumbnail_placeholder->setVisible(advanced);
-	thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
-	floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(advanced);
-	floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(advanced);
-	if(!floaterp->isMinimized())
-	{
-		floaterp->reshape(floater_width, floaterp->getRect().getHeight());
-	}
-
-	bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean();
-
-	if (use_freeze_frame)
-	{
-		// stop all mouse events at fullscreen preview layer
-		floaterp->getParent()->setMouseOpaque(TRUE);
-		
-		// shrink to smaller layout
-		// *TODO: unneeded?
-		floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getRect().getHeight());
-
-		// can see and interact with fullscreen preview now
-		if (previewp)
-		{
-			previewp->setVisible(TRUE);
-			previewp->setEnabled(TRUE);
-		}
-
-		//RN: freeze all avatars
-		LLCharacter* avatarp;
-		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
-			iter != LLCharacter::sInstances.end(); ++iter)
-		{
-			avatarp = *iter;
-			floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
-		}
-
-		// freeze everything else
-		gSavedSettings.setBOOL("FreezeTime", TRUE);
-
-		if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
-		{
-			floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
-			LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
-		}
-	}
-	else // turning off freeze frame mode
-	{
-		floaterp->getParent()->setMouseOpaque(FALSE);
-		// *TODO: unneeded?
-		floaterp->reshape(floaterp->getRect().getWidth(), floaterp->getRect().getHeight());
-		if (previewp)
-		{
-			previewp->setVisible(FALSE);
-			previewp->setEnabled(FALSE);
-		}
-
-		//RN: thaw all avatars
-		floaterp->impl.mAvatarPauseHandles.clear();
-
-		// thaw everything else
-		gSavedSettings.setBOOL("FreezeTime", FALSE);
-
-		// restore last tool (e.g. pie menu, etc)
-		if (floaterp->impl.mLastToolset)
-		{
-			LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset);
-		}
-	}
+    return LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 }
 
 // This is the main function that keeps all the GUI controls in sync with the saved settings.
@@ -277,788 +94,272 @@ void LLFloaterOutfitSnapshot::Impl::updateLayout(LLFloaterOutfitSnapshot* floate
 // The basic pattern for programmatically changing the GUI settings is to first set the
 // appropriate saved settings and then call this method to sync the GUI with them.
 // FIXME: The above comment seems obsolete now.
-// static
-void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterOutfitSnapshot* floater)
-{
-    LLPanelSnapshot::ESnapshotType shot_type = getActiveSnapshotType(floater);
-    LLFloaterSnapshotBase::ESnapshotFormat shot_format = (LLFloaterSnapshotBase::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
-    LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
-		
-	LLSnapshotLivePreview* previewp = getPreviewView(floater);
-	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
-	// *TODO: Separate maximum size for Web images from postcards
-	LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
-	LLLocale locale(LLLocale::USER_LOCALE);
-	std::string bytes_string;
-	if (got_snap)
-	{
-		LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10 );
-	}
-
-	// Update displayed image resolution.
-	LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
-	image_res_tb->setVisible(got_snap);
-	if (got_snap)
-	{
-		image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
-		image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
-	}
-
-	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
-	floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor( "LabelTextColor" ));
-
-	updateResolution(floater);
-
-	if (previewp)
-	{
-		previewp->setSnapshotType(shot_type);
-		previewp->setSnapshotFormat(shot_format);
-		previewp->setSnapshotBufferType(layer_type);
-	}
-
-	LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
-	if (current_panel)
-	{
-		LLSD info;
-		info["have-snapshot"] = got_snap;
-		current_panel->updateControls(info);
-	}
-	LL_DEBUGS() << "finished updating controls" << LL_ENDL;
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
+// virtual
+void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
 {
-	LLFloaterOutfitSnapshot* floater = LLFloaterOutfitSnapshot::getInstance();
-	switch (status)
-	{
-	case STATUS_READY:
-		setWorking(floater, false);
-		setFinished(floater, false);
-		break;
-	case STATUS_WORKING:
-		setWorking(floater, true);
-		setFinished(floater, false);
-		break;
-	case STATUS_FINISHED:
-		setWorking(floater, false);
-		setFinished(floater, true, ok, msg);
-		break;
-	}
-
-	floater->impl.mStatus = status;
-}
+    LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
+    LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
+    LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
 
-// static
-void LLFloaterOutfitSnapshot::Impl::setNeedRefresh(LLFloaterOutfitSnapshot* floater, bool need)
-{
-	if (!floater) return;
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
 
-	// Don't display the "Refresh to save" message if we're in auto-refresh mode.
-	if (gSavedSettings.getBOOL("AutoSnapshot"))
-	{
-		need = false;
-	}
+    // *TODO: Separate maximum size for Web images from postcards
+    LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
 
-	floater->mRefreshLabel->setVisible(need);
-	floater->impl.mNeedRefresh = need;
-}
+    LLLocale locale(LLLocale::USER_LOCALE);
+    std::string bytes_string;
+    if (got_snap)
+    {
+        LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10);
+    }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
-{
-	if (previewp)
-	{
-		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
-		LL_DEBUGS() << "updating " << (autosnap ? "snapshot" : "thumbnail") << LL_ENDL;
-		previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
-	}
-}
+    // Update displayed image resolution.
+    LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text");
+    image_res_tb->setVisible(got_snap);
+    if (got_snap)
+    {
+        image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth()));
+        image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight()));
+    }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onClickNewSnapshot(void* data)
-{
-	LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterOutfitSnapshot *)data);
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-	if (previewp && view)
-	{
-		view->impl.setStatus(Impl::STATUS_READY);
-		LL_DEBUGS() << "updating snapshot" << LL_ENDL;
-		previewp->mForceUpdateSnapshot = TRUE;
-	}
-}
+    floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
+    floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor"));
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
-{
-	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
-	gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
-	
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;		
-	if (view)
-	{
-		checkAutoSnapshot(getPreviewView(view));
-		updateControls(view);
-	}
-}
+    updateResolution(floater);
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data)
-{
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-	if (view)
-	{
-		updateControls(view);
-        LLSnapshotLivePreview* previewp = getPreviewView(view);
-        if (previewp)
-        {
-            checkAutoSnapshot(previewp);
-            // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
-            LLComboBox* filterbox = static_cast<LLComboBox *>(view->getChild<LLComboBox>("filters_combobox"));
-            std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-            previewp->setFilter(filter_name);
-            previewp->updateSnapshot(TRUE);
-        }
-	}
-}
+    if (previewp)
+    {
+        previewp->setSnapshotType(shot_type);
+        previewp->setSnapshotFormat(shot_format);
+        previewp->setSnapshotBufferType(layer_type);
+    }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
-{
-	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
-	gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() );
-	
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-	if (view)
-	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
-		if(previewp)
-		{
-			previewp->updateSnapshot(TRUE, TRUE);
-		}
-		updateControls(view);
-	}
+    LLPanelSnapshot* current_panel = Impl::getActivePanel(floater);
+    if (current_panel)
+    {
+        LLSD info;
+        info["have-snapshot"] = got_snap;
+        current_panel->updateControls(info);
+    }
+    LL_DEBUGS() << "finished updating controls" << LL_ENDL;
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
+// virtual
+std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix()
 {
-	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
-	gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() );
-	
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-	if (view)
-	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
-		if(previewp)
-		{
-			previewp->updateSnapshot(TRUE, TRUE);
-		}
-		updateControls(view);
-	}
+    return "panel_outfit_snapshot_";
 }
 
-// static
-void LLFloaterOutfitSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
+// Show/hide upload status message.
+// virtual
+void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
 {
-	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
-		
-	if (!view || !check_box || !previewp)
-	{
-		return;
-	}
-
-	gSavedSettings.setBOOL("UseFreezeFrame", check_box->get());
+    mFloater->setSuccessLabelPanelVisible(finished && ok);
+    mFloater->setFailureLabelPanelVisible(finished && !ok);
 
-	if (check_box->get())
-	{
-		previewp->prepareFreezeFrame();
-	}
+    if (finished)
+    {
+        LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
+        std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
+        finished_lbl->setValue(result_text);
 
-	updateLayout(view);
+        LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
+        snapshot_panel->onOpen(LLSD());
+    }
 }
 
-// Show/hide upload progress indicators.
-// static
-void LLFloaterOutfitSnapshot::Impl::setWorking(LLFloaterOutfitSnapshot* floater, bool working)
+void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
 {
-	LLUICtrl* working_lbl = floater->getChild<LLUICtrl>("working_lbl");
-	working_lbl->setVisible(working);
-	floater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
+    LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
 
-	if (working)
-	{
-		const std::string panel_name = getActivePanel(floater, false)->getName();
-		const std::string prefix = panel_name.substr(std::string("panel_outfit_snapshot_").size());
-		std::string progress_text = floater->getString(prefix + "_" + "progress_str");
-		working_lbl->setValue(progress_text);
-	}
-
-	// All controls should be disabled while posting.
-	floater->setCtrlsEnabled(!working);
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
-	if (active_panel)
-	{
-		active_panel->enableControls(!working);
-	}
-}
+    if (!view)
+    {
+        llassert(view);
+        return;
+    }
 
-// Show/hide upload status message.
-// static
-void LLFloaterOutfitSnapshot::Impl::setFinished(LLFloaterOutfitSnapshot* floater, bool finished, bool ok, const std::string& msg)
-{
-	floater->mSucceessLblPanel->setVisible(finished && ok);
-	floater->mFailureLblPanel->setVisible(finished && !ok);
+    S32 width = OUTFIT_SNAPSHOT_WIDTH;
+    S32 height = OUTFIT_SNAPSHOT_HEIGHT;
 
-	if (finished)
-	{
-		LLUICtrl* finished_lbl = floater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
-		std::string result_text = floater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
-		finished_lbl->setValue(result_text);
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    if (previewp)
+    {
+        S32 original_width = 0, original_height = 0;
+        previewp->getSize(original_width, original_height);
 
-		//LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
-		//panel_container->openPreviousPanel();
-		//panel_container->getCurrentPanel()->onOpen(LLSD());
-        LLPanel* snapshot_panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
-        snapshot_panel->onOpen(LLSD());
-	}
-}
+        if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
+        { //clamp snapshot resolution to window size when showing UI or HUD in snapshot
+            width = llmin(width, gViewerWindow->getWindowWidthRaw());
+            height = llmin(height, gViewerWindow->getWindowHeightRaw());
+        }
 
-// Apply a new resolution selected from the given combobox.
-// static
-void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data)
-{
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-		
-	if (!view)
-	{
-		llassert(view);
-		return;
-	}
-		
-	S32 width = OUTFIT_SNAPSHOT_WIDTH;
-	S32 height = OUTFIT_SNAPSHOT_HEIGHT;
-	
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
-	if (previewp)
-	{
-		S32 original_width = 0 , original_height = 0 ;
-		previewp->getSize(original_width, original_height) ;
-		
-		if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot"))
-		{ //clamp snapshot resolution to window size when showing UI or HUD in snapshot
-			width = llmin(width, gViewerWindow->getWindowWidthRaw());
-			height = llmin(height, gViewerWindow->getWindowHeightRaw());
-		}
-        
 
         llassert(width > 0 && height > 0);
 
         // use the resolution from the selected pre-canned drop-down choice
         LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
         previewp->setSize(width, height);
-		
-		if(original_width != width || original_height != height)
-		{
-			//previewp->setSize(width, height);
 
-			// hide old preview as the aspect ratio could be wrong
-			checkAutoSnapshot(previewp, FALSE);
-			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
+        if (original_width != width || original_height != height)
+        {
+            // hide old preview as the aspect ratio could be wrong
+            checkAutoSnapshot(previewp, FALSE);
+            LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
             previewp->updateSnapshot(TRUE);
-		}
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
-{
-	LLComboBox* combobox = (LLComboBox*)ctrl;
-
-	LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data;
-		
-	if (view)
-	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
-		if (previewp)
-		{
-			previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex());
-		}
-		checkAutoSnapshot(previewp, TRUE);
-	}
-}
-
-// static
-void LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished(bool status)
-{
-	setStatus(STATUS_FINISHED, status, "profile");
-}
-
-
-// static
-void LLFloaterOutfitSnapshot::Impl::onSendingPostcardFinished(bool status)
-{
-	setStatus(STATUS_FINISHED, status, "postcard");
+        }
+    }
 }
 
-
 ///----------------------------------------------------------------------------
-/// Class LLFloaterSnapshot
+/// Class LLFloaterOutfitSnapshot
 ///----------------------------------------------------------------------------
 
 // Default constructor
 LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key)
-    : LLFloaterSnapshotBase(key),
-	  mRefreshBtn(NULL),
-	  mRefreshLabel(NULL),
-	  mSucceessLblPanel(NULL),
-	  mFailureLblPanel(NULL),
-      mOutfitGallery(NULL),
-	  impl (*(new Impl))
+: LLFloaterSnapshotBase(key),
+mOutfitGallery(NULL)
 {
+    impl = new Impl(this);
 }
 
-// Destroys the object
 LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot()
 {
-	if (impl.mPreviewHandle.get()) impl.mPreviewHandle.get()->die();
-
-	//unfreeze everything else
-	gSavedSettings.setBOOL("FreezeTime", FALSE);
-
-	if (impl.mLastToolset)
-	{
-		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
-	}
-
-	delete &impl;
 }
 
-
+// virtual
 BOOL LLFloaterOutfitSnapshot::postBuild()
 {
-	mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
-	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
-	mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
-	mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
-	mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
+    mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
+    childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
+    mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
+    mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
+    mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
 
-	childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
-	getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
+    childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
+    getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
 
-	childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
-	getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
+    childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
+    getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
 
-	getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
-	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
+    getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
+    childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
 
-	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
-	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
-    
+    getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
+    childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
 
-	// Filters
-	LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
+
+    // Filters
+    LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
     std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
     for (U32 i = 0; i < filter_list.size(); i++)
     {
         filterbox->add(filter_list[i]);
     }
-    childSetCommitCallback("filters_combobox", Impl::onClickFilter, this);
-    
-	LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterOutfitSnapshot::Impl::onSnapshotUploadFinished, _1));
-	LLPostCard::setPostResultCallback(boost::bind(&LLFloaterOutfitSnapshot::Impl::onSendingPostcardFinished, _1));
-
-	sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
-
-	// create preview window
-	LLRect full_screen_rect = getRootView()->getRect();
-	LLSnapshotLivePreview::Params p;
-	p.rect(full_screen_rect);
-	LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
-	LLView* parent_view = gSnapshotFloaterView->getParent();
-	
-	parent_view->removeChild(gSnapshotFloaterView);
-	// make sure preview is below snapshot floater
-	parent_view->addChild(previewp);
-	parent_view->addChild(gSnapshotFloaterView);
-	
-	//move snapshot floater to special purpose snapshotfloaterview
-	gFloaterView->removeChild(this);
-	gSnapshotFloaterView->addChild(this);
+    childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
 
-	impl.mPreviewHandle = previewp->getHandle();
-    previewp->setContainer(this);
-	impl.updateControls(this);
-	impl.updateLayout(this);
-	
-	previewp->mKeepAspectRatio = FALSE;
-	previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
-
-	return TRUE;
-}
+    LLWebProfile::setImageUploadResultCallback(boost::bind(&ImplBase::onSnapshotUploadFinished, this, _1));
 
-void LLFloaterOutfitSnapshot::draw()
-{
-	LLSnapshotLivePreview* previewp = impl.getPreviewView(this);
+    sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 
-	if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
-	{
-		// don't render snapshot window in snapshot, even if "show ui" is turned on
-		return;
-	}
+    // create preview window
+    LLRect full_screen_rect = getRootView()->getRect();
+    LLSnapshotLivePreview::Params p;
+    p.rect(full_screen_rect);
+    LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
+    LLView* parent_view = gSnapshotFloaterView->getParent();
 
-	LLFloater::draw();
+    parent_view->removeChild(gSnapshotFloaterView);
+    // make sure preview is below snapshot floater
+    parent_view->addChild(previewp);
+    parent_view->addChild(gSnapshotFloaterView);
 
-	if (previewp && !isMinimized() && sThumbnailPlaceholder->getVisible())
-	{		
-		if(previewp->getThumbnailImage())
-		{
-			bool working = impl.getStatus() == Impl::STATUS_WORKING;
-			const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
-			const S32 thumbnail_w = previewp->getThumbnailWidth();
-			const S32 thumbnail_h = previewp->getThumbnailHeight();
+    //move snapshot floater to special purpose snapshotfloaterview
+    gFloaterView->removeChild(this);
+    gSnapshotFloaterView->addChild(this);
 
-			// calc preview offset within the preview rect
-			const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
-			const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ; // preview y pos within the preview rect
-
-			// calc preview offset within the floater rect
-			S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
-			S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
-			gGL.matrixMode(LLRender::MM_MODELVIEW);
-			// Apply floater transparency to the texture unless the floater is focused.
-			F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
-			LLColor4 color = working ? LLColor4::grey4 : LLColor4::white;
-			gl_draw_scaled_image(offset_x, offset_y, 
-					thumbnail_w, thumbnail_h,
-					previewp->getThumbnailImage(), color % alpha);
+    impl->mPreviewHandle = previewp->getHandle();
+    previewp->setContainer(this);
+    impl->updateControls(this);
+    impl->updateLayout(this);
 
-			previewp->drawPreviewRect(offset_x, offset_y) ;
+    previewp->mKeepAspectRatio = FALSE;
+    previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
 
-			gGL.pushUIMatrix();
-			LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
-			sThumbnailPlaceholder->draw();
-			gGL.popUIMatrix();
-		}
-	}
-	impl.updateLayout(this);
+    return TRUE;
 }
 
+// virtual
 void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
 {
-	LLSnapshotLivePreview* preview = LLFloaterOutfitSnapshot::Impl::getPreviewView(this);
-	if(preview)
-	{
-		LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
-		preview->updateSnapshot(TRUE);
-	}
-	focusFirstItem(FALSE);
-	gSnapshotFloaterView->setEnabled(TRUE);
-	gSnapshotFloaterView->setVisible(TRUE);
-	gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
+    LLSnapshotLivePreview* preview = getPreviewView();
+    if (preview)
+    {
+        LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
+        preview->updateSnapshot(TRUE);
+    }
+    focusFirstItem(FALSE);
+    gSnapshotFloaterView->setEnabled(TRUE);
+    gSnapshotFloaterView->setVisible(TRUE);
+    gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
 
-	impl.updateControls(this);
-	impl.updateLayout(this);
+    impl->updateControls(this);
+    impl->updateLayout(this);
 
-	// Initialize default tab.
-	//getChild<LLSideTrayPanelContainer>("panel_container")->getCurrentPanel()->onOpen(LLSD());
-    //parent->openPanel(panel_name);
     LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
     snapshot_panel->onOpen(LLSD());
     postPanelSwitch();
 
 }
 
-void LLFloaterOutfitSnapshot::onClose(bool app_quitting)
-{
-	getParent()->setMouseOpaque(FALSE);
-
-	//unfreeze everything, hide fullscreen preview
-	LLSnapshotLivePreview* previewp = LLFloaterOutfitSnapshot::Impl::getPreviewView(this);
-	if (previewp)
-	{
-		previewp->setVisible(FALSE);
-		previewp->setEnabled(FALSE);
-	}
-
-	gSavedSettings.setBOOL("FreezeTime", FALSE);
-	impl.mAvatarPauseHandles.clear();
-
-	if (impl.mLastToolset)
-	{
-		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
-	}
-}
-
-// virtual
-S32 LLFloaterOutfitSnapshot::notify(const LLSD& info)
-{
-	if (info.has("set-ready"))
-	{
-		impl.setStatus(Impl::STATUS_READY);
-		return 1;
-	}
-
-	if (info.has("set-working"))
-	{
-		impl.setStatus(Impl::STATUS_WORKING);
-		return 1;
-	}
-
-	if (info.has("set-finished"))
-	{
-		LLSD data = info["set-finished"];
-		impl.setStatus(Impl::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString());
-		return 1;
-	}
-    
-	if (info.has("snapshot-updating"))
-	{
-        // Disable the send/post/save buttons until snapshot is ready.
-        impl.updateControls(this);
-		return 1;
-	}
-
-	if (info.has("snapshot-updated"))
-	{
-        // Enable the send/post/save buttons.
-        impl.updateControls(this);
-        // We've just done refresh.
-        impl.setNeedRefresh(this, false);
-            
-        // The refresh button is initially hidden. We show it after the first update,
-        // i.e. when preview appears.
-        if (!mRefreshBtn->getVisible())
-        {
-            mRefreshBtn->setVisible(true);
-        }
-		return 1;
-	}    
-    
-	return 0;
-}
-
-//static 
+// static 
 void LLFloaterOutfitSnapshot::update()
 {
-	LLFloaterOutfitSnapshot* inst = findInstance();
-	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); 
-	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); 
-	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); 
-
-	if (!inst && !floater_facebook && !floater_flickr && !floater_twitter)
-		return;
-	
-	BOOL changed = FALSE;
-	LL_DEBUGS() << "npreviews: " << LLSnapshotLivePreview::sList.size() << LL_ENDL;
-	for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
-		 iter != LLSnapshotLivePreview::sList.end(); ++iter)
-	{
-		changed |= LLSnapshotLivePreview::onIdle(*iter);
-	}
-    
-	if (inst && changed)
-	{
-		LL_DEBUGS() << "changed" << LL_ENDL;
-		inst->impl.updateControls(inst);
-	}
+    LLFloaterOutfitSnapshot* inst = getInstance();
+    if (inst != NULL)
+    {
+        inst->impl->updateLivePreview();
+    }
 }
 
 // static
 LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
 {
-	return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
+    return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
 }
 
-// static
-LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
-{
-	return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
-}
-
-// static
+// virtual
 void LLFloaterOutfitSnapshot::saveTexture()
 {
-	LL_DEBUGS() << "saveTexture" << LL_ENDL;
+    LL_DEBUGS() << "saveTexture" << LL_ENDL;
 
-	// FIXME: duplicated code
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return;
-	}
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
-	if (!previewp)
-	{
-		llassert(previewp != NULL);
-		return;
-	}
+    LLSnapshotLivePreview* previewp = getPreviewView();
+    if (!previewp)
+    {
+        llassert(previewp != NULL);
+        return;
+    }
 
-    if (instance->mOutfitGallery)
+    if (mOutfitGallery)
     {
-        instance->mOutfitGallery->onBeforeOutfitSnapshotSave();
+        mOutfitGallery->onBeforeOutfitSnapshotSave();
     }
-    previewp->saveTexture(TRUE, instance->getOutfitID().asString());
-    if (instance->mOutfitGallery)
+    previewp->saveTexture(TRUE, getOutfitID().asString());
+    if (mOutfitGallery)
     {
-        instance->mOutfitGallery->onAfterOutfitSnapshotSave();
+        mOutfitGallery->onAfterOutfitSnapshotSave();
     }
-    instance->closeFloater();
-}
-
-// static
-void LLFloaterOutfitSnapshot::postSave()
-{
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return;
-	}
-
-	instance->impl.updateControls(instance);
-	instance->impl.setStatus(Impl::STATUS_WORKING);
-}
-
-// static
-void LLFloaterOutfitSnapshot::postPanelSwitch()
-{
-	LLFloaterOutfitSnapshot* instance = getInstance();
-	instance->impl.updateControls(instance);
-
-	// Remove the success/failure indicator whenever user presses a snapshot option button.
-	instance->impl.setStatus(Impl::STATUS_READY);
-}
-
-// static
-LLPointer<LLImageFormatted> LLFloaterOutfitSnapshot::getImageData()
-{
-	// FIXME: May not work for textures.
-
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return NULL;
-	}
-
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
-	if (!previewp)
-	{
-		llassert(previewp != NULL);
-		return NULL;
-	}
-
-	LLPointer<LLImageFormatted> img = previewp->getFormattedImage();
-	if (!img.get())
-	{
-		LL_WARNS() << "Empty snapshot image data" << LL_ENDL;
-		llassert(img.get() != NULL);
-	}
-
-	return img;
-}
-
-// static
-const LLVector3d& LLFloaterOutfitSnapshot::getPosTakenGlobal()
-{
-	LLFloaterOutfitSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return LLVector3d::zero;
-	}
-
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
-	if (!previewp)
-	{
-		llassert(previewp != NULL);
-		return LLVector3d::zero;
-	}
-
-	return previewp->getPosTakenGlobal();
+    closeFloater();
 }
 
 ///----------------------------------------------------------------------------
-/// Class LLSnapshotFloaterView
+/// Class LLOutfitSnapshotFloaterView
 ///----------------------------------------------------------------------------
 
-LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView (const Params& p) : LLFloaterView (p)
+LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p)
 {
 }
 
 LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView()
 {
 }
-
-BOOL LLOutfitSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
-{
-	// use default handler when not in freeze-frame mode
-	if(!gSavedSettings.getBOOL("FreezeTime"))
-	{
-		return LLFloaterView::handleKey(key, mask, called_from_parent);
-	}
-
-	if (called_from_parent)
-	{
-		// pass all keystrokes down
-		LLFloaterView::handleKey(key, mask, called_from_parent);
-	}
-	else
-	{
-		// bounce keystrokes back down
-		LLFloaterView::handleKey(key, mask, TRUE);
-	}
-	return TRUE;
-}
-
-BOOL LLOutfitSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	// use default handler when not in freeze-frame mode
-	if(!gSavedSettings.getBOOL("FreezeTime"))
-	{
-		return LLFloaterView::handleMouseDown(x, y, mask);
-	}
-	// give floater a change to handle mouse, else camera tool
-	if (childrenHandleMouseDown(x, y, mask) == NULL)
-	{
-		LLToolMgr::getInstance()->getCurrentTool()->handleMouseDown( x, y, mask );
-	}
-	return TRUE;
-}
-
-BOOL LLOutfitSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
-{
-	// use default handler when not in freeze-frame mode
-	if(!gSavedSettings.getBOOL("FreezeTime"))
-	{
-		return LLFloaterView::handleMouseUp(x, y, mask);
-	}
-	// give floater a change to handle mouse, else camera tool
-	if (childrenHandleMouseUp(x, y, mask) == NULL)
-	{
-		LLToolMgr::getInstance()->getCurrentTool()->handleMouseUp( x, y, mask );
-	}
-	return TRUE;
-}
-
-BOOL LLOutfitSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)
-{
-	// use default handler when not in freeze-frame mode
-	if(!gSavedSettings.getBOOL("FreezeTime"))
-	{
-		return LLFloaterView::handleHover(x, y, mask);
-	}	
-	// give floater a change to handle mouse, else camera tool
-	if (childrenHandleHover(x, y, mask) == NULL)
-	{
-		LLToolMgr::getInstance()->getCurrentTool()->handleHover( x, y, mask );
-	}
-	return TRUE;
-}
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 9a7b30ebd8..37e264b0e7 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -1,25 +1,25 @@
-/** 
+/**
  * @file llfloateroutfitsnapshot.h
  * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2016, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -30,71 +30,87 @@
 #include "llfloater.h"
 #include "llfloatersnapshot.h"
 #include "lloutfitgallery.h"
+#include "llsnapshotlivepreview.h"
 
-class LLSpinCtrl;
+///----------------------------------------------------------------------------
+/// Class LLFloaterOutfitSnapshot
+///----------------------------------------------------------------------------
 
 class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase
 {
-	LOG_CLASS(LLFloaterOutfitSnapshot);
+    LOG_CLASS(LLFloaterOutfitSnapshot);
 
 public:
 
-	LLFloaterOutfitSnapshot(const LLSD& key);
-	virtual ~LLFloaterOutfitSnapshot();
-    
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
-	/*virtual*/ S32 notify(const LLSD& info);
-	
-	static void update();
-
-	// TODO: create a snapshot model instead
-	static LLFloaterOutfitSnapshot* getInstance();
-	static LLFloaterOutfitSnapshot* findInstance();
-	static void saveTexture();
-	static void postSave();
-	static void postPanelSwitch();
-	static LLPointer<LLImageFormatted> getImageData();
-	static const LLVector3d& getPosTakenGlobal();
-
-	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
+    LLFloaterOutfitSnapshot(const LLSD& key);
+    /*virtual*/ ~LLFloaterOutfitSnapshot();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& key);
+
+    static void update();
+
+    static LLFloaterOutfitSnapshot* getInstance();
+    /*virtual*/ void saveTexture();
+
+    static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
 
     void setOutfitID(LLUUID id) { mOutfitID = id; }
     LLUUID getOutfitID() { return mOutfitID; }
     void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
-private:
-	static LLUICtrl* sThumbnailPlaceholder;
-	LLUICtrl *mRefreshBtn, *mRefreshLabel;
-	LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
 
-	class Impl;
-	Impl& impl;
+    class Impl;
+    friend Impl;
+private:
 
     LLUUID mOutfitID;
     LLOutfitGallery* mOutfitGallery;
 };
 
+///----------------------------------------------------------------------------
+/// Class LLFloaterOutfitSnapshot::Impl
+///----------------------------------------------------------------------------
+
+class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
+{
+    LOG_CLASS(LLFloaterOutfitSnapshot::Impl);
+public:
+    Impl(LLFloaterSnapshotBase* floater)
+        : LLFloaterSnapshotBase::ImplBase(floater)
+    {}
+    ~Impl()
+    {}
+    void updateResolution(void* data);
+
+    /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
+    /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
+    /*virtual*/ std::string getSnapshotPanelPrefix();
+
+    /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
+
+private:
+    /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
+    /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
+};
+
+///----------------------------------------------------------------------------
+/// Class LLOutfitSnapshotFloaterView
+///----------------------------------------------------------------------------
+
 class LLOutfitSnapshotFloaterView : public LLFloaterView
 {
 public:
-	struct Params 
-	:	public LLInitParam::Block<Params, LLFloaterView::Params>
-	{
-	};
+    struct Params
+        : public LLInitParam::Block<Params, LLFloaterView::Params>
+    {
+    };
 
 protected:
-	LLOutfitSnapshotFloaterView (const Params& p);
-	friend class LLUICtrlFactory;
+    LLOutfitSnapshotFloaterView(const Params& p);
+    friend class LLUICtrlFactory;
 
 public:
-	virtual ~LLOutfitSnapshotFloaterView();
-
-	/*virtual*/	BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
-	/*virtual*/	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-	/*virtual*/	BOOL handleMouseUp(S32 x, S32 y, MASK mask);
-	/*virtual*/	BOOL handleHover(S32 x, S32 y, MASK mask);
+    virtual ~LLOutfitSnapshotFloaterView();
 };
 
 extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index e5a2bd03cd..2585c7c6a5 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -4,7 +4,7 @@
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2016, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -28,7 +28,6 @@
 
 #include "llfloatersnapshot.h"
 
-#include "llagent.h"
 #include "llfacebookconnect.h"
 #include "llfloaterreg.h"
 #include "llfloaterfacebook.h"
@@ -51,7 +50,7 @@
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
-LLUICtrl* LLFloaterSnapshot::sThumbnailPlaceholder = NULL;
+LLUICtrl* LLFloaterSnapshotBase::sThumbnailPlaceholder = NULL;
 LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
 
 const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
@@ -61,101 +60,8 @@ const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
 
 static LLDefaultChildRegistry::Register<LLSnapshotFloaterView> r("snapshot_floater_view");
 
-
-LLFloaterSnapshotBase::ImplBase::ImplBase()
-{
-}
-
-LLFloaterSnapshotBase::ImplBase::~ImplBase()
-{
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterSnapshot::Impl
-///----------------------------------------------------------------------------
-
-class LLFloaterSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
-{
-	LOG_CLASS(LLFloaterSnapshot::Impl);
-public:
-	typedef enum e_status
-	{
-		STATUS_READY,
-		STATUS_WORKING,
-		STATUS_FINISHED
-	} EStatus;
-
-	Impl()
-	:	mAvatarPauseHandles(),
-		mLastToolset(NULL),
-		mAspectRatioCheckOff(false),
-		mNeedRefresh(false),
-		mStatus(STATUS_READY)
-	{
-	}
-	~Impl()
-	{
-		//unpause avatars
-		mAvatarPauseHandles.clear();
-
-	}
-	static void onClickNewSnapshot(void* data);
-	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
-	static void onClickFilter(LLUICtrl *ctrl, void* data);
-	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
-	static void onClickUICheck(LLUICtrl *ctrl, void* data);
-	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
-	static void applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked);
-	static void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
-	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
-	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
-	static void onImageQualityChange(LLFloaterSnapshot* view, S32 quality_val);
-	static void onImageFormatChange(LLFloaterSnapshot* view);
-	static void applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h);
-	static void onSnapshotUploadFinished(bool status);
-	static void onSendingPostcardFinished(bool status);
-	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
-	static void setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height) ;
-	static void updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
-
-	static LLPanelSnapshot* getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found = true);
-    static LLPanelSnapshot::ESnapshotType getActiveSnapshotType(LLFloaterSnapshot* floater);
-    static LLFloaterSnapshotBase::ESnapshotFormat getImageFormat(LLFloaterSnapshot* floater);
-	static LLSpinCtrl* getWidthSpinner(LLFloaterSnapshot* floater);
-	static LLSpinCtrl* getHeightSpinner(LLFloaterSnapshot* floater);
-	static void enableAspectRatioCheckbox(LLFloaterSnapshot* floater, BOOL enable);
-	static void setAspectRatioCheckboxValue(LLFloaterSnapshot* floater, BOOL checked);
-
-	static LLSnapshotLivePreview* getPreviewView(LLFloaterSnapshot *floater);
-	static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);
-	static void updateControls(LLFloaterSnapshot* floater);
-	static void updateLayout(LLFloaterSnapshot* floater);
-	static void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
-	EStatus getStatus() const { return mStatus; }
-	static void setNeedRefresh(LLFloaterSnapshot* floater, bool need);
-
-private:
-	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);
-	static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);
-	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
-	static void checkAspectRatio(LLFloaterSnapshot *view, S32 index) ;
-	static void setWorking(LLFloaterSnapshot* floater, bool working);
-	static void setFinished(LLFloaterSnapshot* floater, bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
-
-
-public:
-	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
-
-	LLToolset*	mLastToolset;
-	LLHandle<LLView> mPreviewHandle;
-	bool mAspectRatioCheckOff ;
-	bool mNeedRefresh;
-	EStatus mStatus;
-};
-
-// static
-LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshot* floater, bool ok_if_not_found)
+// virtual
+LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
 {
 	LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
 	LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel());
@@ -166,63 +72,40 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshot* floa
 	return active_panel;
 }
 
-// static
-LLPanelSnapshot::ESnapshotType LLFloaterSnapshot::Impl::getActiveSnapshotType(LLFloaterSnapshot* floater)
+// virtual
+LLSnapshotModel::ESnapshotType LLFloaterSnapshotBase::ImplBase::getActiveSnapshotType(LLFloaterSnapshotBase* floater)
 {
- //   LLPanelSnapshot::ESnapshotType type = LLPanelSnapshot::SNAPSHOT_WEB;
-	//std::string name;
 	LLPanelSnapshot* spanel = getActivePanel(floater);
 
-	//if (spanel)
-	//{
-	//	name = spanel->getName();
-	//}
-
-	//if (name == "panel_snapshot_postcard")
-	//{
-	//	type = LLPanelSnapshot::SNAPSHOT_POSTCARD;
-	//}
-	//else if (name == "panel_snapshot_inventory")
-	//{
-	//	type = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
-	//}
-	//else if (name == "panel_snapshot_local")
-	//{
-	//	type = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
-	//}
-
 	//return type;
     if (spanel)
     {
         return spanel->getSnapshotType();
     }
-    return LLPanelSnapshot::SNAPSHOT_WEB;
+	return LLSnapshotModel::SNAPSHOT_WEB;
 }
 
-// static
-LLFloaterSnapshotBase::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshot* floater)
+// virtual
+LLSnapshotModel::ESnapshotFormat LLFloaterSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	// FIXME: if the default is not PNG, profile uploads may fail.
-	return active_panel ? active_panel->getImageFormat() : LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
+	return active_panel ? active_panel->getImageFormat() : LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
 }
 
-// static
-LLSpinCtrl* LLFloaterSnapshot::Impl::getWidthSpinner(LLFloaterSnapshot* floater)
+LLSpinCtrl* LLFloaterSnapshot::Impl::getWidthSpinner(LLFloaterSnapshotBase* floater)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	return active_panel ? active_panel->getWidthSpinner() : floater->getChild<LLSpinCtrl>("snapshot_width");
 }
 
-// static
-LLSpinCtrl* LLFloaterSnapshot::Impl::getHeightSpinner(LLFloaterSnapshot* floater)
+LLSpinCtrl* LLFloaterSnapshot::Impl::getHeightSpinner(LLFloaterSnapshotBase* floater)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	return active_panel ? active_panel->getHeightSpinner() : floater->getChild<LLSpinCtrl>("snapshot_height");
 }
 
-// static
-void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshot* floater, BOOL enable)
+void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshotBase* floater, BOOL enable)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	if (active_panel)
@@ -231,8 +114,7 @@ void LLFloaterSnapshot::Impl::enableAspectRatioCheckbox(LLFloaterSnapshot* float
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshot* floater, BOOL checked)
+void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshotBase* floater, BOOL checked)
 {
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	if (active_panel)
@@ -241,38 +123,41 @@ void LLFloaterSnapshot::Impl::setAspectRatioCheckboxValue(LLFloaterSnapshot* flo
 	}
 }
 
-// static
-LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
+LLSnapshotLivePreview* LLFloaterSnapshotBase::getPreviewView()
+{
+	return impl->getPreviewView();
+}
+
+LLSnapshotLivePreview* LLFloaterSnapshotBase::ImplBase::getPreviewView()
 {
-	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)floater->impl.mPreviewHandle.get();
+	LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
 	return previewp;
 }
 
-// static
-LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)
+// virtual
+LLSnapshotModel::ESnapshotLayerType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater)
 {
-	LLViewerWindow::ESnapshotType type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 	LLSD value = floater->getChild<LLUICtrl>("layer_types")->getValue();
 	const std::string id = value.asString();
 	if (id == "colors")
-		type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+		type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 	else if (id == "depth")
-		type = LLViewerWindow::SNAPSHOT_TYPE_DEPTH;
+		type = LLSnapshotModel::SNAPSHOT_TYPE_DEPTH;
 	return type;
 }
 
-// static
-void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshot* floater, const std::string& comboname)
+void LLFloaterSnapshot::Impl::setResolution(LLFloaterSnapshotBase* floater, const std::string& comboname)
 {
 	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
 		combo->setVisible(TRUE);
 	updateResolution(combo, floater, FALSE); // to sync spinners with combo
 }
 
-//static 
-void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
+//virtual 
+void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floaterp)
 {
-	LLSnapshotLivePreview* previewp = getPreviewView(floaterp);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 
 	BOOL advanced = gSavedSettings.getBOOL("AdvanceSnapshot");
 
@@ -330,7 +215,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 			iter != LLCharacter::sInstances.end(); ++iter)
 		{
 			avatarp = *iter;
-			floaterp->impl.mAvatarPauseHandles.push_back(avatarp->requestPause());
+			floaterp->impl->mAvatarPauseHandles.push_back(avatarp->requestPause());
 		}
 
 		// freeze everything else
@@ -338,7 +223,7 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 
 		if (LLToolMgr::getInstance()->getCurrentToolset() != gCameraToolset)
 		{
-			floaterp->impl.mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
+			floaterp->impl->mLastToolset = LLToolMgr::getInstance()->getCurrentToolset();
 			LLToolMgr::getInstance()->setCurrentToolset(gCameraToolset);
 		}
 	}
@@ -354,15 +239,15 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 		}
 
 		//RN: thaw all avatars
-		floaterp->impl.mAvatarPauseHandles.clear();
+		floaterp->impl->mAvatarPauseHandles.clear();
 
 		// thaw everything else
 		gSavedSettings.setBOOL("FreezeTime", FALSE);
 
 		// restore last tool (e.g. pie menu, etc)
-		if (floaterp->impl.mLastToolset)
+		if (floaterp->impl->mLastToolset)
 		{
-			LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl.mLastToolset);
+			LLToolMgr::getInstance()->setCurrentToolset(floaterp->impl->mLastToolset);
 		}
 	}
 }
@@ -373,15 +258,15 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 // The basic pattern for programmatically changing the GUI settings is to first set the
 // appropriate saved settings and then call this method to sync the GUI with them.
 // FIXME: The above comment seems obsolete now.
-// static
-void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
+// virtual
+void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater)
 {
-	LLPanelSnapshot::ESnapshotType shot_type = getActiveSnapshotType(floater);
-	ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
-	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
+	LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater);
+	LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat");
+	LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater);
 
 	floater->getChild<LLComboBox>("local_format_combo")->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
-	floater->getChildView("layer_types")->setEnabled(shot_type == LLPanelSnapshot::SNAPSHOT_LOCAL);
+	floater->getChildView("layer_types")->setEnabled(shot_type == LLSnapshotModel::SNAPSHOT_LOCAL);
 
 	LLPanelSnapshot* active_panel = getActivePanel(floater);
 	if (active_panel)
@@ -395,7 +280,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 			S32 w = gViewerWindow->getWindowWidthRaw();
 			LL_DEBUGS() << "Initializing width spinner (" << width_ctrl->getName() << "): " << w << LL_ENDL;
 			width_ctrl->setValue(w);
-			if(getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			if (getActiveSnapshotType(floater) == LLSnapshotModel::SNAPSHOT_TEXTURE)
 			{
 				width_ctrl->setIncrement(w >> 1);
 			}
@@ -405,7 +290,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 			S32 h = gViewerWindow->getWindowHeightRaw();
 			LL_DEBUGS() << "Initializing height spinner (" << height_ctrl->getName() << "): " << h << LL_ENDL;
 			height_ctrl->setValue(h);
-			if(getActiveSnapshotType(floater) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			if (getActiveSnapshotType(floater) == LLSnapshotModel::SNAPSHOT_TEXTURE)
 			{
 				height_ctrl->setIncrement(h >> 1);
 			}
@@ -437,7 +322,7 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 		}
 	}
 		
-	LLSnapshotLivePreview* previewp = getPreviewView(floater);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	BOOL got_bytes = previewp && previewp->getDataSize() > 0;
 	BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
 
@@ -462,35 +347,35 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 
 	floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
 	floater->getChild<LLUICtrl>("file_size_label")->setColor(
-			shot_type == LLPanelSnapshot::SNAPSHOT_POSTCARD
+			shot_type == LLSnapshotModel::SNAPSHOT_POSTCARD
 			&& got_bytes
 			&& previewp->getDataSize() > MAX_POSTCARD_DATASIZE ? LLUIColor(LLColor4::red) : LLUIColorTable::instance().getColor( "LabelTextColor" ));
 
 	// Update the width and height spinners based on the corresponding resolution combos. (?)
 	switch(shot_type)
 	{
-	  case LLPanelSnapshot::SNAPSHOT_WEB:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	  case LLSnapshotModel::SNAPSHOT_WEB:
+		layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "profile_size_combo");
 		break;
-	  case LLPanelSnapshot::SNAPSHOT_POSTCARD:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	  case LLSnapshotModel::SNAPSHOT_POSTCARD:
+		layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "postcard_size_combo");
 		break;
-	  case LLPanelSnapshot::SNAPSHOT_TEXTURE:
-		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
+	  case LLSnapshotModel::SNAPSHOT_TEXTURE:
+		layer_type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR;
 		floater->getChild<LLUICtrl>("layer_types")->setValue("colors");
 		setResolution(floater, "texture_size_combo");
 		break;
-	  case  LLPanelSnapshot::SNAPSHOT_LOCAL:
+	  case  LLSnapshotModel::SNAPSHOT_LOCAL:
 		setResolution(floater, "local_size_combo");
 		break;
 	  default:
 		break;
 	}
-	setAspectRatioCheckboxValue(floater, !floater->impl.mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot"));
+	setAspectRatioCheckboxValue(floater, !floater->impl->mAspectRatioCheckOff && gSavedSettings.getBOOL("KeepAspectForSnapshot"));
 
 	if (previewp)
 	{
@@ -509,33 +394,32 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 	LL_DEBUGS() << "finished updating controls" << LL_ENDL;
 }
 
-// static
-void LLFloaterSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg)
+//virtual
+void LLFloaterSnapshotBase::ImplBase::setStatus(EStatus status, bool ok, const std::string& msg)
 {
-	LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
 	switch (status)
 	{
 	case STATUS_READY:
-		setWorking(floater, false);
-		setFinished(floater, false);
+		setWorking(false);
+		setFinished(false);
 		break;
 	case STATUS_WORKING:
-		setWorking(floater, true);
-		setFinished(floater, false);
+		setWorking(true);
+		setFinished(false);
 		break;
 	case STATUS_FINISHED:
-		setWorking(floater, false);
-		setFinished(floater, true, ok, msg);
+		setWorking(false);
+		setFinished(true, ok, msg);
 		break;
 	}
 
-	floater->impl.mStatus = status;
+	mStatus = status;
 }
 
-// static
-void LLFloaterSnapshot::Impl::setNeedRefresh(LLFloaterSnapshot* floater, bool need)
+// virtual
+void LLFloaterSnapshotBase::ImplBase::setNeedRefresh(bool need)
 {
-	if (!floater) return;
+	if (!mFloater) return;
 
 	// Don't display the "Refresh to save" message if we're in auto-refresh mode.
 	if (gSavedSettings.getBOOL("AutoSnapshot"))
@@ -543,12 +427,12 @@ void LLFloaterSnapshot::Impl::setNeedRefresh(LLFloaterSnapshot* floater, bool ne
 		need = false;
 	}
 
-	floater->mRefreshLabel->setVisible(need);
-	floater->impl.mNeedRefresh = need;
+	mFloater->setRefreshLabelVisible(need);
+	mNeedRefresh = need;
 }
 
-// static
-void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
+// virtual
+void LLFloaterSnapshotBase::ImplBase::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
 {
 	if (previewp)
 	{
@@ -559,43 +443,43 @@ void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp,
 }
 
 // static
-void LLFloaterSnapshot::Impl::onClickNewSnapshot(void* data)
+void LLFloaterSnapshotBase::ImplBase::onClickNewSnapshot(void* data)
 {
-	LLSnapshotLivePreview* previewp = getPreviewView((LLFloaterSnapshot *)data);
-	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
-	if (previewp && view)
+	LLFloaterSnapshotBase* floater = (LLFloaterSnapshotBase *)data;
+	LLSnapshotLivePreview* previewp = floater->getPreviewView();
+	if (previewp)
 	{
-		view->impl.setStatus(Impl::STATUS_READY);
+		floater->impl->setStatus(ImplBase::STATUS_READY);
 		LL_DEBUGS() << "updating snapshot" << LL_ENDL;
 		previewp->mForceUpdateSnapshot = TRUE;
 	}
 }
 
 // static
-void LLFloaterSnapshot::Impl::onClickAutoSnap(LLUICtrl *ctrl, void* data)
+void LLFloaterSnapshotBase::ImplBase::onClickAutoSnap(LLUICtrl *ctrl, void* data)
 {
 	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 	gSavedSettings.setBOOL( "AutoSnapshot", check->get() );
 	
-	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		
+	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;		
 	if (view)
 	{
-		checkAutoSnapshot(getPreviewView(view));
-		updateControls(view);
+		view->impl->checkAutoSnapshot(view->getPreviewView());
+		view->impl->updateControls(view);
 	}
 }
 
 // static
-void LLFloaterSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data)
+void LLFloaterSnapshotBase::ImplBase::onClickFilter(LLUICtrl *ctrl, void* data)
 {
-	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
+	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;
 	if (view)
 	{
-		updateControls(view);
-        LLSnapshotLivePreview* previewp = getPreviewView(view);
+		view->impl->updateControls(view);
+		LLSnapshotLivePreview* previewp = view->getPreviewView();
         if (previewp)
         {
-            checkAutoSnapshot(previewp);
+			view->impl->checkAutoSnapshot(previewp);
             // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
             LLComboBox* filterbox = static_cast<LLComboBox *>(view->getChild<LLComboBox>("filters_combobox"));
             std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
@@ -606,7 +490,7 @@ void LLFloaterSnapshot::Impl::onClickFilter(LLUICtrl *ctrl, void* data)
 }
 
 // static
-void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
+void LLFloaterSnapshotBase::ImplBase::onClickUICheck(LLUICtrl *ctrl, void* data)
 {
 	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 	gSavedSettings.setBOOL( "RenderUIInSnapshot", check->get() );
@@ -614,17 +498,17 @@ void LLFloaterSnapshot::Impl::onClickUICheck(LLUICtrl *ctrl, void* data)
 	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
 	if (view)
 	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		LLSnapshotLivePreview* previewp = view->getPreviewView();
 		if(previewp)
 		{
 			previewp->updateSnapshot(TRUE, TRUE);
 		}
-		updateControls(view);
+		view->impl->updateControls(view);
 	}
 }
 
 // static
-void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
+void LLFloaterSnapshotBase::ImplBase::onClickHUDCheck(LLUICtrl *ctrl, void* data)
 {
 	LLCheckBoxCtrl *check = (LLCheckBoxCtrl *)ctrl;
 	gSavedSettings.setBOOL( "RenderHUDInSnapshot", check->get() );
@@ -632,17 +516,16 @@ void LLFloaterSnapshot::Impl::onClickHUDCheck(LLUICtrl *ctrl, void* data)
 	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
 	if (view)
 	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		LLSnapshotLivePreview* previewp = view->getPreviewView();
 		if(previewp)
 		{
 			previewp->updateSnapshot(TRUE, TRUE);
 		}
-		updateControls(view);
+		view->impl->updateControls(view);
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL checked)
+void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshotBase* view, BOOL checked)
 {
 	gSavedSettings.setBOOL("KeepAspectForSnapshot", checked);
 
@@ -655,7 +538,7 @@ void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL
 			combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
 		}
 
-		LLSnapshotLivePreview* previewp = getPreviewView(view) ;
+		LLSnapshotLivePreview* previewp = getPreviewView() ;
 		if(previewp)
 		{
 			previewp->mKeepAspectRatio = gSavedSettings.getBOOL("KeepAspectForSnapshot") ;
@@ -673,11 +556,11 @@ void LLFloaterSnapshot::Impl::applyKeepAspectCheck(LLFloaterSnapshot* view, BOOL
 }
 
 // static
-void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
+void LLFloaterSnapshotBase::ImplBase::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
 {
 	LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
-	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	LLFloaterSnapshotBase *view = (LLFloaterSnapshotBase *)data;
+	LLSnapshotLivePreview* previewp = view->getPreviewView();
 		
 	if (!view || !check_box || !previewp)
 	{
@@ -691,16 +574,15 @@ void LLFloaterSnapshot::Impl::onCommitFreezeFrame(LLUICtrl* ctrl, void* data)
 		previewp->prepareFreezeFrame();
 	}
 
-	updateLayout(view);
+	view->impl->updateLayout(view);
 }
 
-// static
-void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 index)
+void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshotBase *view, S32 index)
 {
-	LLSnapshotLivePreview *previewp = getPreviewView(view) ;
+	LLSnapshotLivePreview *previewp = getPreviewView() ;
 
 	// Don't round texture sizes; textures are commonly stretched in world, profiles, etc and need to be "squashed" during upload, not cropped here
-	if(LLPanelSnapshot::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
+	if (LLSnapshotModel::SNAPSHOT_TEXTURE == getActiveSnapshotType(view))
 	{
 		previewp->mKeepAspectRatio = FALSE ;
 		return ;
@@ -724,7 +606,7 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
 		keep_aspect = FALSE;
 	}
 
-	view->impl.mAspectRatioCheckOff = !enable_cb;
+	view->impl->mAspectRatioCheckOff = !enable_cb;
 
 	if (previewp)
 	{
@@ -733,51 +615,55 @@ void LLFloaterSnapshot::Impl::checkAspectRatio(LLFloaterSnapshot *view, S32 inde
 }
 
 // Show/hide upload progress indicators.
-// static
-void LLFloaterSnapshot::Impl::setWorking(LLFloaterSnapshot* floater, bool working)
+void LLFloaterSnapshotBase::ImplBase::setWorking(bool working)
 {
-	LLUICtrl* working_lbl = floater->getChild<LLUICtrl>("working_lbl");
+	LLUICtrl* working_lbl = mFloater->getChild<LLUICtrl>("working_lbl");
 	working_lbl->setVisible(working);
-	floater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
+	mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
 
 	if (working)
 	{
-		const std::string panel_name = getActivePanel(floater, false)->getName();
-		const std::string prefix = panel_name.substr(std::string("panel_snapshot_").size());
-		std::string progress_text = floater->getString(prefix + "_" + "progress_str");
+		const std::string panel_name = getActivePanel(mFloater, false)->getName();
+		const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size());
+		std::string progress_text = mFloater->getString(prefix + "_" + "progress_str");
 		working_lbl->setValue(progress_text);
 	}
 
 	// All controls should be disabled while posting.
-	floater->setCtrlsEnabled(!working);
-	LLPanelSnapshot* active_panel = getActivePanel(floater);
+	mFloater->setCtrlsEnabled(!working);
+	LLPanelSnapshot* active_panel = getActivePanel(mFloater);
 	if (active_panel)
 	{
 		active_panel->enableControls(!working);
 	}
 }
 
+//virtual
+std::string LLFloaterSnapshot::Impl::getSnapshotPanelPrefix()
+{
+	return "panel_snapshot_";
+}
+
 // Show/hide upload status message.
-// static
-void LLFloaterSnapshot::Impl::setFinished(LLFloaterSnapshot* floater, bool finished, bool ok, const std::string& msg)
+// virtual
+void LLFloaterSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg)
 {
-	floater->mSucceessLblPanel->setVisible(finished && ok);
-	floater->mFailureLblPanel->setVisible(finished && !ok);
+	mFloater->setSuccessLabelPanelVisible(finished && ok);
+	mFloater->setFailureLabelPanelVisible(finished && !ok);
 
 	if (finished)
 	{
-		LLUICtrl* finished_lbl = floater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
-		std::string result_text = floater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
+		LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
+		std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
 		finished_lbl->setValue(result_text);
 
-		LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
+		LLSideTrayPanelContainer* panel_container = mFloater->getChild<LLSideTrayPanelContainer>("panel_container");
 		panel_container->openPreviousPanel();
 		panel_container->getCurrentPanel()->onOpen(LLSD());
 	}
 }
 
 // Apply a new resolution selected from the given combobox.
-// static
 void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update)
 {
 	LLComboBox* combobox = (LLComboBox*)ctrl;
@@ -797,7 +683,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 	S32 width = sdres[0];
 	S32 height = sdres[1];
 	
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (previewp && combobox->getCurrentIndex() >= 0)
 	{
 		S32 original_width = 0 , original_height = 0 ;
@@ -827,7 +713,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 				new_height = spanel->getTypedPreviewHeight();
 
 				// Limit custom size for inventory snapshots to 512x512 px.
-				if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+				if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE)
 				{
 					new_width = llmin(new_width, MAX_TEXTURE_SIZE);
 					new_height = llmin(new_height, MAX_TEXTURE_SIZE);
@@ -865,7 +751,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 		{
 			getWidthSpinner(view)->setValue(width);
 			getHeightSpinner(view)->setValue(height);
-			if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+			if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE)
 			{
 				getWidthSpinner(view)->setIncrement(width >> 1);
 				getHeightSpinner(view)->setIncrement(height >> 1);
@@ -879,7 +765,7 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 			// hide old preview as the aspect ratio could be wrong
 			checkAutoSnapshot(previewp, FALSE);
 			LL_DEBUGS() << "updating thumbnail" << LL_ENDL;
-			getPreviewView(view)->updateSnapshot(TRUE);
+			getPreviewView()->updateSnapshot(TRUE);
 			if(do_update)
 			{
 				LL_DEBUGS() << "Will update controls" << LL_ENDL;
@@ -898,40 +784,37 @@ void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data)
 		
 	if (view)
 	{
-		LLSnapshotLivePreview* previewp = getPreviewView(view);
+		LLSnapshotLivePreview* previewp = view->getPreviewView();
 		if (previewp)
 		{
-			previewp->setSnapshotBufferType((LLViewerWindow::ESnapshotType)combobox->getCurrentIndex());
+			previewp->setSnapshotBufferType((LLSnapshotModel::ESnapshotLayerType)combobox->getCurrentIndex());
 		}
-		checkAutoSnapshot(previewp, TRUE);
+		view->impl->checkAutoSnapshot(previewp, TRUE);
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::onImageQualityChange(LLFloaterSnapshot* view, S32 quality_val)
+void LLFloaterSnapshot::Impl::onImageQualityChange(LLFloaterSnapshotBase* view, S32 quality_val)
 {
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (previewp)
 	{
 		previewp->setSnapshotQuality(quality_val);
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::onImageFormatChange(LLFloaterSnapshot* view)
+void LLFloaterSnapshot::Impl::onImageFormatChange(LLFloaterSnapshotBase* view)
 {
 	if (view)
 	{
 		gSavedSettings.setS32("SnapshotFormat", getImageFormat(view));
 		LL_DEBUGS() << "image format changed, updating snapshot" << LL_ENDL;
-		getPreviewView(view)->updateSnapshot(TRUE);
+		getPreviewView()->updateSnapshot(TRUE);
 		updateControls(view);
 	}
 }
 
 // Sets the named size combo to "custom" mode.
-// static
-void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
+void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshotBase* floater, const std::string& comboname)
 {
 	LLComboBox* combo = floater->getChild<LLComboBox>(comboname);
 	combo->setCurrentByIndex(combo->getItemCount() - 1); // "custom" is always the last index
@@ -939,7 +822,6 @@ void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const s
 }
 
 // Update supplied width and height according to the constrain proportions flag; limit them by max_val.
-//static
 BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value)
 {
 	S32 w = width ;
@@ -984,20 +866,18 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3
 	return (w != width || h != height) ;
 }
 
-//static
-void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshot *view, S32 width, S32 height)
+void LLFloaterSnapshot::Impl::setImageSizeSpinnersValues(LLFloaterSnapshotBase* view, S32 width, S32 height)
 {
 	getWidthSpinner(view)->forceSetValue(width);
 	getHeightSpinner(view)->forceSetValue(height);
-	if (getActiveSnapshotType(view) == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+	if (getActiveSnapshotType(view) == LLSnapshotModel::SNAPSHOT_TEXTURE)
 	{
 		getWidthSpinner(view)->setIncrement(width >> 1);
 		getHeightSpinner(view)->setIncrement(height >> 1);
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshot* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed)
+void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed)
 {
 	getWidthSpinner(view)->resetDirty();
 	getHeightSpinner(view)->resetDirty();
@@ -1007,13 +887,12 @@ void LLFloaterSnapshot::Impl::updateSpinners(LLFloaterSnapshot* view, LLSnapshot
 	}
 }
 
-// static
-void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32 w, S32 h)
+void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshotBase* view, S32 w, S32 h)
 {
 	LL_DEBUGS() << "applyCustomResolution(" << w << ", " << h << ")" << LL_ENDL;
 	if (!view) return;
 
-	LLSnapshotLivePreview* previewp = getPreviewView(view);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (previewp)
 	{
 		S32 curw,curh;
@@ -1037,16 +916,15 @@ void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshot* view, S32
 }
 
 // static
-void LLFloaterSnapshot::Impl::onSnapshotUploadFinished(bool status)
+void LLFloaterSnapshotBase::ImplBase::onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status)
 {
-	setStatus(STATUS_FINISHED, status, "profile");
+	floater->impl->setStatus(STATUS_FINISHED, status, "profile");
 }
 
-
 // static
-void LLFloaterSnapshot::Impl::onSendingPostcardFinished(bool status)
+void LLFloaterSnapshot::Impl::onSendingPostcardFinished(LLFloaterSnapshotBase* floater, bool status)
 {
-	setStatus(STATUS_FINISHED, status, "postcard");
+	floater->impl->setStatus(STATUS_FINISHED, status, "postcard");
 }
 
 ///----------------------------------------------------------------------------
@@ -1055,12 +933,27 @@ void LLFloaterSnapshot::Impl::onSendingPostcardFinished(bool status)
 
 // Default constructor
 LLFloaterSnapshotBase::LLFloaterSnapshotBase(const LLSD& key)
-    : LLFloater(key)
+    : LLFloater(key),
+	  mRefreshBtn(NULL),
+	  mRefreshLabel(NULL),
+	  mSucceessLblPanel(NULL),
+	  mFailureLblPanel(NULL)
 {
 }
 
 LLFloaterSnapshotBase::~LLFloaterSnapshotBase()
 {
+	if (impl->mPreviewHandle.get()) impl->mPreviewHandle.get()->die();
+
+	//unfreeze everything else
+	gSavedSettings.setBOOL("FreezeTime", FALSE);
+
+	if (impl->mLastToolset)
+	{
+		LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset);
+	}
+
+	delete impl;
 }
 
 ///----------------------------------------------------------------------------
@@ -1069,57 +962,41 @@ LLFloaterSnapshotBase::~LLFloaterSnapshotBase()
 
 // Default constructor
 LLFloaterSnapshot::LLFloaterSnapshot(const LLSD& key)
-    : LLFloaterSnapshotBase(key),
-	  mRefreshBtn(NULL),
-	  mRefreshLabel(NULL),
-	  mSucceessLblPanel(NULL),
-	  mFailureLblPanel(NULL),
-	  impl (*(new Impl))
+    : LLFloaterSnapshotBase(key)
 {
+	impl = new Impl(this);
 }
 
-// Destroys the object
 LLFloaterSnapshot::~LLFloaterSnapshot()
 {
-	if (impl.mPreviewHandle.get()) impl.mPreviewHandle.get()->die();
-
-	//unfreeze everything else
-	gSavedSettings.setBOOL("FreezeTime", FALSE);
-
-	if (impl.mLastToolset)
-	{
-		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
-	}
-
-	delete &impl;
 }
 
-
+// virtual
 BOOL LLFloaterSnapshot::postBuild()
 {
 	mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
-	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
+	childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
 	mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
 	mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
 	mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
 
-	childSetCommitCallback("ui_check", Impl::onClickUICheck, this);
+	childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
 	getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
 
-	childSetCommitCallback("hud_check", Impl::onClickHUDCheck, this);
+	childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
 	getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
 
-	impl.setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot"));
+	((Impl*)impl)->setAspectRatioCheckboxValue(this, gSavedSettings.getBOOL("KeepAspectForSnapshot"));
 
 	childSetCommitCallback("layer_types", Impl::onCommitLayerTypes, this);
 	getChild<LLUICtrl>("layer_types")->setValue("colors");
 	getChildView("layer_types")->setEnabled(FALSE);
 
 	getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
-	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
+	childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
 
 	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
-	childSetCommitCallback("auto_snapshot_check", Impl::onClickAutoSnap, this);
+	childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
     
 
 	// Filters
@@ -1129,10 +1006,10 @@ BOOL LLFloaterSnapshot::postBuild()
     {
         filterbox->add(filter_list[i]);
     }
-    childSetCommitCallback("filters_combobox", Impl::onClickFilter, this);
+    childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
     
-	LLWebProfile::setImageUploadResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSnapshotUploadFinished, _1));
-	LLPostCard::setPostResultCallback(boost::bind(&LLFloaterSnapshot::Impl::onSendingPostcardFinished, _1));
+	LLWebProfile::setImageUploadResultCallback(boost::bind(&ImplBase::onSnapshotUploadFinished, this, _1));
+	LLPostCard::setPostResultCallback(boost::bind(&Impl::onSendingPostcardFinished, this, _1));
 
 	sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 
@@ -1159,10 +1036,10 @@ BOOL LLFloaterSnapshot::postBuild()
 	getChild<LLComboBox>("local_size_combo")->selectNthItem(8);
 	getChild<LLComboBox>("local_format_combo")->selectNthItem(0);
 
-	impl.mPreviewHandle = previewp->getHandle();
+	impl->mPreviewHandle = previewp->getHandle();
     previewp->setContainer(this);
-	impl.updateControls(this);
-	impl.updateLayout(this);
+	impl->updateControls(this);
+	impl->updateLayout(this);
 	
 
 	previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect());
@@ -1170,9 +1047,10 @@ BOOL LLFloaterSnapshot::postBuild()
 	return TRUE;
 }
 
-void LLFloaterSnapshot::draw()
+// virtual
+void LLFloaterSnapshotBase::draw()
 {
-	LLSnapshotLivePreview* previewp = impl.getPreviewView(this);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 
 	if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock()))
 	{
@@ -1186,7 +1064,7 @@ void LLFloaterSnapshot::draw()
 	{		
 		if(previewp->getThumbnailImage())
 		{
-			bool working = impl.getStatus() == Impl::STATUS_WORKING;
+			bool working = impl->getStatus() == ImplBase::STATUS_WORKING;
 			const LLRect& thumbnail_rect = getThumbnailPlaceholderRect();
 			const S32 thumbnail_w = previewp->getThumbnailWidth();
 			const S32 thumbnail_h = previewp->getThumbnailHeight();
@@ -1215,12 +1093,13 @@ void LLFloaterSnapshot::draw()
 			gGL.popUIMatrix();
 		}
 	}
-	impl.updateLayout(this);
+	impl->updateLayout(this);
 }
 
+//virtual
 void LLFloaterSnapshot::onOpen(const LLSD& key)
 {
-	LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(this);
+	LLSnapshotLivePreview* preview = getPreviewView();
 	if(preview)
 	{
 		LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
@@ -1231,19 +1110,20 @@ void LLFloaterSnapshot::onOpen(const LLSD& key)
 	gSnapshotFloaterView->setVisible(TRUE);
 	gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
 
-	impl.updateControls(this);
-	impl.updateLayout(this);
+	impl->updateControls(this);
+	impl->updateLayout(this);
 
 	// Initialize default tab.
 	getChild<LLSideTrayPanelContainer>("panel_container")->getCurrentPanel()->onOpen(LLSD());
 }
 
-void LLFloaterSnapshot::onClose(bool app_quitting)
+//virtual
+void LLFloaterSnapshotBase::onClose(bool app_quitting)
 {
 	getParent()->setMouseOpaque(FALSE);
 
 	//unfreeze everything, hide fullscreen preview
-	LLSnapshotLivePreview* previewp = LLFloaterSnapshot::Impl::getPreviewView(this);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (previewp)
 	{
 		previewp->setVisible(FALSE);
@@ -1251,146 +1131,150 @@ void LLFloaterSnapshot::onClose(bool app_quitting)
 	}
 
 	gSavedSettings.setBOOL("FreezeTime", FALSE);
-	impl.mAvatarPauseHandles.clear();
+	impl->mAvatarPauseHandles.clear();
 
-	if (impl.mLastToolset)
+	if (impl->mLastToolset)
 	{
-		LLToolMgr::getInstance()->setCurrentToolset(impl.mLastToolset);
+		LLToolMgr::getInstance()->setCurrentToolset(impl->mLastToolset);
 	}
 }
 
 // virtual
-S32 LLFloaterSnapshot::notify(const LLSD& info)
+S32 LLFloaterSnapshotBase::notify(const LLSD& info)
 {
-	// A child panel wants to change snapshot resolution.
-	if (info.has("combo-res-change"))
+	if (info.has("set-ready"))
 	{
-		std::string combo_name = info["combo-res-change"]["control-name"].asString();
-		impl.updateResolution(getChild<LLUICtrl>(combo_name), this);
+		impl->setStatus(ImplBase::STATUS_READY);
 		return 1;
 	}
 
-	if (info.has("custom-res-change"))
+	if (info.has("set-working"))
 	{
-		LLSD res = info["custom-res-change"];
-		impl.applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger());
+		impl->setStatus(ImplBase::STATUS_WORKING);
 		return 1;
 	}
 
-	if (info.has("keep-aspect-change"))
+	if (info.has("set-finished"))
 	{
-		impl.applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean());
+		LLSD data = info["set-finished"];
+		impl->setStatus(ImplBase::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString());
 		return 1;
 	}
 
-	if (info.has("image-quality-change"))
+	if (info.has("snapshot-updating"))
 	{
-		impl.onImageQualityChange(this, info["image-quality-change"].asInteger());
+		// Disable the send/post/save buttons until snapshot is ready.
+		impl->updateControls(this);
 		return 1;
 	}
 
-	if (info.has("image-format-change"))
+	if (info.has("snapshot-updated"))
 	{
-		impl.onImageFormatChange(this);
+		// Enable the send/post/save buttons.
+		impl->updateControls(this);
+		// We've just done refresh.
+		impl->setNeedRefresh(false);
+
+		// The refresh button is initially hidden. We show it after the first update,
+		// i.e. when preview appears.
+		if (!mRefreshBtn->getVisible())
+		{
+			mRefreshBtn->setVisible(true);
+		}
 		return 1;
 	}
 
-	if (info.has("set-ready"))
+	return 0;
+}
+
+// virtual
+S32 LLFloaterSnapshot::notify(const LLSD& info)
+{
+	bool res = LLFloaterSnapshotBase::notify(info);
+	if (res)
+		return res;
+	// A child panel wants to change snapshot resolution.
+	if (info.has("combo-res-change"))
 	{
-		impl.setStatus(Impl::STATUS_READY);
+		std::string combo_name = info["combo-res-change"]["control-name"].asString();
+		((Impl*)impl)->updateResolution(getChild<LLUICtrl>(combo_name), this);
 		return 1;
 	}
 
-	if (info.has("set-working"))
+	if (info.has("custom-res-change"))
 	{
-		impl.setStatus(Impl::STATUS_WORKING);
+		LLSD res = info["custom-res-change"];
+		((Impl*)impl)->applyCustomResolution(this, res["w"].asInteger(), res["h"].asInteger());
 		return 1;
 	}
 
-	if (info.has("set-finished"))
+	if (info.has("keep-aspect-change"))
 	{
-		LLSD data = info["set-finished"];
-		impl.setStatus(Impl::STATUS_FINISHED, data["ok"].asBoolean(), data["msg"].asString());
+		((Impl*)impl)->applyKeepAspectCheck(this, info["keep-aspect-change"].asBoolean());
 		return 1;
 	}
-    
-	if (info.has("snapshot-updating"))
+
+	if (info.has("image-quality-change"))
 	{
-        // Disable the send/post/save buttons until snapshot is ready.
-        impl.updateControls(this);
+		((Impl*)impl)->onImageQualityChange(this, info["image-quality-change"].asInteger());
 		return 1;
 	}
 
-	if (info.has("snapshot-updated"))
+	if (info.has("image-format-change"))
 	{
-        // Enable the send/post/save buttons.
-        impl.updateControls(this);
-        // We've just done refresh.
-        impl.setNeedRefresh(this, false);
-            
-        // The refresh button is initially hidden. We show it after the first update,
-        // i.e. when preview appears.
-        if (!mRefreshBtn->getVisible())
-        {
-            mRefreshBtn->setVisible(true);
-        }
+		((Impl*)impl)->onImageFormatChange(this);
 		return 1;
-	}    
+	}
     
 	return 0;
 }
 
-//static 
-void LLFloaterSnapshot::update()
+void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
 {
-	LLFloaterSnapshot* inst = findInstance();
-	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); 
-	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); 
-	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); 
+	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
+	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
+	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
 
-	if (!inst && !floater_facebook && !floater_flickr && !floater_twitter)
+	if (!mFloater && !floater_facebook && !floater_flickr && !floater_twitter)
 		return;
-	
+
 	BOOL changed = FALSE;
 	LL_DEBUGS() << "npreviews: " << LLSnapshotLivePreview::sList.size() << LL_ENDL;
 	for (std::set<LLSnapshotLivePreview*>::iterator iter = LLSnapshotLivePreview::sList.begin();
-		 iter != LLSnapshotLivePreview::sList.end(); ++iter)
+		iter != LLSnapshotLivePreview::sList.end(); ++iter)
 	{
 		changed |= LLSnapshotLivePreview::onIdle(*iter);
 	}
-    
-	if (inst && changed)
+
+	if (mFloater && changed)
 	{
 		LL_DEBUGS() << "changed" << LL_ENDL;
-		inst->impl.updateControls(inst);
+		updateControls(mFloater);
 	}
 }
 
-// static
-LLFloaterSnapshot* LLFloaterSnapshot::getInstance()
+//static 
+void LLFloaterSnapshot::update()
 {
-	return LLFloaterReg::getTypedInstance<LLFloaterSnapshot>("snapshot");
+	LLFloaterSnapshot* inst = getInstance();
+	if (inst != NULL)
+	{
+		inst->impl->updateLivePreview();
+	}
 }
 
 // static
-LLFloaterSnapshot* LLFloaterSnapshot::findInstance()
+LLFloaterSnapshot* LLFloaterSnapshot::getInstance()
 {
-	return LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
+	return LLFloaterReg::getTypedInstance<LLFloaterSnapshot>("snapshot");
 }
 
-// static
+// virtual
 void LLFloaterSnapshot::saveTexture()
 {
 	LL_DEBUGS() << "saveTexture" << LL_ENDL;
 
-	// FIXME: duplicated code
-	LLFloaterSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return;
-	}
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (!previewp)
 	{
 		llassert(previewp != NULL);
@@ -1400,18 +1284,10 @@ void LLFloaterSnapshot::saveTexture()
 	previewp->saveTexture();
 }
 
-// static
 BOOL LLFloaterSnapshot::saveLocal()
 {
 	LL_DEBUGS() << "saveLocal" << LL_ENDL;
-	// FIXME: duplicated code
-    LLFloaterSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return FALSE;
-	}
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (!previewp)
 	{
 		llassert(previewp != NULL);
@@ -1421,43 +1297,26 @@ BOOL LLFloaterSnapshot::saveLocal()
 	return previewp->saveLocal();
 }
 
-// static
-void LLFloaterSnapshot::postSave()
+void LLFloaterSnapshotBase::postSave()
 {
-	LLFloaterSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return;
-	}
-
-	instance->impl.updateControls(instance);
-	instance->impl.setStatus(Impl::STATUS_WORKING);
+	impl->updateControls(this);
+	impl->setStatus(ImplBase::STATUS_WORKING);
 }
 
-// static
-void LLFloaterSnapshot::postPanelSwitch()
+// virtual
+void LLFloaterSnapshotBase::postPanelSwitch()
 {
-	LLFloaterSnapshot* instance = getInstance();
-	instance->impl.updateControls(instance);
+	impl->updateControls(this);
 
 	// Remove the success/failure indicator whenever user presses a snapshot option button.
-	instance->impl.setStatus(Impl::STATUS_READY);
+	impl->setStatus(ImplBase::STATUS_READY);
 }
 
-// static
-LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData()
+LLPointer<LLImageFormatted> LLFloaterSnapshotBase::getImageData()
 {
 	// FIXME: May not work for textures.
 
-	LLFloaterSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return NULL;
-	}
-
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (!previewp)
 	{
 		llassert(previewp != NULL);
@@ -1474,17 +1333,9 @@ LLPointer<LLImageFormatted> LLFloaterSnapshot::getImageData()
 	return img;
 }
 
-// static
-const LLVector3d& LLFloaterSnapshot::getPosTakenGlobal()
+const LLVector3d& LLFloaterSnapshotBase::getPosTakenGlobal()
 {
-	LLFloaterSnapshot* instance = findInstance();
-	if (!instance)
-	{
-		llassert(instance != NULL);
-		return LLVector3d::zero;
-	}
-
-	LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
+	LLSnapshotLivePreview* previewp = getPreviewView();
 	if (!previewp)
 	{
 		llassert(previewp != NULL);
@@ -1497,7 +1348,7 @@ const LLVector3d& LLFloaterSnapshot::getPosTakenGlobal()
 // static
 void LLFloaterSnapshot::setAgentEmail(const std::string& email)
 {
-	LLFloaterSnapshot* instance = findInstance();
+	LLFloaterSnapshot* instance = getInstance();
 	if (instance)
 	{
 		LLSideTrayPanelContainer* panel_container = instance->getChild<LLSideTrayPanelContainer>("panel_container");
@@ -1518,6 +1369,7 @@ LLSnapshotFloaterView::~LLSnapshotFloaterView()
 {
 }
 
+// virtual
 BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 {
 	// use default handler when not in freeze-frame mode
@@ -1539,6 +1391,7 @@ BOOL LLSnapshotFloaterView::handleKey(KEY key, MASK mask, BOOL called_from_paren
 	return TRUE;
 }
 
+// virtual
 BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	// use default handler when not in freeze-frame mode
@@ -1554,6 +1407,7 @@ BOOL LLSnapshotFloaterView::handleMouseDown(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+// virtual
 BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
 {
 	// use default handler when not in freeze-frame mode
@@ -1569,6 +1423,7 @@ BOOL LLSnapshotFloaterView::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+// virtual
 BOOL LLSnapshotFloaterView::handleHover(S32 x, S32 y, MASK mask)
 {
 	// use default handler when not in freeze-frame mode
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 5f9857c8c5..431888d2d0 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -4,7 +4,7 @@
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2016, Linden Research, Inc.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -27,36 +27,109 @@
 #ifndef LL_LLFLOATERSNAPSHOT_H
 #define LL_LLFLOATERSNAPSHOT_H
 
+#include "llagent.h"
 #include "llfloater.h"
+#include "llpanelsnapshot.h"
+#include "llsnapshotmodel.h"
 
 class LLSpinCtrl;
+class LLSnapshotLivePreview;
 
 class LLFloaterSnapshotBase : public LLFloater
 {
     LOG_CLASS(LLFloaterSnapshotBase);
 
 public:
-    typedef enum e_snapshot_format
-    {
-        SNAPSHOT_FORMAT_PNG,
-        SNAPSHOT_FORMAT_JPEG,
-        SNAPSHOT_FORMAT_BMP
-    } ESnapshotFormat;
 
     LLFloaterSnapshotBase(const LLSD& key);
     virtual ~LLFloaterSnapshotBase();
 
-    ///*virtual*/ S32 notify(const LLSD& info);
+	/*virtual*/ void draw();
+	/*virtual*/ void onClose(bool app_quitting);
+	virtual S32 notify(const LLSD& info);
 
-    //static LLFloaterSnapshotBase* getInstance();
-    //static LLFloaterSnapshotBase* findInstance();
-    //static void saveTexture();
-    //static BOOL saveLocal();
-    //static void postSave();
+	// TODO: create a snapshot model instead
+	virtual void saveTexture() = 0;
+	void postSave();
+	virtual void postPanelSwitch();
+	LLPointer<LLImageFormatted> getImageData();
+	LLSnapshotLivePreview* getPreviewView();
+	const LLVector3d& getPosTakenGlobal();
+
+	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
+
+	void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
+	void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
+	void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
+
+	class ImplBase;
+	friend ImplBase;
+	ImplBase* impl;
 
 protected:
-    class ImplBase;
-    //ImplBase& impl;
+	static LLUICtrl* sThumbnailPlaceholder;
+	LLUICtrl *mRefreshBtn, *mRefreshLabel;
+	LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
+};
+
+class LLFloaterSnapshotBase::ImplBase
+{
+public:
+	typedef enum e_status
+	{
+		STATUS_READY,
+		STATUS_WORKING,
+		STATUS_FINISHED
+	} EStatus;
+
+	ImplBase(LLFloaterSnapshotBase* floater) : mAvatarPauseHandles(),
+		mLastToolset(NULL),
+		mAspectRatioCheckOff(false),
+		mNeedRefresh(false),
+		mStatus(STATUS_READY),
+		mFloater(floater)
+	{}
+	virtual ~ImplBase()
+	{
+		//unpause avatars
+		mAvatarPauseHandles.clear();
+	}
+
+	static void onClickNewSnapshot(void* data);
+	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
+	static void onClickFilter(LLUICtrl *ctrl, void* data);
+	static void onClickUICheck(LLUICtrl *ctrl, void* data);
+	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
+	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
+	static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
+
+	virtual LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) = 0;
+	virtual LLSnapshotModel::ESnapshotType getActiveSnapshotType(LLFloaterSnapshotBase* floater);
+	virtual LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater) = 0;
+	virtual std::string getSnapshotPanelPrefix() = 0;
+
+	LLSnapshotLivePreview* getPreviewView();
+	virtual void updateControls(LLFloaterSnapshotBase* floater) = 0;
+	virtual void updateLayout(LLFloaterSnapshotBase* floater);
+	virtual void updateLivePreview();
+	virtual void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null);
+	virtual EStatus getStatus() const { return mStatus; }
+	virtual void setNeedRefresh(bool need);
+
+	virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
+	virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
+	void setWorking(bool working);
+	virtual void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) = 0;
+
+public:
+	LLFloaterSnapshotBase* mFloater;
+	std::vector<LLAnimPauseRequest> mAvatarPauseHandles;
+
+	LLToolset*	mLastToolset;
+	LLHandle<LLView> mPreviewHandle;
+	bool mAspectRatioCheckOff;
+	bool mNeedRefresh;
+	EStatus mStatus;
 };
 
 class LLFloaterSnapshot : public LLFloaterSnapshotBase
@@ -64,51 +137,65 @@ class LLFloaterSnapshot : public LLFloaterSnapshotBase
 	LOG_CLASS(LLFloaterSnapshot);
 
 public:
-	//typedef enum e_snapshot_format
-	//{
-	//	SNAPSHOT_FORMAT_PNG,
-	//	SNAPSHOT_FORMAT_JPEG,
-	//	SNAPSHOT_FORMAT_BMP
-	//} ESnapshotFormat;
-
 	LLFloaterSnapshot(const LLSD& key);
-	virtual ~LLFloaterSnapshot();
+	/*virtual*/ ~LLFloaterSnapshot();
     
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
 	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ S32 notify(const LLSD& info);
 	
 	static void update();
 
-	// TODO: create a snapshot model instead
 	static LLFloaterSnapshot* getInstance();
-	static LLFloaterSnapshot* findInstance();
-	static void saveTexture();
-	static BOOL saveLocal();
-	static void postSave();
-	static void postPanelSwitch();
-	static LLPointer<LLImageFormatted> getImageData();
-	static const LLVector3d& getPosTakenGlobal();
+	/*virtual*/ void saveTexture();
+	BOOL saveLocal();
 	static void setAgentEmail(const std::string& email);
 
-	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
-
-private:
-	static LLUICtrl* sThumbnailPlaceholder;
-	LLUICtrl *mRefreshBtn, *mRefreshLabel;
-	LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
-
 	class Impl;
-	Impl& impl;
+	friend Impl;
 };
 
-class LLFloaterSnapshotBase::ImplBase
+///----------------------------------------------------------------------------
+/// Class LLFloaterSnapshot::Impl
+///----------------------------------------------------------------------------
+
+class LLFloaterSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase
 {
+	LOG_CLASS(LLFloaterSnapshot::Impl);
 public:
-    ImplBase();
-    ~ImplBase();
+	Impl(LLFloaterSnapshotBase* floater)
+		: LLFloaterSnapshotBase::ImplBase(floater)
+	{}
+	~Impl()
+	{}
+
+	void applyKeepAspectCheck(LLFloaterSnapshotBase* view, BOOL checked);
+	void updateResolution(LLUICtrl* ctrl, void* data, BOOL do_update = TRUE);
+	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
+	void onImageQualityChange(LLFloaterSnapshotBase* view, S32 quality_val);
+	void onImageFormatChange(LLFloaterSnapshotBase* view);
+	void applyCustomResolution(LLFloaterSnapshotBase* view, S32 w, S32 h);
+	static void onSendingPostcardFinished(LLFloaterSnapshotBase* floater, bool status);
+	BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
+	void setImageSizeSpinnersValues(LLFloaterSnapshotBase *view, S32 width, S32 height);
+	void updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
+
+	/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
+	/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
+	LLSpinCtrl* getWidthSpinner(LLFloaterSnapshotBase* floater);
+	LLSpinCtrl* getHeightSpinner(LLFloaterSnapshotBase* floater);
+	void enableAspectRatioCheckbox(LLFloaterSnapshotBase* floater, BOOL enable);
+	void setAspectRatioCheckboxValue(LLFloaterSnapshotBase* floater, BOOL checked);
+	/*virtual*/ std::string getSnapshotPanelPrefix();
+
+	void setResolution(LLFloaterSnapshotBase* floater, const std::string& comboname);
+	/*virtual*/ void updateControls(LLFloaterSnapshotBase* floater);
+
+private:
+	/*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater);
+	void comboSetCustom(LLFloaterSnapshotBase *floater, const std::string& comboname);
+	void checkAspectRatio(LLFloaterSnapshotBase *view, S32 index);
+	void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null);
 };
 
 class LLSnapshotFloaterView : public LLFloaterView
diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
index 984ba587ed..4bab89ace2 100644
--- a/indra/newview/llfloatertwitter.cpp
+++ b/indra/newview/llfloatertwitter.cpp
@@ -241,8 +241,8 @@ void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible)
 			mPreviewHandle = previewp->getHandle();
 
             previewp->setContainer(this);
-            previewp->setSnapshotType(LLPanelSnapshot::SNAPSHOT_WEB);
-			previewp->setSnapshotFormat(LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
+            previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
+            previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
             previewp->setThumbnailSubsampled(TRUE);     // We want the preview to reflect the *saved* image
             previewp->setAllowRenderUI(FALSE);          // We do not want the rendered UI in our snapshots
             previewp->setAllowFullScreenPreview(FALSE);  // No full screen preview in SL Share mode
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 7bd9c0bd94..f6af3d63f6 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1115,8 +1115,12 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
 void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id)
 {
     LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot");
-    LLFloaterOutfitSnapshot::getInstance()->setOutfitID(selected_outfit_id);
-    LLFloaterOutfitSnapshot::getInstance()->setGallery(this);
+    LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance();
+    if (snapshot_floater)
+    {
+        snapshot_floater->setOutfitID(selected_outfit_id);
+        snapshot_floater->getInstance()->setGallery(this);
+    }
 }
 
 void LLOutfitGallery::onBeforeOutfitSnapshotSave()
diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp
index e320c4ce8b..a17e3f9e78 100644
--- a/indra/newview/llpanelsnapshot.cpp
+++ b/indra/newview/llpanelsnapshot.cpp
@@ -29,6 +29,8 @@
 
 // libs
 #include "llcombobox.h"
+#include "llfloater.h"
+#include "llfloatersnapshot.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
 #include "lltrans.h"
@@ -50,6 +52,10 @@ S32 power_of_two(S32 sz, S32 upper)
 	return res;
 }
 
+LLPanelSnapshot::LLPanelSnapshot()
+	: mSnapshotFloater(NULL)
+{}
+
 // virtual
 BOOL LLPanelSnapshot::postBuild()
 {
@@ -67,6 +73,8 @@ BOOL LLPanelSnapshot::postBuild()
         getChild<LLUICtrl>(getAspectRatioCBName())->setCommitCallback(boost::bind(&LLPanelSnapshot::onKeepAspectRatioCommit, this, _1));
     }
 	updateControls(LLSD());
+
+	mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>();
 	return TRUE;
 }
 
@@ -88,9 +96,9 @@ void LLPanelSnapshot::onOpen(const LLSD& key)
 	}
 }
 
-LLFloaterSnapshotBase::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
+LLSnapshotModel::ESnapshotFormat LLPanelSnapshot::getImageFormat() const
 {
-	return LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
+	return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG;
 }
 
 void LLPanelSnapshot::enableControls(BOOL enable)
@@ -228,7 +236,7 @@ void LLPanelSnapshot::onKeepAspectRatioCommit(LLUICtrl* ctrl)
     getParentByType<LLFloater>()->notify(LLSD().with("keep-aspect-change", ctrl->getValue().asBoolean()));
 }
 
-LLPanelSnapshot::ESnapshotType LLPanelSnapshot::getSnapshotType()
+LLSnapshotModel::ESnapshotType LLPanelSnapshot::getSnapshotType()
 {
-    return LLPanelSnapshot::SNAPSHOT_WEB;
+	return LLSnapshotModel::SNAPSHOT_WEB;
 }
diff --git a/indra/newview/llpanelsnapshot.h b/indra/newview/llpanelsnapshot.h
index 3868020cdf..55273797cc 100644
--- a/indra/newview/llpanelsnapshot.h
+++ b/indra/newview/llpanelsnapshot.h
@@ -27,9 +27,13 @@
 #ifndef LL_LLPANELSNAPSHOT_H
 #define LL_LLPANELSNAPSHOT_H
 
-#include "llfloatersnapshot.h"
+//#include "llfloatersnapshot.h"
+#include "llpanel.h"
+#include "llsnapshotmodel.h"
 
+class LLSpinCtrl;
 class LLSideTrayPanelContainer;
+class LLFloaterSnapshotBase;
 
 /**
  * Snapshot panel base class.
@@ -37,13 +41,7 @@ class LLSideTrayPanelContainer;
 class LLPanelSnapshot: public LLPanel
 {
 public:
-    enum ESnapshotType
-    {
-        SNAPSHOT_POSTCARD,
-        SNAPSHOT_TEXTURE,
-        SNAPSHOT_LOCAL,
-        SNAPSHOT_WEB
-    };
+	LLPanelSnapshot();
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
@@ -59,8 +57,8 @@ public:
 	virtual LLSpinCtrl* getWidthSpinner();
 	virtual LLSpinCtrl* getHeightSpinner();
 	virtual void enableAspectRatioCheckbox(BOOL enable);
-    virtual LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const;
-    virtual ESnapshotType getSnapshotType();
+    virtual LLSnapshotModel::ESnapshotFormat getImageFormat() const;
+	virtual LLSnapshotModel::ESnapshotType getSnapshotType();
 	virtual void updateControls(const LLSD& info) = 0; ///< Update controls from saved settings
 	void enableControls(BOOL enable);
 
@@ -74,6 +72,8 @@ protected:
 	void onCustomResolutionCommit();
 	void onResolutionComboCommit(LLUICtrl* ctrl);
 	void onKeepAspectRatioCommit(LLUICtrl* ctrl);
+
+	LLFloaterSnapshotBase* mSnapshotFloater;
 };
 
 #endif // LL_LLPANELSNAPSHOT_H
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index 057e046e30..408eb8fbf3 100644
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -32,7 +32,6 @@
 #include "llspinctrl.h"
 
 #include "llfloatersnapshot.h" // FIXME: replace with a snapshot storage model
-#include "llfloateroutfitsnapshot.h"
 #include "llpanelsnapshot.h"
 #include "llsnapshotlivepreview.h"
 #include "llviewercontrol.h" // gSavedSettings
@@ -48,10 +47,10 @@ class LLPanelSnapshotInventoryBase
 public:
     LLPanelSnapshotInventoryBase();
 
+	/*virtual*/ BOOL postBuild();
 protected:
-    virtual void onSend() = 0;
-    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
-
+    void onSend();
+    /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
 };
 
 class LLPanelSnapshotInventory
@@ -74,7 +73,6 @@ private:
 	/*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
 	/*virtual*/ void updateControls(const LLSD& info);
 
-    /*virtual*/ void onSend();
 };
 
 class LLPanelOutfitSnapshotInventory
@@ -95,7 +93,6 @@ private:
     /*virtual*/ std::string getImageSizePanelName() const	{ return LLStringUtil::null; }
     /*virtual*/ void updateControls(const LLSD& info);
 
-    /*virtual*/ void onSend();
     /*virtual*/ void cancel();
 };
 
@@ -107,9 +104,14 @@ LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase()
 {
 }
 
-LLPanelSnapshot::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType()
+BOOL LLPanelSnapshotInventoryBase::postBuild()
+{
+    return LLPanelSnapshot::postBuild();
+}
+
+LLSnapshotModel::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType()
 {
-    return LLPanelSnapshot::SNAPSHOT_TEXTURE;
+    return LLSnapshotModel::SNAPSHOT_TEXTURE;
 }
 
 LLPanelSnapshotInventory::LLPanelSnapshotInventory()
@@ -125,7 +127,7 @@ BOOL LLPanelSnapshotInventory::postBuild()
 	getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(FALSE);
 
 	getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1));
-	return LLPanelSnapshot::postBuild();
+	return LLPanelSnapshotInventoryBase::postBuild();
 }
 
 // virtual
@@ -149,10 +151,13 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
 	getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected);
 }
 
-void LLPanelSnapshotInventory::onSend()
+void LLPanelSnapshotInventoryBase::onSend()
 {
-	LLFloaterSnapshot::saveTexture();
-	LLFloaterSnapshot::postSave();
+    if (mSnapshotFloater)
+    {
+        mSnapshotFloater->saveTexture();
+        mSnapshotFloater->postSave();
+    }
 }
 
 LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory()
@@ -164,7 +169,7 @@ LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory()
 // virtual
 BOOL LLPanelOutfitSnapshotInventory::postBuild()
 {
-    return LLPanelSnapshot::postBuild();
+    return LLPanelSnapshotInventoryBase::postBuild();
 }
 
 // virtual
@@ -181,13 +186,10 @@ void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info)
     getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot);
 }
 
-void LLPanelOutfitSnapshotInventory::onSend()
-{
-    LLFloaterOutfitSnapshot::saveTexture();
-    LLFloaterOutfitSnapshot::postSave();
-}
-
 void LLPanelOutfitSnapshotInventory::cancel()
 {
-    getParentByType<LLFloater>()->closeFloater();
+    if (mSnapshotFloater)
+    {
+        mSnapshotFloater->closeFloater();
+    }
 }
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 954eb63a28..3652c10586 100644
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -56,9 +56,9 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "local_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "local_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "local_image_size_lp"; }
-    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const;
-    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
-    /*virtual*/ void updateControls(const LLSD& info);
+	/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const;
+	/*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
+	/*virtual*/ void updateControls(const LLSD& info);
 
 	S32 mLocalFormat;
 
@@ -96,23 +96,23 @@ void LLPanelSnapshotLocal::onOpen(const LLSD& key)
 }
 
 // virtual
-LLFloaterSnapshotBase::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
+LLSnapshotModel::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() const
 {
-    LLFloaterSnapshotBase::ESnapshotFormat fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
+	LLSnapshotModel::ESnapshotFormat fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
 
 	LLComboBox* local_format_combo = getChild<LLComboBox>("local_format_combo");
 	const std::string id  = local_format_combo->getValue().asString();
 	if (id == "PNG")
 	{
-		fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG;
+		fmt = LLSnapshotModel::SNAPSHOT_FORMAT_PNG;
 	}
 	else if (id == "JPEG")
 	{
-		fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG;
+		fmt = LLSnapshotModel::SNAPSHOT_FORMAT_JPEG;
 	}
 	else if (id == "BMP")
 	{
-		fmt = LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP;
+		fmt = LLSnapshotModel::SNAPSHOT_FORMAT_BMP;
 	}
 
 	return fmt;
@@ -121,11 +121,11 @@ LLFloaterSnapshotBase::ESnapshotFormat LLPanelSnapshotLocal::getImageFormat() co
 // virtual
 void LLPanelSnapshotLocal::updateControls(const LLSD& info)
 {
-    LLFloaterSnapshotBase::ESnapshotFormat fmt =
-        (LLFloaterSnapshotBase::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
+	LLSnapshotModel::ESnapshotFormat fmt =
+		(LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
 	getChild<LLComboBox>("local_format_combo")->selectNthItem((S32) fmt);
 
-	const bool show_quality_ctrls = (fmt == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
+	const bool show_quality_ctrls = (fmt == LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
 	getChild<LLUICtrl>("image_quality_slider")->setVisible(show_quality_ctrls);
 	getChild<LLUICtrl>("image_quality_level")->setVisible(show_quality_ctrls);
 
@@ -164,10 +164,10 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
 	LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
 
 	floater->notify(LLSD().with("set-working", true));
-	BOOL saved = LLFloaterSnapshot::saveLocal();
+	BOOL saved = floater->saveLocal();
 	if (saved)
 	{
-		LLFloaterSnapshot::postSave();
+		mSnapshotFloater->postSave();
 		goBack();
 		floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
 	}
@@ -177,7 +177,7 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
 	}
 }
 
-LLPanelSnapshot::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
+LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
 {
-    return LLPanelSnapshot::SNAPSHOT_LOCAL;
+	return LLSnapshotModel::SNAPSHOT_LOCAL;
 }
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 0fc9ceec83..269f16c5e4 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -62,6 +62,8 @@ private:
 	void onSendToFacebook();
 	void onSendToTwitter();
 	void onSendToFlickr();
+
+	LLFloaterSnapshotBase* mSnapshotFloater;
 };
 
 static LLPanelInjector<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions");
@@ -86,6 +88,7 @@ LLPanelSnapshotOptions::~LLPanelSnapshotOptions()
 // virtual
 BOOL LLPanelSnapshotOptions::postBuild()
 {
+	mSnapshotFloater = getParentByType<LLFloaterSnapshotBase>();
 	return LLPanel::postBuild();
 }
 
@@ -112,7 +115,7 @@ void LLPanelSnapshotOptions::openPanel(const std::string& panel_name)
 
 	parent->openPanel(panel_name);
 	parent->getCurrentPanel()->onOpen(LLSD());
-	LLFloaterSnapshot::postPanelSwitch();
+	mSnapshotFloater->postPanelSwitch();
 }
 
 void LLPanelSnapshotOptions::onSaveToProfile()
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index dcd12a7a47..12adcdec8d 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -65,13 +65,13 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "postcard_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "postcard_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "postcard_image_size_lp"; }
-    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshotBase::SNAPSHOT_FORMAT_JPEG; }
-    /*virtual*/ LLPanelSnapshot::ESnapshotType getSnapshotType();
-    /*virtual*/ void updateControls(const LLSD& info);
+	/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; }
+	/*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType();
+	/*virtual*/ void updateControls(const LLSD& info);
 
 	bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
-    static void sendPostcardFinished(LLSD result);
-    void sendPostcard();
+	static void sendPostcardFinished(LLSD result);
+	void sendPostcard();
 
 	void onMsgFormFocusRecieved();
 	void onFormatComboCommit(LLUICtrl* ctrl);
@@ -192,8 +192,8 @@ void LLPanelSnapshotPostcard::sendPostcard()
             getChild<LLUICtrl>("to_form")->getValue().asString(),
             getChild<LLUICtrl>("subject_form")->getValue().asString(),
             getChild<LLUICtrl>("msg_form")->getValue().asString(),
-            LLFloaterSnapshot::getPosTakenGlobal(),
-            LLFloaterSnapshot::getImageData(),
+            mSnapshotFloater->getPosTakenGlobal(),
+            mSnapshotFloater->getImageData(),
             boost::bind(&LLPanelSnapshotPostcard::sendPostcardFinished, _4)));
 
         LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
@@ -207,7 +207,7 @@ void LLPanelSnapshotPostcard::sendPostcard()
     // Give user feedback of the event.
     gViewerWindow->playSnapshotAnimAndSound();
 
-    LLFloaterSnapshot::postSave();
+    mSnapshotFloater->postSave();
 }
 
 void LLPanelSnapshotPostcard::onMsgFormFocusRecieved()
@@ -267,7 +267,7 @@ void LLPanelSnapshotPostcard::onSend()
 	sendPostcard();
 }
 
-LLPanelSnapshot::ESnapshotType LLPanelSnapshotPostcard::getSnapshotType()
+LLSnapshotModel::ESnapshotType LLPanelSnapshotPostcard::getSnapshotType()
 {
-    return LLPanelSnapshot::SNAPSHOT_POSTCARD;
+    return LLSnapshotModel::SNAPSHOT_POSTCARD;
 }
diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp
index b6fc45fb63..38dec78030 100644
--- a/indra/newview/llpanelsnapshotprofile.cpp
+++ b/indra/newview/llpanelsnapshotprofile.cpp
@@ -58,7 +58,7 @@ private:
 	/*virtual*/ std::string getAspectRatioCBName() const	{ return "profile_keep_aspect_check"; }
 	/*virtual*/ std::string getImageSizeComboName() const	{ return "profile_size_combo"; }
 	/*virtual*/ std::string getImageSizePanelName() const	{ return "profile_image_size_lp"; }
-    /*virtual*/ LLFloaterSnapshotBase::ESnapshotFormat getImageFormat() const { return LLFloaterSnapshotBase::SNAPSHOT_FORMAT_PNG; }
+	/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; }
 	/*virtual*/ void updateControls(const LLSD& info);
 
 	void onSend();
@@ -96,6 +96,6 @@ void LLPanelSnapshotProfile::onSend()
 	std::string caption = getChild<LLUICtrl>("caption")->getValue().asString();
 	bool add_location = getChild<LLUICtrl>("add_location_cb")->getValue().asBoolean();
 
-	LLWebProfile::uploadImage(LLFloaterSnapshot::getImageData(), caption, add_location);
-	LLFloaterSnapshot::postSave();
+	LLWebProfile::uploadImage(mSnapshotFloater->getImageData(), caption, add_location);
+	mSnapshotFloater->postSave();
 }
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 15aa62f5d3..049aae1336 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -86,13 +86,13 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Param
 	mNeedsFlash(TRUE),
 	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
 	mDataSize(0),
-    mSnapshotType(LLPanelSnapshot::SNAPSHOT_POSTCARD),
-    mSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
+	mSnapshotType(LLSnapshotModel::SNAPSHOT_POSTCARD),
+	mSnapshotFormat(LLSnapshotModel::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
 	mSnapshotUpToDate(FALSE),
 	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
 	mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
 	mSnapshotActive(FALSE),
-	mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR),
+	mSnapshotBufferType(LLSnapshotModel::SNAPSHOT_TYPE_COLOR),
     mFilterName(""),
     mAllowRenderUI(TRUE),
     mAllowFullScreenPreview(TRUE),
@@ -737,7 +737,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
                 previewp->getWidth(),
                 previewp->getHeight(),
                 previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
-                previewp->getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE,
+                previewp->getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE,
                 previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"),
                 FALSE,
                 previewp->mSnapshotBufferType,
@@ -813,7 +813,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
         mViewerImage[mCurImageIndex] = LLViewerTextureManager::getLocalTexture(scaled.get(), FALSE);
         LLPointer<LLViewerTexture> curr_preview_image = mViewerImage[mCurImageIndex];
         gGL.getTexUnit(0)->bind(curr_preview_image);
-        curr_preview_image->setFilteringOption(getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
+        curr_preview_image->setFilteringOption(getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
         curr_preview_image->setAddressMode(LLTexUnit::TAM_CLAMP);
 
 
@@ -827,7 +827,7 @@ void LLSnapshotLivePreview::prepareFreezeFrame()
 S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 {
     S32 width = getWidth();
-    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
     {
         width = LLImageRaw::biasedDimToPowerOfTwo(width,MAX_TEXTURE_SIZE);
     }
@@ -836,7 +836,7 @@ S32 LLSnapshotLivePreview::getEncodedImageWidth() const
 S32 LLSnapshotLivePreview::getEncodedImageHeight() const
 {
     S32 height = getHeight();
-    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
     {
         height = LLImageRaw::biasedDimToPowerOfTwo(height,MAX_TEXTURE_SIZE);
     }
@@ -854,7 +854,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
             mPreviewImage->getHeight(),
             mPreviewImage->getComponents());
         
-        if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+        if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
 		{
             // We don't store the intermediate formatted image in mFormattedImage in the J2C case 
 			LL_DEBUGS() << "Encoding new image of format J2C" << LL_ENDL;
@@ -881,7 +881,7 @@ LLPointer<LLImageRaw> LLSnapshotLivePreview::getEncodedImage()
 		{
             // Update mFormattedImage if necessary
             getFormattedImage();
-            if (getSnapshotFormat() == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
+            if (getSnapshotFormat() == LLSnapshotModel::SNAPSHOT_FORMAT_BMP)
             {
                 // BMP hack : copy instead of decode otherwise decode will crash.
                 mPreviewImageEncoded->copy(mPreviewImage);
@@ -903,23 +903,23 @@ void LLSnapshotLivePreview::estimateDataSize()
     // Compression ratio
     F32 ratio = 1.0;
     
-    if (getSnapshotType() == LLPanelSnapshot::SNAPSHOT_TEXTURE)
+    if (getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE)
     {
         ratio = 8.0;    // This is what we shoot for when compressing to J2C
     }
     else
     {
-        LLFloaterSnapshotBase::ESnapshotFormat format = getSnapshotFormat();
+        LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
         switch (format)
         {
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+            case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
                 ratio = 3.0;    // Average observed PNG compression ratio
                 break;
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+            case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
                 // Observed from JPG compression tests
                 ratio = (110 - mSnapshotQuality) / 2;
                 break;
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
+            case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
                 ratio = 1.0;    // No compression with BMP
                 break;
         }
@@ -947,18 +947,18 @@ LLPointer<LLImageFormatted>	LLSnapshotLivePreview::getFormattedImage()
         }
         
         // Create the new formatted image of the appropriate format.
-        LLFloaterSnapshotBase::ESnapshotFormat format = getSnapshotFormat();
+        LLSnapshotModel::ESnapshotFormat format = getSnapshotFormat();
         LL_DEBUGS() << "Encoding new image of format " << format << LL_ENDL;
             
         switch (format)
         {
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+		    case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
                 mFormattedImage = new LLImagePNG();
                 break;
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+			case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
                 mFormattedImage = new LLImageJPEG(mSnapshotQuality);
                 break;
-            case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
+			case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
                 mFormattedImage = new LLImageBMP();
                 break;
         }
@@ -978,7 +978,7 @@ void LLSnapshotLivePreview::setSize(S32 w, S32 h)
 	setHeight(h);
 }
 
-void LLSnapshotLivePreview::setSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat format)
+void LLSnapshotLivePreview::setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format)
 {
     if (mSnapshotFormat != format)
     {
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index b822707d29..b689c50320 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLSNAPSHOTLIVEPREVIEW_H
 #define LL_LLSNAPSHOTLIVEPREVIEW_H
 
-#include "llpanelsnapshot.h"
+#include "llsnapshotmodel.h"
 #include "llviewertexture.h"
 #include "llviewerwindow.h"
 
@@ -72,8 +72,8 @@ public:
 	void setMaxImageSize(S32 size) ;
 	S32  getMaxImageSize() {return mMaxImageSize ;}
 
-    LLPanelSnapshot::ESnapshotType getSnapshotType() const { return mSnapshotType; }
-    LLFloaterSnapshotBase::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
+    LLSnapshotModel::ESnapshotType getSnapshotType() const { return mSnapshotType; }
+    LLSnapshotModel::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
 	BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
 	BOOL isSnapshotActive() { return mSnapshotActive; }
 	LLViewerTexture* getThumbnailImage() const { return mThumbnailImage ; }
@@ -90,10 +90,10 @@ public:
 	void setImageScaled(BOOL scaled) { mImageScaled[mCurImageIndex] = scaled; }
 	const LLVector3d& getPosTakenGlobal() const { return mPosTakenGlobal; }
 
-    void setSnapshotType(LLPanelSnapshot::ESnapshotType type) { mSnapshotType = type; }
-    void setSnapshotFormat(LLFloaterSnapshotBase::ESnapshotFormat format);
+    void setSnapshotType(LLSnapshotModel::ESnapshotType type) { mSnapshotType = type; }
+    void setSnapshotFormat(LLSnapshotModel::ESnapshotFormat format);
 	bool setSnapshotQuality(S32 quality, bool set_by_user = true);
-	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
+	void setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType type) { mSnapshotBufferType = type; }
     void setAllowRenderUI(BOOL allow) { mAllowRenderUI = allow; }
     void setAllowFullScreenPreview(BOOL allow) { mAllowFullScreenPreview = allow; }
     void setFilter(std::string filter_name) { mFilterName = filter_name; }
@@ -161,14 +161,14 @@ private:
 	LLVector3d					mPosTakenGlobal;
 	S32							mSnapshotQuality;
 	S32							mDataSize;
-    LLPanelSnapshot::ESnapshotType				mSnapshotType;
-    LLFloaterSnapshotBase::ESnapshotFormat	mSnapshotFormat;
+    LLSnapshotModel::ESnapshotType				mSnapshotType;
+    LLSnapshotModel::ESnapshotFormat	mSnapshotFormat;
 	BOOL						mSnapshotUpToDate;
 	LLFrameTimer				mFallAnimTimer;
 	LLVector3					mCameraPos;
 	LLQuaternion				mCameraRot;
 	BOOL						mSnapshotActive;
-	LLViewerWindow::ESnapshotType mSnapshotBufferType;
+	LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType;
     std::string                 mFilterName;
 
 public:
diff --git a/indra/newview/llsnapshotmodel.h b/indra/newview/llsnapshotmodel.h
new file mode 100644
index 0000000000..71402fb5bc
--- /dev/null
+++ b/indra/newview/llsnapshotmodel.h
@@ -0,0 +1,55 @@
+/**
+* @file llsnapshotmodel.h
+* @brief Snapshot model for storing snapshot data etc.
+*
+* $LicenseInfo:firstyear=2004&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2016, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLSNAPSHOTMODEL_H
+#define LL_LLSNAPSHOTMODEL_H
+
+class LLSnapshotModel
+{
+public:
+	enum ESnapshotType
+	{
+		SNAPSHOT_POSTCARD,
+		SNAPSHOT_TEXTURE,
+		SNAPSHOT_LOCAL,
+		SNAPSHOT_WEB
+	};
+
+	typedef enum e_snapshot_format
+	{
+		SNAPSHOT_FORMAT_PNG,
+		SNAPSHOT_FORMAT_JPEG,
+		SNAPSHOT_FORMAT_BMP
+	} ESnapshotFormat;
+
+	typedef enum
+	{
+		SNAPSHOT_TYPE_COLOR,
+		SNAPSHOT_TYPE_DEPTH
+	} ESnapshotLayerType;
+};
+
+#endif // LL_LLSNAPSHOTMODEL_H
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index f0dafec240..f2b8a5ce06 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -779,12 +779,17 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
     if (uploadInfo->showUploadDialog())
         LLUploadDialog::modalUploadFinished();
 
-    // Let the Snapshot floater know we have finished uploading a snapshot to inventory.
+    // Let the Snapshot floater know we have finished uploading a snapshot to inventory
     LLFloater* floater_snapshot = LLFloaterReg::findInstance("snapshot");
-    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot)
+    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_snapshot && floater_snapshot->isShown())
     {
         floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
     }
+    LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot");
+    if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown())
+    {
+        floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory")));
+    }
 }
 
 //=========================================================================
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 0644e1b196..459397a0f7 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -37,6 +37,7 @@
 #include "llfloatermap.h"
 #include "llfloatermodelpreview.h"
 #include "llfloatersnapshot.h"
+#include "llfloateroutfitsnapshot.h"
 #include "llimage.h"
 #include "llimagebmp.h"
 #include "llimagepng.h"
@@ -507,9 +508,11 @@ class LLFileEnableCloseAllWindows : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
-		bool is_floater_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain();
-		bool open_children = gFloaterView->allChildrenClosed() && !is_floater_snapshot_opened;
+		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
+		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
+		bool is_floaters_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain()
+			|| floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain();
+		bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
 		return !open_children;
 	}
 };
@@ -520,7 +523,12 @@ class LLFileCloseAllWindows : public view_listener_t
 	{
 		bool app_quitting = false;
 		gFloaterView->closeAllChildren(app_quitting);
-		LLFloaterSnapshot::getInstance()->closeFloater(app_quitting);
+		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
+		if (floater_snapshot)
+			floater_snapshot->closeFloater(app_quitting);
+		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
+		if (floater_outfit_snapshot)
+			floater_outfit_snapshot->closeFloater(app_quitting);
 		if (gMenuHolder) gMenuHolder->hideMenus();
 		return true;
 	}
@@ -551,18 +559,18 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 		{
 			gViewerWindow->playSnapshotAnimAndSound();
 			LLPointer<LLImageFormatted> formatted;
-            LLFloaterSnapshotBase::ESnapshotFormat fmt = (LLFloaterSnapshotBase::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
+            LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
 			switch (fmt)
 			{
-			case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+			case LLSnapshotModel::SNAPSHOT_FORMAT_JPEG:
 				formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
 				break;
 			default:
 				LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
-			case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+			case LLSnapshotModel::SNAPSHOT_FORMAT_PNG:
 				formatted = new LLImagePNG;
 				break;
-			case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
+			case LLSnapshotModel::SNAPSHOT_FORMAT_BMP:
 				formatted = new LLImageBMP;
 				break;
 			}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c17c50fd88..cd9ab3e672 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4364,7 +4364,7 @@ void LLViewerWindow::movieSize(S32 new_width, S32 new_height)
 	}
 }
 
-BOOL LLViewerWindow::saveSnapshot( const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
+BOOL LLViewerWindow::saveSnapshot(const std::string& filepath, S32 image_width, S32 image_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
 {
 	LL_INFOS() << "Saving snapshot to: " << filepath << LL_ENDL;
 
@@ -4403,7 +4403,7 @@ void LLViewerWindow::playSnapshotAnimAndSound()
 	send_sound_trigger(LLUUID(gSavedSettings.getString("UISndSnapshot")), 1.0f);
 }
 
-BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
+BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type)
 {
 	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
 }
@@ -4412,7 +4412,7 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p
 // Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy
 // the results over to the final raw image.
 BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, 
-								 BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)
+	BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type, S32 max_size)
 {
 	if (!raw)
 	{
@@ -4620,7 +4620,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 						LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot");
 					}
 				
-					if (type == SNAPSHOT_TYPE_COLOR)
+					if (type == LLSnapshotModel::SNAPSHOT_TYPE_COLOR)
 					{
 						glReadPixels(
 									 subimage_x_offset, out_y + subimage_y_offset,
@@ -4629,7 +4629,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 									 raw->getData() + output_buffer_offset
 									 );
 					}
-					else // SNAPSHOT_TYPE_DEPTH
+					else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH
 					{
 						LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
 						glReadPixels(
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ad06f00234..cdf5b686a7 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -46,6 +46,7 @@
 #include "llhandle.h"
 #include "llinitparam.h"
 #include "lltrace.h"
+#include "llsnapshotmodel.h"
 
 #include <boost/function.hpp>
 #include <boost/signals2.hpp>
@@ -342,15 +343,11 @@ public:
 
 	// snapshot functionality.
 	// perhaps some of this should move to llfloatershapshot?  -MG
-	typedef enum
-	{
-		SNAPSHOT_TYPE_COLOR,
-		SNAPSHOT_TYPE_DEPTH
-	} ESnapshotType;
-	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);
+
+	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR);
 	BOOL			rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
-								BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE );
-	BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
+		BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, LLSnapshotModel::ESnapshotLayerType type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_SNAPSHOT_IMAGE_SIZE);
+	BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
 	BOOL			isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
 	void			resetSnapshotLoc() const { sSnapshotDir.clear(); }
 	BOOL		    saveImageNumbered(LLImageFormatted *image, bool force_picker = false);
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
index 1fe5fc9800..97b405c1d0 100644
--- a/indra/newview/llviewerwindowlistener.cpp
+++ b/indra/newview/llviewerwindowlistener.cpp
@@ -65,9 +65,9 @@ LLViewerWindowListener::LLViewerWindowListener(LLViewerWindow* llviewerwindow):
 
 void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
 {
-    typedef std::map<LLSD::String, LLViewerWindow::ESnapshotType> TypeMap;
+    typedef std::map<LLSD::String, LLSnapshotModel::ESnapshotLayerType> TypeMap;
     TypeMap types;
-#define tp(name) types[#name] = LLViewerWindow::SNAPSHOT_TYPE_##name
+#define tp(name) types[#name] = LLSnapshotModel::SNAPSHOT_TYPE_##name
     tp(COLOR);
     tp(DEPTH);
 #undef  tp
@@ -84,7 +84,7 @@ void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
     if (event.has("showui"))
         showui = event["showui"].asBoolean();
     bool rebuild(event["rebuild"]); // defaults to false
-    LLViewerWindow::ESnapshotType type(LLViewerWindow::SNAPSHOT_TYPE_COLOR);
+    LLSnapshotModel::ESnapshotLayerType type(LLSnapshotModel::SNAPSHOT_TYPE_COLOR);
     if (event.has("type"))
     {
         TypeMap::const_iterator found = types.find(event["type"]);
-- 
cgit v1.2.3


From d3c4a6dbb163e45c044a2cbd5ae2440c0a031450 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 3 Jun 2016 13:45:51 +0300
Subject: linux build fix

---
 indra/newview/llfloateroutfitsnapshot.h | 2 +-
 indra/newview/llfloatersnapshot.h       | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 37e264b0e7..c5c9ef09cb 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -60,7 +60,7 @@ public:
     void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; }
 
     class Impl;
-    friend Impl;
+    friend class Impl;
 private:
 
     LLUUID mOutfitID;
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 431888d2d0..259d4f75a3 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -63,7 +63,7 @@ public:
 	void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); }
 
 	class ImplBase;
-	friend ImplBase;
+	friend class ImplBase;
 	ImplBase* impl;
 
 protected:
@@ -152,7 +152,7 @@ public:
 	static void setAgentEmail(const std::string& email);
 
 	class Impl;
-	friend Impl;
+	friend class Impl;
 };
 
 ///----------------------------------------------------------------------------
-- 
cgit v1.2.3


From 3959d7b83f1fdca7d8daf5494dbc02a645cb868f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 3 Jun 2016 14:57:52 +0300
Subject: MAINT-6471 FIXED Side scroll bar cut off

---
 indra/newview/skins/default/xui/en/panel_outfit_gallery.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
index 9a547f615d..c1272c6bf8 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml
@@ -9,7 +9,7 @@
    layout="topleft"
    left="0"
    top="0"
-   width="312">
+   width="318">
   <string name="outfit_photo_string">
     Photo of "[OUTFIT_NAME]" outfit
   </string>
-- 
cgit v1.2.3


From e2e208898be7bcc3d3801bfd537a5d84201a1563 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 3 Jun 2016 16:06:10 +0300
Subject: mac build fix

---
 indra/newview/llfloateroutfitsnapshot.cpp | 2 --
 indra/newview/llviewermenufile.cpp        | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 4c4e9bcc48..c29c607449 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -53,8 +53,6 @@
 ///----------------------------------------------------------------------------
 LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL;
 
-const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
-
 const S32 OUTFIT_SNAPSHOT_WIDTH = 256;
 const S32 OUTFIT_SNAPSHOT_HEIGHT = 256;
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 459397a0f7..54b12cae12 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -510,8 +510,8 @@ class LLFileEnableCloseAllWindows : public view_listener_t
 	{
 		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
 		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
-		bool is_floaters_snapshot_opened = floater_snapshot && floater_snapshot->isInVisibleChain()
-			|| floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain();
+		bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
+			|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
 		bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
 		return !open_children;
 	}
-- 
cgit v1.2.3


From 2da3148759760abc97fdcb51b1feb6db28c38277 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 3 Jun 2016 17:53:24 +0300
Subject: MAINT-6475 FIXED Inconsistent sort order in "Outfit Gallery" tab

---
 indra/newview/lloutfitgallery.cpp | 19 ++++++++++++++++++-
 indra/newview/lloutfitgallery.h   | 15 ---------------
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index f6af3d63f6..a4315b9189 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -145,6 +145,23 @@ void LLOutfitGallery::updateRowsIfNeeded()
     }
 }
 
+bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
+{
+    if((item1->mIsDefaultImage() && item2->mIsDefaultImage()) || (!item1->mIsDefaultImage() && !item2->mIsDefaultImage()))
+    {
+        std::string name1 = item1->getItemName();
+        std::string name2 = item2->getItemName();
+
+        LLStringUtil::toUpper(name1);
+        LLStringUtil::toUpper(name2);
+        return name1 < name2;
+    }
+    else
+    {
+        return item2->mIsDefaultImage();
+    }
+}
+
 void LLOutfitGallery::reArrangeRows(S32 row_diff)
 {
  
@@ -161,7 +178,7 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
     
     mItemsInRow+= row_diff;
     updateGalleryWidth();
-    std::sort(buf_items.begin(), buf_items.end(), LLOutfitGalleryItem::compareGalleryItem());
+    std::sort(buf_items.begin(), buf_items.end(), compareGalleryItem);
     
     for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
     {
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index ad3f2a7129..385a1e1c7a 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -258,21 +258,6 @@ public:
     
     bool isHidden() {return mHidden;}
     void setHidden(bool hidden) {mHidden = hidden;}
-
-    struct compareGalleryItem
-    {
-        bool operator()(LLOutfitGalleryItem* a, LLOutfitGalleryItem* b)
-        {
-            if((a->mIsDefaultImage() && b->mIsDefaultImage()) || (!a->mIsDefaultImage() && !b->mIsDefaultImage()))
-            {
-                return a->getItemName().compare(b->getItemName()) < 0;
-            }
-            else
-            {
-                return b->mIsDefaultImage();
-            }
-        }
-    };
     
 private:
     LLPointer<LLViewerTexture> mTexturep;
-- 
cgit v1.2.3


From 3cbab4d820963565c23f72e0bb6efd519c97462d Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 6 Jun 2016 16:47:09 +0300
Subject: MAINT-6474 FIXED No easy way to remove an image from a VOB Folder

---
 indra/newview/lloutfitgallery.cpp                  | 57 ++++++++++++++++++++--
 indra/newview/lloutfitgallery.h                    |  7 ++-
 indra/newview/lloutfitslist.cpp                    |  8 ++-
 indra/newview/lloutfitslist.h                      |  1 +
 .../default/xui/en/menu_gallery_outfit_tab.xml     | 11 ++++-
 .../skins/default/xui/en/menu_outfit_gear.xml      |  8 ++-
 6 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index a4315b9189..f414179f9c 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -147,7 +147,7 @@ void LLOutfitGallery::updateRowsIfNeeded()
 
 bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
 {
-    if((item1->mIsDefaultImage() && item2->mIsDefaultImage()) || (!item1->mIsDefaultImage() && !item2->mIsDefaultImage()))
+    if((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage()))
     {
         std::string name1 = item1->getItemName();
         std::string name2 = item2->getItemName();
@@ -158,7 +158,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
     }
     else
     {
-        return item2->mIsDefaultImage();
+        return item2->isDefaultImage();
     }
 }
 
@@ -577,6 +577,15 @@ bool LLOutfitGallery::canWearSelected()
     return false;
 }
 
+bool LLOutfitGallery::hasDefaultImage(const LLUUID& outfit_cat_id)
+{
+    if (mOutfitMap[outfit_cat_id])
+    {
+        return mOutfitMap[outfit_cat_id]->isDefaultImage();
+    }
+    return false;
+}
+
 void LLOutfitGallery::updateMessageVisibility()
 {
     if(mItems.empty())
@@ -731,7 +740,7 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu()
     registrar.add("Outfit.UploadPhoto", boost::bind(&LLOutfitGalleryContextMenu::onUploadPhoto, this, selected_id));
     registrar.add("Outfit.SelectPhoto", boost::bind(&LLOutfitGalleryContextMenu::onSelectPhoto, this, selected_id));
     registrar.add("Outfit.TakeSnapshot", boost::bind(&LLOutfitGalleryContextMenu::onTakeSnapshot, this, selected_id));
-    
+    registrar.add("Outfit.RemovePhoto", boost::bind(&LLOutfitGalleryContextMenu::onRemovePhoto, this, selected_id));
     enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2));
     enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2));
     
@@ -756,6 +765,16 @@ void LLOutfitGalleryContextMenu::onSelectPhoto(const LLUUID& outfit_cat_id)
     }
 }
 
+void LLOutfitGalleryContextMenu::onRemovePhoto(const LLUUID& outfit_cat_id)
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery && outfit_cat_id.notNull())
+    {
+        gallery->checkRemovePhoto(outfit_cat_id);
+        gallery->refreshOutfit(outfit_cat_id);
+    }
+}
+
 void LLOutfitGalleryContextMenu::onTakeSnapshot(const LLUUID& outfit_cat_id)
 {
     LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
@@ -800,6 +819,15 @@ bool LLOutfitGalleryContextMenu::onEnable(LLSD::String param)
 
 bool LLOutfitGalleryContextMenu::onVisible(LLSD::String param)
 {
+    if ("remove_photo" == param)
+    {
+        LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+        LLUUID selected_id = mUUIDs.front();
+        if (gallery && selected_id.notNull())
+        {
+            return !gallery->hasDefaultImage(selected_id);
+        }
+    }
     return LLOutfitContextMenu::onVisible(param);
 }
 
@@ -817,6 +845,7 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("upload_photo", have_selection);
     mMenu->setItemVisible("select_photo", have_selection);
     mMenu->setItemVisible("take_snapshot", have_selection);
+    mMenu->setItemVisible("remove_photo", !hasDefaultImage());
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
@@ -840,6 +869,17 @@ void LLOutfitGalleryGearMenu::onSelectPhoto()
     }
 }
 
+void LLOutfitGalleryGearMenu::onRemovePhoto()
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    LLUUID selected_outfit_id = getSelectedOutfitID();
+    if (gallery && !selected_outfit_id.isNull())
+    {
+        gallery->checkRemovePhoto(selected_outfit_id);
+        gallery->refreshOutfit(selected_outfit_id);
+    }
+}
+
 void LLOutfitGalleryGearMenu::onTakeSnapshot()
 {
     LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
@@ -850,6 +890,17 @@ void LLOutfitGalleryGearMenu::onTakeSnapshot()
     }
 }
 
+bool LLOutfitGalleryGearMenu::hasDefaultImage()
+{
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    LLUUID selected_outfit_id = getSelectedOutfitID();
+    if (gallery && selected_outfit_id.notNull())
+    {
+        return gallery->hasDefaultImage(selected_outfit_id);
+    }
+    return true;
+}
+
 void LLOutfitGallery::onTextureSelectionChanged(LLInventoryItem* itemp)
 {
 }
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 385a1e1c7a..19bfc10586 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -105,6 +105,7 @@ public:
     /*virtual*/ bool getHasExpandableFolders() { return FALSE; }
 
     void updateMessageVisibility();
+    bool hasDefaultImage(const LLUUID& outfit_cat_id);
 
     void refreshTextures(const LLUUID& category_id);
     void refreshOutfit(const LLUUID& category_id);
@@ -209,6 +210,7 @@ protected:
     bool onVisible(LLSD::String param);
     void onUploadPhoto(const LLUUID& outfit_cat_id);
     void onSelectPhoto(const LLUUID& outfit_cat_id);
+    void onRemovePhoto(const LLUUID& outfit_cat_id);
     void onTakeSnapshot(const LLUUID& outfit_cat_id);
     void onCreate(const LLSD& data);
     void onRemoveOutfit(const LLUUID& outfit_cat_id);
@@ -230,6 +232,9 @@ private:
     /*virtual*/ void onUploadFoto();
     /*virtual*/ void onSelectPhoto();
     /*virtual*/ void onTakeSnapshot();
+    /*virtual*/ void onRemovePhoto();
+
+    bool hasDefaultImage();
 };
 
 class LLOutfitGalleryItem : public LLPanel
@@ -254,7 +259,7 @@ public:
     void setSelected(bool value);
     
     std::string getItemName() {return mOutfitName;}
-    bool mIsDefaultImage() {return mDefaultImage;}
+    bool isDefaultImage() {return mDefaultImage;}
     
     bool isHidden() {return mHidden;}
     void setHidden(bool hidden) {mHidden = hidden;}
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 31fe6839f3..2e6599090a 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1093,6 +1093,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
     registrar.add("Gear.UploadPhoto", boost::bind(&LLOutfitListGearMenuBase::onUploadFoto, this));
     registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this));
     registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this));
+    registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this));
 
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
     enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
@@ -1241,6 +1242,10 @@ void LLOutfitListGearMenuBase::onTakeSnapshot()
 
 }
 
+void LLOutfitListGearMenuBase::onRemovePhoto()
+{
+
+}
 LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
@@ -1255,7 +1260,8 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("collapse", TRUE);
     mMenu->setItemVisible("upload_photo", FALSE);
     mMenu->setItemVisible("select_photo", FALSE);
-    mMenu->setItemVisible("take_snapshot", FALSE);    
+    mMenu->setItemVisible("take_snapshot", FALSE);
+    mMenu->setItemVisible("remove_photo", FALSE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 696a18a36a..c4dd2cd075 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -166,6 +166,7 @@ protected:
     virtual void onUploadFoto();
     virtual void onSelectPhoto();
     virtual void onTakeSnapshot();
+    virtual void onRemovePhoto();
 
     const LLUUID& getSelectedOutfitID();
 
diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
index b9e29788dc..1b08767edc 100755
--- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml
@@ -62,7 +62,16 @@
         <on_click
         function="Outfit.TakeSnapshot" />
     </menu_item_call>
-    
+    <menu_item_call
+        label="Remove Photo"
+        layout="topleft"
+        name="remove_photo">
+        <on_click
+        function="Outfit.RemovePhoto" />
+        <on_visible
+        function="Outfit.OnVisible"
+        parameter="remove_photo" />
+    </menu_item_call>
     <menu_item_separator name="sepatator1" />
     <menu
         height="175"
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index e527e1f901..6b8a784560 100644
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -60,7 +60,13 @@
         <on_click
          function="Gear.TakeSnapshot" />
     </menu_item_call>
-
+    <menu_item_call
+     label="Remove Photo"
+     layout="topleft"
+     name="remove_photo">
+        <on_click
+         function="Gear.RemovePhoto" />
+    </menu_item_call>
   <menu_item_separator name="sepatator1" />
             <!-- copied (with minor modifications) from menu_inventory_add.xml -->
             <!--  *TODO: generate dynamically? -->
-- 
cgit v1.2.3


From e9e6862513476f83734d9edb7da79d2a009f1c4a Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Mon, 6 Jun 2016 17:18:48 +0300
Subject: MAINT-6465 FIXED Snapshop "file size" is split apart and looks bad

---
 .../default/xui/en/floater_outfit_snapshot.xml     | 52 +---------------------
 .../skins/default/xui/en/floater_snapshot.xml      |  4 +-
 2 files changed, 4 insertions(+), 52 deletions(-)

diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
index 34f02e535f..5941471907 100644
--- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
@@ -19,66 +19,18 @@
    name="unknown">
     unknown
   </floater.string>
-  <string
-   name="postcard_progress_str">
-    Sending Email
-  </string>
-  <string
-      name="facebook_progress_str">
-    Posting to Facebook
-  </string>
-  <string
-      name="profile_progress_str">
-    Posting
-  </string>
   <string
    name="inventory_progress_str">
     Saving to Inventory
   </string>
-  <string
-   name="local_progress_str">
-    Saving to Computer
-  </string>
-  <string
-        name="facebook_succeeded_str">
-    Image uploaded
-  </string>
-  <string
-        name="profile_succeeded_str">
-    Image uploaded
-  </string>
-  <string
- 	 name="postcard_succeeded_str">
-    Email Sent!
-  </string>
   <string
  	 name="inventory_succeeded_str">
     Saved to Inventory!
   </string>
-  <string
- 	 name="local_succeeded_str">
-    Saved to Computer!
-  </string>
-  <string
-     name="facebook_failed_str">
-    Failed to upload image to your Facebook timeline.
-  </string>
-  <string
-     name="profile_failed_str">
-    Failed to upload image to your Profile Feed.
-  </string>
-  <string
- 	 name="postcard_failed_str">
-    Failed to send email.
-  </string>
   <string
  	 name="inventory_failed_str">
     Failed to save to inventory.
   </string>
-  <string
- 	 name="local_failed_str">
-    Failed to save to computer.
-  </string>
   <button
      follows="left|top"
      height="25"
@@ -358,7 +310,7 @@
 	width="400"
 	height="400"
     follows="top|left"/>
-  <!--view_border 
+  <view_border 
    bevel_style="in" 
    height="21"
    layout="topleft"
@@ -366,7 +318,7 @@
    top_pad="0"
    right="-10"
    follows="left|top|right"
-   left_delta="0"/>-->
+   left_delta="0"/>
    <text
     type="string"
     font="SansSerifSmall"
diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml
index 420aced6a2..76adaad57c 100644
--- a/indra/newview/skins/default/xui/en/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml
@@ -406,7 +406,7 @@
 	width="400"
 	height="400"
     follows="top|left"/>
-  <!--view_border 
+  <view_border 
    bevel_style="in" 
    height="21"
    layout="topleft"
@@ -414,7 +414,7 @@
    top_pad="0"
    right="-10"
    follows="left|top|right"
-   left_delta="0"/>-->
+   left_delta="0"/>
    <text
     type="string"
     font="SansSerifSmall"
-- 
cgit v1.2.3


From 29078e7696c0cdee21e336ddb701f6c7966a33e0 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 8 Jun 2016 16:08:36 +0300
Subject: MAINT-6473 Request for Drag & Drop functionality for adding images to
 Outfit Folders

---
 indra/newview/llappearancemgr.cpp   | 21 +++++++++++++++++++++
 indra/newview/llappearancemgr.h     |  1 +
 indra/newview/llinventorybridge.cpp | 27 +++++++++++++++++++++------
 indra/newview/lloutfitgallery.cpp   | 17 +----------------
 4 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index cc676550ab..e7e85467cd 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
 #include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llagentcamera.h"
@@ -1515,6 +1516,26 @@ void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit)
 	wearInventoryCategory(cat, false, false);
 }
 
+// Remove existing photo link from outfit folder.
+void LLAppearanceMgr::removeOutfitPhoto(const LLUUID& outfit_id)
+{
+    LLInventoryModel::cat_array_t sub_cat_array;
+    LLInventoryModel::item_array_t outfit_item_array;
+    gInventory.collectDescendents(
+        outfit_id,
+        sub_cat_array,
+        outfit_item_array,
+        LLInventoryModel::EXCLUDE_TRASH);
+    BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
+    {
+        LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
+        if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+        {
+            gInventory.removeItem(outfit_item->getUUID());
+        }
+    }
+}
+
 // Open outfit renaming dialog.
 void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id)
 {
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index bf181cb4ad..3646f245c1 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -61,6 +61,7 @@ public:
 	void changeOutfit(bool proceed, const LLUUID& category, bool append);
 	void replaceCurrentOutfit(const LLUUID& new_outfit);
 	void renameOutfit(const LLUUID& outfit_id);
+	void removeOutfitPhoto(const LLUUID& outfit_id);
 	void takeOffOutfit(const LLUUID& cat_id);
 	void addCategoryToCurrentOutfit(const LLUUID& cat_id);
 	S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 86cc6dfae1..9f0b35fc8c 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4358,12 +4358,14 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
 // Returns true if the item can be moved to Current Outfit or any outfit folder.
 static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
 {
-	if ((inv_item->getInventoryType() != LLInventoryType::IT_WEARABLE) &&
-		(inv_item->getInventoryType() != LLInventoryType::IT_GESTURE) &&
-		(inv_item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) &&
-        (inv_item->getInventoryType() != LLInventoryType::IT_OBJECT) &&
-        (inv_item->getInventoryType() != LLInventoryType::IT_TEXTURE))
-    {
+	LLInventoryType::EType inv_type = inv_item->getInventoryType();
+	if ((inv_type != LLInventoryType::IT_WEARABLE) &&
+		(inv_type != LLInventoryType::IT_GESTURE) &&
+		(inv_type != LLInventoryType::IT_ATTACHMENT) &&
+		(inv_type != LLInventoryType::IT_OBJECT) &&
+		(inv_type != LLInventoryType::IT_SNAPSHOT) &&
+		(inv_type != LLInventoryType::IT_TEXTURE))
+	{
 		return FALSE;
 	}
 
@@ -4373,6 +4375,11 @@ static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_curr
 		return FALSE;
 	}
 
+	if((inv_type == LLInventoryType::IT_TEXTURE) || (inv_type == LLInventoryType::IT_SNAPSHOT))
+	{
+		return TRUE;
+	}
+
 	if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
 	{
 		return FALSE;
@@ -4423,6 +4430,14 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
 
 void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit)
 {
+	if((inv_item->getInventoryType() == LLInventoryType::IT_TEXTURE) || (inv_item->getInventoryType() == LLInventoryType::IT_SNAPSHOT))
+	{
+		LLAppearanceMgr::instance().removeOutfitPhoto(mUUID);
+		LLPointer<LLInventoryCallback> cb = NULL;
+		link_inventory_object(mUUID, LLConstPointer<LLInventoryObject>(inv_item), cb);
+		return;
+	}
+
 	// BAP - should skip if dup.
 	if (move_is_into_current_outfit)
 	{
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index f414179f9c..dcc4d70a2c 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1073,22 +1073,7 @@ void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
 
 bool LLOutfitGallery::checkRemovePhoto(LLUUID outfit_id)
 {
-    //remove existing photo link from outfit folder
-    LLInventoryModel::cat_array_t sub_cat_array;
-    LLInventoryModel::item_array_t outfit_item_array;
-    gInventory.collectDescendents(
-        outfit_id,
-        sub_cat_array,
-        outfit_item_array,
-        LLInventoryModel::EXCLUDE_TRASH);
-    BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
-    {
-        LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
-        if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
-        {
-            gInventory.removeItem(outfit_item->getUUID());
-        }
-    }
+    LLAppearanceMgr::instance().removeOutfitPhoto(outfit_id);
     return true;
 }
 
-- 
cgit v1.2.3


From 2fc4663d0afe9869d06f4ca7001636cdcc38042c Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Wed, 8 Jun 2016 16:39:00 -0400
Subject: first pass at new buildscripts logging convention

---
 build.sh | 85 +++++++++++++++++++++++++++++++---------------------------------
 1 file changed, 41 insertions(+), 44 deletions(-)

diff --git a/build.sh b/build.sh
index 20d3a41f83..9a4a8d1054 100755
--- a/build.sh
+++ b/build.sh
@@ -16,11 +16,11 @@
 # * The special style in which python is invoked is intentional to permit
 #   use of a native python install on windows - which requires paths in DOS form
 
-check_for()
-{
-    if [ -e "$2" ]; then found_dict='FOUND'; else found_dict='MISSING'; fi
-    echo "$1 ${found_dict} '$2' " 1>&2
-}
+# check_for() ]
+# { ]
+#     if [ -e "$2" !#\; then found_dict='FOUND'; else found_dict='MISSING'; fi ]
+#     echo "$1 ${found_dict} '$2' " 1>&2 ]
+# } ]
 
 build_dir_Darwin()
 {
@@ -107,7 +107,8 @@ pre_build()
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
      -DGRID:STRING="\"$viewer_grid\"" \
      -DLL_TESTS:BOOL="$run_tests" \
-     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
+     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
+     2>&$stderr
 
   end_section "Configure $variant"
 }
@@ -119,12 +120,12 @@ package_llphysicsextensions_tpv()
   if [ "$variant" = "Release" ]
   then 
       llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml
-      "$autobuild" build --quiet --config-file $llpetpvcfg -c Tpv
+      "$autobuild" build --quiet --config-file $llpetpvcfg -c Tpv 2>&$stderr
       
       # capture the package file name for use in upload later...
       PKGTMP=`mktemp -t pgktpv.XXXXXX`
       trap "rm $PKGTMP* 2>/dev/null" 0
-      "$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)"
+      "$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)" 2>&$stderr
       tpv_status=$?
       if [ -r "${PKGTMP}" ]
       then
@@ -146,18 +147,17 @@ build()
   local variant="$1"
   if $build_viewer
   then
-    "$autobuild" build --no-configure -c $variant
+    "$autobuild" build --no-configure -c $variant 2>&$stderr
     build_ok=$?
 
     # Run build extensions
-    if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]; then
-        for extension in ${build_dir}/packages/build-extensions/*.sh; do
+    if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]
+    then
+        for extension in ${build_dir}/packages/build-extensions/*.sh
+        do
             begin_section "Extension $extension"
-            . $extension
+            . $extension 2>&$trace
             end_section "Extension $extension"
-            if [ $build_ok -ne 0 ]; then
-                break
-            fi
         done
     fi
 
@@ -173,25 +173,23 @@ build()
   fi
 }
 
-# Check to see if we were invoked from the wrapper, if not, re-exec ourselves from there
-if [ "x$arch" = x ]
+################################################################
+# Start of the actual script
+################################################################
+
+# Check to see if we were invoked from the master buildscripts wrapper, if not, fail
+if [ "x${BUILDSCRIPTS_SUPPORT_FUNCTIONS}" = x ]
 then
-  top=`hg root`
-  if [ -x "$top/../buildscripts/hg/bin/build.sh" ]
-  then
-    exec "$top/../buildscripts/hg/bin/build.sh" "$top"
-  else
-    cat <<EOF
-This script, if called in a development environment, requires that the branch
-independent build script repository be checked out next to this repository.
-This repository is located at http://bitbucket.org/lindenlabinternal/sl-buildscripts
-EOF
+    echo "This script relies on being run by the master Linden Lab buildscripts" 1>&2
     exit 1
-  fi
 fi
 
 # Check to see if we're skipping the platform
-eval '$build_'"$arch" || pass
+if ! '$build_'"$arch"
+then
+    record_event "building on architecture $arch is disabled"
+    pass
+fi
 
 # ensure AUTOBUILD is in native path form for child processes
 AUTOBUILD="$(native_path "$AUTOBUILD")"
@@ -235,14 +233,13 @@ do
 
   begin_section "Initialize $variant Build Directory"
   rm -rf "$build_dir"
-  mkdir -p "$build_dir"
-  mkdir -p "$build_dir/tmp"
+  mkdir -p "$build_dir/tmp" 2>&$stderr
   end_section "Initialize $variant Build Directory"
 
   if pre_build "$variant" "$build_dir"
   then
       begin_section "Build $variant"
-      build "$variant" "$build_dir" 2>&1 | tee -a "$build_log" | sed -n 's/^ *\(##teamcity.*\)/\1/p'
+      build "$variant" "$build_dir"
       if `cat "$build_dir/build_ok"`
       then
           case "$variant" in
@@ -270,7 +267,7 @@ do
               fi
               if [ -d "$build_dir/doxygen/html" ]
               then
-                  tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3  "$build_dir/doxygen/html"
+                  tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3  "$build_dir/doxygen/html" 2>&$stderr
                   upload_item docs "$build_dir/viewer-doxygen.tar.bz2" binary/octet-stream
               fi
               ;;
@@ -307,13 +304,13 @@ then
           --distribution unstable \
           --newversion "${VIEWER_VERSION}" \
           "Automated build #$build_id, repository $branch revision $revision." \
-          >> "$build_log" 2>&1
+          2>&$stderr
 
       # build the debian package
-      $pkg_default_debuild_command  >>"$build_log" 2>&1 || record_failure "\"$pkg_default_debuild_command\" failed."
+      $pkg_default_debuild_command 2>&$stderr || record_failure "\"$pkg_default_debuild_command\" failed."
 
       # Unmangle the changelog file
-      hg revert debian/changelog
+      hg revert debian/changelog 2>&$stderr
 
       end_section "Build Viewer Debian Package"
 
@@ -324,8 +321,8 @@ then
           done
       fi
       # Move any .deb results.
-      mkdir -p ../packages_public
-      mkdir -p ../packages_private
+      mkdir -p ../packages_public 2>&$stderr
+      mkdir -p ../packages_private 2>&$stderr
       mv ${build_dir}/packages/*.deb ../packages_public 2>/dev/null || true
       mv ${build_dir}/packages/packages_private/*.deb ../packages_private 2>/dev/null || true
 
@@ -345,7 +342,7 @@ then
       # doesn't make a remote repo again.
       for debian_repo_type in debian_repo debian_repo_private; do
         if [ -d "$build_log_dir/$debian_repo_type" ]; then
-          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed
+          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed 2>&$stderr
         fi
       done
 
@@ -359,10 +356,10 @@ then
       end_section "Upload Debian Repository"
       
     else
-      echo debian build not enabled
+      record_event "debian build not enabled"
     fi
   else
-    echo skipping debian build due to failed build.
+    record_event "skipping debian build due to failed build"
   fi
 fi
 
@@ -376,7 +373,7 @@ then
     package=$(installer_$arch)
     if [ x"$package" = x ] || test -d "$package"
     then
-      # Coverity doesn't package, so it's ok, anything else is fail
+      record_event "??? mystery event $package // $build_coverity"
       succeeded=$build_coverity
     else
       # Upload base package.
@@ -428,12 +425,12 @@ then
     fi
     end_section Upload Installer
   else
-    echo skipping upload of installer
+    record_event "skipping upload of installer"
   fi
 
   
 else
-  echo skipping upload of installer due to failed build.
+    record_event "skipping upload of installer due to failed build"
 fi
 
 # The branch independent build.sh script invoking this script will finish processing
-- 
cgit v1.2.3


From 7e910beac39341707940e94ae329952e7f6ab965 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 9 Jun 2016 06:04:27 -0400
Subject: use autobuild --quiet because it puts everything on stderr

---
 build.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/build.sh b/build.sh
index 9a4a8d1054..e54b8ff047 100755
--- a/build.sh
+++ b/build.sh
@@ -101,7 +101,7 @@ pre_build()
     && [ -r "$master_message_template_checkout/message_template.msg" ] \
     && template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
 
-    "$autobuild" configure -c $variant -- \
+    "$autobuild" configure --quiet -c $variant -- \
      -DPACKAGE:BOOL=ON \
      -DRELEASE_CRASH_REPORTING:BOOL=ON \
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
@@ -202,7 +202,7 @@ then
 fi
 
 # load autobuild provided shell functions and variables
-eval "$("$autobuild" source_environment)"
+eval "$("$autobuild" --quiet source_environment)"
 
 # something about the additional_packages mechanism messes up buildscripts results.py on Linux
 # since we don't care about those packages on Linux, just zero it out, yes - a HACK
-- 
cgit v1.2.3


From 1671de36a0172b1a5aed799bd050a8f015599262 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 9 Jun 2016 07:59:50 -0400
Subject: correct check for disabled build; remove unused function

---
 build.sh | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/build.sh b/build.sh
index e54b8ff047..a978af89ab 100755
--- a/build.sh
+++ b/build.sh
@@ -16,12 +16,6 @@
 # * The special style in which python is invoked is intentional to permit
 #   use of a native python install on windows - which requires paths in DOS form
 
-# check_for() ]
-# { ]
-#     if [ -e "$2" !#\; then found_dict='FOUND'; else found_dict='MISSING'; fi ]
-#     echo "$1 ${found_dict} '$2' " 1>&2 ]
-# } ]
-
 build_dir_Darwin()
 {
   echo build-darwin-i386
@@ -185,7 +179,7 @@ then
 fi
 
 # Check to see if we're skipping the platform
-if ! '$build_'"$arch"
+if ! eval '$build_'"$arch"
 then
     record_event "building on architecture $arch is disabled"
     pass
-- 
cgit v1.2.3


From 97f11bc635935def177d4c1a58ba1c6a76f0b540 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 9 Jun 2016 10:03:07 -0400
Subject: move build number informative output to stdout

---
 indra/cmake/BuildVersion.cmake | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index 195d6e705e..6ffa698a1c 100644
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -12,7 +12,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
 
         if (DEFINED ENV{revision})
            set(VIEWER_VERSION_REVISION $ENV{revision})
-           message("Revision (from environment): ${VIEWER_VERSION_REVISION}")
+           message(STATUS "Revision (from environment): ${VIEWER_VERSION_REVISION}")
 
         else (DEFINED ENV{revision})
           find_program(MERCURIAL
@@ -33,23 +33,23 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
               string(REGEX REPLACE "[^0-9a-f]" "" VIEWER_VERSION_REVISION ${VIEWER_VERSION_REVISION})
             endif (NOT ${hg_id_result} EQUAL 0)
             if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
-              message("Revision (from hg) ${VIEWER_VERSION_REVISION}")
+              message(STATUS "Revision (from hg) ${VIEWER_VERSION_REVISION}")
             else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
-              message("Revision not set (repository not found?); using 0")
+              message(STATUS "Revision not set (repository not found?); using 0")
               set(VIEWER_VERSION_REVISION 0 )
             endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
            else (MERCURIAL)
-              message("Revision not set: mercurial not found; using 0")
+              message(STATUS "Revision not set: mercurial not found; using 0")
               set(VIEWER_VERSION_REVISION 0)
            endif (MERCURIAL)
         endif (DEFINED ENV{revision})
-        message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
+        message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
     else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
         message(SEND_ERROR "Cannot get viewer version from '${VIEWER_VERSION_BASE_FILE}'") 
     endif ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
 
     if ("${VIEWER_VERSION_REVISION}" STREQUAL "")
-      message("Ultimate fallback, revision was blank or not set: will use 0")
+      message(STATUS "Ultimate fallback, revision was blank or not set: will use 0")
       set(VIEWER_VERSION_REVISION 0)
     endif ("${VIEWER_VERSION_REVISION}" STREQUAL "")
 
-- 
cgit v1.2.3


From 9adf2dbeb7e7dcc1d3b4188899b58c089f4d99c8 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 9 Jun 2016 17:40:38 +0300
Subject: MAINT-6472 Show outfit tooltips in Outfit Gallery. Increase space
 between image and outfit name.

---
 indra/newview/lloutfitgallery.cpp                                | 1 +
 indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index dcc4d70a2c..224f2b7f49 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -666,6 +666,7 @@ void LLOutfitGalleryItem::draw()
 void LLOutfitGalleryItem::setOutfitName(std::string name)
 {
     mOutfitNameText->setText(name);
+    mOutfitNameText->setToolTip(name);
     mOutfitName = name;
 }
 
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
index 77c546c6e7..e3f0f1128b 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery_item.xml
@@ -49,7 +49,7 @@
       height="10"
       layout="topleft"
       name="outfit_name"
-      top="0"
+      top="2"
       width="150"
       use_ellipses="true">
       Summer hipster, Pierce Pierce Pierce Pierce
@@ -62,7 +62,7 @@
       height="10"
       layout="topleft"
       name="outfit_worn_text"
-      top="10"
+      top="12"
       width="150">
       (worn)
     </text>
-- 
cgit v1.2.3


From 554db00bdf20692f58c3eb42b83731011e9ad119 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 10 Jun 2016 18:04:16 +0300
Subject: MAINT-6475 Add menu item for changing sort priority

---
 indra/newview/app_settings/settings.xml                 | 11 +++++++++++
 indra/newview/lloutfitgallery.cpp                       | 17 ++++++++++++++++-
 indra/newview/lloutfitgallery.h                         |  1 +
 indra/newview/lloutfitslist.cpp                         |  9 +++++++++
 indra/newview/lloutfitslist.h                           |  1 +
 indra/newview/skins/default/xui/en/menu_outfit_gear.xml | 11 +++++++++++
 6 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a8d42be2a1..57a71ce93d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14592,6 +14592,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>OutfitGallerySortByName</key>
+    <map>
+      <key>Comment</key>
+      <string>Always sort outfits by name in Outfit Gallery</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>OutfitOperationsTimeout</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 224f2b7f49..055d4dbe9f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -46,6 +46,7 @@
 #include "lllocalbitmaps.h"
 #include "llnotificationsutil.h"
 #include "lltexturectrl.h"
+#include "llviewercontrol.h"
 #include "llviewermenufile.h"
 #include "llwearableitemslist.h"
 
@@ -147,7 +148,8 @@ void LLOutfitGallery::updateRowsIfNeeded()
 
 bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
 {
-    if((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage()))
+    if(gSavedSettings.getBOOL("OutfitGallerySortByName") ||
+            ((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage())))
     {
         std::string name1 = item1->getItemName();
         std::string name2 = item2->getItemName();
@@ -847,6 +849,8 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("select_photo", have_selection);
     mMenu->setItemVisible("take_snapshot", have_selection);
     mMenu->setItemVisible("remove_photo", !hasDefaultImage());
+    mMenu->setItemVisible("sepatator3", TRUE);
+    mMenu->setItemVisible("sort_folders_by_name", TRUE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
@@ -891,6 +895,17 @@ void LLOutfitGalleryGearMenu::onTakeSnapshot()
     }
 }
 
+void LLOutfitGalleryGearMenu::onChangeSortOrder()
+{
+    bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName");
+    gSavedSettings.setBOOL("OutfitGallerySortByName", sort_by_name);
+    LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
+    if (gallery)
+    {
+        gallery->reArrangeRows();
+    }
+}
+
 bool LLOutfitGalleryGearMenu::hasDefaultImage()
 {
     LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList);
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 19bfc10586..f5954d9cc2 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -233,6 +233,7 @@ private:
     /*virtual*/ void onSelectPhoto();
     /*virtual*/ void onTakeSnapshot();
     /*virtual*/ void onRemovePhoto();
+    /*virtual*/ void onChangeSortOrder();
 
     bool hasDefaultImage();
 };
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 2e6599090a..87c3c5042b 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -1094,6 +1094,7 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist)
     registrar.add("Gear.SelectPhoto", boost::bind(&LLOutfitListGearMenuBase::onSelectPhoto, this));
     registrar.add("Gear.TakeSnapshot", boost::bind(&LLOutfitListGearMenuBase::onTakeSnapshot, this));
     registrar.add("Gear.RemovePhoto", boost::bind(&LLOutfitListGearMenuBase::onRemovePhoto, this));
+    registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this));
 
     enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2));
     enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2));
@@ -1246,6 +1247,12 @@ void LLOutfitListGearMenuBase::onRemovePhoto()
 {
 
 }
+
+void LLOutfitListGearMenuBase::onChangeSortOrder()
+{
+
+}
+
 LLOutfitListGearMenu::LLOutfitListGearMenu(LLOutfitListBase* olist)
     : LLOutfitListGearMenuBase(olist)
 {}
@@ -1262,6 +1269,8 @@ void LLOutfitListGearMenu::onUpdateItemsVisibility()
     mMenu->setItemVisible("select_photo", FALSE);
     mMenu->setItemVisible("take_snapshot", FALSE);
     mMenu->setItemVisible("remove_photo", FALSE);
+    mMenu->setItemVisible("sepatator3", FALSE);
+    mMenu->setItemVisible("sort_folders_by_name", FALSE);
     LLOutfitListGearMenuBase::onUpdateItemsVisibility();
 }
 
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index c4dd2cd075..81be8de94f 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -167,6 +167,7 @@ protected:
     virtual void onSelectPhoto();
     virtual void onTakeSnapshot();
     virtual void onRemovePhoto();
+    virtual void onChangeSortOrder();
 
     const LLUUID& getSelectedOutfitID();
 
diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
index 6b8a784560..7faa4f3d71 100644
--- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml
@@ -261,4 +261,15 @@
          function="Gear.OnVisible"
          parameter="delete" />
     </menu_item_call>
+    <menu_item_separator name="sepatator3" />
+    <menu_item_check
+     label="Sort Folders Always by Name"
+     layout="topleft"
+     name="sort_folders_by_name">
+        <on_click
+         function="Gear.SortByName" />
+        <on_check
+         function="CheckControl"
+         parameter="OutfitGallerySortByName" />
+    </menu_item_check>
 </toggleable_menu>
-- 
cgit v1.2.3


From 5cc46513e723add7cad959d4a687f2ba199b1535 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 16 Jun 2016 17:51:19 -0400
Subject: remove experimental redirects

---
 build.sh | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/build.sh b/build.sh
index a978af89ab..1edc4ae58d 100755
--- a/build.sh
+++ b/build.sh
@@ -101,8 +101,7 @@ pre_build()
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
      -DGRID:STRING="\"$viewer_grid\"" \
      -DLL_TESTS:BOOL="$run_tests" \
-     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
-     2>&$stderr
+     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
 
   end_section "Configure $variant"
 }
@@ -114,12 +113,12 @@ package_llphysicsextensions_tpv()
   if [ "$variant" = "Release" ]
   then 
       llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml
-      "$autobuild" build --quiet --config-file $llpetpvcfg -c Tpv 2>&$stderr
+      "$autobuild" build --quiet --config-file $llpetpvcfg -c Tpv
       
       # capture the package file name for use in upload later...
       PKGTMP=`mktemp -t pgktpv.XXXXXX`
       trap "rm $PKGTMP* 2>/dev/null" 0
-      "$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)" 2>&$stderr
+      "$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)"
       tpv_status=$?
       if [ -r "${PKGTMP}" ]
       then
@@ -141,7 +140,7 @@ build()
   local variant="$1"
   if $build_viewer
   then
-    "$autobuild" build --no-configure -c $variant 2>&$stderr
+    "$autobuild" build --no-configure -c $variant
     build_ok=$?
 
     # Run build extensions
@@ -150,7 +149,7 @@ build()
         for extension in ${build_dir}/packages/build-extensions/*.sh
         do
             begin_section "Extension $extension"
-            . $extension 2>&$trace
+            . $extension
             end_section "Extension $extension"
         done
     fi
@@ -227,7 +226,7 @@ do
 
   begin_section "Initialize $variant Build Directory"
   rm -rf "$build_dir"
-  mkdir -p "$build_dir/tmp" 2>&$stderr
+  mkdir -p "$build_dir/tmp"
   end_section "Initialize $variant Build Directory"
 
   if pre_build "$variant" "$build_dir"
@@ -246,7 +245,7 @@ do
                   then
                       record_dependencies_graph # defined in buildscripts/hg/bin/build.sh
                   else
-                      record_event "TBD - no dependency graph for linux (probable python version dependency)" 1>&2
+                      record_event "TBD - no dependency graph for linux (probable python version dependency)"
                   fi
                   end_section "Autobuild metadata"
               else
@@ -261,7 +260,7 @@ do
               fi
               if [ -d "$build_dir/doxygen/html" ]
               then
-                  tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3  "$build_dir/doxygen/html" 2>&$stderr
+                  tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3  "$build_dir/doxygen/html"
                   upload_item docs "$build_dir/viewer-doxygen.tar.bz2" binary/octet-stream
               fi
               ;;
@@ -297,14 +296,13 @@ then
       dch --force-bad-version \
           --distribution unstable \
           --newversion "${VIEWER_VERSION}" \
-          "Automated build #$build_id, repository $branch revision $revision." \
-          2>&$stderr
+          "Automated build #$build_id, repository $branch revision $revision."
 
       # build the debian package
-      $pkg_default_debuild_command 2>&$stderr || record_failure "\"$pkg_default_debuild_command\" failed."
+      $pkg_default_debuild_command || record_failure "\"$pkg_default_debuild_command\" failed."
 
       # Unmangle the changelog file
-      hg revert debian/changelog 2>&$stderr
+      hg revert debian/changelog
 
       end_section "Build Viewer Debian Package"
 
@@ -315,8 +313,8 @@ then
           done
       fi
       # Move any .deb results.
-      mkdir -p ../packages_public 2>&$stderr
-      mkdir -p ../packages_private 2>&$stderr
+      mkdir -p ../packages_public
+      mkdir -p ../packages_private
       mv ${build_dir}/packages/*.deb ../packages_public 2>/dev/null || true
       mv ${build_dir}/packages/packages_private/*.deb ../packages_private 2>/dev/null || true
 
@@ -336,7 +334,7 @@ then
       # doesn't make a remote repo again.
       for debian_repo_type in debian_repo debian_repo_private; do
         if [ -d "$build_log_dir/$debian_repo_type" ]; then
-          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed 2>&$stderr
+          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed
         fi
       done
 
-- 
cgit v1.2.3


From 1a3f7b599e3ed71216ebb7bad1365896f8ffca11 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 17 Jun 2016 13:33:52 -0400
Subject: introduce deliberate error for buildscript testing

---
 indra/newview/llappviewer.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b6d02ea2f8..5138e021cc 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -717,6 +717,8 @@ LLAppViewer::LLAppViewer()
 
 	gLoggedInTime.stop();
 
+    gBogusVariable = 1;
+    
 	initLoggingAndGetLastDuration();
 	
 	processMarkerFiles();
-- 
cgit v1.2.3


From 26cbfbbc0cf09182593c2bc16ac89b6403b701d4 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 17 Jun 2016 14:42:48 -0400
Subject: simplify early failures

---
 build.sh | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/build.sh b/build.sh
index 1edc4ae58d..d67cb32e7c 100755
--- a/build.sh
+++ b/build.sh
@@ -140,9 +140,8 @@ build()
   local variant="$1"
   if $build_viewer
   then
-    "$autobuild" build --no-configure -c $variant
-    build_ok=$?
-
+    "$autobuild" build --no-configure -c $variant || fatal "failed building $variant"
+    
     # Run build extensions
     if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]
     then
@@ -155,14 +154,12 @@ build()
     fi
 
     # *TODO: Make this a build extension.
-    package_llphysicsextensions_tpv
-    tpvlib_build_ok=$?
-    if [ $build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
-    then
+    package_llphysicsextensions_tpv || fatal "failed building llphysicsextensions packages"
+
+    echo true >"$build_dir"/build_ok
+  else
+      echo "Skipping build due to configuration build_viewer=${build_viewer}"
       echo true >"$build_dir"/build_ok
-    else
-      echo false >"$build_dir"/build_ok
-    fi
   fi
 }
 
-- 
cgit v1.2.3


From 0933ad0c948812f7ee92424f61a6e8e617165c7a Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 17 Jun 2016 15:43:38 -0400
Subject: deliberate syntax error

---
 indra/newview/llappviewer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 5138e021cc..3f62c92f10 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -717,7 +717,7 @@ LLAppViewer::LLAppViewer()
 
 	gLoggedInTime.stop();
 
-    gBogusVariable = 1;
+    syntaxerror
     
 	initLoggingAndGetLastDuration();
 	
-- 
cgit v1.2.3


From 1c40162255909df434b62faedacdec111bacffee Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Fri, 17 Jun 2016 17:42:15 -0400
Subject: remove deliberate syntax error

---
 indra/newview/llappviewer.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3f62c92f10..b6d02ea2f8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -717,8 +717,6 @@ LLAppViewer::LLAppViewer()
 
 	gLoggedInTime.stop();
 
-    syntaxerror
-    
 	initLoggingAndGetLastDuration();
 	
 	processMarkerFiles();
-- 
cgit v1.2.3


From 510957673399be1a4d603bc7e5491fe27c765d8a Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 7 Jul 2016 20:19:29 +0300
Subject: MAINT-6476 FIXED VOB - User can add any size image to an Outfit
 Gallery outfit folders Eliminated overuse of texture memory

---
 indra/newview/lloutfitgallery.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 055d4dbe9f..fc736056b9 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -48,6 +48,7 @@
 #include "lltexturectrl.h"
 #include "llviewercontrol.h"
 #include "llviewermenufile.h"
+#include "llviewertexturelist.h"
 #include "llwearableitemslist.h"
 
 static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
@@ -705,8 +706,7 @@ BOOL LLOutfitGalleryItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
 void LLOutfitGalleryItem::setImageAssetId(LLUUID image_asset_id)
 {
     mImageAssetId = image_asset_id;
-    mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
-    mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+    mTexturep = LLViewerTextureManager::getFetchedTexture(image_asset_id, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
     getChildView("preview_outfit")->setVisible(FALSE);
     mDefaultImage = false;
 }
-- 
cgit v1.2.3


From 9c7b7d13c7e9c0c2376c90d94a60962608fe979d Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Mon, 18 Jul 2016 19:54:00 +0300
Subject: MAINT-6476 VOB - User can add any size image to an Outfit Gallery
 outfit folders Added restriction of image size that can be added to outfit

---
 indra/newview/lloutfitgallery.cpp                  | 32 ++++++++++++++++++++++
 .../newview/skins/default/xui/en/notifications.xml | 12 ++++++++
 2 files changed, 44 insertions(+)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index fc736056b9..a65ab26c52 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -41,11 +41,13 @@
 #include "llfloaterperms.h"
 #include "llfloaterreg.h"
 #include "llfloateroutfitsnapshot.h"
+#include "llimagedimensionsinfo.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodel.h"
 #include "lllocalbitmaps.h"
 #include "llnotificationsutil.h"
 #include "lltexturectrl.h"
+#include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llviewermenufile.h"
 #include "llviewertexturelist.h"
@@ -1057,6 +1059,36 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
         LLLocalBitmap* unit = new LLLocalBitmap(filename);
         if (unit->getValid())
         {
+            std::string exten = gDirUtilp->getExtension(filename);
+            U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+            LLImageDimensionsInfo image_info;
+            std::string image_load_error;
+            if (!image_info.load(filename, codec))
+            {
+                image_load_error = image_info.getLastError();
+            }
+
+            S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
+            S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
+
+            if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
+            {
+                LLStringUtil::format_map_t args;
+                args["WIDTH"] = llformat("%d", max_width);
+                args["HEIGHT"] = llformat("%d", max_height);
+
+                image_load_error = LLTrans::getString("texture_load_dimensions_error", args);
+            }
+
+            if (!image_load_error.empty())
+            {
+                LLSD subst;
+                subst["REASON"] = image_load_error;
+                LLNotificationsUtil::add("ImageLoadError", subst);
+                return;
+            }
+
             S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
             void *nruserdata = NULL;
             nruserdata = (void *)&outfit_id;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 492d963653..f96b8636f5 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11016,4 +11016,16 @@ Cannot create large prims that intersect other players.  Please re-try when othe
      yestext="OK"/>
   </notification>
   
+  
+  <notification
+   icon="alert.tga"
+   name="ImageLoadError"
+   type="alertmodal">
+   [REASON]
+    <tag>fail</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
 </notifications>
-- 
cgit v1.2.3


From 25095cbabe7f05ac9e19d661d974032c0ec90602 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 19 Jul 2016 16:22:02 +0300
Subject: MAINT-6582 [VOB] Snapshot is not sent

---
 indra/newview/llpanelsnapshotpostcard.cpp | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index 12adcdec8d..be8bde09f8 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -95,13 +95,6 @@ LLPanelSnapshotPostcard::LLPanelSnapshotPostcard()
 // virtual
 BOOL LLPanelSnapshotPostcard::postBuild()
 {
-	// pick up the user's up-to-date email address
-	gAgent.sendAgentUserInfoRequest();
-
-	std::string name_string;
-	LLAgentUI::buildFullname(name_string);
-	getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
-
 	// For the first time a user focuses to .the msg box, all text will be selected.
 	getChild<LLUICtrl>("msg_form")->setFocusChangedCallback(boost::bind(&LLPanelSnapshotPostcard::onMsgFormFocusRecieved, this));
 
@@ -115,6 +108,16 @@ BOOL LLPanelSnapshotPostcard::postBuild()
 // virtual
 void LLPanelSnapshotPostcard::onOpen(const LLSD& key)
 {
+	// pick up the user's up-to-date email address
+	if (mAgentEmail.empty())
+	{
+		gAgent.sendAgentUserInfoRequest();
+
+		std::string name_string;
+		LLAgentUI::buildFullname(name_string);
+		getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
+	}
+
 	LLPanelSnapshot::onOpen(key);
 }
 
-- 
cgit v1.2.3


From 97d73a7c31da32f1555215efe6a21a3428153341 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 19 Jul 2016 20:09:46 +0300
Subject: MAINT-6583 FIXED [VOB] Snapshot floater is stuck in "Posting" state.
 Removed wrong callback set from VOB snapshot floater

---
 indra/newview/llfloateroutfitsnapshot.cpp |  2 --
 indra/newview/llfloateroutfitsnapshot.h   |  2 ++
 indra/newview/llfloatersnapshot.cpp       | 16 ++++++++--------
 indra/newview/llfloatersnapshot.h         |  2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index c29c607449..d671c36a1c 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -256,8 +256,6 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
     }
     childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
 
-    LLWebProfile::setImageUploadResultCallback(boost::bind(&ImplBase::onSnapshotUploadFinished, this, _1));
-
     sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 
     // create preview window
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index c5c9ef09cb..c7b221937f 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -82,6 +82,8 @@ public:
     {}
     void updateResolution(void* data);
 
+    static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
+
     /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
     /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
     /*virtual*/ std::string getSnapshotPanelPrefix();
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 2585c7c6a5..98d4034ccf 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -916,7 +916,7 @@ void LLFloaterSnapshot::Impl::applyCustomResolution(LLFloaterSnapshotBase* view,
 }
 
 // static
-void LLFloaterSnapshotBase::ImplBase::onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status)
+void LLFloaterSnapshot::Impl::onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status)
 {
 	floater->impl->setStatus(STATUS_FINISHED, status, "profile");
 }
@@ -1001,14 +1001,14 @@ BOOL LLFloaterSnapshot::postBuild()
 
 	// Filters
 	LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
-    std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
-    for (U32 i = 0; i < filter_list.size(); i++)
-    {
-        filterbox->add(filter_list[i]);
-    }
-    childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
+	std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
+	for (U32 i = 0; i < filter_list.size(); i++)
+	{
+		filterbox->add(filter_list[i]);
+	}
+	childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
     
-	LLWebProfile::setImageUploadResultCallback(boost::bind(&ImplBase::onSnapshotUploadFinished, this, _1));
+	LLWebProfile::setImageUploadResultCallback(boost::bind(&Impl::onSnapshotUploadFinished, this, _1));
 	LLPostCard::setPostResultCallback(boost::bind(&Impl::onSendingPostcardFinished, this, _1));
 
 	sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 259d4f75a3..61639eebc5 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -101,7 +101,6 @@ public:
 	static void onClickUICheck(LLUICtrl *ctrl, void* data);
 	static void onClickHUDCheck(LLUICtrl *ctrl, void* data);
 	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
-	static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
 
 	virtual LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) = 0;
 	virtual LLSnapshotModel::ESnapshotType getActiveSnapshotType(LLFloaterSnapshotBase* floater);
@@ -179,6 +178,7 @@ public:
 	BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
 	void setImageSizeSpinnersValues(LLFloaterSnapshotBase *view, S32 width, S32 height);
 	void updateSpinners(LLFloaterSnapshotBase* view, LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL is_width_changed);
+	static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status);
 
 	/*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true);
 	/*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater);
-- 
cgit v1.2.3


From f09a92f1f32179ae24f150670851bf63aad204c4 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 21 Jul 2016 14:29:29 -0400
Subject: DRTVWR-427: Remove engineInfoLLImageJ2CKDU(), createLLImageJ2CKDU(),
 destroyLLImageJ2CKDU().

These were apparently intended as simple C-style DLL entry points. But as
nobody calls them, and as we decided against building the viewer from DLLs,
they only clutter the code.
---
 indra/llkdu/llimagej2ckdu.cpp | 20 ++------------------
 indra/llkdu/llimagej2ckdu.h   | 12 ------------
 2 files changed, 2 insertions(+), 30 deletions(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 282c859e9e..90b8d10ecc 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -72,23 +72,6 @@ private:
 //
 void set_default_colour_weights(kdu_params *siz);
 
-const char* engineInfoLLImageJ2CKDU()
-{
-	static std::string version = llformat("KDU %s", KDU_CORE_VERSION);
-	return version.c_str();
-}
-
-LLImageJ2CKDU* createLLImageJ2CKDU()
-{
-	return new LLImageJ2CKDU();
-}
-
-void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu)
-{
-	delete kdu;
-	kdu = NULL;
-}
-
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
 {
 	return new LLImageJ2CKDU();
@@ -102,7 +85,8 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
 
 const char* fallbackEngineInfoLLImageJ2CImpl()
 {
-	return engineInfoLLImageJ2CKDU();
+	static std::string version = llformat("KDU %s", KDU_CORE_VERSION);
+	return version.c_str();
 }
 
 class LLKDUDecodeState
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index 02281152bf..b123a6dd52 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -92,16 +92,4 @@ private:
 	LLKDUDecodeState *mDecodeState;
 };
 
-#if LL_WINDOWS
-# define LLSYMEXPORT __declspec(dllexport)
-#elif LL_LINUX
-# define LLSYMEXPORT __attribute__ ((visibility("default")))
-#else
-# define LLSYMEXPORT
-#endif
-
-extern "C" LLSYMEXPORT const char* engineInfoLLImageJ2CKDU();
-extern "C" LLSYMEXPORT LLImageJ2CKDU* createLLImageJ2CKDU();
-extern "C" LLSYMEXPORT void destroyLLImageJ2CKDU(LLImageJ2CKDU* kdu);
-
 #endif
-- 
cgit v1.2.3


From 71b593e88b1e601db84cd3c399865a0bfd8164cf Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 21 Jul 2016 16:49:02 -0400
Subject: MAINT-6584: Streamline static LLImageJ2C implementation API.

Specifically, remove unused function pointer types CreateLLImageJ2CFunction,
DestroyLLImageJ2CFunction and EngineInfoLLImageJ2CFunction.

Also eliminate static fallbackDestroyLLImageJ2CImpl() and
fallbackEngineInfoLLImageJ2CImpl(), leaving only static
fallbackCreateLLImageJ2CImpl().

We do need a factory function to instantiate the appropriate LLImageJ2CImpl
subclass, so leave the fallbackCreateLLImageJ2CImpl() link seam in place.

However, given that every known LLImageJ2CImpl subclass is cheap to
instantiate, make getEngineInfo() a pure virtual method on that subclass: the
static LLImageJ2C::getEngineInfo() method can temporarily construct an
instance to query. While we're at it, make getEngineInfo() return std::string
like LLImageJ2C::getEngineInfo(). It's ridiculous that
fallbackEngineInfoLLImageJ2CImpl() implementations constructed a static
std::string and returned its c_str(), only to have LLImageJ2C::getEngineInfo()
construct ANOTHER std::string from the returned const char*.

fallbackDestroyLLImageJ2CImpl() never did anything useful: it merely deleted
the passed LLImageJ2CImpl subclass pointer as the specific subclass type. But
since LLImageJ2CImpl's destructor is virtual, LLImageJ2C's destructor could
simply delete the stored LLImageJ2CImpl*. In fact, make mImpl a
boost::scoped_ptr<LLImageJ2CImpl> so we don't even have to delete it manually.
---
 indra/llimage/llimagej2c.cpp        | 30 +++++++++++-------------------
 indra/llimage/llimagej2c.h          |  7 ++++---
 indra/llimagej2coj/llimagej2coj.cpp | 15 ++++-----------
 indra/llimagej2coj/llimagej2coj.h   | 11 ++++++-----
 indra/llkdu/llimagej2ckdu.cpp       | 12 +++---------
 indra/llkdu/llimagej2ckdu.h         | 11 ++++++-----
 6 files changed, 34 insertions(+), 52 deletions(-)

diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 7cd59a2983..913313bf15 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -31,18 +31,13 @@
 #include "llmath.h"
 #include "llmemory.h"
 #include "llsd.h"
+#include <boost/scoped_ptr.hpp>
 
-typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();
-typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);
-typedef const char* (*EngineInfoLLImageJ2CFunction)();
-
-// Declare the prototype for theses functions here. Their functionality
-// will be implemented in other files which define a derived LLImageJ2CImpl
-// but only ONE static library which has the implementation for these
-// functions should ever be included.
+// Declare the prototype for this factory function here. It is implemented in
+// other files which define a LLImageJ2CImpl subclass, but only ONE static
+// library which has the implementation for this function should ever be
+// linked.
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();
-void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);
-const char* fallbackEngineInfoLLImageJ2CImpl();
 
 // Test data gathering handle
 LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ;
@@ -51,7 +46,10 @@ const std::string sTesterName("ImageCompressionTester");
 //static
 std::string LLImageJ2C::getEngineInfo()
 {
-    return fallbackEngineInfoLLImageJ2CImpl();
+	// All known LLImageJ2CImpl implementation subclasses are cheap to
+	// construct.
+	boost::scoped_ptr<LLImageJ2CImpl> impl(fallbackCreateLLImageJ2CImpl());
+	return impl->getEngineInfo();
 }
 
 LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
@@ -61,7 +59,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 							mReversible(FALSE),
 							mAreaUsedForDataSizeCalcs(0)
 {
-	mImpl = fallbackCreateLLImageJ2CImpl();
+	mImpl.reset(fallbackCreateLLImageJ2CImpl());
 	claimMem(mImpl);
 
 	// Clear data size table
@@ -83,13 +81,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 }
 
 // virtual
-LLImageJ2C::~LLImageJ2C()
-{
-	if ( mImpl )
-	{
-        fallbackDestroyLLImageJ2CImpl(mImpl);
-	}
-}
+LLImageJ2C::~LLImageJ2C() {}
 
 // virtual
 void LLImageJ2C::resetLastError()
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index ce8195940d..bfaccdfd05 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -30,6 +30,7 @@
 #include "llimage.h"
 #include "llassettype.h"
 #include "llmetricperformancetester.h"
+#include <boost/scoped_ptr.hpp>
 
 // JPEG2000 : compression rate used in j2c conversion.
 const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f;
@@ -94,7 +95,7 @@ protected:
 	S8  mRawDiscardLevel;
 	F32 mRate;
 	BOOL mReversible;
-	LLImageJ2CImpl *mImpl;
+	boost::scoped_ptr<LLImageJ2CImpl> mImpl;
 	std::string mLastError;
 
     // Image compression/decompression tester
@@ -124,11 +125,11 @@ protected:
 	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0;
 	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0;
 
+	virtual std::string getEngineInfo() const = 0;
+
 	friend class LLImageJ2C;
 };
 
-#define LINDEN_J2C_COMMENT_PREFIX "LL_"
-
 //
 // This class is used for performance data gathering only.
 // Tracks the image compression / decompression data,
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index e98f677d9b..0152b879c2 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -33,23 +33,16 @@
 #include "lltimer.h"
 //#include "llmemory.h"
 
-const char* fallbackEngineInfoLLImageJ2CImpl()
-{
-	static std::string version_string =
-		std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
-		+ opj_version();
-	return version_string.c_str();
-}
-
+// Factory function: see declaration in llimagej2c.cpp
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
 {
 	return new LLImageJ2COJ();
 }
 
-void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
+std::string LLImageJ2COJ::getEngineInfo() const
 {
-	delete impl;
-	impl = NULL;
+	return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
+		+ opj_version();
 }
 
 // Return string from message, eliminating final \n if present
diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h
index 40ad4edb00..ae96a175a2 100644
--- a/indra/llimagej2coj/llimagej2coj.h
+++ b/indra/llimagej2coj/llimagej2coj.h
@@ -35,12 +35,13 @@ public:
 	LLImageJ2COJ();
 	virtual ~LLImageJ2COJ();
 protected:
-	/*virtual*/ BOOL getMetadata(LLImageJ2C &base);
-	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
-	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
+	virtual BOOL getMetadata(LLImageJ2C &base);
+	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
+	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
 								BOOL reversible = FALSE);
-	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+    virtual std::string getEngineInfo() const;
 };
 
 #endif
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 90b8d10ecc..0906fc894e 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -72,21 +72,15 @@ private:
 //
 void set_default_colour_weights(kdu_params *siz);
 
+// Factory function: see declaration in llimagej2c.cpp
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
 {
 	return new LLImageJ2CKDU();
 }
 
-void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl)
+std::string LLImageJ2CKDU::getEngineInfo() const
 {
-	delete impl;
-	impl = NULL;
-}
-
-const char* fallbackEngineInfoLLImageJ2CImpl()
-{
-	static std::string version = llformat("KDU %s", KDU_CORE_VERSION);
-	return version.c_str();
+	return llformat("KDU %s", KDU_CORE_VERSION);
 }
 
 class LLKDUDecodeState
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index b123a6dd52..85dc408d4d 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -65,12 +65,13 @@ public:
 	virtual ~LLImageJ2CKDU();
 	
 protected:
-	/*virtual*/ BOOL getMetadata(LLImageJ2C &base);
-	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
-	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
+	virtual BOOL getMetadata(LLImageJ2C &base);
+	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
+	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
 								BOOL reversible=FALSE);
-	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+	virtual std::string getEngineInfo() const;
 	void findDiscardLevelsBoundaries(LLImageJ2C &base);
 
 private:
-- 
cgit v1.2.3


From ab07b1a46150aaf04e7fd80c141bc9c95656b065 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 22 Jul 2016 10:32:53 -0400
Subject: MAINT-6584: Rationalize custom KDU error/warning message classes.

Derive them both from a common base class that does the message logging,
instead of having each handler class log redundantly -- especially since the
put_text() override accepting const kdu_uint16* was simply streaming the
kdu_uint16 pointer to the log file, which would log the hex value of the
pointer.

Although we want a static instance of each of these handler classes, pull it
out rather than nesting the instance within the class itself.
---
 indra/llkdu/llimagej2ckdu.cpp | 93 +++++++++++++++++++++++--------------------
 1 file changed, 49 insertions(+), 44 deletions(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 0906fc894e..44dc9daabd 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -106,62 +106,67 @@ private:
 	S32 mRowGap;
 };
 
-void ll_kdu_error( void )
-{
-	// *FIX: This exception is bad, bad, bad. It gets thrown from a
-	// destructor which can lead to immediate program termination!
-	throw "ll_kdu_error() throwing an exception";
-}
-
 // Stuff for new kdu error handling
-class LLKDUMessageWarning : public kdu_message
+class LLKDUMessage: public kdu_message
 {
 public:
-	/*virtual*/ void put_text(const char *s);
-	/*virtual*/ void put_text(const kdu_uint16 *s);
+	LLKDUMessage(const std::string& type):
+		mType(type)
+	{}
 
-	static LLKDUMessageWarning sDefaultMessage;
-};
-
-class LLKDUMessageError : public kdu_message
-{
-public:
-	/*virtual*/ void put_text(const char *s);
-	/*virtual*/ void put_text(const kdu_uint16 *s);
-	/*virtual*/ void flush(bool end_of_message = false);
-	static LLKDUMessageError sDefaultMessage;
-};
+	virtual void put_text(const char *s)
+	{
+		LL_INFOS() << "KDU " << mType << ": " << s << LL_ENDL;
+	}
 
-void LLKDUMessageWarning::put_text(const char *s)
-{
-	LL_INFOS() << "KDU Warning: " << s << LL_ENDL;
-}
+	virtual void put_text(const kdu_uint16 *s)
+	{
+		// The previous implementation simply streamed 's' to the log. So
+		// either this put_text() override was never called -- or it produced
+		// some baffling log messages -- because I assert that streaming a
+		// const kdu_uint16* to a std::ostream will display only the hex value
+		// of the pointer.
+		LL_INFOS() << "KDU " << mType << ": "
+				   << utf16str_to_utf8str(llutf16string(s)) << LL_ENDL;
+	}
 
-void LLKDUMessageWarning::put_text(const kdu_uint16 *s)
-{
-	LL_INFOS() << "KDU Warning: " << s << LL_ENDL;
-}
+private:
+	std::string mType;
+};
 
-void LLKDUMessageError::put_text(const char *s)
+struct LLKDUMessageWarning : public LLKDUMessage
 {
-	LL_INFOS() << "KDU Error: " << s << LL_ENDL;
-}
+	LLKDUMessageWarning():
+		LLKDUMessage("Warning")
+	{}
+};
+static LLKDUMessageWarning sWarningHandler;
 
-void LLKDUMessageError::put_text(const kdu_uint16 *s)
+struct LLKDUMessageError : public LLKDUMessage
 {
-	LL_INFOS() << "KDU Error: " << s << LL_ENDL;
-}
+	LLKDUMessageError():
+		LLKDUMessage("Error")
+	{}
 
-void LLKDUMessageError::flush(bool end_of_message)
-{
-	if (end_of_message) 
+	virtual void flush(bool end_of_message = false)
 	{
-		throw "KDU throwing an exception";
+		// According to the documentation nat found:
+		// http://pirlwww.lpl.arizona.edu/resources/guide/software/Kakadu/html_pages/globals__kdu$mize_errors.html
+		// "If a kdu_error object is destroyed, handler→flush will be called with
+		// an end_of_message argument equal to true and the process will
+		// subsequently be terminated through exit. The termination may be
+		// avoided, however, by throwing an exception from within the message
+		// terminating handler→flush call."
+		// So throwing an exception here isn't arbitrary: we MUST throw an
+		// exception if we want to recover from a KDU error.
+		if (end_of_message) 
+		{
+			throw "KDU throwing an exception";
+		}
 	}
-}
+};
+static LLKDUMessageError sErrorHandler;
 
-LLKDUMessageWarning LLKDUMessageWarning::sDefaultMessage;
-LLKDUMessageError	LLKDUMessageError::sDefaultMessage;
 static bool kdu_message_initialized = false;
 
 LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(),
@@ -196,8 +201,8 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod
 	if (!kdu_message_initialized)
 	{
 		kdu_message_initialized = true;
-		kdu_customize_errors(&LLKDUMessageError::sDefaultMessage);
-		kdu_customize_warnings(&LLKDUMessageWarning::sDefaultMessage);
+		kdu_customize_errors(&sErrorHandler);
+		kdu_customize_warnings(&sWarningHandler);
 	}
 
 	if (mCodeStreamp)
-- 
cgit v1.2.3


From acdb050ce5e672a6e5c83ef6e95257ce68934d1b Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 22 Jul 2016 11:35:23 -0400
Subject: MAINT-6584: Convert LLImage class hierarchy to standard 'bool'
 instead of legacy BOOL.

---
 indra/llimage/llimage.cpp                |  54 ++++++-------
 indra/llimage/llimage.h                  |  30 +++----
 indra/llimage/llimagebmp.cpp             |  80 +++++++++----------
 indra/llimage/llimagebmp.h               |  16 ++--
 indra/llimage/llimagedxt.cpp             |  24 +++---
 indra/llimage/llimagedxt.h               |  10 +--
 indra/llimage/llimagej2c.cpp             |  56 ++++++-------
 indra/llimage/llimagej2c.h               |  34 ++++----
 indra/llimage/llimagejpeg.cpp            |  66 ++++++++--------
 indra/llimage/llimagejpeg.h              |   8 +-
 indra/llimage/llimagepng.cpp             |  26 +++----
 indra/llimage/llimagepng.h               |   6 +-
 indra/llimage/llimagetga.cpp             | 130 +++++++++++++++----------------
 indra/llimage/llimagetga.h               |  24 +++---
 indra/llimagej2coj/llimagej2coj.cpp      |  34 ++++----
 indra/llimagej2coj/llimagej2coj.h        |  12 +--
 indra/llkdu/llimagej2ckdu.cpp            |  62 +++++++--------
 indra/llkdu/llimagej2ckdu.h              |  16 ++--
 indra/llkdu/tests/llimagej2ckdu_test.cpp |  40 +++++-----
 19 files changed, 364 insertions(+), 364 deletions(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 08462c7834..109ef7e904 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -895,30 +895,30 @@ void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
 	sGlobalRawMemory += getDataSize();
 }
 
-BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
+bool LLImageRaw::resize(U16 width, U16 height, S8 components)
 {
 	if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components))
 	{
-		return TRUE;
+		return true;
 	}
 	// Reallocate the data buffer.
 	deleteData();
 
 	allocateDataSize(width,height,components);
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
-							 const U8 *data, U32 stride, BOOL reverse_y)
+bool LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
+							 const U8 *data, U32 stride, bool reverse_y)
 {
 	if (!getData())
 	{
-		return FALSE;
+		return false;
 	}
 	if (!data)
 	{
-		return FALSE;
+		return false;
 	}
 
 	// Should do some simple bounds checking
@@ -933,7 +933,7 @@ BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
 				data + from_offset, getComponents()*width);
 	}
 
-	return TRUE;
+	return true;
 }
 
 void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
@@ -988,7 +988,7 @@ void LLImageRaw::verticalFlip()
 }
 
 
-void LLImageRaw::expandToPowerOfTwo(S32 max_dim, BOOL scale_image)
+void LLImageRaw::expandToPowerOfTwo(S32 max_dim, bool scale_image)
 {
 	// Find new sizes
 	S32 new_width  = expandDimToPowerOfTwo(getWidth(), max_dim);
@@ -997,7 +997,7 @@ void LLImageRaw::expandToPowerOfTwo(S32 max_dim, BOOL scale_image)
 	scale( new_width, new_height, scale_image );
 }
 
-void LLImageRaw::contractToPowerOfTwo(S32 max_dim, BOOL scale_image)
+void LLImageRaw::contractToPowerOfTwo(S32 max_dim, bool scale_image)
 {
 	// Find new sizes
 	S32 new_width  = contractDimToPowerOfTwo(getWidth(), MIN_IMAGE_SIZE);
@@ -1397,7 +1397,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
 }
 
 
-BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
+bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
 {
 	llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
 
@@ -1406,7 +1406,7 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
 	
 	if( (old_width == new_width) && (old_height == new_height) )
 	{
-		return TRUE;  // Nothing to do.
+		return true;  // Nothing to do.
 	}
 
 	// Reallocate the data buffer.
@@ -1441,7 +1441,7 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
 		U8 *new_data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), new_data_size); 
 		if(NULL == new_data) 
 		{
-			return FALSE; 
+			return false; 
 		}
 
 		bilinear_scale(getData(), old_width, old_height, getComponents(), old_width*getComponents(), new_data, new_width, new_height, getComponents(), new_width*getComponents());
@@ -1476,7 +1476,7 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
 		}
 	}
 
-	return TRUE ;
+	return true ;
 }
 
 void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )
@@ -1795,7 +1795,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
 	ifs.read ((char*)buffer, length);
 	ifs.close();
 	
-	BOOL success;
+	bool success;
 
 	success = image->updateData();
 	if (success)
@@ -1971,7 +1971,7 @@ S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes)
 //----------------------------------------------------------------------------
 
 // Subclasses that can handle more than 4 channels should override this function.
-BOOL LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32  decode_time, S32 first_channel, S32 max_channel)
+bool LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32  decode_time, S32 first_channel, S32 max_channel)
 {
 	llassert( (first_channel == 0) && (max_channel == 4) );
 	return decode( raw_image, decode_time );  // Loads first 4 channels by default.
@@ -2022,7 +2022,7 @@ void LLImageFormatted::sanityCheck()
 
 //----------------------------------------------------------------------------
 
-BOOL LLImageFormatted::copyData(U8 *data, S32 size)
+bool LLImageFormatted::copyData(U8 *data, S32 size)
 {
 	if ( data && ((data != getData()) || (size != getDataSize())) )
 	{
@@ -2030,7 +2030,7 @@ BOOL LLImageFormatted::copyData(U8 *data, S32 size)
 		allocateData(size);
 		memcpy(getData(), data, size);	/* Flawfinder: ignore */
 	}
-	return TRUE;
+	return true;
 }
 
 // LLImageFormatted becomes the owner of data
@@ -2066,7 +2066,7 @@ void LLImageFormatted::appendData(U8 *data, S32 size)
 
 //----------------------------------------------------------------------------
 
-BOOL LLImageFormatted::load(const std::string &filename, int load_size)
+bool LLImageFormatted::load(const std::string &filename, int load_size)
 {
 	resetLastError();
 
@@ -2077,12 +2077,12 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size)
 	if (!apr_file)
 	{
 		setLastError("Unable to open file for reading", filename);
-		return FALSE;
+		return false;
 	}
 	if (file_size == 0)
 	{
 		setLastError("File is empty",filename);
-		return FALSE;
+		return false;
 	}
 
 	// Constrain the load size to acceptable values
@@ -2090,7 +2090,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size)
 	{
 		load_size = file_size;
 	}
-	BOOL res;
+	bool res;
 	U8 *data = allocateData(load_size);
 	apr_size_t bytes_read = load_size;
 	apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
@@ -2098,7 +2098,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size)
 	{
 		deleteData();
 		setLastError("Unable to read file",filename);
-		res = FALSE;
+		res = false;
 	}
 	else
 	{
@@ -2108,7 +2108,7 @@ BOOL LLImageFormatted::load(const std::string &filename, int load_size)
 	return res;
 }
 
-BOOL LLImageFormatted::save(const std::string &filename)
+bool LLImageFormatted::save(const std::string &filename)
 {
 	resetLastError();
 
@@ -2117,15 +2117,15 @@ BOOL LLImageFormatted::save(const std::string &filename)
 	if (!outfile.getFileHandle())
 	{
 		setLastError("Unable to open file for writing", filename);
-		return FALSE;
+		return false;
 	}
 	
 	outfile.write(getData(), 	getDataSize());
 	outfile.close() ;
-	return TRUE;
+	return true;
 }
 
-// BOOL LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
+// bool LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
 // Depricated to remove VFS dependency.
 // Use:
 // LLVFile::writeFile(image->getData(), image->getDataSize(), vfs, uuid, type);
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index cd3f76f1fd..adc650d360 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -199,11 +199,11 @@ public:
 	/*virtual*/ U8* allocateData(S32 size = -1);
 	/*virtual*/ U8* reallocateData(S32 size);
 	
-	BOOL resize(U16 width, U16 height, S8 components);
+	bool resize(U16 width, U16 height, S8 components);
 
 	//U8 * getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const;
-	BOOL setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
-					 const U8 *data, U32 stride = 0, BOOL reverse_y = FALSE);
+	bool setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
+					 const U8 *data, U32 stride = 0, bool reverse_y = false);
 
 	void clear(U8 r=0, U8 g=0, U8 b=0, U8 a=255);
 
@@ -212,10 +212,10 @@ public:
     static S32 biasedDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
     static S32 expandDimToPowerOfTwo(S32 curr_dim, S32 max_dim = MAX_IMAGE_SIZE);
     static S32 contractDimToPowerOfTwo(S32 curr_dim, S32 min_dim = MIN_IMAGE_SIZE);
-	void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
-	void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, BOOL scale_image = TRUE);
+	void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
+	void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true);
 	void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE);
-	BOOL scale( S32 new_width, S32 new_height, BOOL scale_image = TRUE );
+	bool scale( S32 new_width, S32 new_height, bool scale_image = true );
 	
 	// Fill the buffer with a constant color
 	void fill( const LLColor4U& color );
@@ -314,23 +314,23 @@ public:
 	// getRawDiscardLevel() by default returns mDiscardLevel, but may be overridden (LLImageJ2C)
 	virtual S8  getRawDiscardLevel() { return mDiscardLevel; }
 	
-	BOOL load(const std::string& filename, int load_size = 0);
-	BOOL save(const std::string& filename);
+	bool load(const std::string& filename, int load_size = 0);
+	bool save(const std::string& filename);
 
-	virtual BOOL updateData() = 0; // pure virtual
+	virtual bool updateData() = 0; // pure virtual
  	void setData(U8 *data, S32 size);
  	void appendData(U8 *data, S32 size);
 
 	// Loads first 4 channels.
-	virtual BOOL decode(LLImageRaw* raw_image, F32 decode_time) = 0;  
+	virtual bool decode(LLImageRaw* raw_image, F32 decode_time) = 0;  
 	// Subclasses that can handle more than 4 channels should override this function.
-	virtual BOOL decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
+	virtual bool decodeChannels(LLImageRaw* raw_image, F32 decode_time, S32 first_channel, S32 max_channel);
 
-	virtual BOOL encode(const LLImageRaw* raw_image, F32 encode_time) = 0;
+	virtual bool encode(const LLImageRaw* raw_image, F32 encode_time) = 0;
 
 	S8 getCodec() const;
-	BOOL isDecoding() const { return mDecoding ? TRUE : FALSE; }
-	BOOL isDecoded()  const { return mDecoded ? TRUE : FALSE; }
+	bool isDecoding() const { return mDecoding; }
+	bool isDecoded()  const { return mDecoded; }
 	void setDiscardLevel(S8 discard_level) { mDiscardLevel = discard_level; }
 	S8 getDiscardLevel() const { return mDiscardLevel; }
 	S8 getLevels() const { return mLevels; }
@@ -341,7 +341,7 @@ public:
 	virtual void setLastError(const std::string& message, const std::string& filename = std::string());
 	
 protected:
-	BOOL copyData(U8 *data, S32 size); // calls updateData()
+	bool copyData(U8 *data, S32 size); // calls updateData()
 	
 protected:
 	S8 mCodec;
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index a2ce2fee86..2cdd26c22b 100644
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
@@ -78,7 +78,7 @@ LLImageBMP::LLImageBMP()
 	mColorPalette( NULL ),
 	mBitmapOffset( 0 ),
 	mBitsPerPixel( 0 ),
-	mOriginAtTop( FALSE )
+	mOriginAtTop( false )
 {
 	mBitfieldMask[0] = 0;
 	mBitfieldMask[1] = 0;
@@ -92,7 +92,7 @@ LLImageBMP::~LLImageBMP()
 }
 
 
-BOOL LLImageBMP::updateData()
+bool LLImageBMP::updateData()
 {
 	resetLastError();
 
@@ -101,7 +101,7 @@ BOOL LLImageBMP::updateData()
 	if (!mdata || (0 == getDataSize()))
 	{
 		setLastError("Uninitialized instance of LLImageBMP");
-		return FALSE;
+		return false;
 	}
 
 	// Read the bitmap headers in order to get all the useful info
@@ -120,12 +120,12 @@ BOOL LLImageBMP::updateData()
 		if ((mdata[0] != 'B') || (mdata[1] != 'A'))
 		{
 			setLastError("OS/2 bitmap array BMP files are not supported");
-			return FALSE;
+			return false;
 		}
 		else
 		{
 			setLastError("Does not appear to be a bitmap file");
-			return FALSE;
+			return false;
 		}
 	}
 
@@ -160,12 +160,12 @@ BOOL LLImageBMP::updateData()
 	llendianswizzleone(header.mNumColors);
 	llendianswizzleone(header.mNumColorsImportant);
 
-	BOOL windows_nt_version = FALSE;
-	BOOL windows_95_version = FALSE;
+	bool windows_nt_version = false;
+	bool windows_95_version = false;
 	if( 12 == header.mSize )
 	{
 		setLastError("Windows 2.x and OS/2 1.x BMP files are not supported");
-		return FALSE;
+		return false;
 	}
 	else
 	if( 40 == header.mSize )
@@ -173,7 +173,7 @@ BOOL LLImageBMP::updateData()
 		if( 3 == header.mCompression )
 		{
 			// Windows NT
-			windows_nt_version = TRUE;
+			windows_nt_version = true;
 		}
 		else
 		{
@@ -184,32 +184,32 @@ BOOL LLImageBMP::updateData()
 	if( 12 <= header.mSize && 64 <= header.mSize )
 	{
 		setLastError("OS/2 2.x BMP files are not supported");
-		return FALSE;
+		return false;
 	}
 	else
 	if( 108 == header.mSize )
 	{
 		// BITMAPV4HEADER
-		windows_95_version = TRUE;
+		windows_95_version = true;
 	}
 	else
 	if( 108 < header.mSize )
 	{
 		// BITMAPV5HEADER or greater
 		// Should work as long at Microsoft maintained backwards compatibility (which they did in V4 and V5)
-		windows_95_version = TRUE;
+		windows_95_version = true;
 	}
 
 	S32 width = header.mWidth;
 	S32 height = header.mHeight;
 	if (height < 0)
 	{
-		mOriginAtTop = TRUE;
+		mOriginAtTop = true;
 		height = -height;
 	}
 	else
 	{
-		mOriginAtTop = FALSE;
+		mOriginAtTop = false;
 	}
 
 	mBitsPerPixel = header.mBitsPerPixel;
@@ -228,10 +228,10 @@ BOOL LLImageBMP::updateData()
 	case 16: // Started work on 16, but doesn't work yet
 		// These are legal, but we don't support them yet.
 		setLastError("Unsupported bit depth");
-		return FALSE;
+		return false;
 	default:
 		setLastError("Unrecognized bit depth");
-		return FALSE;
+		return false;
 	}
 
 	setSize(width, height, components);
@@ -244,11 +244,11 @@ BOOL LLImageBMP::updateData()
 
 	case 1:
 		setLastError("8 bit RLE compression not supported.");
-		return FALSE;
+		return false;
 
 	case 2: 
 		setLastError("4 bit RLE compression not supported.");
-		return FALSE;
+		return false;
 
 	case 3:
 		// Windows NT or Windows 95
@@ -256,7 +256,7 @@ BOOL LLImageBMP::updateData()
 
 	default:
 		setLastError("Unsupported compression format.");
-		return FALSE;
+		return false;
 	}
 
 	////////////////////////////////////////////////////////////////////
@@ -267,13 +267,13 @@ BOOL LLImageBMP::updateData()
 		if( (16 != header.mBitsPerPixel) && (32 != header.mBitsPerPixel) )
 		{
 			setLastError("Bitfield encoding requires 16 or 32 bits per pixel.");
-			return FALSE;
+			return false;
 		}
 
 		if( 0 != header.mNumColors )
 		{
 			setLastError("Bitfield encoding is not compatible with a color table.");
-			return FALSE;
+			return false;
 		}
 
 		
@@ -322,15 +322,15 @@ BOOL LLImageBMP::updateData()
 		if (!mColorPalette)
 		{
 			LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL;
-			return FALSE;
+			return false;
 		}
 		memcpy( mColorPalette, mdata + FILE_HEADER_SIZE + BITMAP_HEADER_SIZE + extension_size, color_palette_size );	/* Flawfinder: ignore */
 	}
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
+bool LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
 {
 	llassert_always(raw_image);
 	
@@ -341,7 +341,7 @@ BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
 	if (!mdata || (0 == getDataSize()))
 	{
 		setLastError("llimagebmp trying to decode an image with no data!");
-		return FALSE;
+		return false;
 	}
 	
 	raw_image->resize(getWidth(), getHeight(), 3);
@@ -349,7 +349,7 @@ BOOL LLImageBMP::decode(LLImageRaw* raw_image, F32 decode_time)
 	U8* src = mdata + mBitmapOffset;
 	U8* dst = raw_image->getData();
 
-	BOOL success = FALSE;
+	bool success = false;
 
 	switch( mBitsPerPixel )
 	{
@@ -393,7 +393,7 @@ U32 LLImageBMP::countTrailingZeros( U32 m )
 }
 
 
-BOOL LLImageBMP::decodeColorMask16( U8* dst, U8* src )
+bool LLImageBMP::decodeColorMask16( U8* dst, U8* src )
 {
 	llassert( 16 == mBitsPerPixel );
 
@@ -426,10 +426,10 @@ BOOL LLImageBMP::decodeColorMask16( U8* dst, U8* src )
 		src += alignment_bytes;
 	}
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src )
+bool LLImageBMP::decodeColorMask32( U8* dst, U8* src )
 {
 	// Note: alpha is not supported
 
@@ -445,7 +445,7 @@ BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src )
 
 	if (getWidth() * getHeight() * 4 > getDataSize() - mBitmapOffset)
 	{ //here we have situation when data size in src less than actually needed
-		return FALSE;
+		return false;
 	}
 
 	S32 src_row_span = getWidth() * 4;
@@ -469,11 +469,11 @@ BOOL LLImageBMP::decodeColorMask32( U8* dst, U8* src )
 		src += alignment_bytes;
 	}
 
-	return TRUE;
+	return true;
 }
 
 
-BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src )
+bool LLImageBMP::decodeColorTable8( U8* dst, U8* src )
 {
 	llassert( (8 == mBitsPerPixel) && (mColorPaletteColors >= 256) );
 
@@ -482,7 +482,7 @@ BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src )
 
 	if ((getWidth() * getHeight()) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset)
 	{ //here we have situation when data size in src less than actually needed
-		return FALSE;
+		return false;
 	}
 
 	for( S32 row = 0; row < getHeight(); row++ )
@@ -499,11 +499,11 @@ BOOL LLImageBMP::decodeColorTable8( U8* dst, U8* src )
 		src += alignment_bytes;
 	}
 
-	return TRUE;
+	return true;
 }
 
 
-BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
+bool LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
 {
 	llassert( 24 == mBitsPerPixel );
 	llassert( 3 == getComponents() );
@@ -512,7 +512,7 @@ BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
 
 	if ((getWidth() * getHeight() * 3) + getHeight() * alignment_bytes > getDataSize() - mBitmapOffset)
 	{ //here we have situation when data size in src less than actually needed
-		return FALSE;
+		return false;
 	}
 
 	for( S32 row = 0; row < getHeight(); row++ )
@@ -528,10 +528,10 @@ BOOL LLImageBMP::decodeTruecolor24( U8* dst, U8* src )
 		src += alignment_bytes;
 	}
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
+bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
 {
 	llassert_always(raw_image);
 	
@@ -563,7 +563,7 @@ BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
 	// Allocate the new buffer for the data.
 	if(!allocateData(file_bytes)) //memory allocation failed
 	{
-		return FALSE ;
+		return false ;
 	}
 
 	magic[0] = 'B'; magic[1] = 'M';
@@ -663,5 +663,5 @@ BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
 		}
 	}
 
-	return TRUE;
+	return true;
 }
diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h
index db0b45def0..6a5fa4697d 100644
--- a/indra/llimage/llimagebmp.h
+++ b/indra/llimage/llimagebmp.h
@@ -40,15 +40,15 @@ public:
 	LLImageBMP();
 
 	/*virtual*/ std::string getExtension() { return std::string("bmp"); }
-	/*virtual*/ BOOL updateData();
-	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
-	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
+	/*virtual*/ bool updateData();
+	/*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time);
+	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);
 
 protected:
-	BOOL		decodeColorTable8( U8* dst, U8* src );
-	BOOL		decodeColorMask16( U8* dst, U8* src );
-	BOOL		decodeTruecolor24( U8* dst, U8* src );
-	BOOL		decodeColorMask32( U8* dst, U8* src );
+	bool		decodeColorTable8( U8* dst, U8* src );
+	bool		decodeColorMask16( U8* dst, U8* src );
+	bool		decodeTruecolor24( U8* dst, U8* src );
+	bool		decodeColorMask32( U8* dst, U8* src );
 
 	U32			countTrailingZeros( U32 m );
 
@@ -58,7 +58,7 @@ protected:
 	S32			mBitmapOffset;
 	S32			mBitsPerPixel;
 	U32			mBitfieldMask[4]; // rgba
-	BOOL		mOriginAtTop;
+	bool		mOriginAtTop;
 };
 
 #endif
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 04e0e752eb..0ec83415a0 100644
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
@@ -172,7 +172,7 @@ LLImageDXT::~LLImageDXT()
 }
 
 // virtual
-BOOL LLImageDXT::updateData()
+bool LLImageDXT::updateData()
 {
 	resetLastError();
 
@@ -182,7 +182,7 @@ BOOL LLImageDXT::updateData()
 	if (!data || !data_size)
 	{
 		setLastError("LLImageDXT uninitialized");
-		return FALSE;
+		return false;
 	}
 
 	S32 width, height, miplevelmax;
@@ -216,7 +216,7 @@ BOOL LLImageDXT::updateData()
 	discard = llmin(discard, miplevelmax);
 	setDiscardLevel(discard);
 
-	return TRUE;
+	return true;
 }
 
 // discard: 0 = largest (last) mip
@@ -257,7 +257,7 @@ void LLImageDXT::setFormat()
 }
 		
 // virtual
-BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
+bool LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
 {
 	// *TODO: Test! This has been tweaked since its intial inception,
 	//  but we don't use it any more!
@@ -266,7 +266,7 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
 	if (mFileFormat >= FORMAT_DXT1 && mFileFormat <= FORMAT_DXR5)
 	{
 		LL_WARNS() << "Attempt to decode compressed LLImageDXT to Raw (unsupported)" << LL_ENDL;
-		return FALSE;
+		return false;
 	}
 	
 	S32 width = getWidth(), height = getHeight();
@@ -286,16 +286,16 @@ BOOL LLImageDXT::decode(LLImageRaw* raw_image, F32 time)
 	if ((!getData()) || (data + image_size > getData() + getDataSize()))
 	{
 		setLastError("LLImageDXT trying to decode an image with not enough data!");
-		return FALSE;
+		return false;
 	}
 
 	raw_image->resize(width, height, ncomponents);
 	memcpy(raw_image->getData(), data, image_size);	/* Flawfinder: ignore */
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
+bool LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
 {
 	if (discard < 0)
 	{
@@ -310,10 +310,10 @@ BOOL LLImageDXT::getMipData(LLPointer<LLImageRaw>& raw, S32 discard)
 	S32 height = 0;
 	calcDiscardWidthHeight(discard, mFileFormat, width, height);
 	raw = new LLImageRaw(data, width, height, getComponents());
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_mips)
+bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_mips)
 {
 	llassert_always(raw_image);
 	
@@ -395,11 +395,11 @@ BOOL LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
 		prev_mipdata = mipdata;
 	}
 	
-	return TRUE;
+	return true;
 }
 
 // virtual
-BOOL LLImageDXT::encode(const LLImageRaw* raw_image, F32 time)
+bool LLImageDXT::encode(const LLImageRaw* raw_image, F32 time)
 {
 	return encodeDXT(raw_image, time, false);
 }
diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h
index a8756ba8ed..a4a9bcf99c 100644
--- a/indra/llimage/llimagedxt.h
+++ b/indra/llimage/llimagedxt.h
@@ -93,21 +93,21 @@ protected:
 	/*virtual*/ ~LLImageDXT();
 
 private:
-	BOOL encodeDXT(const LLImageRaw* raw_image, F32 decode_time, bool explicit_mips);
+	bool encodeDXT(const LLImageRaw* raw_image, F32 decode_time, bool explicit_mips);
 	
 public:
 	LLImageDXT();
 
 	/*virtual*/ std::string getExtension() { return std::string("dxt"); }
-	/*virtual*/ BOOL updateData();
+	/*virtual*/ bool updateData();
 
-	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
-	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
+	/*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time);
+	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);
 
 	/*virtual*/ S32 calcHeaderSize();
 	/*virtual*/ S32 calcDataSize(S32 discard_level = 0);
 
-	BOOL getMipData(LLPointer<LLImageRaw>& raw, S32 discard=-1);
+	bool getMipData(LLPointer<LLImageRaw>& raw, S32 discard=-1);
 	
 	void setFormat();
 	S32 getMipOffset(S32 discard);
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 913313bf15..68694496bc 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -56,7 +56,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 							mMaxBytes(0),
 							mRawDiscardLevel(-1),
 							mRate(DEFAULT_COMPRESSION_RATE),
-							mReversible(FALSE),
+							mReversible(false),
 							mAreaUsedForDataSizeCalcs(0)
 {
 	mImpl.reset(fallbackCreateLLImageJ2CImpl());
@@ -103,16 +103,16 @@ S8  LLImageJ2C::getRawDiscardLevel()
 	return mRawDiscardLevel;
 }
 
-BOOL LLImageJ2C::updateData()
+bool LLImageJ2C::updateData()
 {
-	BOOL res = TRUE;
+	bool res = true;
 	resetLastError();
 
 	// Check to make sure that this instance has been initialized with data
 	if (!getData() || (getDataSize() < 16))
 	{
 		setLastError("LLImageJ2C uninitialized");
-		res = FALSE;
+		res = false;
 	}
 	else 
 	{
@@ -134,29 +134,29 @@ BOOL LLImageJ2C::updateData()
 	return res;
 }
 
-BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
+bool LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region)
 {
 	setDiscardLevel(discard_level != -1 ? discard_level : 0);
 	return mImpl->initDecode(*this,raw_image,discard_level,region);
 }
 
-BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
+bool LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
 {
 	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size,levels);
 }
 
-BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
+bool LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)
 {
 	return decodeChannels(raw_imagep, decode_time, 0, 4);
 }
 
 
-// Returns TRUE to mean done, whether successful or not.
-BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
+// Returns true to mean done, whether successful or not.
+bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count )
 {
 	LLTimer elapsed;
 
-	BOOL res = TRUE;
+	bool res = true;
 	
 	resetLastError();
 
@@ -164,13 +164,13 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
 	if (!getData() || (getDataSize() < 16))
 	{
 		setLastError("LLImageJ2C uninitialized");
-		res = TRUE; // done
+		res = true; // done
 	}
 	else
 	{
 		// Update the raw discard level
 		updateRawDiscardLevel();
-		mDecoding = TRUE;
+		mDecoding = true;
 		res = mImpl->decodeImpl(*this, *raw_imagep, decode_time, first_channel, max_channel_count);
 	}
 	
@@ -183,7 +183,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
 		}
 		else
 		{
-			mDecoding = FALSE;
+			mDecoding = false;
 		}
 	}
 
@@ -202,7 +202,7 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
 		tester->updateDecompressionStats(elapsed.getElapsedTimeF32()) ;
 		if (res)
 		{
-			// The whole data stream is finally decompressed when res is returned as TRUE
+			// The whole data stream is finally decompressed when res is returned as true
 			tester->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ;
 		}
 	}
@@ -211,17 +211,17 @@ BOOL LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir
 }
 
 
-BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
+bool LLImageJ2C::encode(const LLImageRaw *raw_imagep, F32 encode_time)
 {
 	return encode(raw_imagep, NULL, encode_time);
 }
 
 
-BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
+bool LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time)
 {
 	LLTimer elapsed;
 	resetLastError();
-	BOOL res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
+	bool res = mImpl->encodeImpl(*this, *raw_imagep, comment_text, encode_time, mReversible);
 	if (!mLastError.empty())
 	{
 		LLImage::setLastError(mLastError);
@@ -237,7 +237,7 @@ BOOL LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text,
 		tester->updateCompressionStats(elapsed.getElapsedTimeF32()) ;
 		if (res)
 		{
-			// The whole data stream is finally compressed when res is returned as TRUE
+			// The whole data stream is finally compressed when res is returned as true
 			tester->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ;
 		}
 	}
@@ -340,15 +340,15 @@ void LLImageJ2C::setMaxBytes(S32 max_bytes)
 	mMaxBytes = max_bytes;
 }
 
-void LLImageJ2C::setReversible(const BOOL reversible)
+void LLImageJ2C::setReversible(const bool reversible)
 {
  	mReversible = reversible;
 }
 
 
-BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
+bool LLImageJ2C::loadAndValidate(const std::string &filename)
 {
-	BOOL res = TRUE;
+	bool res = true;
 	
 	resetLastError();
 
@@ -359,12 +359,12 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 	if (!apr_file)
 	{
 		setLastError("Unable to open file for reading", filename);
-		res = FALSE;
+		res = false;
 	}
 	else if (file_size == 0)
 	{
 		setLastError("File is empty",filename);
-		res = FALSE;
+		res = false;
 	}
 	else
 	{
@@ -377,7 +377,7 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 		{
 			FREE_MEM(LLImageBase::getPrivatePool(), data);
 			setLastError("Unable to read entire file");
-			res = FALSE;
+			res = false;
 		}
 		else
 		{
@@ -394,21 +394,21 @@ BOOL LLImageJ2C::loadAndValidate(const std::string &filename)
 }
 
 
-BOOL LLImageJ2C::validate(U8 *data, U32 file_size)
+bool LLImageJ2C::validate(U8 *data, U32 file_size)
 {
 
 	resetLastError();
 	
 	setData(data, file_size);
 
-	BOOL res = updateData();
+	bool res = updateData();
 	if ( res )
 	{
 		// Check to make sure that this instance has been initialized with data
 		if (!getData() || (0 == getDataSize()))
 		{
 			setLastError("LLImageJ2C uninitialized");
-			res = FALSE;
+			res = false;
 		}
 		else
 		{
@@ -425,7 +425,7 @@ BOOL LLImageJ2C::validate(U8 *data, U32 file_size)
 
 void LLImageJ2C::decodeFailed()
 {
-	mDecoding = FALSE;
+	mDecoding = false;
 }
 
 void LLImageJ2C::updateRawDiscardLevel()
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index bfaccdfd05..44aff98494 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -48,10 +48,10 @@ public:
 
 	// Base class overrides
 	/*virtual*/ std::string getExtension() { return std::string("j2c"); }
-	/*virtual*/ BOOL updateData();
-	/*virtual*/ BOOL decode(LLImageRaw *raw_imagep, F32 decode_time);
-	/*virtual*/ BOOL decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count);
-	/*virtual*/ BOOL encode(const LLImageRaw *raw_imagep, F32 encode_time);
+	/*virtual*/ bool updateData();
+	/*virtual*/ bool decode(LLImageRaw *raw_imagep, F32 decode_time);
+	/*virtual*/ bool decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count);
+	/*virtual*/ bool encode(const LLImageRaw *raw_imagep, F32 encode_time);
 	/*virtual*/ S32 calcHeaderSize();
 	/*virtual*/ S32 calcDataSize(S32 discard_level = 0);
 	/*virtual*/ S32 calcDiscardLevelBytes(S32 bytes);
@@ -60,17 +60,17 @@ public:
 	/*virtual*/ void resetLastError();
 	/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string());
 	
-	BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region);
-	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels);
+	bool initDecode(LLImageRaw &raw_image, int discard_level, int* region);
+	bool initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels);
 	
 	// Encode with comment text 
-	BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0);
+	bool encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0);
 
-	BOOL validate(U8 *data, U32 file_size);
-	BOOL loadAndValidate(const std::string &filename);
+	bool validate(U8 *data, U32 file_size);
+	bool loadAndValidate(const std::string &filename);
 
 	// Encode accessors
-	void setReversible(const BOOL reversible); // Use non-lossy?
+	void setReversible(const bool reversible); // Use non-lossy?
 	void setMaxBytes(S32 max_bytes);
 	S32 getMaxBytes() const { return mMaxBytes; }
 
@@ -94,7 +94,7 @@ protected:
 
 	S8  mRawDiscardLevel;
 	F32 mRate;
-	BOOL mReversible;
+	bool mReversible;
 	boost::scoped_ptr<LLImageJ2CImpl> mImpl;
 	std::string mLastError;
 
@@ -112,18 +112,18 @@ protected:
 	// Return value:
 	// true: image size and number of channels was determined
 	// false: error on decode
-	virtual BOOL getMetadata(LLImageJ2C &base) = 0;
+	virtual bool getMetadata(LLImageJ2C &base) = 0;
 	// Decode the raw image optionally aborting (to continue later) after
 	// decode_time seconds.  Decode at most max_channel_count and start
 	// decoding channel first_channel.
 	// Return value:
 	// true: decoding complete (even if it failed)
 	// false: time expired while decoding
-	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;
-	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
-							BOOL reversible=FALSE) = 0;
-	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0;
-	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0;
+	virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;
+	virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
+							bool reversible=false) = 0;
+	virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0;
+	virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0) = 0;
 
 	virtual std::string getEngineInfo() const = 0;
 
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index e419c77ff2..60b2d0faa5 100644
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
@@ -45,7 +45,7 @@ LLImageJPEG::~LLImageJPEG()
 	delete[] mOutputBuffer;
 }
 
-BOOL LLImageJPEG::updateData()
+bool LLImageJPEG::updateData()
 {
 	resetLastError();
 
@@ -53,7 +53,7 @@ BOOL LLImageJPEG::updateData()
 	if (!getData() || (0 == getDataSize()))
 	{
 		setLastError("Uninitialized instance of LLImageJPEG");
-		return FALSE;
+		return false;
 	}
 
 	////////////////////////////////////////
@@ -79,7 +79,7 @@ BOOL LLImageJPEG::updateData()
 	if(setjmp(sSetjmpBuffer))
 	{
 		jpeg_destroy_decompress(&cinfo);
-		return FALSE;
+		return false;
 	}
 	try
 	{
@@ -106,7 +106,7 @@ BOOL LLImageJPEG::updateData()
 		
 		////////////////////////////////////////
 		// Step 3: read file parameters with jpeg_read_header()
-		jpeg_read_header( &cinfo, TRUE );
+		jpeg_read_header( &cinfo, true );
 
 		// Data set by jpeg_read_header
 		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)
@@ -115,13 +115,13 @@ BOOL LLImageJPEG::updateData()
 		// More data set by jpeg_read_header
 		cinfo.num_components;
 		cinfo.jpeg_color_space;	// Colorspace of image
-		cinfo.saw_JFIF_marker;		// TRUE if a JFIF APP0 marker was seen
+		cinfo.saw_JFIF_marker;		// true if a JFIF APP0 marker was seen
 		cinfo.JFIF_major_version;	// Version information from JFIF marker
 		cinfo.JFIF_minor_version;  //
 		cinfo.density_unit;		// Resolution data from JFIF marker
 		cinfo.X_density;
 		cinfo.Y_density;
-		cinfo.saw_Adobe_marker;	// TRUE if an Adobe APP14 marker was seen
+		cinfo.saw_Adobe_marker;	// true if an Adobe APP14 marker was seen
 		cinfo.Adobe_transform;     // Color transform code from Adobe marker
 		*/
 	}
@@ -129,13 +129,13 @@ BOOL LLImageJPEG::updateData()
 	{
 		jpeg_destroy_decompress(&cinfo);
 
-		return FALSE;
+		return false;
 	}
 	////////////////////////////////////////
 	// Step 4: Release JPEG decompression object 
 	jpeg_destroy_decompress(&cinfo);
 
-	return TRUE;
+	return true;
 }
 
 // Initialize source --- called by jpeg_read_header
@@ -154,7 +154,7 @@ boolean LLImageJPEG::decodeFillInputBuffer( j_decompress_ptr cinfo )
 	// Should never get here, since we provide the entire buffer up front.
 	ERREXIT(cinfo, JERR_INPUT_EMPTY);
 
-	return TRUE;
+	return true;
 }
 
 // Skip data --- used to skip over a potentially large amount of
@@ -182,7 +182,7 @@ void LLImageJPEG::decodeTermSource (j_decompress_ptr cinfo)
 
 
 // Returns true when done, whether or not decode was successful.
-BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
+bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 {
 	llassert_always(raw_image);
 	
@@ -192,7 +192,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 	if (!getData() || (0 == getDataSize()))
 	{
 		setLastError("LLImageJPEG trying to decode an image with no data!");
-		return TRUE;  // done
+		return true;  // done
 	}
 	
 	S32 row_stride = 0;
@@ -220,7 +220,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 	if(setjmp(sSetjmpBuffer))
 	{
 		jpeg_destroy_decompress(&cinfo);
-		return TRUE; // done
+		return true; // done
 	}
 	try
 	{
@@ -247,11 +247,11 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 		////////////////////////////////////////
 		// Step 3: read file parameters with jpeg_read_header()
 		
-		jpeg_read_header(&cinfo, TRUE);
+		jpeg_read_header(&cinfo, true);
 
 		// We can ignore the return value from jpeg_read_header since
 		//   (a) suspension is not possible with our data source, and
-		//   (b) we passed TRUE to reject a tables-only JPEG file as an error.
+		//   (b) we passed true to reject a tables-only JPEG file as an error.
 		// See libjpeg.doc for more info.
 
 		setSize(cinfo.image_width, cinfo.image_height, 3); // Force to 3 components (RGB)
@@ -314,7 +314,7 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 	catch (int)
 	{
 		jpeg_destroy_decompress(&cinfo);
-		return TRUE; // done
+		return true; // done
 	}
 
 	// Check to see whether any corrupt-data warnings occurred
@@ -322,10 +322,10 @@ BOOL LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
 	{
 		// TODO: extract the warning to find out what went wrong.
 		setLastError( "Unable to decode JPEG image.");
-		return TRUE; // done
+		return true; // done
 	}
 
-	return TRUE;
+	return true;
 }
 
 
@@ -344,11 +344,11 @@ void LLImageJPEG::encodeInitDestination ( j_compress_ptr cinfo )
 // 
 //  In typical applications, this should write the entire output buffer
 //  (ignoring the current state of next_output_byte & free_in_buffer),
-//  reset the pointer & count to the start of the buffer, and return TRUE
+//  reset the pointer & count to the start of the buffer, and return true
 //  indicating that the buffer has been dumped.
 // 
 //  In applications that need to be able to suspend compression due to output
-//  overrun, a FALSE return indicates that the buffer cannot be emptied now.
+//  overrun, a false return indicates that the buffer cannot be emptied now.
 //  In this situation, the compressor will return to its caller (possibly with
 //  an indication that it has not accepted all the supplied scanlines).  The
 //  application should resume compression after it has made more room in the
@@ -357,7 +357,7 @@ void LLImageJPEG::encodeInitDestination ( j_compress_ptr cinfo )
 // 
 //  When suspending, the compressor will back up to a convenient restart point
 //  (typically the start of the current MCU). next_output_byte & free_in_buffer
-//  indicate where the restart point will be if the current call returns FALSE.
+//  indicate where the restart point will be if the current call returns false.
 //  Data beyond this point will be regenerated after resumption, so do not
 //  write it out when emptying the buffer externally.
 
@@ -374,7 +374,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )
   if (!new_buffer)
   {
   	LL_ERRS() << "Out of memory in LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )" << LL_ENDL;
-  	return FALSE;
+  	return false;
   }
   memcpy( new_buffer, self->mOutputBuffer, self->mOutputBufferSize );	/* Flawfinder: ignore */
   delete[] self->mOutputBuffer;
@@ -386,7 +386,7 @@ boolean LLImageJPEG::encodeEmptyOutputBuffer( j_compress_ptr cinfo )
   self->mOutputBufferSize = new_buffer_size;
   self->claimMem(new_buffer_size);
 
-  return TRUE;
+  return true;
 }
 
 //  Terminate destination --- called by jpeg_finish_compress
@@ -465,11 +465,11 @@ void LLImageJPEG::errorOutputMessage( j_common_ptr cinfo )
 	std::string error = buffer ;
 	LLImage::setLastError(error);
 
-	BOOL is_decode = (cinfo->is_decompressor != 0);
+	bool is_decode = (cinfo->is_decompressor != 0);
 	LL_WARNS() << "LLImageJPEG " << (is_decode ? "decode " : "encode ") << " failed: " << buffer << LL_ENDL;
 }
 
-BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
+bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 {
 	llassert_always(raw_image);
 	
@@ -482,7 +482,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 		break;
 	default:
 		setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
-		return FALSE;
+		return false;
 	}
 
 	setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
@@ -531,7 +531,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 		mOutputBuffer = NULL;
 		disclaimMem(mOutputBufferSize);
 		mOutputBufferSize = 0;
-		return FALSE;
+		return false;
 	}
 
 	try
@@ -576,7 +576,7 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 			break;
 		default:
 			setLastError("Unable to encode a JPEG image that doesn't have 1 or 3 components.");
-			return FALSE;
+			return false;
 		}
 
 		// Now use the library's routine to set default compression parameters.
@@ -585,15 +585,15 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 		jpeg_set_defaults(&cinfo);
 
 		// Now you can set any non-default parameters you wish to.
-		jpeg_set_quality(&cinfo, mEncodeQuality, TRUE );  // limit to baseline-JPEG values
+		jpeg_set_quality(&cinfo, mEncodeQuality, true );  // limit to baseline-JPEG values
 
 		////////////////////////////////////////
 		// Step 4: Start compressor 
 		//
-		// TRUE ensures that we will write a complete interchange-JPEG file.
-		// Pass TRUE unless you are very sure of what you're doing.
+		// true ensures that we will write a complete interchange-JPEG file.
+		// Pass true unless you are very sure of what you're doing.
    
-		jpeg_start_compress(&cinfo, TRUE);
+		jpeg_start_compress(&cinfo, true);
 
 		////////////////////////////////////////
 		// Step 5: while (scan lines remain to be written) 
@@ -647,8 +647,8 @@ BOOL LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
 		mOutputBuffer = NULL;
 		disclaimMem(mOutputBufferSize);
 		mOutputBufferSize = 0;
-		return FALSE;
+		return false;
 	}
 
-	return TRUE;
+	return true;
 }
diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h
index 2142660c81..7a849a8421 100644
--- a/indra/llimage/llimagejpeg.h
+++ b/indra/llimage/llimagejpeg.h
@@ -51,9 +51,9 @@ public:
 	LLImageJPEG(S32 quality = 75);
 
 	/*virtual*/ std::string getExtension() { return std::string("jpg"); }
-	/*virtual*/ BOOL updateData();
-	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
-	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
+	/*virtual*/ bool updateData();
+	/*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time);
+	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);
 
 	void			setEncodeQuality( S32 q )	{ mEncodeQuality = q; } // on a scale from 1 to 100
 	S32				getEncodeQuality()			{ return mEncodeQuality; }
@@ -73,7 +73,7 @@ public:
 	static void		errorEmitMessage(j_common_ptr cinfo, int msg_level);
 	static void		errorOutputMessage(j_common_ptr cinfo);
 
-	static BOOL		decompress(LLImageJPEG* imagep);
+	static bool		decompress(LLImageJPEG* imagep);
 
 protected:
 	U8*				mOutputBuffer;		// temp buffer used during encoding
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 7735dc1379..a299602d79 100644
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -47,7 +47,7 @@ LLImagePNG::~LLImagePNG()
 // Virtual
 // Parse PNG image information and set the appropriate
 // width, height and component (channel) information.
-BOOL LLImagePNG::updateData()
+bool LLImagePNG::updateData()
 {
     resetLastError();
 
@@ -55,7 +55,7 @@ BOOL LLImagePNG::updateData()
     if (!getData() || (0 == getDataSize()))
     {
         setLastError("Uninitialized instance of LLImagePNG");
-        return FALSE;
+        return false;
     }
 
 	// Decode the PNG data and extract sizing information
@@ -63,25 +63,25 @@ BOOL LLImagePNG::updateData()
 	if (!pngWrapper.isValidPng(getData()))
 	{
 		setLastError("LLImagePNG data does not have a valid PNG header!");
-		return FALSE;
+		return false;
 	}
 
 	LLPngWrapper::ImageInfo infop;
 	if (! pngWrapper.readPng(getData(), getDataSize(), NULL, &infop))
 	{
 		setLastError(pngWrapper.getErrorMessage());
-		return FALSE;
+		return false;
 	}
 
 	setSize(infop.mWidth, infop.mHeight, infop.mComponents);
 
-	return TRUE;
+	return true;
 }
 
 // Virtual
 // Decode an in-memory PNG image into the raw RGB or RGBA format
 // used within SecondLife.
-BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
+bool LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
 {
 	llassert_always(raw_image);
 
@@ -91,7 +91,7 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
     if (!getData() || (0 == getDataSize()))
     {
         setLastError("LLImagePNG trying to decode an image with no data!");
-        return FALSE;
+        return false;
     }
 
 	// Decode the PNG data into the raw image
@@ -99,21 +99,21 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
 	if (!pngWrapper.isValidPng(getData()))
 	{
 		setLastError("LLImagePNG data does not have a valid PNG header!");
-		return FALSE;
+		return false;
 	}
 
 	if (! pngWrapper.readPng(getData(), getDataSize(), raw_image))
 	{
 		setLastError(pngWrapper.getErrorMessage());
-		return FALSE;
+		return false;
 	}
 
-	return TRUE;
+	return true;
 }
 
 // Virtual
 // Encode the in memory RGB image into PNG format.
-BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
+bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
 {
 	llassert_always(raw_image);
 
@@ -133,7 +133,7 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
 	{
 		setLastError(pngWrapper.getErrorMessage());
 		delete[] tmpWriteBuffer;
-		return FALSE;
+		return false;
 	}
 
 	// Resize internal buffer and copy from temp
@@ -143,6 +143,6 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
 
 	delete[] tmpWriteBuffer;
 
-	return TRUE;
+	return true;
 }
 
diff --git a/indra/llimage/llimagepng.h b/indra/llimage/llimagepng.h
index 1fbd850a2e..ef16f2996f 100644
--- a/indra/llimage/llimagepng.h
+++ b/indra/llimage/llimagepng.h
@@ -38,9 +38,9 @@ public:
 	LLImagePNG();
 
 	/*virtual*/ std::string getExtension() { return std::string("png"); }
-	/*virtual*/ BOOL updateData();
-	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
-	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
+	/*virtual*/ bool updateData();
+	/*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time);
+	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time);
 };
 
 #endif
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index d0ae105ba7..5ad7658ec1 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -61,7 +61,7 @@ LLImageTGA::LLImageTGA()
 	  mColorMapStart( 0 ),
 	  mColorMapLength( 0 ),
 	  mColorMapBytesPerEntry( 0 ),
-	  mIs15Bit( FALSE ),
+	  mIs15Bit( false ),
 
 	  mAttributeBits(0),
 	  mColorMapDepth(0),
@@ -94,7 +94,7 @@ LLImageTGA::LLImageTGA(const std::string& file_name)
 	  mColorMapStart( 0 ),
 	  mColorMapLength( 0 ),
 	  mColorMapBytesPerEntry( 0 ),
-	  mIs15Bit( FALSE )
+	  mIs15Bit( false )
 {
 	loadFile(file_name);
 }
@@ -104,7 +104,7 @@ LLImageTGA::~LLImageTGA()
 	delete [] mColorMap;
 }
 
-BOOL LLImageTGA::updateData()
+bool LLImageTGA::updateData()
 {
 	resetLastError();
 
@@ -112,7 +112,7 @@ BOOL LLImageTGA::updateData()
 	if (!getData() || (0 == getDataSize()))
 	{
 		setLastError("LLImageTGA uninitialized");
-		return FALSE;
+		return false;
 	}
 	
 	// Pull image information from the header...
@@ -185,13 +185,13 @@ BOOL LLImageTGA::updateData()
 	case 0:
 		// No image data included in file
 		setLastError("Unable to load file.  TGA file contains no image data.");
-		return FALSE;
+		return false;
 	case 1:
 		// Colormapped uncompressed
 		if( 8 != mPixelSize )
 		{
 			setLastError("Unable to load file.  Colormapped images must have 8 bits per pixel.");
-			return FALSE;
+			return false;
 		}
 		break;
 	case 2:
@@ -202,7 +202,7 @@ BOOL LLImageTGA::updateData()
 		if( 8 != mPixelSize )
 		{
 			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
-			return FALSE;
+			return false;
 		}
 		break;
 	case 9:
@@ -216,12 +216,12 @@ BOOL LLImageTGA::updateData()
 		if( 8 != mPixelSize )
 		{
 			setLastError("Unable to load file.  Monochrome images must have 8 bits per pixel.");
-			return FALSE;
+			return false;
 		}
 		break;
 	default:
 		setLastError("Unable to load file.  Unrecoginzed TGA image type.");
-		return FALSE;
+		return false;
 	}
 
 	// discard the ID field, if any
@@ -266,8 +266,8 @@ BOOL LLImageTGA::updateData()
 			mColorMap = new U8[ color_map_bytes ];  
 			if (!mColorMap)
 			{
-				LL_ERRS() << "Out of Memory in BOOL LLImageTGA::updateData()" << LL_ENDL;
-				return FALSE;
+				LL_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << LL_ENDL;
+				return false;
 			}
 			memcpy( mColorMap, getData() + mDataOffset, color_map_bytes );	/* Flawfinder: ignore */
 		}
@@ -302,28 +302,28 @@ BOOL LLImageTGA::updateData()
 //		if( mAttributeBits != 8 )
 //		{
 //			setLastError("Unable to load file. 32 bit TGA image does not have 8 bits of alpha.");
-//			return FALSE;
+//			return false;
 //		}
 		mAttributeBits = 8;
 		break;
 	case 15:
 	case 16:
 		components = 3;
-		mIs15Bit = TRUE;  // 16th bit is used for Targa hardware interupts and is ignored.
+		mIs15Bit = true;  // 16th bit is used for Targa hardware interupts and is ignored.
 		break;
 	case 8:
 		components = 1;
 		break;
 	default:
 		setLastError("Unable to load file. Unknown pixel size.");
-		return FALSE;
+		return false;
 	}
 	setSize(width, height, components);
 	
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
+bool LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
 {
 	llassert_always(raw_image);
 	
@@ -331,7 +331,7 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
 	if (!getData() || (0 == getDataSize()))
 	{
 		setLastError("LLImageTGA trying to decode an image with no data!");
-		return FALSE;
+		return false;
 	}
 
 	// Copy everything after the header.
@@ -343,18 +343,18 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
 		(getComponents() != 4) )
 	{
 		setLastError("TGA images with a number of components other than 1, 3, and 4 are not supported.");
-		return FALSE;
+		return false;
 	}
 
 
 	if( mOriginRightBit )
 	{
 		setLastError("TGA images with origin on right side are not supported.");
-		return FALSE;
+		return false;
 	}
 
-	BOOL flipped = (mOriginTopBit != 0);
-	BOOL rle_compressed = ((mImageType & 0x08) != 0);
+	bool flipped = (mOriginTopBit != 0);
+	bool rle_compressed = ((mImageType & 0x08) != 0);
 
 	if( mColorMap )
 	{
@@ -366,10 +366,10 @@ BOOL LLImageTGA::decode(LLImageRaw* raw_image, F32 decode_time)
 	}
 }
 
-BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
+bool LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped )
 {
-	BOOL success = FALSE;
-	BOOL alpha_opaque = FALSE;
+	bool success = false;
+	bool alpha_opaque = false;
 	if( rle )
 	{
 
@@ -404,7 +404,7 @@ BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped
 	}
 	else
 	{
-		BOOL alpha_opaque;
+		bool alpha_opaque;
 		success = decodeTruecolorNonRle( raw_image, alpha_opaque );
 		if (alpha_opaque && raw_image->getComponents() == 4)
 		{
@@ -430,9 +430,9 @@ BOOL LLImageTGA::decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped
 }
 
 
-BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaque )
+bool LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, bool &alpha_opaque )
 {
-	alpha_opaque = TRUE;
+	alpha_opaque = true;
 
 	// Origin is the bottom left
 	U8* dst = raw_image->getData();
@@ -442,7 +442,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu
 	
 	if (pixels * (mIs15Bit ? 2 : getComponents()) > getDataSize() - mDataOffset)
 	{ //here we have situation when data size in src less than actually needed
-		return FALSE;
+		return false;
 	}
 
 	if (getComponents() == 4)
@@ -456,7 +456,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu
 			dst[3] = src[3]; // Alpha
 			if (dst[3] != 255)
 			{
-				alpha_opaque = FALSE;
+				alpha_opaque = false;
 			}
 			dst += 4;
 			src += 4;
@@ -490,7 +490,7 @@ BOOL LLImageTGA::decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaqu
 		memcpy(dst, src, pixels);	/* Flawfinder: ignore */
 	}
 
-	return TRUE;
+	return true;
 }
 
 void LLImageTGA::decodeColorMapPixel8( U8* dst, const U8* src )
@@ -523,14 +523,14 @@ void LLImageTGA::decodeColorMapPixel32( U8* dst, const U8* src )
 }
 
 
-BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
+bool LLImageTGA::decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped )
 {
 	// If flipped, origin is the top left.  Need to reverse the order of the rows.
 	// Otherwise the origin is the bottom left.
 
 	if( 8 != mPixelSize )
 	{
-		return FALSE;
+		return false;
 	}
 
 	U8* src = getData() + mDataOffset;
@@ -544,7 +544,7 @@ BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
 		case 2:	pixel_decoder = &LLImageTGA::decodeColorMapPixel15; break;
 		case 3:	pixel_decoder = &LLImageTGA::decodeColorMapPixel24; break;
 		case 4:	pixel_decoder = &LLImageTGA::decodeColorMapPixel32; break;
-		default: llassert(0); return FALSE;
+		default: llassert(0); return false;
 	}
 
 	if( rle )
@@ -613,12 +613,12 @@ BOOL LLImageTGA::decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped )
 		}
 	}
 
-	return TRUE;
+	return true;
 }
 
 
 
-BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
+bool LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
 {
 	llassert_always(raw_image);
 	
@@ -642,7 +642,7 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
 		mImageType = 2;		
 		break;
 	default:
-		return FALSE;
+		return false;
 	}
 
 	// Color map stuff (unsupported)
@@ -678,7 +678,7 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
 		bytes_per_pixel = 4;		
 		break;
 	default:
-		return FALSE;
+		return false;
 	}
 	mPixelSize = U8(bytes_per_pixel * 8);		// 8, 16, 24, 32 bits per pixel
 
@@ -765,13 +765,13 @@ BOOL LLImageTGA::encode(const LLImageRaw* raw_image, F32 encode_time)
 		break;
 	}
 	
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque )
+bool LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, bool &alpha_opaque )
 {
 	llassert( getComponents() == 4 );
-	alpha_opaque = TRUE;
+	alpha_opaque = true;
 
 	U8* dst = raw_image->getData();
 	U32* dst_pixels = (U32*) dst;
@@ -788,7 +788,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 		// Read RLE block header
 		
 		if (src >= last_src)
-			return FALSE;
+			return false;
 
 		U8 block_header_byte = *src;
 		src++;
@@ -799,7 +799,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 			// Encoded (duplicate-pixel) block
 
 			if (src + 3 >= last_src)
-				return FALSE;
+				return false;
 			
 			rgba_byte_p[0] = src[2];
 			rgba_byte_p[1] = src[1];
@@ -807,7 +807,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 			rgba_byte_p[3] = src[3];
 			if (rgba_byte_p[3] != 255)
 			{
-				alpha_opaque = FALSE;
+				alpha_opaque = false;
 			}
 
 			src += 4;
@@ -826,7 +826,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 			do
 			{
 				if (src + 3 >= last_src)
-					return FALSE;
+					return false;
 				
 				((U8*)dst_pixels)[0] = src[2];
 				((U8*)dst_pixels)[1] = src[1];
@@ -834,7 +834,7 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 				((U8*)dst_pixels)[3] = src[3];
 				if (src[3] != 255)
 				{
-					alpha_opaque = FALSE;
+					alpha_opaque = false;
 				}
 				src += 4;
 				dst_pixels++;
@@ -844,10 +844,10 @@ BOOL LLImageTGA::decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque
 		}
 	}
 
-	return TRUE; 
+	return true; 
 }
 
-BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
+bool LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 {
 	llassert( getComponents() == 3 );
 	llassert( mIs15Bit );
@@ -863,7 +863,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 		// Read RLE block header
 
 		if (src >= last_src)
-			return FALSE;
+			return false;
 
 		U8 block_header_byte = *src;
 		src++;
@@ -875,7 +875,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 			do
 			{
 				if (src + 2 >= last_src)
-					return FALSE;
+					return false;
 				
 				decodeTruecolorPixel15( dst, src );   // slow
 				dst += 3;
@@ -890,7 +890,7 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 			do
 			{
 				if (src + 2 >= last_src)
-					return FALSE;
+					return false;
 
 				decodeTruecolorPixel15( dst, src );
 				dst += 3;
@@ -901,12 +901,12 @@ BOOL LLImageTGA::decodeTruecolorRle15( LLImageRaw* raw_image )
 		}
 	}
 
-	return TRUE;
+	return true;
 }
 
 
 
-BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
+bool LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 {
 	llassert( getComponents() == 3 );
 
@@ -921,7 +921,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 		// Read RLE block header
 
 		if (src >= last_src)
-			return FALSE;
+			return false;
 	
 		U8 block_header_byte = *src;
 		src++;
@@ -933,7 +933,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 			do
 			{
 				if (src + 2 >= last_src)
-					return FALSE;
+					return false;
 				dst[0] = src[2];
 				dst[1] = src[1];
 				dst[2] = src[0];
@@ -949,7 +949,7 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 			do
 			{
 				if (src + 2 >= last_src)
-					return FALSE;
+					return false;
 				
 				dst[0] = src[2];
 				dst[1] = src[1];
@@ -962,11 +962,11 @@ BOOL LLImageTGA::decodeTruecolorRle24( LLImageRaw* raw_image )
 		}
 	}
 
-	return TRUE;
+	return true;
 }
 
 
-BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
+bool LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 {
 	llassert( getComponents() == 1 );
 
@@ -981,7 +981,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 		// Read RLE block header
 
 		if (src >= last_src)
-			return FALSE;
+			return false;
 
 		U8 block_header_byte = *src;
 		src++;
@@ -990,7 +990,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 		if( block_header_byte & 0x80 )
 		{
 			if (src >= last_src)
-				return FALSE;
+				return false;
 			
 			// Encoded (duplicate-pixel) block
 			memset( dst, *src, block_pixel_count );
@@ -1003,7 +1003,7 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 			do
 			{
 				if (src >= last_src)
-					return FALSE;
+					return false;
 				
 				*dst = *src;
 				dst++;
@@ -1014,13 +1014,13 @@ BOOL LLImageTGA::decodeTruecolorRle8( LLImageRaw* raw_image )
 		}
 	}
 
-	return TRUE;
+	return true;
 }
 
 
 // Decoded and process the image for use in avatar gradient masks.
 // Processing happens during the decode for speed.
-BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight )
+bool LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight )
 {
 	llassert_always(raw_image);
 	
@@ -1043,14 +1043,14 @@ BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight
 	if (!getData() || (0 == getDataSize()))
 	{
 		setLastError("LLImageTGA trying to decode an image with no data!");
-		return FALSE;
+		return false;
 	}
 
 	// Only works for unflipped monochrome RLE images
 	if( (getComponents() != 1) || (mImageType != 11) || mOriginTopBit || mOriginRightBit ) 
 	{
 		LL_ERRS() << "LLImageTGA trying to alpha-gradient process an image that's not a standard RLE, one component image" << LL_ENDL;
-		return FALSE;
+		return false;
 	}
 
 	raw_image->resize(getWidth(), getHeight(), getComponents());
@@ -1136,7 +1136,7 @@ BOOL LLImageTGA::decodeAndProcess( LLImageRaw* raw_image, F32 domain, F32 weight
 			}
 		}
 	}
-	return TRUE;
+	return true;
 }
 
 // Reads a .tga file and creates an LLImageTGA with its data.
diff --git a/indra/llimage/llimagetga.h b/indra/llimage/llimagetga.h
index 5da3525149..b1f34dcdad 100644
--- a/indra/llimage/llimagetga.h
+++ b/indra/llimage/llimagetga.h
@@ -41,25 +41,25 @@ public:
 	LLImageTGA(const std::string& file_name);
 
 	/*virtual*/ std::string getExtension() { return std::string("tga"); }
-	/*virtual*/ BOOL updateData();
-	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time=0.0);
-	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time=0.0);
+	/*virtual*/ bool updateData();
+	/*virtual*/ bool decode(LLImageRaw* raw_image, F32 decode_time=0.0);
+	/*virtual*/ bool encode(const LLImageRaw* raw_image, F32 encode_time=0.0);
 
-	BOOL			 decodeAndProcess(LLImageRaw* raw_image, F32 domain, F32 weight);
+	bool			 decodeAndProcess(LLImageRaw* raw_image, F32 domain, F32 weight);
 	
 private:
-	BOOL			 decodeTruecolor( LLImageRaw* raw_image, BOOL rle, BOOL flipped );
+	bool			 decodeTruecolor( LLImageRaw* raw_image, bool rle, bool flipped );
 
-	BOOL			 decodeTruecolorRle8( LLImageRaw* raw_image );
-	BOOL			 decodeTruecolorRle15( LLImageRaw* raw_image );
-	BOOL			 decodeTruecolorRle24( LLImageRaw* raw_image );
-	BOOL			 decodeTruecolorRle32( LLImageRaw* raw_image, BOOL &alpha_opaque );
+	bool			 decodeTruecolorRle8( LLImageRaw* raw_image );
+	bool			 decodeTruecolorRle15( LLImageRaw* raw_image );
+	bool			 decodeTruecolorRle24( LLImageRaw* raw_image );
+	bool			 decodeTruecolorRle32( LLImageRaw* raw_image, bool &alpha_opaque );
 
 	void			 decodeTruecolorPixel15( U8* dst, const U8* src );
 
-	BOOL			 decodeTruecolorNonRle( LLImageRaw* raw_image, BOOL &alpha_opaque );
+	bool			 decodeTruecolorNonRle( LLImageRaw* raw_image, bool &alpha_opaque );
 	
-	BOOL			 decodeColorMap( LLImageRaw* raw_image, BOOL rle, BOOL flipped );
+	bool			 decodeColorMap( LLImageRaw* raw_image, bool rle, bool flipped );
 
 	void			 decodeColorMapPixel8(U8* dst, const U8* src);
 	void			 decodeColorMapPixel15(U8* dst, const U8* src);
@@ -100,7 +100,7 @@ private:
 	S32		mColorMapLength; 
 	S32		mColorMapBytesPerEntry;
 
-	BOOL	mIs15Bit;
+	bool	mIs15Bit;
 
 	static const U8 s5to8bits[32];
 };
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 0152b879c2..3bb1778d9d 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -100,19 +100,19 @@ LLImageJ2COJ::~LLImageJ2COJ()
 {
 }
 
-BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
 {
 	// No specific implementation for this method in the OpenJpeg case
-	return FALSE;
+	return false;
 }
 
-BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
+bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
 {
 	// No specific implementation for this method in the OpenJpeg case
-	return FALSE;
+	return false;
 }
 
-BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
+bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
 {
 	//
 	// FIXME: Get the comment field out of the texture
@@ -179,7 +179,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
 			opj_image_destroy(image);
 		}
 
-		return TRUE; // done
+		return true; // done
 	}
 
 	// sometimes we get bad data out of the cache - check to see if the decode succeeded
@@ -189,8 +189,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
 		{
 			// if we didn't get the discard level we're expecting, fail
 			opj_image_destroy(image);
-			base.mDecoding = FALSE;
-			return TRUE;
+			base.mDecoding = false;
+			return true;
 		}
 	}
 	
@@ -202,7 +202,7 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
 			opj_image_destroy(image);
 		}
 			
-		return TRUE;
+		return true;
 	}
 
 	// Copy image data into our raw image format (instead of the separate channel format
@@ -249,18 +249,18 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
 			LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL;
 			opj_image_destroy(image);
 
-			return TRUE; // done
+			return true; // done
 		}
 	}
 
 	/* free image data structure */
 	opj_image_destroy(image);
 
-	return TRUE; // done
+	return true; // done
 }
 
 
-BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
+bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
 {
 	const S32 MAX_COMPS = 5;
 	opj_cparameters_t parameters;	/* compression parameters */
@@ -381,7 +381,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
 	{
 		opj_cio_close(cio);
 		LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL;
-		return FALSE;
+		return false;
 	}
 	codestream_length = cio_tell(cio);
 
@@ -400,10 +400,10 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con
 
 	/* free image data */
 	opj_image_destroy(image);
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
+bool LLImageJ2COJ::getMetadata(LLImageJ2C &base)
 {
 	//
 	// FIXME: We get metadata by decoding the ENTIRE image.
@@ -466,7 +466,7 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
 	if(!image)
 	{
 		LL_WARNS() << "ERROR -> getMetadata: failed to decode image!" << LL_ENDL;
-		return FALSE;
+		return false;
 	}
 
 	// Copy image data into our raw image format (instead of the separate channel format
@@ -480,5 +480,5 @@ BOOL LLImageJ2COJ::getMetadata(LLImageJ2C &base)
 
 	/* free image data structure */
 	opj_image_destroy(image);
-	return TRUE;
+	return true;
 }
diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h
index ae96a175a2..5c6193944e 100644
--- a/indra/llimagej2coj/llimagej2coj.h
+++ b/indra/llimagej2coj/llimagej2coj.h
@@ -35,12 +35,12 @@ public:
 	LLImageJ2COJ();
 	virtual ~LLImageJ2COJ();
 protected:
-	virtual BOOL getMetadata(LLImageJ2C &base);
-	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
-	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
-								BOOL reversible = FALSE);
-	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+	virtual bool getMetadata(LLImageJ2C &base);
+	virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
+	virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
+								bool reversible = false);
+	virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+	virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
     virtual std::string getEngineInfo() const;
 };
 
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 44dc9daabd..0b2ac03b9d 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -88,11 +88,11 @@ class LLKDUDecodeState
 public:
 	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap);
 	~LLKDUDecodeState();
-	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE);
+	bool processTileDecode(F32 decode_time, bool limit_time = true);
 
 private:
 	S32 mNumComponents;
-	BOOL mUseYCC;
+	bool mUseYCC;
 	kdu_dims mDims;
 	kdu_sample_allocator mAllocator;
 	kdu_tile_comp mComps[4];
@@ -190,7 +190,7 @@ LLImageJ2CKDU::~LLImageJ2CKDU()
 // Stuff for new simple decode
 void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
 
-void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode)
+void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode)
 {
 	S32 data_size = base.getDataSize();
 	S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
@@ -316,12 +316,12 @@ void LLImageJ2CKDU::cleanupCodeStream()
 	mTileIndicesp = NULL;
 }
 
-BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
+bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
 {
 	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);
 }
 
-BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
+bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels)
 {
 	mPrecinctsSize = precincts_size;
 	if (mPrecinctsSize != -1)
@@ -345,10 +345,10 @@ BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
 		mLevels = llclamp(mLevels,MIN_DECOMPOSITION_LEVELS,MAX_DECOMPOSITION_LEVELS);
 		base.setLevels(mLevels);
 	}
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
+bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
 {
 	base.resetLastError();
 
@@ -360,7 +360,7 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 		//findDiscardLevelsBoundaries(base);
 
 		base.updateRawDiscardLevel();
-		setupCodeStream(base, TRUE, mode);
+		setupCodeStream(base, true, mode);
 
 		mRawImagep = &raw_image;
 		mCodeStreamp->change_appearance(false, true, false);
@@ -408,20 +408,20 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 	catch (const char* msg)
 	{
 		base.setLastError(ll_safe_string(msg));
-		return FALSE;
+		return false;
 	}
 	catch (...)
 	{
 		base.setLastError("Unknown J2C error");
-		return FALSE;
+		return false;
 	}
 
-	return TRUE;
+	return true;
 }
 
 
-// Returns TRUE to mean done, whether successful or not.
-BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
+// Returns true to mean done, whether successful or not.
+bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
 {
 	ECodeStreamMode mode = MODE_FAST;
 
@@ -433,7 +433,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 		{
 			// Initializing the J2C decode failed, bail out.
 			cleanupCodeStream();
-			return TRUE; // done
+			return true; // done
 		}
 	}
 
@@ -492,7 +492,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 				{
 					// Not finished decoding yet.
 					//					setLastError("Ran out of time while decoding");
-					return FALSE;
+					return false;
 				}
 			}
 			catch (const char* msg)
@@ -500,14 +500,14 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 				base.setLastError(ll_safe_string(msg));
 				base.decodeFailed();
 				cleanupCodeStream();
-				return TRUE; // done
+				return true; // done
 			}
 			catch (...)
 			{
 				base.setLastError( "Unknown J2C error" );
 				base.decodeFailed();
 				cleanupCodeStream();
-				return TRUE; // done
+				return true; // done
 			}
 
 
@@ -519,11 +519,11 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 
 	cleanupCodeStream();
 
-	return TRUE;
+	return true;
 }
 
 
-BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)
+bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
 {
 	// Declare and set simple arguments
 	bool transpose = false;
@@ -691,36 +691,36 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
 	catch(const char* msg)
 	{
 		base.setLastError(ll_safe_string(msg));
-		return FALSE;
+		return false;
 	}
 	catch( ... )
 	{
 		base.setLastError( "Unknown J2C error" );
-		return FALSE;
+		return false;
 	}
 
-	return TRUE;
+	return true;
 }
 
-BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
+bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
 {
 	// *FIX: kdu calls our callback function if there's an error, and
 	// then bombs. To regain control, we throw an exception, and
 	// catch it here.
 	try
 	{
-		setupCodeStream(base, FALSE, MODE_FAST);
-		return TRUE;
+		setupCodeStream(base, false, MODE_FAST);
+		return true;
 	}
 	catch (const char* msg)
 	{
 		base.setLastError(ll_safe_string(msg));
-		return FALSE;
+		return false;
 	}
 	catch (...)
 	{
 		base.setLastError( "Unknown J2C error" );
-		return FALSE;
+		return false;
 	}
 }
 
@@ -830,7 +830,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
 	{
 		//std::cout << "Parsing discard level = " << discard_level << std::endl;
 		// Create the input codestream object.
-		setupCodeStream(base, TRUE, MODE_FAST);
+		setupCodeStream(base, true, MODE_FAST);
 		mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL);
 		mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true);
 		siz_params *siz_in = mCodeStreamp->access_siz();
@@ -1189,7 +1189,7 @@ LLKDUDecodeState::~LLKDUDecodeState()
 	mTile.close();
 }
 
-BOOL LLKDUDecodeState::processTileDecode(F32 decode_time, BOOL limit_time)
+bool LLKDUDecodeState::processTileDecode(F32 decode_time, bool limit_time)
 /* Decompresses a tile, writing the data into the supplied byte buffer.
 The buffer contains interleaved image components, if there are any.
 Although you may think of the buffer as belonging entirely to this tile,
@@ -1221,11 +1221,11 @@ separation between consecutive rows in the real buffer. */
 		{
 			if (limit_time && decode_timer.getElapsedTimeF32() > decode_time)
 			{
-				return FALSE;
+				return false;
 			}
 		}
 	}
-	return TRUE;
+	return true;
 }
 
 // kdc_flow_control 
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index 85dc408d4d..da84749796 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -65,18 +65,18 @@ public:
 	virtual ~LLImageJ2CKDU();
 	
 protected:
-	virtual BOOL getMetadata(LLImageJ2C &base);
-	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
-	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
-								BOOL reversible=FALSE);
-	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
-	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
+	virtual bool getMetadata(LLImageJ2C &base);
+	virtual bool decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);
+	virtual bool encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,
+								bool reversible=false);
+	virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
+	virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
 	virtual std::string getEngineInfo() const;
 	void findDiscardLevelsBoundaries(LLImageJ2C &base);
 
 private:
-	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
-	void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode);
+	bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
+	void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode);
 	void cleanupCodeStream();
 
 	// Encode variable
diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp
index 0605fad068..e8b550baa6 100644
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -60,7 +60,7 @@ LLImageRaw::~LLImageRaw() { }
 U8* LLImageRaw::allocateData(S32 ) { return NULL; }
 void LLImageRaw::deleteData() { }
 U8* LLImageRaw::reallocateData(S32 ) { return NULL; }
-BOOL LLImageRaw::resize(U16, U16, S8) { return TRUE; } // this method always returns TRUE...
+bool LLImageRaw::resize(U16, U16, S8) { return true; } // this method always returns true...
 
 LLImageBase::LLImageBase()
 : LLTrace::MemTrackable<LLImageBase>("LLImageBase"),
@@ -89,8 +89,8 @@ LLImageFormatted::~LLImageFormatted() { }
 U8* LLImageFormatted::allocateData(S32 ) { return NULL; }
 S32 LLImageFormatted::calcDataSize(S32 ) { return 0; }
 S32 LLImageFormatted::calcDiscardLevelBytes(S32 ) { return 0; }
-BOOL LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return FALSE; }
-BOOL LLImageFormatted::copyData(U8 *, S32) { return TRUE; }  // this method always returns TRUE...
+bool LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return false; }
+bool LLImageFormatted::copyData(U8 *, S32) { return true; }  // this method always returns true...
 void LLImageFormatted::deleteData() { }
 void LLImageFormatted::dump() { }
 U8* LLImageFormatted::reallocateData(S32 ) { return NULL; }
@@ -103,14 +103,14 @@ LLImageJ2C::~LLImageJ2C() { }
 S32 LLImageJ2C::calcDataSize(S32 ) { return 0; }
 S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; }
 S32 LLImageJ2C::calcHeaderSize() { return 0; }
-BOOL LLImageJ2C::decode(LLImageRaw*, F32) { return FALSE; }
-BOOL LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return FALSE; }
+bool LLImageJ2C::decode(LLImageRaw*, F32) { return false; }
+bool LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return false; }
 void LLImageJ2C::decodeFailed() { }
-BOOL LLImageJ2C::encode(const LLImageRaw*, F32) { return FALSE; }
+bool LLImageJ2C::encode(const LLImageRaw*, F32) { return false; }
 S8  LLImageJ2C::getRawDiscardLevel() { return 0; }
 void LLImageJ2C::resetLastError() { }
 void LLImageJ2C::setLastError(const std::string&, const std::string&) { }
-BOOL LLImageJ2C::updateData() { return FALSE; }
+bool LLImageJ2C::updateData() { return false; }
 void LLImageJ2C::updateRawDiscardLevel() { }
 
 LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { }
@@ -212,12 +212,12 @@ namespace tut
 		{
 		public:
 			// Provides public access to some protected methods for testing
-			BOOL callGetMetadata(LLImageJ2C &base) { return getMetadata(base); }
-			BOOL callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
+			bool callGetMetadata(LLImageJ2C &base) { return getMetadata(base); }
+			bool callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)
 			{
 				return decodeImpl(base, raw_image, decode_time, first_channel, max_channel_count);
 			}
-			BOOL callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text)
+			bool callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text)
 			{
 				return encodeImpl(base, raw_image, comment_text);
 			}
@@ -254,10 +254,10 @@ namespace tut
 	void llimagej2ckdu_object_t::test<1>()
 	{
 		LLImageJ2C* image = new LLImageJ2C();
-		BOOL res = mImage->callGetMetadata(*image);
-		// Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return TRUE
-		// Note that is linking with KDU, that call will throw an exception and fail, returning FALSE
-		ensure("getMetadata() test failed", res == TRUE);
+		bool res = mImage->callGetMetadata(*image);
+		// Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return true
+		// Note that is linking with KDU, that call will throw an exception and fail, returning false
+		ensure("getMetadata() test failed", res);
 	}
 
 	// Test 2 : test decodeImpl()
@@ -266,9 +266,9 @@ namespace tut
 	{
 		LLImageJ2C* image = new LLImageJ2C();
 		LLImageRaw* raw = new LLImageRaw();
-		BOOL res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0);
-		// Decoding returns TRUE whenever there's nothing else to do, including if decoding failed, so we'll get TRUE here
-		ensure("decodeImpl() test failed", res == TRUE);
+		bool res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0);
+		// Decoding returns true whenever there's nothing else to do, including if decoding failed, so we'll get true here
+		ensure("decodeImpl() test failed", res);
 	}
 
 	// Test 3 : test encodeImpl()
@@ -277,8 +277,8 @@ namespace tut
 	{
 		LLImageJ2C* image = new LLImageJ2C();
 		LLImageRaw* raw = new LLImageRaw();
-		BOOL res = mImage->callEncodeImpl(*image, *raw, NULL);
-		// Encoding returns TRUE unless an exception was raised, so we'll get TRUE here though nothing really was done
-		ensure("encodeImpl() test failed", res == TRUE);
+		bool res = mImage->callEncodeImpl(*image, *raw, NULL);
+		// Encoding returns true unless an exception was raised, so we'll get true here though nothing really was done
+		ensure("encodeImpl() test failed", res);
 	}
 }
-- 
cgit v1.2.3


From 7187ec75a7095ab7bf1d49896d2f4f72b7899243 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 26 Jul 2016 19:18:03 +0300
Subject: MAINT-6476 VOB - User can add any size image to an Outfit Gallery
 outfit folders Added restriction of image size that can be added to outfit
 via "Select Photo"

---
 indra/newview/lloutfitgallery.cpp                  | 60 +++++++++++++++++++---
 indra/newview/lloutfitgallery.h                    |  4 +-
 indra/newview/lltexturectrl.cpp                    |  7 ++-
 indra/newview/lltexturectrl.h                      |  3 ++
 .../newview/skins/default/xui/en/notifications.xml |  4 +-
 indra/newview/skins/default/xui/en/strings.xml     |  3 ++
 6 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index a65ab26c52..a93cbb30f5 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -55,6 +55,9 @@
 
 static LLPanelInjector<LLOutfitGallery> t_outfit_gallery("outfit_gallery");
 
+#define MAX_OUTFIT_PHOTO_WIDTH 256
+#define MAX_OUTFIT_PHOTO_HEIGHT 256
+
 LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
     : LLOutfitListBase(),
       mTexturesObserver(NULL),
@@ -74,7 +77,8 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
       mItemHorizontalGap(p.item_horizontal_gap),
       mItemsInRow(p.items_in_row),
       mRowPanWidthFactor(p.row_panel_width_factor),
-      mGalleryWidthFactor(p.gallery_width_factor)
+      mGalleryWidthFactor(p.gallery_width_factor),
+      mTextureSelected(NULL)
 {
     updateGalleryWidth();
 }
@@ -1069,8 +1073,8 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
                 image_load_error = image_info.getLastError();
             }
 
-            S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
-            S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
+            S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
+            S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
 
             if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
             {
@@ -1078,14 +1082,14 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
                 args["WIDTH"] = llformat("%d", max_width);
                 args["HEIGHT"] = llformat("%d", max_height);
 
-                image_load_error = LLTrans::getString("texture_load_dimensions_error", args);
+                image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
             }
 
             if (!image_load_error.empty())
             {
                 LLSD subst;
                 subst["REASON"] = image_load_error;
-                LLNotificationsUtil::add("ImageLoadError", subst);
+                LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
                 return;
             }
 
@@ -1158,7 +1162,43 @@ void LLOutfitGallery::onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LL
         else
         {
             image_item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+            if (image_item_id.isNull())
+            {
+                LL_WARNS() << "id or image_item_id is NULL!" << LL_ENDL;
+                return;
+            }
+        }
+
+        std::string image_load_error;
+        S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
+        S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
+        if (mTextureSelected.isNull() ||
+            mTextureSelected->getFullWidth() == 0 ||
+            mTextureSelected->getFullHeight() == 0)
+        {
+            image_load_error = LLTrans::getString("outfit_photo_verify_dimensions_error");
+            LL_WARNS() << "Cannot verify selected texture dimensions" << LL_ENDL;
+            return;
+        }
+        S32 width = mTextureSelected->getFullWidth();
+        S32 height = mTextureSelected->getFullHeight();
+        if ((width > max_width) || (height > max_height))
+        {
+            LLStringUtil::format_map_t args;
+            args["WIDTH"] = llformat("%d", max_width);
+            args["HEIGHT"] = llformat("%d", max_height);
+
+            image_load_error = LLTrans::getString("outfit_photo_select_dimensions_error", args);
         }
+
+        if (!image_load_error.empty())
+        {
+            LLSD subst;
+            subst["REASON"] = image_load_error;
+            LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
+            return;
+        }
+
         checkRemovePhoto(getSelectedOutfitUUID());
         linkPhotoToOutfit(image_item_id, getSelectedOutfitUUID());
     }
@@ -1196,15 +1236,14 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
                 NULL);
 
             mFloaterHandle = floaterp->getHandle();
+            mTextureSelected = NULL;
 
             LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
             if (texture_floaterp)
             {
                 texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1));
-            }
-            if (texture_floaterp)
-            {
                 texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
+                texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
             }
 
             floaterp->openFloater();
@@ -1241,3 +1280,8 @@ void LLOutfitGallery::onAfterOutfitSnapshotSave()
         mOutfitLinkPending = selected_outfit_id;
     }
 }
+
+void LLOutfitGallery::onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture)
+{
+    mTextureSelected = texture;
+}
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index f5954d9cc2..6b13f264a4 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -111,6 +111,7 @@ public:
     void refreshOutfit(const LLUUID& category_id);
 
     void onTexturePickerCommit(LLTextureCtrl::ETexturePickOp op, LLUUID id);
+    void onTexturePickerUpdateImageStats(LLPointer<LLViewerTexture> texture);
     void onBeforeOutfitSnapshotSave();
     void onAfterOutfitSnapshotSave();
 protected:
@@ -168,6 +169,7 @@ private:
     bool mGalleryCreated;
     int mRowCount;
     int mItemsAddedCount;
+    LLPointer<LLViewerTexture> mTextureSelected;
     /* Params */
     int mRowPanelHeight;
     int mVerticalGap;
@@ -266,7 +268,7 @@ public:
     void setHidden(bool hidden) {mHidden = hidden;}
     
 private:
-    LLPointer<LLViewerTexture> mTexturep;
+    LLPointer<LLViewerFetchedTexture> mTexturep;
     LLUUID mImageAssetId;
     LLTextBox* mOutfitNameText;
     LLTextBox* mOutfitWornText;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 858486514f..f77e0349b5 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -118,7 +118,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	mPreviewSettingChanged(false),
 	mOnFloaterCommitCallback(NULL),
 	mOnFloaterCloseCallback(NULL),
-	mSetImageAssetIDCallback(NULL)
+	mSetImageAssetIDCallback(NULL),
+	mOnUpdateImageStatsCallback(NULL)
 {
 	buildFromFile("floater_texture_ctrl.xml");
 	mCanApplyImmediately = can_apply_immediately;
@@ -195,6 +196,10 @@ void LLFloaterTexturePicker::updateImageStats()
 		{
 			std::string formatted_dims = llformat("%d x %d", mTexturep->getFullWidth(),mTexturep->getFullHeight());
 			mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
+			if (mOnUpdateImageStatsCallback)
+			{
+				mOnUpdateImageStatsCallback(mTexturep);
+			}
 		}
 		else
 		{
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3ea052ad57..471a36094c 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -240,6 +240,7 @@ private:
 typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLUUID id)> floater_commit_callback;
 typedef boost::function<void()> floater_close_callback;
 typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
+typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback;
 
 class LLFloaterTexturePicker : public LLFloater
 {
@@ -298,6 +299,7 @@ public:
 	void setOnFloaterCloseCallback(const floater_close_callback& cb) { mOnFloaterCloseCallback = cb; }
 	void setOnFloaterCommitCallback(const floater_commit_callback& cb) { mOnFloaterCommitCallback = cb; }
 	void setSetImageAssetIDCallback(const set_image_asset_id_callback& cb) { mSetImageAssetIDCallback = cb; }
+	void setOnUpdateImageStatsCallback(const set_on_update_image_stats_callback& cb) { mOnUpdateImageStatsCallback = cb; }
 	const LLUUID& getDefaultImageAssetID() { return mDefaultImageAssetID; }
 	const LLUUID& getBlankImageAssetID() { return mBlankImageAssetID; }
 
@@ -364,6 +366,7 @@ private:
 	floater_close_callback mOnFloaterCloseCallback;
 	floater_commit_callback mOnFloaterCommitCallback;
 	set_image_asset_id_callback mSetImageAssetIDCallback;
+	set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
 };
 
 #endif  // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f96b8636f5..bb9c767f2b 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11019,9 +11019,9 @@ Cannot create large prims that intersect other players.  Please re-try when othe
   
   <notification
    icon="alert.tga"
-   name="ImageLoadError"
+   name="OutfitPhotoLoadError"
    type="alertmodal">
-   [REASON]
+    [REASON]
     <tag>fail</tag>
     <usetemplate
      name="okbutton"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ae63546082..17bb9a9e43 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3806,6 +3806,9 @@ Abuse Report</string>
 
   <string name="DefaultMimeType">none/none</string>
   <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string>
+  <string name="outfit_photo_load_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image</string>
+  <string name="outfit_photo_select_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please select another texture</string>
+  <string name="outfit_photo_verify_dimensions_error">Cannot verify photo dimensions. Please wait until photo size is displayed in picker</string>
 
   <!-- language specific white-space characters, delimiters, spacers, item separation symbols -->
   <string name="sentences_separator" value=" "></string>
-- 
cgit v1.2.3


From 5e2676994cf1816ff1a39eb69d90662b5087d367 Mon Sep 17 00:00:00 2001
From: Ansariel Hiller <ansarielhiller@yahoo.de>
Date: Tue, 26 Jul 2016 19:26:28 +0000
Subject: Fix HttpCoroutineAdapter name for clarity

---
 indra/llmessage/message.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index cecb2021e7..290b67feb3 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -4007,7 +4007,7 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st
 {
     LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("untrustedSimulatorMessage", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
     LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
 
-- 
cgit v1.2.3


From b779ca0aed88ec73284790781a53575e709f3010 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Tue, 26 Jul 2016 17:43:39 -0400
Subject: fail build on a failed configure

---
 build.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/build.sh b/build.sh
index d67cb32e7c..cd2a9ebf5e 100755
--- a/build.sh
+++ b/build.sh
@@ -101,7 +101,8 @@ pre_build()
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
      -DGRID:STRING="\"$viewer_grid\"" \
      -DLL_TESTS:BOOL="$run_tests" \
-     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
+     -DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
+    || fatal "$variant configuration failed"
 
   end_section "Configure $variant"
 }
-- 
cgit v1.2.3


From 03bff896bd18b71c9a2d8e0b163647b1cd64b871 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Wed, 3 Aug 2016 20:40:03 -0400
Subject: MAINT-6584: Use RAII classes to manage helper object lifespans.

Use boost::scoped_ptr instead of raw pointers to LLKDUMemSource,
LLKDUDecodeState, kdu_coords and kdu_dims so cleanup is simpler, and automated
on destruction of LLImageJ2CKDU.

Replace pointer to kdu_codestream with a custom RAII class. kdu_codestream is
itself an opaque handle, so we don't need to add another layer of indirection.
Just wrap it to ensure its destroy() method is reliably called when needed.

Make static instances of LLKDUMessageWarning and LLKDUMessageError
self-register, eliminating the companion static bool and explicit checks in
code.
---
 indra/llkdu/llimagej2ckdu.cpp | 98 +++++++++++++++++--------------------------
 indra/llkdu/llimagej2ckdu.h   | 45 +++++++++++++++++---
 2 files changed, 78 insertions(+), 65 deletions(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 0b2ac03b9d..0d37b123ec 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -138,15 +138,21 @@ struct LLKDUMessageWarning : public LLKDUMessage
 {
 	LLKDUMessageWarning():
 		LLKDUMessage("Warning")
-	{}
+	{
+		kdu_customize_warnings(this);
+	}
 };
+// Instantiating LLKDUMessageWarning calls kdu_customize_warnings() with the
+// new instance. Make it static so this only happens once.
 static LLKDUMessageWarning sWarningHandler;
 
 struct LLKDUMessageError : public LLKDUMessage
 {
 	LLKDUMessageError():
 		LLKDUMessage("Error")
-	{}
+	{
+		kdu_customize_errors(this);
+	}
 
 	virtual void flush(bool end_of_message = false)
 	{
@@ -165,20 +171,20 @@ struct LLKDUMessageError : public LLKDUMessage
 		}
 	}
 };
+// Instantiating LLKDUMessageError calls kdu_customize_errors() with the new
+// instance. Make it static so this only happens once.
 static LLKDUMessageError sErrorHandler;
 
-static bool kdu_message_initialized = false;
-
 LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(),
-mInputp(NULL),
-mCodeStreamp(NULL),
-mTPosp(NULL),
-mTileIndicesp(NULL),
-mRawImagep(NULL),
-mDecodeState(NULL),
-mBlocksSize(-1),
-mPrecinctsSize(-1),
-mLevels(0)
+	mInputp(),
+	mCodeStreamp(),
+	mTPosp(),
+	mTileIndicesp(),
+	mRawImagep(NULL),
+	mDecodeState(),
+	mBlocksSize(-1),
+	mPrecinctsSize(-1),
+	mLevels(0)
 {
 }
 
@@ -198,38 +204,27 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
 	//
 	//  Initialization
 	//
-	if (!kdu_message_initialized)
-	{
-		kdu_message_initialized = true;
-		kdu_customize_errors(&sErrorHandler);
-		kdu_customize_warnings(&sWarningHandler);
-	}
-
-	if (mCodeStreamp)
-	{
-		mCodeStreamp->destroy();
-		delete mCodeStreamp;
-		mCodeStreamp = NULL;
-	}
+	mCodeStreamp.reset();
 
 	if (!mInputp && base.getData())
 	{
 		// The compressed data has been loaded
 		// Setup the source for the codestream
-		mInputp = new LLKDUMemSource(base.getData(), data_size);
+		mInputp.reset(new LLKDUMemSource(base.getData(), data_size));
 	}
 
 	if (mInputp)
 	{
+		// This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset().
 		mInputp->reset();
 	}
-	mCodeStreamp = new kdu_codestream;
 
-	mCodeStreamp->create(mInputp);
+	mCodeStreamp->create(mInputp.get());
 
 	// Set the maximum number of bytes to use from the codestream
-	// *TODO: This seems to be wrong. The base class should have no idea of how j2c compression works so no
-	// good way of computing what's the byte range to be used.
+	// *TODO: This seems to be wrong. The base class should have no idea of
+	// how j2c compression works so no good way of computing what's the byte
+	// range to be used.
 	mCodeStreamp->set_max_bytes(max_bytes,true);
 
 	//	If you want to flip or rotate the image for some reason, change
@@ -286,34 +281,18 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
 	
 	if (!keep_codestream)
 	{
-		mCodeStreamp->destroy();
-		delete mCodeStreamp;
-		mCodeStreamp = NULL;
-		delete mInputp;
-		mInputp = NULL;
+		mCodeStreamp.reset();
+		mInputp.reset();
 	}
 }
 
 void LLImageJ2CKDU::cleanupCodeStream()
 {
-	delete mInputp;
-	mInputp = NULL;
-
-	delete mDecodeState;
-	mDecodeState = NULL;
-
-	if (mCodeStreamp)
-	{
-		mCodeStreamp->destroy();
-		delete mCodeStreamp;
-		mCodeStreamp = NULL;
-	}
-
-	delete mTPosp;
-	mTPosp = NULL;
-
-	delete mTileIndicesp;
-	mTileIndicesp = NULL;
+	mInputp.reset();
+	mDecodeState.reset();
+	mCodeStreamp.reset();
+	mTPosp.reset();
+	mTileIndicesp.reset();
 }
 
 bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
@@ -395,12 +374,12 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 
 		if (!mTileIndicesp)
 		{
-			mTileIndicesp = new kdu_dims;
+			mTileIndicesp.reset(new kdu_dims);
 		}
 		mCodeStreamp->get_valid_tiles(*mTileIndicesp);
 		if (!mTPosp)
 		{
-			mTPosp = new kdu_coords;
+			mTPosp.reset(new kdu_coords);
 			mTPosp->y = 0;
 			mTPosp->x = 0;
 		}
@@ -427,7 +406,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 
 	LLTimer decode_timer;
 
-	if (!mCodeStreamp)
+	if (!mCodeStreamp->exists())
 	{
 		if (!initDecode(base, raw_image, decode_time, mode, first_channel, max_channel_count))
 		{
@@ -478,15 +457,14 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 					kdu_coords offset = tile_dims.pos - dims.pos;
 					int row_gap = channels*dims.size.x; // inter-row separation
 					kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels;
-					mDecodeState = new LLKDUDecodeState(tile, buf, row_gap);
+					mDecodeState.reset(new LLKDUDecodeState(tile, buf, row_gap));
 				}
 				// Do the actual processing
 				F32 remaining_time = decode_time - decode_timer.getElapsedTimeF32();
 				// This is where we do the actual decode.  If we run out of time, return false.
 				if (mDecodeState->processTileDecode(remaining_time, (decode_time > 0.0f)))
 				{
-					delete mDecodeState;
-					mDecodeState = NULL;
+					mDecodeState.reset();
 				}
 				else
 				{
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index da84749796..5fb093826e 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -48,6 +48,8 @@
 #endif
 
 #include "kdu_sample_processing.h"
+#include <boost/scoped_ptr.hpp>
+#include <boost/noncopyable.hpp>
 
 class LLKDUDecodeState;
 class LLKDUMemSource;
@@ -79,18 +81,51 @@ private:
 	void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode);
 	void cleanupCodeStream();
 
+	// Helper class to hold a kdu_codestream, which is a handle to the
+	// underlying implementation object. When CodeStreamHolder is reset() or
+	// destroyed, it calls kdu_codestream::destroy() -- which kdu_codestream
+	// itself does not.
+	//
+	// Call through it like a smart pointer using operator->().
+	//
+	// Every RAII class must be noncopyable. For this we don't need move
+	// support.
+	class CodeStreamHolder: public boost::noncopyable
+	{
+	public:
+		~CodeStreamHolder()
+		{
+			reset();
+		}
+
+		void reset()
+		{
+			if (mCodeStream.exists())
+			{
+				mCodeStream.destroy();
+			}
+		}
+
+		kdu_codestream* operator->() { return &mCodeStream; }
+
+	private:
+		kdu_codestream mCodeStream;
+	};
+
 	// Encode variable
-	LLKDUMemSource *mInputp;
-	kdu_codestream *mCodeStreamp;
-	kdu_coords *mTPosp; // tile position
-	kdu_dims *mTileIndicesp;
+	boost::scoped_ptr<LLKDUMemSource> mInputp;
+	CodeStreamHolder mCodeStreamp;
+	boost::scoped_ptr<kdu_coords> mTPosp; // tile position
+	boost::scoped_ptr<kdu_dims> mTileIndicesp;
 	int mBlocksSize;
 	int mPrecinctsSize;
 	int mLevels;
 
 	// Temporary variables for in-progress decodes...
+	// We don't own this LLImageRaw. We're simply pointing to an instance
+	// passed into initDecode().
 	LLImageRaw *mRawImagep;
-	LLKDUDecodeState *mDecodeState;
+	boost::scoped_ptr<LLKDUDecodeState> mDecodeState;
 };
 
 #endif
-- 
cgit v1.2.3


From 2339e759fc2d6f36a4b9425022a22a747ec55dad Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 27 Jul 2016 05:49:07 +0300
Subject: MAINT-4327/MAINT-6584 Supress the crash on memory allocation error
 when decoding J2C images

---
 indra/llimage/llimage.cpp     | 6 ++++--
 indra/llkdu/llimagej2ckdu.cpp | 7 +++++++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 109ef7e904..91fa8c6ad1 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -773,7 +773,8 @@ const U8* LLImageBase::getData() const
 { 
 	if(mBadBufferAllocation)
 	{
-		LL_ERRS() << "Bad memory allocation for the image buffer!" << LL_ENDL ;
+		LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL ;
+		return NULL;
 	}
 
 	return mData; 
@@ -783,7 +784,8 @@ U8* LLImageBase::getData()
 { 
 	if(mBadBufferAllocation)
 	{
-		LL_ERRS() << "Bad memory allocation for the image buffer!" << LL_ENDL ;
+		LL_WARNS() << "Bad memory allocation for the image buffer!" << LL_ENDL;
+		return NULL;
 	}
 
 	return mData; 
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 0d37b123ec..0863240686 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -422,6 +422,13 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 
 	// Now we are ready to walk through the tiles processing them one-by-one.
 	kdu_byte *buffer = raw_image.getData();
+	if (!buffer)
+	{
+		base.setLastError("Memory error");
+		base.decodeFailed();
+		cleanupCodeStream();
+		return true; // done
+	}
 
 	while (mTPosp->y < mTileIndicesp->size.y)
 	{
-- 
cgit v1.2.3


From 0888078bd86136ed198d38b95f79f4bd1bdc3ed1 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 29 Jul 2016 12:44:52 +0300
Subject: MAINT-6601 FIXED [VOB] Texture picker generates WARNING spam in
 SecondLife.log

---
 indra/newview/lltexturectrl.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index f77e0349b5..a93f8da3f0 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -479,7 +479,6 @@ void LLFloaterTexturePicker::draw()
 		mTexturep = NULL;
 		if(mImageAssetID.notNull())
 		{
-            LL_WARNS() << "mImageAssetID: " << mImageAssetID << LL_ENDL;
 			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
 			mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		}
-- 
cgit v1.2.3


From 84677aad4cfb5b892f9037118b0bb6cdbe9d6309 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 1 Aug 2016 15:18:32 +0300
Subject: MAINT-6602 disable ability to select local textures

---
 indra/newview/lloutfitgallery.cpp | 1 +
 indra/newview/lltexturectrl.cpp   | 5 +++++
 indra/newview/lltexturectrl.h     | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index a93cbb30f5..65fd3f95ab 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1244,6 +1244,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
                 texture_floaterp->setTextureSelectedCallback(boost::bind(&LLOutfitGallery::onTextureSelectionChanged, this, _1));
                 texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
                 texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
+                texture_floaterp->setLocalTextureEnabled(FALSE);
             }
 
             floaterp->openFloater();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index a93f8da3f0..fd13f60606 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -941,6 +941,11 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 	mInventoryPanel->setFilterSubString(search_string);
 }
 
+void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
+{
+	mModeSelector->setIndexEnabled(1,enabled);
+}
+
 void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
 {
 	LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 471a36094c..61f99de5c0 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -322,6 +322,8 @@ public:
 	static void		onBtnUpload(void* userdata);
 	static void		onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
 
+	void 			setLocalTextureEnabled(BOOL enabled);
+
 protected:
 	LLPointer<LLViewerTexture> mTexturep;
 	LLView*				mOwner;
-- 
cgit v1.2.3


From 13f19b1634a4d20c6daed965d52ea412ca4b0455 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 1 Aug 2016 17:25:20 +0300
Subject: Backed out changeset: c21a7e6d9796

---
 indra/newview/llmeshrepository.cpp | 13 +++++++------
 indra/newview/llmeshrepository.h   |  4 ++--
 indra/newview/llvovolume.cpp       |  5 ++---
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 18634de500..d7665716b7 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3906,8 +3906,8 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
 
 bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
 {
-	const LLSD* mesh = mThread->getMeshHeader(mesh_id);
-	if (mesh && mesh->has("physics_mesh") && (*mesh)["physics_mesh"].has("size") && ((*mesh)["physics_mesh"]["size"].asInteger() > 0))
+	LLSD mesh = mThread->getMeshHeader(mesh_id);
+	if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
 	{
 		return true;
 	}
@@ -3921,26 +3921,27 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
 	return false;
 }
 
-const LLSD* LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
+LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
 {
 	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
 
 	return mThread->getMeshHeader(mesh_id);
 }
 
-const LLSD* LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
+LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)
 {
+	static LLSD dummy_ret;
 	if (mesh_id.notNull())
 	{
 		LLMutexLock lock(mHeaderMutex);
 		mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
 		if (iter != mMeshHeader.end() && mMeshHeaderSize[mesh_id] > 0)
 		{
-			return &(iter->second);
+			return iter->second;
 		}
 	}
 
-	return NULL;
+	return dummy_ret;
 }
 
 
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 8a1166522f..d35c44397b 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -305,7 +305,7 @@ public:
 	bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
 	bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
-	const LLSD* getMeshHeader(const LLUUID& mesh_id);
+	LLSD& getMeshHeader(const LLUUID& mesh_id);
 
 	void notifyLoadedMeshes();
 	S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -506,7 +506,7 @@ public:
 	bool meshRezEnabled();
 	
 
-	const LLSD* getMeshHeader(const LLUUID& mesh_id);
+	LLSD& getMeshHeader(const LLUUID& mesh_id);
 
 	void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
 			bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true,
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 486f6fae61..8f0b233f01 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3627,9 +3627,8 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v
 	F32 radius = getScale().length()*0.5f;
 
 	if (isMesh())
-	{
-		const LLSD* header_ptr = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
-		LLSD header = header_ptr ? *header_ptr : LLSD();
+	{	
+		LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
 
 		return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value);
 	}
-- 
cgit v1.2.3


From 9b07078b470d40c4b6454d21da2909c35517b248 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 1 Aug 2016 18:00:54 +0300
Subject: MAINT-6460 Crash calculating mesh complexity

---
 indra/newview/llmeshrepository.cpp | 14 ++++++++++++++
 indra/newview/llmeshrepository.h   |  1 +
 indra/newview/llvovolume.cpp       |  6 ++----
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d7665716b7..8bc75c8433 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4031,6 +4031,20 @@ void LLMeshRepository::uploadError(LLSD& args)
 	mUploadErrorQ.push(args);
 }
 
+F32 LLMeshRepository::getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
+{
+    if (mThread && mesh_id.notNull())
+    {
+        LLMutexLock lock(mThread->mHeaderMutex);
+        LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
+        if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
+        {
+            return getStreamingCost(iter->second, radius, bytes, bytes_visible, lod, unscaled_value);
+        }
+    }
+    return 0.f;
+}
+
 //static
 F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
 {
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index d35c44397b..a762042597 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -475,6 +475,7 @@ public:
 	
 	static LLDeadmanTimer sQuiescentTimer;		// Time-to-complete-mesh-downloads after significant events
 
+	F32 getStreamingCost(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
 	static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
 
 	LLMeshRepository();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8f0b233f01..e69a8d1d1d 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3627,10 +3627,8 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v
 	F32 radius = getScale().length()*0.5f;
 
 	if (isMesh())
-	{	
-		LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
-
-		return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD, unscaled_value);
+	{
+		return gMeshRepo.getStreamingCost(getVolume()->getParams().getSculptID(), radius, bytes, visible_bytes, mLOD, unscaled_value);
 	}
 	else
 	{
-- 
cgit v1.2.3


From ce3658455230cf392f45cc99f44a737ee59f13bd Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 1 Aug 2016 18:58:41 +0300
Subject: MAINT-6460 getMeshSize crash

---
 indra/newview/llmeshrepository.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 8bc75c8433..54f8fb93d0 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3956,10 +3956,11 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
 
 S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
 {
-	if (mThread)
+	if (mThread && mesh_id.notNull())
 	{
+		LLMutexLock lock(mThread->mHeaderMutex);
 		LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
-		if (iter != mThread->mMeshHeader.end())
+		if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
 		{
 			LLSD& header = iter->second;
 
-- 
cgit v1.2.3


From 6c56c9bf6763e22442cdc16706f0fb978a0ec46d Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 9 Aug 2016 15:38:16 +0300
Subject: MAINT-6620 FIXED Use internal or external browser according to
 Preferences

---
 indra/newview/llfloaterbuycurrency.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index e21a8594bc..91436e52fe 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -280,7 +280,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
 
 void LLFloaterBuyCurrencyUI::onClickErrorWeb()
 {
-	LLWeb::loadURLExternal(mManager.errorURI());
+	LLWeb::loadURL(mManager.errorURI());
 	closeFloater();
 	// Update L$ balance
 	LLStatusBar::sendMoneyBalanceRequest();
-- 
cgit v1.2.3


From f4f30dae0f173517fa1cd58cead142d60cbcc839 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 8 Aug 2016 21:31:11 +0300
Subject: MAINT-6612 Server release notes in Help -> About Second Life never
 fetch on any region.

---
 doc/contributions.txt            |  1 +
 indra/newview/llfloaterabout.cpp | 74 +++++++++++++++++++++++++++-------------
 2 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 1daee0f92b..d968e80250 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -198,6 +198,7 @@ Ansariel Hiller
 	MAINT-6552
 	STORM-2133
 	MAINT-6511
+	MAINT-6612
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index bababca652..8d17f4c198 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -108,6 +108,7 @@ private:
 	static const std::string sCheckUpdateListenerName;
 	
     static void startFetchServerReleaseNotes();
+    static void fetchServerReleaseNotesCoro(const std::string& cap_url);
     static void handleServerReleaseNotes(LLSD results);
 };
 
@@ -224,35 +225,62 @@ void LLFloaterAbout::startFetchServerReleaseNotes()
     // an URL suitable for external browsers in the "Location:" HTTP header.
     std::string cap_url = region->getCapability("ServerReleaseNotes");
 
-    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
-        &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
+    LLCoros::instance().launch("fetchServerReleaseNotesCoro", boost::bind(&LLFloaterAbout::fetchServerReleaseNotesCoro, cap_url));
 
 }
 
+/*static*/
+void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)
+{
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("fetchServerReleaseNotesCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        handleServerReleaseNotes(httpResults);
+    }
+    else
+    {
+        handleServerReleaseNotes(result);
+    }
+}
+
 /*static*/
 void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
 {
-//     LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
-//     if (floater_about)
-//     {
-        LLSD http_headers;
-        if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
-        {
-            LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-            http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
-        }
-        else
-        {
-            http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
-        }
-        
-        std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
-        if (location.empty())
-        {
-            location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
-        }
-        LLAppViewer::instance()->setServerReleaseNotesURL(location);
-//    }
+    LLSD http_headers;
+    if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
+    {
+        LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+        http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    }
+    else
+    {
+        http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    }
+
+    std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
+    if (location.empty())
+    {
+        location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
+    }
+    LLAppViewer::instance()->setServerReleaseNotesURL(location);
+
+    LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
+    if (floater_about)
+    {
+        floater_about->setSupportText(location);
+    }
 }
 
 class LLFloaterAboutListener: public LLEventAPI
-- 
cgit v1.2.3


From de0a8782be1f95cb1ca5e74b38df0a73f69356c6 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 9 Aug 2016 16:23:27 +0300
Subject: MAINT-6614 Fixed typo in InventoryTrashMaxCapacity comment

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f1d0901a81..ca81696a50 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4870,7 +4870,7 @@
     <key>InventoryTrashMaxCapacity</key>
     <map>
         <key>Comment</key>
-        <string>Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded.</string>
+        <string>Maximum capacity of the Trash folder. User will be offered to clean it up when exceeded.</string>
         <key>Persist</key>
         <integer>1</integer>
         <key>Type</key>
-- 
cgit v1.2.3


From 5924155f29d9c971dcec4fd21e77466a455ef98d Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 9 Aug 2016 19:29:14 +0300
Subject: MAINT-6612 Server release notes in Help

---
 indra/newview/llfloaterabout.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 8d17f4c198..c2d0d9f06b 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -276,7 +276,7 @@ void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
     }
     LLAppViewer::instance()->setServerReleaseNotesURL(location);
 
-    LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
+    LLFloaterAbout* floater_about = LLFloaterReg::findTypedInstance<LLFloaterAbout>("sl_about");
     if (floater_about)
     {
         floater_about->setSupportText(location);
-- 
cgit v1.2.3


From e76b5643effc0a38c28a561ce403c97033419398 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 10 Aug 2016 13:31:25 +0300
Subject: MAINT-6608 FIXED URI parser problem with links with username,
 password

---
 indra/llcommon/lluriparser.cpp |  4 ++--
 indra/llcommon/lluriparser.h   |  2 +-
 indra/llui/llurlentry.cpp      | 12 +++++++++---
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index 82d0dc8b4b..c275b90120 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -205,9 +205,9 @@ void LLUriParser::glue(std::string& uri) const
 	uri = first_part + second_part;
 }
 
-void LLUriParser::glueFirst(std::string& uri) const
+void LLUriParser::glueFirst(std::string& uri, bool use_scheme) const
 {
-	if (mScheme.size())
+	if (use_scheme && mScheme.size())
 	{
 		uri = mScheme;
 		uri += "://";
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index 2df8085ae6..cfbf54f3c8 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -60,7 +60,7 @@ public:
 
 	void extractParts();
 	void glue(std::string& uri) const;
-	void glueFirst(std::string& uri) const;
+	void glueFirst(std::string& uri, bool use_scheme = true) const;
 	void glueSecond(std::string& uri) const;
 	bool test() const;
 	S32 normalize();
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index e4848362a7..797fae81c4 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -205,9 +205,15 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
 
 	std::string label;
 	up.extractParts();
-	up.glueFirst(label);
-	std::string query = url.substr(label.size());
-	return query;
+	up.glueFirst(label, false);
+
+	size_t pos = url.find(label);
+	if (pos == std::string::npos)
+	{
+		return "";
+	}
+	pos += label.size();
+	return url.substr(pos);
 }
 
 
-- 
cgit v1.2.3


From 1e2d10d13a90fcb79130f967c299e04ea664f0aa Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 10 Aug 2016 14:35:15 +0300
Subject: SL-437 Remove Checkbox from Abuse Report Submission

---
 indra/newview/llfloaterreporter.cpp                | 28 +++++-----------------
 .../skins/default/xui/en/floater_report_abuse.xml  | 10 +-------
 2 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index ed6f4ede9f..5d77972180 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -192,7 +192,6 @@ BOOL LLFloaterReporter::postBuild()
 	mOwnerName = LLStringUtil::null;
 
 	getChild<LLUICtrl>("summary_edit")->setFocus(TRUE);
-	getChild<LLCheckBoxCtrl>("screen_check")->set(TRUE);
 
 	mDefaultSummary = getChild<LLUICtrl>("details_edit")->getValue().asString();
 
@@ -246,8 +245,6 @@ LLFloaterReporter::~LLFloaterReporter()
 // virtual
 void LLFloaterReporter::draw()
 {
-	getChildView("screen_check")->setEnabled(TRUE );
-
 	LLFloater::draw();
 }
 
@@ -255,7 +252,6 @@ void LLFloaterReporter::enableControls(BOOL enable)
 {
 	getChildView("category_combo")->setEnabled(enable);
 	getChildView("chat_check")->setEnabled(enable);
-	getChildView("screen_check")->setEnabled(enable);
 	getChildView("screenshot")->setEnabled(FALSE);
 	getChildView("pick_btn")->setEnabled(enable);
 	getChildView("summary_edit")->setEnabled(enable);
@@ -452,19 +448,10 @@ void LLFloaterReporter::onClickSend(void *userdata)
 		}
 		else
 		{
-			if(self->getChild<LLUICtrl>("screen_check")->getValue())
-			{
-				self->getChildView("send_btn")->setEnabled(FALSE);
-				self->getChildView("cancel_btn")->setEnabled(FALSE);
-				// the callback from uploading the image calls sendReportViaLegacy()
-				self->uploadImage();
-			}
-			else
-			{
-				self->sendReportViaLegacy(self->gatherReport());
-				LLUploadDialog::modalUploadFinished();
-				self->closeFloater();
-			}
+			self->getChildView("send_btn")->setEnabled(FALSE);
+			self->getChildView("cancel_btn")->setEnabled(FALSE);
+			// the callback from uploading the image calls sendReportViaLegacy()
+			self->uploadImage();
 		}
 	}
 }
@@ -713,10 +700,7 @@ LLSD LLFloaterReporter::gatherReport()
 	// only send a screenshot ID if we're asked to and the email is 
 	// going to LL - Estate Owners cannot see the screenshot asset
 	LLUUID screenshot_id = LLUUID::null;
-	if (getChild<LLUICtrl>("screen_check")->getValue())
-	{
-		screenshot_id = getChild<LLUICtrl>("screenshot")->getValue();
-	};
+	screenshot_id = getChild<LLUICtrl>("screenshot")->getValue();
 
 	LLSD report = LLSD::emptyMap();
 	report["report-type"] = (U8) mReportType;
@@ -770,7 +754,7 @@ void LLFloaterReporter::finishedARPost(const LLSD &)
 
 void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report)
 {
-	if(getChild<LLUICtrl>("screen_check")->getValue().asBoolean() && !sshot_url.empty())
+	if(!sshot_url.empty())
     {
 		// try to upload screenshot
         LLResourceUploadInfo::ptr_t uploadInfo(new  LLARScreenShotUploader(report, mResourceDatap->mAssetInfo.mUuid, mResourceDatap->mAssetInfo.mType));
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index af62c7a9bc..225266af86 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -21,14 +21,6 @@
      name="screenshot"
      top="15"
      width="220" />
-    <check_box
-     height="15"
-     label="Use this screenshot"
-     layout="topleft"
-     left="8"
-     name="screen_check"
-     top_pad="-12"
-     width="116" />
     <text
      type="string"
      length="1"
@@ -39,7 +31,7 @@
      layout="topleft"
      left="10"
      name="reporter_title"
-     top_pad="0"
+     top_pad="-2"
      width="100">
         Reporter:
     </text>
-- 
cgit v1.2.3


From 78e1706ad06c4c32bcfac999398fc506c69eb9db Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 10 Aug 2016 18:18:34 +0300
Subject: MAINT-6569 Agent search was failing due to timeout

---
 indra/newview/llfloateravatarpicker.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 72892b47a4..aa7bfbfdb7 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -55,6 +55,8 @@
 
 //#include "llsdserialize.h"
 
+static const U32 AVATAR_PICKER_SEARCH_TIMEOUT = 180U;
+
 //put it back as a member once the legacy path is out?
 static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
@@ -463,10 +465,13 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
         httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
     LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
 
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+    httpOpts->setTimeout(AVATAR_PICKER_SEARCH_TIMEOUT);
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
 
     LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
     LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-- 
cgit v1.2.3


From e3c58f74781186f084f60b35b931c5bb5d75e1ba Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 10 Aug 2016 19:02:57 +0300
Subject: MAINT-6554 reducing log spam

---
 indra/newview/llvovolume.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 50ccb2f74a..4aef6480cb 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4451,7 +4451,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE);
 	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
 	{
-		LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
+		LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
 	}
 
 	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
-- 
cgit v1.2.3


From 529778219388a445075880e86bc0e846004952c7 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 15 Aug 2016 17:05:23 +0300
Subject: MAINT-6634 "My graphics driver is out of date" was listed 3 times in
 Alerts

---
 indra/newview/llappviewer.cpp                      | 12 ++++--
 .../newview/skins/default/xui/en/notifications.xml | 45 ++--------------------
 indra/newview/skins/default/xui/en/strings.xml     |  6 +++
 3 files changed, 18 insertions(+), 45 deletions(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 950692a788..e1242513e1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1124,17 +1124,23 @@ bool LLAppViewer::init()
 #if LL_WINDOWS
 	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
 	{
+		std::string url;
 		if (gGLManager.mIsIntel)
 		{
-			LLNotificationsUtil::add("IntelOldDriver");
+			url = LLTrans::getString("IntelDriverPage");
 		}
 		else if (gGLManager.mIsNVIDIA)
 		{
-			LLNotificationsUtil::add("NVIDIAOldDriver");
+			url = LLTrans::getString("NVIDIADriverPage");
 		}
 		else if (gGLManager.mIsATI)
 		{
-			LLNotificationsUtil::add("AMDOldDriver");
+			url = LLTrans::getString("AMDDriverPage");
+		}
+
+		if (!url.empty())
+		{
+			LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url));
 		}
 	}
 #endif
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 54e90ac496..6fdeedc8ae 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1638,14 +1638,14 @@ Visit [_URL] for more information?
 
   <notification
    icon="alertmodal.tga"
-   name="IntelOldDriver"
+   name="OldGPUDriver"
    type="alertmodal">
      There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
 
-    Visit [_URL] to check for driver updates?
+    Visit [URL] to check for driver updates?
     <tag>confirm</tag>
     <url option="0" name="url">
-      http://www.intel.com/p/en_US/support/detect/graphics
+    [URL]
     </url>
     <usetemplate
      ignoretext="My graphics driver is out of date"
@@ -1655,45 +1655,6 @@ Visit [_URL] for more information?
     <tag>fail</tag>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="AMDOldDriver"
-   type="alertmodal">
-    There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
-
-    Visit [_URL] to check for driver updates?
-    <tag>confirm</tag>
-    <url option="0" name="url">
-      http://support.amd.com/us/Pages/AMDSupportHub.aspx
-    </url>
-    <usetemplate
-     ignoretext="My graphics driver is out of date"
-     name="okcancelignore"
-     notext="No"
-     yestext="Yes"/>
-    <tag>fail</tag>
-  </notification>
-
-  <notification
- icon="alertmodal.tga"
- name="NVIDIAOldDriver"
- type="alertmodal">
-    There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
-
-    Visit [_URL] to check for driver updates?
-    <tag>confirm</tag>
-    <url option="0" name="url">
-      http://www.nvidia.com/Download/index.aspx?lang=en-us
-    </url>
-    <usetemplate
-     ignoretext="My graphics driver is out of date"
-     name="okcancelignore"
-     notext="No"
-     yestext="Yes"/>
-    <tag>fail</tag>
-  </notification>
-
-
   <notification
    icon="alertmodal.tga"
    name="UnknownGPU"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index ac92e6fa9f..27c08f560f 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2835,6 +2835,12 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
 	<string name="Multiple Media">Multiple Media</string>
 	<string name="Play Media">Play/Pause Media</string>
 
+	<!-- Drivers support/update pages -->
+	<string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string>
+	<string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=en-us</string>
+	<string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string>
+
+
 	<!-- OSMessageBox messages -->
 	<string name="MBCmdLineError">
 		An error was found parsing the command line.
-- 
cgit v1.2.3


From 5b94ed9f4e8bff5d2079b012434d16df4ab27397 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 15 Aug 2016 20:01:56 +0300
Subject: MAINT-6634 fixed string

---
 indra/newview/llappviewer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e1242513e1..64bc7fb2c4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1131,7 +1131,7 @@ bool LLAppViewer::init()
 		}
 		else if (gGLManager.mIsNVIDIA)
 		{
-			url = LLTrans::getString("NVIDIADriverPage");
+			url = LLTrans::getString("NvidiaDriverPage");
 		}
 		else if (gGLManager.mIsATI)
 		{
-- 
cgit v1.2.3


From b25ee9095deca0cd0c7eedafda89e021734d0ca7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 14:13:56 -0400
Subject: Remove VSTool, its build info and all invocations.

VSTool manipulates the SecondLife.sln solution file for the convenience of a
developer subsequently running Visual Studio interactively. But the cost of
having it sometimes break TeamCity automated builds is too high -- especially
since we never expect to run Visual Studio interactively on a TC build host.

Also remove the CMake UNATTENDED variable that controlled it.
---
 autobuild.xml                         |  34 --
 indra/cmake/Variables.cmake           |   1 -
 indra/newview/CMakeLists.txt          |  15 -
 indra/tools/vstool/DispatchUtility.cs | 271 -------------
 indra/tools/vstool/README.txt         |   9 -
 indra/tools/vstool/VSTool.csproj      |  98 -----
 indra/tools/vstool/VSTool.exe         | Bin 24576 -> 0 bytes
 indra/tools/vstool/VSTool.sln         |  19 -
 indra/tools/vstool/app.config         |   3 -
 indra/tools/vstool/main.cs            | 729 ----------------------------------
 10 files changed, 1179 deletions(-)
 delete mode 100644 indra/tools/vstool/DispatchUtility.cs
 delete mode 100644 indra/tools/vstool/README.txt
 delete mode 100755 indra/tools/vstool/VSTool.csproj
 delete mode 100755 indra/tools/vstool/VSTool.exe
 delete mode 100755 indra/tools/vstool/VSTool.sln
 delete mode 100644 indra/tools/vstool/app.config
 delete mode 100755 indra/tools/vstool/main.cs

diff --git a/autobuild.xml b/autobuild.xml
index 072dfa678a..5a91ba15f5 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2617,14 +2617,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2663,20 +2655,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
@@ -2705,14 +2688,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2749,20 +2724,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 63e296b556..8292a0c63d 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -164,7 +164,6 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
-set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index dce0ea73cd..586a56b49a 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1799,21 +1799,6 @@ if (WINDOWS)
    windows-crash-logger
     )
 
-    # sets the 'working directory' for debugging from visual studio.
-    if (NOT UNATTENDED)
-        add_custom_command(
-            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
-            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-            ARGS
-              --solution
-              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-              --workingdir
-              ${VIEWER_BINARY_NAME}
-              "${CMAKE_CURRENT_SOURCE_DIR}"
-            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
-            )
-    endif (NOT UNATTENDED)
-
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs
deleted file mode 100644
index 6056ac55a1..0000000000
--- a/indra/tools/vstool/DispatchUtility.cs
+++ /dev/null
@@ -1,271 +0,0 @@
-#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Reflection;
-using System.Security.Permissions;
-
-#endregion
-
-namespace TestDispatchUtility
-{
-	/// <summary>
-	/// Provides helper methods for working with COM IDispatch objects that have a registered type library.
-	/// </summary>
-	public static class DispatchUtility
-	{
-		#region Private Constants
-
-		private const int S_OK = 0; //From WinError.h
-		private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800
-
-		#endregion
-
-		#region Public Methods
-
-		/// <summary>
-		/// Gets whether the specified object implements IDispatch.
-		/// </summary>
-		/// <param name="obj">An object to check.</param>
-		/// <returns>True if the object implements IDispatch.  False otherwise.</returns>
-		public static bool ImplementsIDispatch(object obj)
-		{
-			bool result = obj is IDispatchInfo;
-			return result;
-		}
-
-		/// <summary>
-		/// Gets a Type that can be used with reflection.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
-		/// <returns>A .NET Type that can be used with reflection.</returns>
-		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
-		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-		public static Type GetType(object obj, bool throwIfNotFound)
-		{
-			RequireReference(obj, "obj");
-			Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
-			return result;
-		}
-
-		/// <summary>
-		/// Tries to get the DISPID for the requested member name.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="name">The name of a member to lookup.</param>
-		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
-		/// If the method returns false, this value should be ignored.</param>
-		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
-		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
-		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-		public static bool TryGetDispId(object obj, string name, out int dispId)
-		{
-			RequireReference(obj, "obj");
-			bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
-			return result;
-		}
-
-		/// <summary>
-		/// Invokes a member by DISPID.
-		/// </summary>
-		/// <param name="obj">An object that implements IDispatch.</param>
-		/// <param name="dispId">The DISPID of a member.  This can be obtained using
-		/// <see cref="TryGetDispId(object, string, out int)"/>.</param>
-		/// <param name="args">The arguments to pass to the member.</param>
-		/// <returns>The member's return value.</returns>
-		/// <remarks>
-		/// This can invoke a method or a property get accessor.
-		/// </remarks>
-		public static object Invoke(object obj, int dispId, object[] args)
-		{
-			string memberName = "[DispId=" + dispId + "]";
-			object result = Invoke(obj, memberName, args);
-			return result;
-		}
-
-		/// <summary>
-		/// Invokes a member by name.
-		/// </summary>
-		/// <param name="obj">An object.</param>
-		/// <param name="memberName">The name of the member to invoke.</param>
-		/// <param name="args">The arguments to pass to the member.</param>
-		/// <returns>The member's return value.</returns>
-		/// <remarks>
-		/// This can invoke a method or a property get accessor.
-		/// </remarks>
-		public static object Invoke(object obj, string memberName, object[] args)
-		{
-			RequireReference(obj, "obj");
-			Type type = obj.GetType();
-			object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty,
-				null, obj, args, null);
-			return result;
-		}
-
-		#endregion
-
-		#region Private Methods
-
-		/// <summary>
-		/// Requires that the value is non-null.
-		/// </summary>
-		/// <typeparam name="T">The type of the value.</typeparam>
-		/// <param name="value">The value to check.</param>
-		/// <param name="name">The name of the value.</param>
-		private static void RequireReference<T>(T value, string name) where T : class
-		{
-			if (value == null)
-			{
-				throw new ArgumentNullException(name);
-			}
-		}
-
-		/// <summary>
-		/// Gets a Type that can be used with reflection.
-		/// </summary>
-		/// <param name="dispatch">An object that implements IDispatch.</param>
-		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
-		/// <returns>A .NET Type that can be used with reflection.</returns>
-		private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
-		{
-			RequireReference(dispatch, "dispatch");
-
-			Type result = null;
-			int typeInfoCount;
-			int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
-			if (hr == S_OK && typeInfoCount > 0)
-			{
-				// Type info isn't usually culture-aware for IDispatch, so we might as well pass
-				// the default locale instead of looking up the current thread's LCID each time
-				// (via CultureInfo.CurrentCulture.LCID).
-				dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
-			}
-
-			if (result == null && throwIfNotFound)
-			{
-				// If the GetTypeInfoCount called failed, throw an exception for that.
-				Marshal.ThrowExceptionForHR(hr);
-
-				// Otherwise, throw the same exception that Type.GetType would throw.
-				throw new TypeLoadException();
-			}
-
-			return result;
-		}
-
-		/// <summary>
-		/// Tries to get the DISPID for the requested member name.
-		/// </summary>
-		/// <param name="dispatch">An object that implements IDispatch.</param>
-		/// <param name="name">The name of a member to lookup.</param>
-		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
-		/// If the method returns false, this value should be ignored.</param>
-		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
-		private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
-		{
-			RequireReference(dispatch, "dispatch");
-			RequireReference(name, "name");
-
-			bool result = false;
-
-			// Members names aren't usually culture-aware for IDispatch, so we might as well
-			// pass the default locale instead of looking up the current thread's LCID each time
-			// (via CultureInfo.CurrentCulture.LCID).
-			Guid iidNull = Guid.Empty;
-			int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId);
-
-			const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
-			const int DISPID_UNKNOWN = -1; //From OAIdl.idl
-			if (hr == S_OK)
-			{
-				result = true;
-			}
-			else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
-			{
-				// This is the only supported "error" case because it means IDispatch
-				// is saying it doesn't know the member we asked about.
-				result = false;
-			}
-			else
-			{
-				// The other documented result codes are all errors.
-				Marshal.ThrowExceptionForHR(hr);
-			}
-
-			return result;
-		}
-
-		#endregion
-
-		#region Private Interfaces
-
-		/// <summary>
-		/// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
-		/// </summary>
-		/// <remarks>
-		/// This interface only declares the first three methods of IDispatch.  It omits the
-		/// fourth method (Invoke) because there are already plenty of ways to do dynamic
-		/// invocation in .NET.  But the first three methods provide dynamic type metadata
-		/// discovery, which .NET doesn't provide normally if you have a System.__ComObject
-		/// RCW instead of a strongly-typed RCW.
-		/// <para/>
-		/// Note: The original declaration of IDispatch is in OAIdl.idl.
-		/// </remarks>
-		[ComImport]
-		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
-		[Guid("00020400-0000-0000-C000-000000000046")]
-		private interface IDispatchInfo
-		{
-			/// <summary>
-			/// Gets the number of Types that the object provides (0 or 1).
-			/// </summary>
-			/// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
-			/// </remarks>
-			[PreserveSig]
-			int GetTypeInfoCount(out int typeInfoCount);
-
-			/// <summary>
-			/// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
-			/// </summary>
-			/// <param name="typeInfoIndex">Must be 0.</param>
-			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
-			/// <param name="typeInfo">Returns the object's Type information.</param>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
-			/// </remarks>
-			void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
-				MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
-
-			/// <summary>
-			/// Gets the DISPID of the specified member name.
-			/// </summary>
-			/// <param name="riid">Must be IID_NULL.  Pass a copy of Guid.Empty.</param>
-			/// <param name="name">The name of the member to look up.</param>
-			/// <param name="nameCount">Must be 1.</param>
-			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
-			/// <param name="dispId">If a member with the requested <paramref name="name"/>
-			/// is found, this returns its DISPID and the method's return value is 0.
-			/// If the method returns a non-zero value, then this parameter's output value is
-			/// undefined.</param>
-			/// <returns>Zero for success. Non-zero for failure.</returns>
-			/// <remarks>
-			/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
-			/// </remarks>
-			[PreserveSig]
-			int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId);
-
-			// NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
-			// We can invoke methods using .NET's Type.InvokeMember method with the special
-			// [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
-			// and invoke methods on that through reflection.
-			// Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
-		}
-
-		#endregion
-	}
-}
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
deleted file mode 100644
index e419180031..0000000000
--- a/indra/tools/vstool/README.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-VSTool is a command line utility to manipulate VisualStudio settings. 
-
-The windows cmake project configuration uses VSTool.exe
-
-A handy upgrade:
- figure out how to make cmake build this csharp app
- - or write the app using script (jscript?!?) so it doesn't need to be built.
-
-
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
deleted file mode 100755
index 7f431e85c7..0000000000
--- a/indra/tools/vstool/VSTool.csproj
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <ProjectType>Local</ProjectType>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ApplicationIcon>
-    </ApplicationIcon>
-    <AssemblyKeyContainerName>
-    </AssemblyKeyContainerName>
-    <AssemblyName>VSTool</AssemblyName>
-    <AssemblyOriginatorKeyFile>
-    </AssemblyOriginatorKeyFile>
-    <DefaultClientScript>JScript</DefaultClientScript>
-    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
-    <DefaultTargetSchema>IE50</DefaultTargetSchema>
-    <DelaySign>false</DelaySign>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>VSTool</RootNamespace>
-    <RunPostBuildEvent>Always</RunPostBuildEvent>
-    <StartupObject>VSTool.VSToolMain</StartupObject>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <UpgradeBackupLocation>
-    </UpgradeBackupLocation>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
-    <OldToolsVersion>2.0</OldToolsVersion>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <OutputPath>.\</OutputPath>
-    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
-    <BaseAddress>285212672</BaseAddress>
-    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DocumentationFile>
-    </DocumentationFile>
-    <DebugSymbols>true</DebugSymbols>
-    <FileAlignment>4096</FileAlignment>
-    <NoStdLib>false</NoStdLib>
-    <NoWarn>
-    </NoWarn>
-    <Optimize>false</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>full</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <OutputPath>.\</OutputPath>
-    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
-    <BaseAddress>285212672</BaseAddress>
-    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
-    <ConfigurationOverrideFile>
-    </ConfigurationOverrideFile>
-    <DefineConstants>TRACE</DefineConstants>
-    <DocumentationFile>
-    </DocumentationFile>
-    <DebugSymbols>false</DebugSymbols>
-    <FileAlignment>4096</FileAlignment>
-    <NoStdLib>false</NoStdLib>
-    <NoWarn>
-    </NoWarn>
-    <Optimize>true</Optimize>
-    <RegisterForComInterop>false</RegisterForComInterop>
-    <RemoveIntegerChecks>false</RemoveIntegerChecks>
-    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
-    <WarningLevel>4</WarningLevel>
-    <DebugType>none</DebugType>
-    <ErrorReport>prompt</ErrorReport>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System">
-      <Name>System</Name>
-    </Reference>
-    <Reference Include="System.Data">
-      <Name>System.Data</Name>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="main.cs">
-      <SubType>Code</SubType>
-    </Compile>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
-</Project>
\ No newline at end of file
diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe
deleted file mode 100755
index 854290b90a..0000000000
Binary files a/indra/tools/vstool/VSTool.exe and /dev/null differ
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
deleted file mode 100755
index 21e3d75971..0000000000
--- a/indra/tools/vstool/VSTool.sln
+++ /dev/null
@@ -1,19 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config
deleted file mode 100644
index 8494f728ff..0000000000
--- a/indra/tools/vstool/app.config
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<configuration>
-<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
deleted file mode 100755
index ef2e582b90..0000000000
--- a/indra/tools/vstool/main.cs
+++ /dev/null
@@ -1,729 +0,0 @@
-// Code about getting running instances visual studio
-// was borrowed from 
-// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
-
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-using Microsoft.CSharp;
-
-namespace VSTool
-{
-    // The MessageFilter class comes from:
-    // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
-    // It allows vstool to get timing error messages from 
-    // visualstudio and handle them.
-    public class MessageFilter : IOleMessageFilter
-    {
-        //
-        // Class containing the IOleMessageFilter
-        // thread error-handling functions.
-
-        // Start the filter.
-        public static void Register()
-        {
-            IOleMessageFilter newFilter = new MessageFilter(); 
-            IOleMessageFilter oldFilter = null; 
-            CoRegisterMessageFilter(newFilter, out oldFilter);
-        }
-
-        // Done with the filter, close it.
-        public static void Revoke()
-        {
-            IOleMessageFilter oldFilter = null; 
-            CoRegisterMessageFilter(null, out oldFilter);
-        }
-
-        //
-        // IOleMessageFilter functions.
-        // Handle incoming thread requests.
-        int IOleMessageFilter.HandleInComingCall(int dwCallType, 
-          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 
-          lpInterfaceInfo) 
-        {
-            //Return the flag SERVERCALL_ISHANDLED.
-            return 0;
-        }
-
-        // Thread call was rejected, so try again.
-        int IOleMessageFilter.RetryRejectedCall(System.IntPtr 
-          hTaskCallee, int dwTickCount, int dwRejectType)
-        {
-            if (dwRejectType == 2)
-            // flag = SERVERCALL_RETRYLATER.
-            {
-                // Retry the thread call immediately if return >=0 & 
-                // <100.
-                return 99;
-            }
-            // Too busy; cancel call.
-            return -1;
-        }
-
-        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 
-          int dwTickCount, int dwPendingType)
-        {
-            //Return the flag PENDINGMSG_WAITDEFPROCESS.
-            return 2; 
-        }
-
-        // Implement the IOleMessageFilter interface.
-        [DllImport("Ole32.dll")]
-        private static extern int 
-          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
-          IOleMessageFilter oldFilter);
-    }
-
-    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 
-    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
-    interface IOleMessageFilter 
-    {
-        [PreserveSig]
-        int HandleInComingCall( 
-            int dwCallType, 
-            IntPtr hTaskCaller, 
-            int dwTickCount, 
-            IntPtr lpInterfaceInfo);
-
-        [PreserveSig]
-        int RetryRejectedCall( 
-            IntPtr hTaskCallee, 
-            int dwTickCount,
-            int dwRejectType);
-
-        [PreserveSig]
-        int MessagePending( 
-            IntPtr hTaskCallee, 
-            int dwTickCount,
-            int dwPendingType);
-    }
-
-    class ViaCOM
-    {
-        public static object GetProperty(object from_obj, string prop_name)
-        {
-            try
-            {
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    prop_name,
-                    BindingFlags.GetProperty, null,
-                    from_obj,
-                    null);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error getting property: \"{0}\"", prop_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-
-        public static object SetProperty(object from_obj, string prop_name, object new_value)
-        {
-            try
-            {
-                object[] args = { new_value };
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    prop_name,
-                    BindingFlags.DeclaredOnly |
-                    BindingFlags.Public |
-                    BindingFlags.NonPublic |
-                    BindingFlags.Instance |
-                    BindingFlags.SetProperty,
-                    null,
-                    from_obj,
-                    args);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error setting property: \"{0}\"", prop_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-
-        public static object CallMethod(object from_obj, string method_name, params object[] args)
-        {
-            try
-            {
-                Type objType = from_obj.GetType();
-                return objType.InvokeMember(
-                    method_name,
-                    BindingFlags.DeclaredOnly |
-                    BindingFlags.Public |
-                    BindingFlags.NonPublic |
-                    BindingFlags.Instance |
-                    BindingFlags.InvokeMethod,
-                    null,
-                    from_obj,
-                    args);
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("Error calling method \"{0}\"", method_name);
-                Console.WriteLine(e.Message);
-                throw e;
-            }
-        }
-    };
-
-    /// <summary>
-	/// The main entry point class for VSTool.
-	/// </summary>
-    class VSToolMain
-    {
-        #region Interop imports
-        [DllImport("ole32.dll")]  
-        public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
- 
-        [DllImport("ole32.dll")]  
-        public static extern int  CreateBindCtx(int reserved, out IBindCtx ppbc);
-        #endregion 
-
-        static System.Boolean ignore_case = true;
-
-        static string solution_name = null;
-        static bool use_new_vs = false;
-        static Hashtable projectDict = new Hashtable();
-        static string startup_project = null;
-        static string config = null;
-
-        static object dte = null;
-        static object solution = null;
-
-        /// <summary>
-		/// The main entry point for the application.
-		/// </summary>
-		[STAThread]
-		static int Main(string[] args)
-		{
-            int retVal = 0;
-            bool need_save = false;
-
-            try
-            {
-                parse_command_line(args);
-
-                Console.WriteLine("Editing solution: {0}", solution_name);
-
-                bool found_open_solution = GetDTEAndSolution();
-
-                if (dte == null || solution == null)
-                {
-                    retVal = 1;
-                }
-                else
-                {
-                    MessageFilter.Register();
-
-                    // Walk through all of the projects in the solution
-                    // and list the type of each project.
-                    foreach (DictionaryEntry p in projectDict)
-                    {
-                        string project_name = (string)p.Key;
-                        string working_dir = (string)p.Value;
-                        if (SetProjectWorkingDir(solution, project_name, working_dir))
-                        {
-                            need_save = true;
-                        }
-                    }
-
-                    if (config != null)
-                    {
-                        need_save = SetActiveConfig(config);
-                    }
-
-                    if (startup_project != null)
-                    {
-                        need_save = SetStartupProject(startup_project);
-                    }
-
-                    if (need_save)
-                    {
-                        if (found_open_solution == false)
-                        {
-                            ViaCOM.CallMethod(solution, "Close", null);
-                        }
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine(e.Message);
-                retVal = 1;
-            }
-            finally
-            {
-                if (solution != null)
-                {
-                    Marshal.ReleaseComObject(solution);
-                    solution = null;
-                }
-
-                if (dte != null)
-                {
-                    Marshal.ReleaseComObject(dte);
-                    dte = null;
-                }
-
-                MessageFilter.Revoke();
-            }
-            return retVal;
-        }
-
-        public static bool parse_command_line(string[] args)
-        {
-            string options_desc = 
-                "--solution <solution_name>   : MSVC solution name. (required)\n" +
-                "--use_new_vs                 : Ignore running versions of visual studio.\n" +
-                "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
-                "--config <config>            : Set the active config for the solution.\n" +
-                "--startup <project>          : Set the startup project for the solution.\n";
-
-            try
-            {
-                // Command line param parsing loop.
-                int i = 0;
-                for (; i < args.Length; ++i)
-                {
-                    if ("--solution" == args[i])
-                    {
-                        if (solution_name != null)
-                        {
-                            throw new ApplicationException("Found second --solution option");
-                        }
-                        solution_name = args[++i];
-                    }
-                    else if ("--use_new_vs" == args[i])
-                    {
-                        use_new_vs = true;
-                    }
-
-                    else if ("--workingdir" == args[i])
-                    {
-                        string project_name = args[++i];
-                        string working_dir = args[++i];
-                        projectDict.Add(project_name, working_dir);
-                    }
-                    else if ("--config" == args[i])
-                    {
-                        if (config != null)
-                        {
-                            throw new ApplicationException("Found second --config option");
-                        }
-                        config = args[++i];
-                    }
-                    else if ("--startup" == args[i])
-                    {
-                        if (startup_project != null)
-                        {
-                            throw new ApplicationException("Found second --startup option");
-                        }
-                        startup_project = args[++i];
-                    }
-                    else
-                    {
-                        throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
-                    }
-                }
-
-                if (solution_name == null)
-                {
-                    throw new ApplicationException("The --solution option is required.");
-                }
-            }
-            catch(ApplicationException e)
-            {
-
-                Console.WriteLine("Oops! " + e.Message);
-                Console.Write("Command line:");
-                foreach (string arg in args)
-                {
-                    Console.Write(" " + arg);
-                }
-                Console.Write("\n\n");
-                Console.WriteLine("VSTool command line usage");
-                Console.Write(options_desc);
-                throw e;
-            }
-            return true;
-        }
-
-        public static bool GetDTEAndSolution()
-        {
-            bool found_open_solution = true;
-
-            Console.WriteLine("Looking for existing VisualStudio instance...");
-
-            // Get an instance of the currently running Visual Studio .NET IDE.
-            // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
-            string full_solution_name = System.IO.Path.GetFullPath(solution_name);
-            if (false == use_new_vs)
-            {
-                dte = GetIDEInstance(full_solution_name);
-            }
-
-            if (dte == null)
-            {
-                try
-                {
-                    Console.WriteLine("  Didn't find open solution, starting new background VisualStudio instance...");
-                    Console.WriteLine("  Reading .sln file version...");
-                    string version = GetSolutionVersion(full_solution_name);
-
-                    Console.WriteLine("  Using version: {0}...", version);
-                    string progid = GetVSProgID(version);
-
-                    Type objType = Type.GetTypeFromProgID(progid);
-                    dte = System.Activator.CreateInstance(objType);
-                    Console.WriteLine("  Reading solution: \"{0}\"", full_solution_name);
-
-                    solution = ViaCOM.GetProperty(dte, "Solution");
-                    object[] openArgs = { full_solution_name };
-                    ViaCOM.CallMethod(solution, "Open", openArgs);
-                }
-                catch (Exception e)
-                {
-                    Console.WriteLine(e.Message);
-                    Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
-                    solution = null;
-                    dte = null;
-                    return found_open_solution;
-                }
-                found_open_solution = false;
-            }
-
-            if (solution == null)
-            {
-                solution = ViaCOM.GetProperty(dte, "Solution");
-            }
-
-            return found_open_solution;
-        }
-
-        /// <summary>
-        /// Get the DTE object for the instance of Visual Studio IDE that has 
-        /// the specified solution open.
-        /// </summary>
-        /// <param name="solutionFile">The absolute filename of the solution</param>
-        /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
-        public static object GetIDEInstance( string solutionFile )
-        {
-            Hashtable runningInstances = GetIDEInstances( true );
-            IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
-
-            while ( enumerator.MoveNext() )
-            {
-                try
-                {
-                    object ide = enumerator.Value;
-                    if (ide != null)
-                    {
-                        object sol = ViaCOM.GetProperty(ide, "Solution");
-                        if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
-                        {
-                            return ide;
-                        }
-                    }
-                } 
-                catch{}
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Get a table of the currently running instances of the Visual Studio .NET IDE.
-        /// </summary>
-        /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
-        /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
-        public static Hashtable GetIDEInstances( bool openSolutionsOnly )
-        {
-            Hashtable runningIDEInstances = new Hashtable();
-            Hashtable runningObjects = GetRunningObjectTable();
-
-            IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
-            while ( rotEnumerator.MoveNext() )
-            {
-                string candidateName = (string) rotEnumerator.Key;
-                if (!candidateName.StartsWith("!VisualStudio.DTE"))
-                    continue;
-
-                object ide = rotEnumerator.Value;
-                if (ide == null)
-                    continue;
-
-                if (openSolutionsOnly)
-                {
-                    try
-                    {
-                        object sol = ViaCOM.GetProperty(ide, "Solution");
-                        string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
-                        if (solutionFile != String.Empty)
-                        {
-                            runningIDEInstances[ candidateName ] = ide;
-                        }
-                    } 
-                    catch {}
-                }
-                else
-                {
-                    runningIDEInstances[ candidateName ] = ide;
-                }                       
-            }
-            return runningIDEInstances;
-        }
-
-        /// <summary>
-        /// Get a snapshot of the running object table (ROT).
-        /// </summary>
-        /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
-        [STAThread]
-        public static Hashtable GetRunningObjectTable()
-        {
-            Hashtable result = new Hashtable();
-
-            int numFetched = 0;
-            IRunningObjectTable runningObjectTable;   
-            IEnumMoniker monikerEnumerator;
-            IMoniker[] monikers = new IMoniker[1];
-
-            GetRunningObjectTable(0, out runningObjectTable);    
-            runningObjectTable.EnumRunning(out monikerEnumerator);
-            monikerEnumerator.Reset();          
-            
-            while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
-            {     
-                IBindCtx ctx;
-                CreateBindCtx(0, out ctx);     
-                    
-                string runningObjectName;
-                monikers[0].GetDisplayName(ctx, null, out runningObjectName);
-
-                object runningObjectVal;  
-                runningObjectTable.GetObject( monikers[0], out runningObjectVal); 
-
-                result[ runningObjectName ] = runningObjectVal;
-            } 
-
-            return result;
-        }
-
-        public static string GetSolutionVersion(string solutionFullFileName) 
-        {
-            string version;
-            System.IO.StreamReader solutionStreamReader = null;
-            string firstLine;
-            string format;
-            
-            try
-            {
-                solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
-                do
-                {
-                    firstLine = solutionStreamReader.ReadLine();
-                }
-                while (firstLine == "");
-                
-                format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
-        
-                switch(format)
-                {
-                    case "7.00":
-                        version = "VC70";
-                        break;
-
-                    case "8.00":
-                        version = "VC71";
-                        break;
-
-                    case "9.00":
-                        version = "VC80";
-                        break;
-                
-                    case "10.00":
-                        version = "VC90";
-                        break;
-
-                    case "11.00":
-                        version = "VC100";
-                        break;
-
-                    case "12.00":
-                        version = "VC120";
-                        break;
-
-                    default:
-                        throw new ApplicationException("Unknown .sln version: " + format);
-                }
-            }
-            finally
-            {
-                if(solutionStreamReader != null) 
-                {
-                    solutionStreamReader.Close();
-                }
-            }
-            
-            return version;
-        }
-
-        public static string GetVSProgID(string version)
-        {
-            string progid = null;
-            switch(version)
-            {
-                case "VC70":
-                    progid = "VisualStudio.DTE.7";
-                    break;
-
-                case "VC71":
-                    progid = "VisualStudio.DTE.7.1";
-                    break;
-
-                case "VC80":
-                    progid = "VisualStudio.DTE.8.0";
-                    break;
-                
-                case "VC90":
-                    progid = "VisualStudio.DTE.9.0";
-                    break;
-
-                case "VC100":
-                    progid = "VisualStudio.DTE.10.0";
-                    break;
-
-                case "VC120":
-                    progid = "VisualStudio.DTE.12.0";
-                    break;
-
-                default:
-                    throw new ApplicationException("Can't handle VS version: " + version);
-            }
-
-            return progid;
-        }
-
-        public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
-        {
-            bool made_change = false;
-            Console.WriteLine("Looking for project {0}...", project_name);
-            try
-            {
-                object prjs = ViaCOM.GetProperty(sol, "Projects");
-                object count = ViaCOM.GetProperty(prjs, "Count");
-                for(int i = 1; i <= (int)count; ++i)
-                {
-                    object[] prjItemArgs = { (object)i };
-                    object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
-                    string name = (string)ViaCOM.GetProperty(prj, "Name");
-                    if (0 == string.Compare(name, project_name, ignore_case))
-                    {
-                        Console.WriteLine("Found project: {0}", project_name);
-                        Console.WriteLine("Setting working directory");
-
-                        string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
-                        Console.WriteLine(full_project_name);
-
-                        // *NOTE:Mani Thanks to incompatibilities between different versions of the 
-                        // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
-                        // the VCProjectEngine types from a different version than the one built 
-                        // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built 
-                        // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, 
-                        // without the type casting. Its tedious code, but it seems to work.
-
-                        // oCfgs should be assigned to a 'Project.Configurations' collection.
-                        object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
-
-                        // oCount will be assigned to the number of configs present in oCfgs.
-                        object oCount = ViaCOM.GetProperty(oCfgs, "Count");
-
-                        for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
-                        {
-                            object[] itemArgs = {(object)cfgIndex};
-                            object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
-                            object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
-                            ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
-                        }
-
-                        break;
-                    }
-                }
-                made_change = true;
-            }
-            catch( Exception e )
-            {
-                Console.WriteLine(e.Message);
-                Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
-            }
-
-            return made_change;
-        }
-
-        public static bool SetStartupProject(string startup_project)
-        {
-            bool result = false;
-            try
-            {
-                // You need the 'unique name of the project to set StartupProjects.
-                // find the project by generic name.
-                Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
-                object prjs = ViaCOM.GetProperty(solution, "Projects");
-                object count = ViaCOM.GetProperty(prjs, "Count");
-                for (int i = 1; i <= (int)count; ++i)
-                {
-                    object[] itemArgs = { (object)i };
-                    object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
-                    object prjName = ViaCOM.GetProperty(prj, "Name");
-                    if (0 == string.Compare((string)prjName, startup_project, ignore_case))
-                    {
-                        object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
-                        ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
-                        Console.WriteLine("  Success!");
-                        result = true;
-                        break;
-                    }
-                }
-
-                if (result == false)
-                {
-                    Console.WriteLine("  Could not find project \"{0}\" in the solution.", startup_project);
-                }
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("  Failed to set the startup project!");
-                Console.WriteLine(e.Message);
-            }
-            return result;
-        }
-
-        public static bool SetActiveConfig(string config)
-        {
-            bool result = false;
-            try
-            {
-                Console.WriteLine("Trying to set active config to \"{0}\"", config);
-                object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
-                object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
-                object[] itemArgs = { (object)config };
-                object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
-                ViaCOM.CallMethod(solCfg, "Activate", null);
-                Console.WriteLine("  Success!");
-                result = true;
-            }
-            catch (Exception e)
-            {
-                Console.WriteLine("  Failed to set \"{0}\" as the active config.", config);
-                Console.WriteLine(e.Message);
-            }
-            return result;
-        }
-    }
-}
-- 
cgit v1.2.3


From 454da876dc648d34aacf27217952e640f4fdaa88 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 17:12:37 -0400
Subject: Backed out changeset e187a6b45ce6: restored VSTool et al.

---
 autobuild.xml                         |  34 ++
 indra/cmake/Variables.cmake           |   1 +
 indra/newview/CMakeLists.txt          |  15 +
 indra/tools/vstool/DispatchUtility.cs | 271 +++++++++++++
 indra/tools/vstool/README.txt         |   9 +
 indra/tools/vstool/VSTool.csproj      |  98 +++++
 indra/tools/vstool/VSTool.exe         | Bin 0 -> 24576 bytes
 indra/tools/vstool/VSTool.sln         |  19 +
 indra/tools/vstool/app.config         |   3 +
 indra/tools/vstool/main.cs            | 729 ++++++++++++++++++++++++++++++++++
 10 files changed, 1179 insertions(+)
 create mode 100644 indra/tools/vstool/DispatchUtility.cs
 create mode 100644 indra/tools/vstool/README.txt
 create mode 100755 indra/tools/vstool/VSTool.csproj
 create mode 100755 indra/tools/vstool/VSTool.exe
 create mode 100755 indra/tools/vstool/VSTool.sln
 create mode 100644 indra/tools/vstool/app.config
 create mode 100755 indra/tools/vstool/main.cs

diff --git a/autobuild.xml b/autobuild.xml
index 5a91ba15f5..072dfa678a 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2617,6 +2617,14 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>RelWithDebInfo</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2655,11 +2663,20 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>RelWithDebInfo</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
+                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
@@ -2688,6 +2705,14 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>Release</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2724,11 +2749,20 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
+                  <string>&amp;&amp;</string>
+                  <string>..\indra\tools\vstool\VSTool.exe</string>
+                  <string>--solution</string>
+                  <string>SecondLife.sln</string>
+                  <string>--config</string>
+                  <string>Release</string>
+                  <string>--startup</string>
+                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
+                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 8292a0c63d..63e296b556 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -164,6 +164,7 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
+set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 586a56b49a..dce0ea73cd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1799,6 +1799,21 @@ if (WINDOWS)
    windows-crash-logger
     )
 
+    # sets the 'working directory' for debugging from visual studio.
+    if (NOT UNATTENDED)
+        add_custom_command(
+            TARGET ${VIEWER_BINARY_NAME} POST_BUILD
+            COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
+            ARGS
+              --solution
+              ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
+              --workingdir
+              ${VIEWER_BINARY_NAME}
+              "${CMAKE_CURRENT_SOURCE_DIR}"
+            COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
+            )
+    endif (NOT UNATTENDED)
+
     if (PACKAGE)
       add_custom_command(
         OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs
new file mode 100644
index 0000000000..6056ac55a1
--- /dev/null
+++ b/indra/tools/vstool/DispatchUtility.cs
@@ -0,0 +1,271 @@
+#region Using Directives
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using System.Security.Permissions;
+
+#endregion
+
+namespace TestDispatchUtility
+{
+	/// <summary>
+	/// Provides helper methods for working with COM IDispatch objects that have a registered type library.
+	/// </summary>
+	public static class DispatchUtility
+	{
+		#region Private Constants
+
+		private const int S_OK = 0; //From WinError.h
+		private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800
+
+		#endregion
+
+		#region Public Methods
+
+		/// <summary>
+		/// Gets whether the specified object implements IDispatch.
+		/// </summary>
+		/// <param name="obj">An object to check.</param>
+		/// <returns>True if the object implements IDispatch.  False otherwise.</returns>
+		public static bool ImplementsIDispatch(object obj)
+		{
+			bool result = obj is IDispatchInfo;
+			return result;
+		}
+
+		/// <summary>
+		/// Gets a Type that can be used with reflection.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
+		/// <returns>A .NET Type that can be used with reflection.</returns>
+		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
+		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+		public static Type GetType(object obj, bool throwIfNotFound)
+		{
+			RequireReference(obj, "obj");
+			Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
+			return result;
+		}
+
+		/// <summary>
+		/// Tries to get the DISPID for the requested member name.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="name">The name of a member to lookup.</param>
+		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
+		/// If the method returns false, this value should be ignored.</param>
+		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
+		/// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
+		[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
+		public static bool TryGetDispId(object obj, string name, out int dispId)
+		{
+			RequireReference(obj, "obj");
+			bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
+			return result;
+		}
+
+		/// <summary>
+		/// Invokes a member by DISPID.
+		/// </summary>
+		/// <param name="obj">An object that implements IDispatch.</param>
+		/// <param name="dispId">The DISPID of a member.  This can be obtained using
+		/// <see cref="TryGetDispId(object, string, out int)"/>.</param>
+		/// <param name="args">The arguments to pass to the member.</param>
+		/// <returns>The member's return value.</returns>
+		/// <remarks>
+		/// This can invoke a method or a property get accessor.
+		/// </remarks>
+		public static object Invoke(object obj, int dispId, object[] args)
+		{
+			string memberName = "[DispId=" + dispId + "]";
+			object result = Invoke(obj, memberName, args);
+			return result;
+		}
+
+		/// <summary>
+		/// Invokes a member by name.
+		/// </summary>
+		/// <param name="obj">An object.</param>
+		/// <param name="memberName">The name of the member to invoke.</param>
+		/// <param name="args">The arguments to pass to the member.</param>
+		/// <returns>The member's return value.</returns>
+		/// <remarks>
+		/// This can invoke a method or a property get accessor.
+		/// </remarks>
+		public static object Invoke(object obj, string memberName, object[] args)
+		{
+			RequireReference(obj, "obj");
+			Type type = obj.GetType();
+			object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty,
+				null, obj, args, null);
+			return result;
+		}
+
+		#endregion
+
+		#region Private Methods
+
+		/// <summary>
+		/// Requires that the value is non-null.
+		/// </summary>
+		/// <typeparam name="T">The type of the value.</typeparam>
+		/// <param name="value">The value to check.</param>
+		/// <param name="name">The name of the value.</param>
+		private static void RequireReference<T>(T value, string name) where T : class
+		{
+			if (value == null)
+			{
+				throw new ArgumentNullException(name);
+			}
+		}
+
+		/// <summary>
+		/// Gets a Type that can be used with reflection.
+		/// </summary>
+		/// <param name="dispatch">An object that implements IDispatch.</param>
+		/// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
+		/// <returns>A .NET Type that can be used with reflection.</returns>
+		private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
+		{
+			RequireReference(dispatch, "dispatch");
+
+			Type result = null;
+			int typeInfoCount;
+			int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
+			if (hr == S_OK && typeInfoCount > 0)
+			{
+				// Type info isn't usually culture-aware for IDispatch, so we might as well pass
+				// the default locale instead of looking up the current thread's LCID each time
+				// (via CultureInfo.CurrentCulture.LCID).
+				dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
+			}
+
+			if (result == null && throwIfNotFound)
+			{
+				// If the GetTypeInfoCount called failed, throw an exception for that.
+				Marshal.ThrowExceptionForHR(hr);
+
+				// Otherwise, throw the same exception that Type.GetType would throw.
+				throw new TypeLoadException();
+			}
+
+			return result;
+		}
+
+		/// <summary>
+		/// Tries to get the DISPID for the requested member name.
+		/// </summary>
+		/// <param name="dispatch">An object that implements IDispatch.</param>
+		/// <param name="name">The name of a member to lookup.</param>
+		/// <param name="dispId">If the method returns true, this holds the DISPID on output.
+		/// If the method returns false, this value should be ignored.</param>
+		/// <returns>True if the member was found and resolved to a DISPID.  False otherwise.</returns>
+		private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
+		{
+			RequireReference(dispatch, "dispatch");
+			RequireReference(name, "name");
+
+			bool result = false;
+
+			// Members names aren't usually culture-aware for IDispatch, so we might as well
+			// pass the default locale instead of looking up the current thread's LCID each time
+			// (via CultureInfo.CurrentCulture.LCID).
+			Guid iidNull = Guid.Empty;
+			int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId);
+
+			const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
+			const int DISPID_UNKNOWN = -1; //From OAIdl.idl
+			if (hr == S_OK)
+			{
+				result = true;
+			}
+			else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
+			{
+				// This is the only supported "error" case because it means IDispatch
+				// is saying it doesn't know the member we asked about.
+				result = false;
+			}
+			else
+			{
+				// The other documented result codes are all errors.
+				Marshal.ThrowExceptionForHR(hr);
+			}
+
+			return result;
+		}
+
+		#endregion
+
+		#region Private Interfaces
+
+		/// <summary>
+		/// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
+		/// </summary>
+		/// <remarks>
+		/// This interface only declares the first three methods of IDispatch.  It omits the
+		/// fourth method (Invoke) because there are already plenty of ways to do dynamic
+		/// invocation in .NET.  But the first three methods provide dynamic type metadata
+		/// discovery, which .NET doesn't provide normally if you have a System.__ComObject
+		/// RCW instead of a strongly-typed RCW.
+		/// <para/>
+		/// Note: The original declaration of IDispatch is in OAIdl.idl.
+		/// </remarks>
+		[ComImport]
+		[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+		[Guid("00020400-0000-0000-C000-000000000046")]
+		private interface IDispatchInfo
+		{
+			/// <summary>
+			/// Gets the number of Types that the object provides (0 or 1).
+			/// </summary>
+			/// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
+			/// </remarks>
+			[PreserveSig]
+			int GetTypeInfoCount(out int typeInfoCount);
+
+			/// <summary>
+			/// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
+			/// </summary>
+			/// <param name="typeInfoIndex">Must be 0.</param>
+			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
+			/// <param name="typeInfo">Returns the object's Type information.</param>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
+			/// </remarks>
+			void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
+				MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
+
+			/// <summary>
+			/// Gets the DISPID of the specified member name.
+			/// </summary>
+			/// <param name="riid">Must be IID_NULL.  Pass a copy of Guid.Empty.</param>
+			/// <param name="name">The name of the member to look up.</param>
+			/// <param name="nameCount">Must be 1.</param>
+			/// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
+			/// <param name="dispId">If a member with the requested <paramref name="name"/>
+			/// is found, this returns its DISPID and the method's return value is 0.
+			/// If the method returns a non-zero value, then this parameter's output value is
+			/// undefined.</param>
+			/// <returns>Zero for success. Non-zero for failure.</returns>
+			/// <remarks>
+			/// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
+			/// </remarks>
+			[PreserveSig]
+			int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId);
+
+			// NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
+			// We can invoke methods using .NET's Type.InvokeMember method with the special
+			// [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
+			// and invoke methods on that through reflection.
+			// Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
+		}
+
+		#endregion
+	}
+}
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt
new file mode 100644
index 0000000000..e419180031
--- /dev/null
+++ b/indra/tools/vstool/README.txt
@@ -0,0 +1,9 @@
+VSTool is a command line utility to manipulate VisualStudio settings. 
+
+The windows cmake project configuration uses VSTool.exe
+
+A handy upgrade:
+ figure out how to make cmake build this csharp app
+ - or write the app using script (jscript?!?) so it doesn't need to be built.
+
+
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj
new file mode 100755
index 0000000000..7f431e85c7
--- /dev/null
+++ b/indra/tools/vstool/VSTool.csproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+  <PropertyGroup>
+    <ProjectType>Local</ProjectType>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
+    <AssemblyKeyContainerName>
+    </AssemblyKeyContainerName>
+    <AssemblyName>VSTool</AssemblyName>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
+    <DefaultClientScript>JScript</DefaultClientScript>
+    <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
+    <DefaultTargetSchema>IE50</DefaultTargetSchema>
+    <DelaySign>false</DelaySign>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>VSTool</RootNamespace>
+    <RunPostBuildEvent>Always</RunPostBuildEvent>
+    <StartupObject>VSTool.VSToolMain</StartupObject>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <OldToolsVersion>2.0</OldToolsVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <OutputPath>.\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>true</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>false</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>full</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <OutputPath>.\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
+    <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
+    <ConfigurationOverrideFile>
+    </ConfigurationOverrideFile>
+    <DefineConstants>TRACE</DefineConstants>
+    <DocumentationFile>
+    </DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
+    <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>true</Optimize>
+    <RegisterForComInterop>false</RegisterForComInterop>
+    <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+    <WarningLevel>4</WarningLevel>
+    <DebugType>none</DebugType>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="main.cs">
+      <SubType>Code</SubType>
+    </Compile>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe
new file mode 100755
index 0000000000..854290b90a
Binary files /dev/null and b/indra/tools/vstool/VSTool.exe differ
diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln
new file mode 100755
index 0000000000..21e3d75971
--- /dev/null
+++ b/indra/tools/vstool/VSTool.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config
new file mode 100644
index 0000000000..8494f728ff
--- /dev/null
+++ b/indra/tools/vstool/app.config
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs
new file mode 100755
index 0000000000..ef2e582b90
--- /dev/null
+++ b/indra/tools/vstool/main.cs
@@ -0,0 +1,729 @@
+// Code about getting running instances visual studio
+// was borrowed from 
+// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using Microsoft.CSharp;
+
+namespace VSTool
+{
+    // The MessageFilter class comes from:
+    // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
+    // It allows vstool to get timing error messages from 
+    // visualstudio and handle them.
+    public class MessageFilter : IOleMessageFilter
+    {
+        //
+        // Class containing the IOleMessageFilter
+        // thread error-handling functions.
+
+        // Start the filter.
+        public static void Register()
+        {
+            IOleMessageFilter newFilter = new MessageFilter(); 
+            IOleMessageFilter oldFilter = null; 
+            CoRegisterMessageFilter(newFilter, out oldFilter);
+        }
+
+        // Done with the filter, close it.
+        public static void Revoke()
+        {
+            IOleMessageFilter oldFilter = null; 
+            CoRegisterMessageFilter(null, out oldFilter);
+        }
+
+        //
+        // IOleMessageFilter functions.
+        // Handle incoming thread requests.
+        int IOleMessageFilter.HandleInComingCall(int dwCallType, 
+          System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 
+          lpInterfaceInfo) 
+        {
+            //Return the flag SERVERCALL_ISHANDLED.
+            return 0;
+        }
+
+        // Thread call was rejected, so try again.
+        int IOleMessageFilter.RetryRejectedCall(System.IntPtr 
+          hTaskCallee, int dwTickCount, int dwRejectType)
+        {
+            if (dwRejectType == 2)
+            // flag = SERVERCALL_RETRYLATER.
+            {
+                // Retry the thread call immediately if return >=0 & 
+                // <100.
+                return 99;
+            }
+            // Too busy; cancel call.
+            return -1;
+        }
+
+        int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 
+          int dwTickCount, int dwPendingType)
+        {
+            //Return the flag PENDINGMSG_WAITDEFPROCESS.
+            return 2; 
+        }
+
+        // Implement the IOleMessageFilter interface.
+        [DllImport("Ole32.dll")]
+        private static extern int 
+          CoRegisterMessageFilter(IOleMessageFilter newFilter, out 
+          IOleMessageFilter oldFilter);
+    }
+
+    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 
+    InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
+    interface IOleMessageFilter 
+    {
+        [PreserveSig]
+        int HandleInComingCall( 
+            int dwCallType, 
+            IntPtr hTaskCaller, 
+            int dwTickCount, 
+            IntPtr lpInterfaceInfo);
+
+        [PreserveSig]
+        int RetryRejectedCall( 
+            IntPtr hTaskCallee, 
+            int dwTickCount,
+            int dwRejectType);
+
+        [PreserveSig]
+        int MessagePending( 
+            IntPtr hTaskCallee, 
+            int dwTickCount,
+            int dwPendingType);
+    }
+
+    class ViaCOM
+    {
+        public static object GetProperty(object from_obj, string prop_name)
+        {
+            try
+            {
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    prop_name,
+                    BindingFlags.GetProperty, null,
+                    from_obj,
+                    null);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error getting property: \"{0}\"", prop_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+
+        public static object SetProperty(object from_obj, string prop_name, object new_value)
+        {
+            try
+            {
+                object[] args = { new_value };
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    prop_name,
+                    BindingFlags.DeclaredOnly |
+                    BindingFlags.Public |
+                    BindingFlags.NonPublic |
+                    BindingFlags.Instance |
+                    BindingFlags.SetProperty,
+                    null,
+                    from_obj,
+                    args);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error setting property: \"{0}\"", prop_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+
+        public static object CallMethod(object from_obj, string method_name, params object[] args)
+        {
+            try
+            {
+                Type objType = from_obj.GetType();
+                return objType.InvokeMember(
+                    method_name,
+                    BindingFlags.DeclaredOnly |
+                    BindingFlags.Public |
+                    BindingFlags.NonPublic |
+                    BindingFlags.Instance |
+                    BindingFlags.InvokeMethod,
+                    null,
+                    from_obj,
+                    args);
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Error calling method \"{0}\"", method_name);
+                Console.WriteLine(e.Message);
+                throw e;
+            }
+        }
+    };
+
+    /// <summary>
+	/// The main entry point class for VSTool.
+	/// </summary>
+    class VSToolMain
+    {
+        #region Interop imports
+        [DllImport("ole32.dll")]  
+        public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); 
+ 
+        [DllImport("ole32.dll")]  
+        public static extern int  CreateBindCtx(int reserved, out IBindCtx ppbc);
+        #endregion 
+
+        static System.Boolean ignore_case = true;
+
+        static string solution_name = null;
+        static bool use_new_vs = false;
+        static Hashtable projectDict = new Hashtable();
+        static string startup_project = null;
+        static string config = null;
+
+        static object dte = null;
+        static object solution = null;
+
+        /// <summary>
+		/// The main entry point for the application.
+		/// </summary>
+		[STAThread]
+		static int Main(string[] args)
+		{
+            int retVal = 0;
+            bool need_save = false;
+
+            try
+            {
+                parse_command_line(args);
+
+                Console.WriteLine("Editing solution: {0}", solution_name);
+
+                bool found_open_solution = GetDTEAndSolution();
+
+                if (dte == null || solution == null)
+                {
+                    retVal = 1;
+                }
+                else
+                {
+                    MessageFilter.Register();
+
+                    // Walk through all of the projects in the solution
+                    // and list the type of each project.
+                    foreach (DictionaryEntry p in projectDict)
+                    {
+                        string project_name = (string)p.Key;
+                        string working_dir = (string)p.Value;
+                        if (SetProjectWorkingDir(solution, project_name, working_dir))
+                        {
+                            need_save = true;
+                        }
+                    }
+
+                    if (config != null)
+                    {
+                        need_save = SetActiveConfig(config);
+                    }
+
+                    if (startup_project != null)
+                    {
+                        need_save = SetStartupProject(startup_project);
+                    }
+
+                    if (need_save)
+                    {
+                        if (found_open_solution == false)
+                        {
+                            ViaCOM.CallMethod(solution, "Close", null);
+                        }
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine(e.Message);
+                retVal = 1;
+            }
+            finally
+            {
+                if (solution != null)
+                {
+                    Marshal.ReleaseComObject(solution);
+                    solution = null;
+                }
+
+                if (dte != null)
+                {
+                    Marshal.ReleaseComObject(dte);
+                    dte = null;
+                }
+
+                MessageFilter.Revoke();
+            }
+            return retVal;
+        }
+
+        public static bool parse_command_line(string[] args)
+        {
+            string options_desc = 
+                "--solution <solution_name>   : MSVC solution name. (required)\n" +
+                "--use_new_vs                 : Ignore running versions of visual studio.\n" +
+                "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
+                "--config <config>            : Set the active config for the solution.\n" +
+                "--startup <project>          : Set the startup project for the solution.\n";
+
+            try
+            {
+                // Command line param parsing loop.
+                int i = 0;
+                for (; i < args.Length; ++i)
+                {
+                    if ("--solution" == args[i])
+                    {
+                        if (solution_name != null)
+                        {
+                            throw new ApplicationException("Found second --solution option");
+                        }
+                        solution_name = args[++i];
+                    }
+                    else if ("--use_new_vs" == args[i])
+                    {
+                        use_new_vs = true;
+                    }
+
+                    else if ("--workingdir" == args[i])
+                    {
+                        string project_name = args[++i];
+                        string working_dir = args[++i];
+                        projectDict.Add(project_name, working_dir);
+                    }
+                    else if ("--config" == args[i])
+                    {
+                        if (config != null)
+                        {
+                            throw new ApplicationException("Found second --config option");
+                        }
+                        config = args[++i];
+                    }
+                    else if ("--startup" == args[i])
+                    {
+                        if (startup_project != null)
+                        {
+                            throw new ApplicationException("Found second --startup option");
+                        }
+                        startup_project = args[++i];
+                    }
+                    else
+                    {
+                        throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
+                    }
+                }
+
+                if (solution_name == null)
+                {
+                    throw new ApplicationException("The --solution option is required.");
+                }
+            }
+            catch(ApplicationException e)
+            {
+
+                Console.WriteLine("Oops! " + e.Message);
+                Console.Write("Command line:");
+                foreach (string arg in args)
+                {
+                    Console.Write(" " + arg);
+                }
+                Console.Write("\n\n");
+                Console.WriteLine("VSTool command line usage");
+                Console.Write(options_desc);
+                throw e;
+            }
+            return true;
+        }
+
+        public static bool GetDTEAndSolution()
+        {
+            bool found_open_solution = true;
+
+            Console.WriteLine("Looking for existing VisualStudio instance...");
+
+            // Get an instance of the currently running Visual Studio .NET IDE.
+            // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
+            string full_solution_name = System.IO.Path.GetFullPath(solution_name);
+            if (false == use_new_vs)
+            {
+                dte = GetIDEInstance(full_solution_name);
+            }
+
+            if (dte == null)
+            {
+                try
+                {
+                    Console.WriteLine("  Didn't find open solution, starting new background VisualStudio instance...");
+                    Console.WriteLine("  Reading .sln file version...");
+                    string version = GetSolutionVersion(full_solution_name);
+
+                    Console.WriteLine("  Using version: {0}...", version);
+                    string progid = GetVSProgID(version);
+
+                    Type objType = Type.GetTypeFromProgID(progid);
+                    dte = System.Activator.CreateInstance(objType);
+                    Console.WriteLine("  Reading solution: \"{0}\"", full_solution_name);
+
+                    solution = ViaCOM.GetProperty(dte, "Solution");
+                    object[] openArgs = { full_solution_name };
+                    ViaCOM.CallMethod(solution, "Open", openArgs);
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e.Message);
+                    Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
+                    solution = null;
+                    dte = null;
+                    return found_open_solution;
+                }
+                found_open_solution = false;
+            }
+
+            if (solution == null)
+            {
+                solution = ViaCOM.GetProperty(dte, "Solution");
+            }
+
+            return found_open_solution;
+        }
+
+        /// <summary>
+        /// Get the DTE object for the instance of Visual Studio IDE that has 
+        /// the specified solution open.
+        /// </summary>
+        /// <param name="solutionFile">The absolute filename of the solution</param>
+        /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
+        public static object GetIDEInstance( string solutionFile )
+        {
+            Hashtable runningInstances = GetIDEInstances( true );
+            IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
+
+            while ( enumerator.MoveNext() )
+            {
+                try
+                {
+                    object ide = enumerator.Value;
+                    if (ide != null)
+                    {
+                        object sol = ViaCOM.GetProperty(ide, "Solution");
+                        if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
+                        {
+                            return ide;
+                        }
+                    }
+                } 
+                catch{}
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Get a table of the currently running instances of the Visual Studio .NET IDE.
+        /// </summary>
+        /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
+        /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
+        public static Hashtable GetIDEInstances( bool openSolutionsOnly )
+        {
+            Hashtable runningIDEInstances = new Hashtable();
+            Hashtable runningObjects = GetRunningObjectTable();
+
+            IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
+            while ( rotEnumerator.MoveNext() )
+            {
+                string candidateName = (string) rotEnumerator.Key;
+                if (!candidateName.StartsWith("!VisualStudio.DTE"))
+                    continue;
+
+                object ide = rotEnumerator.Value;
+                if (ide == null)
+                    continue;
+
+                if (openSolutionsOnly)
+                {
+                    try
+                    {
+                        object sol = ViaCOM.GetProperty(ide, "Solution");
+                        string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
+                        if (solutionFile != String.Empty)
+                        {
+                            runningIDEInstances[ candidateName ] = ide;
+                        }
+                    } 
+                    catch {}
+                }
+                else
+                {
+                    runningIDEInstances[ candidateName ] = ide;
+                }                       
+            }
+            return runningIDEInstances;
+        }
+
+        /// <summary>
+        /// Get a snapshot of the running object table (ROT).
+        /// </summary>
+        /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
+        [STAThread]
+        public static Hashtable GetRunningObjectTable()
+        {
+            Hashtable result = new Hashtable();
+
+            int numFetched = 0;
+            IRunningObjectTable runningObjectTable;   
+            IEnumMoniker monikerEnumerator;
+            IMoniker[] monikers = new IMoniker[1];
+
+            GetRunningObjectTable(0, out runningObjectTable);    
+            runningObjectTable.EnumRunning(out monikerEnumerator);
+            monikerEnumerator.Reset();          
+            
+            while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
+            {     
+                IBindCtx ctx;
+                CreateBindCtx(0, out ctx);     
+                    
+                string runningObjectName;
+                monikers[0].GetDisplayName(ctx, null, out runningObjectName);
+
+                object runningObjectVal;  
+                runningObjectTable.GetObject( monikers[0], out runningObjectVal); 
+
+                result[ runningObjectName ] = runningObjectVal;
+            } 
+
+            return result;
+        }
+
+        public static string GetSolutionVersion(string solutionFullFileName) 
+        {
+            string version;
+            System.IO.StreamReader solutionStreamReader = null;
+            string firstLine;
+            string format;
+            
+            try
+            {
+                solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
+                do
+                {
+                    firstLine = solutionStreamReader.ReadLine();
+                }
+                while (firstLine == "");
+                
+                format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
+        
+                switch(format)
+                {
+                    case "7.00":
+                        version = "VC70";
+                        break;
+
+                    case "8.00":
+                        version = "VC71";
+                        break;
+
+                    case "9.00":
+                        version = "VC80";
+                        break;
+                
+                    case "10.00":
+                        version = "VC90";
+                        break;
+
+                    case "11.00":
+                        version = "VC100";
+                        break;
+
+                    case "12.00":
+                        version = "VC120";
+                        break;
+
+                    default:
+                        throw new ApplicationException("Unknown .sln version: " + format);
+                }
+            }
+            finally
+            {
+                if(solutionStreamReader != null) 
+                {
+                    solutionStreamReader.Close();
+                }
+            }
+            
+            return version;
+        }
+
+        public static string GetVSProgID(string version)
+        {
+            string progid = null;
+            switch(version)
+            {
+                case "VC70":
+                    progid = "VisualStudio.DTE.7";
+                    break;
+
+                case "VC71":
+                    progid = "VisualStudio.DTE.7.1";
+                    break;
+
+                case "VC80":
+                    progid = "VisualStudio.DTE.8.0";
+                    break;
+                
+                case "VC90":
+                    progid = "VisualStudio.DTE.9.0";
+                    break;
+
+                case "VC100":
+                    progid = "VisualStudio.DTE.10.0";
+                    break;
+
+                case "VC120":
+                    progid = "VisualStudio.DTE.12.0";
+                    break;
+
+                default:
+                    throw new ApplicationException("Can't handle VS version: " + version);
+            }
+
+            return progid;
+        }
+
+        public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
+        {
+            bool made_change = false;
+            Console.WriteLine("Looking for project {0}...", project_name);
+            try
+            {
+                object prjs = ViaCOM.GetProperty(sol, "Projects");
+                object count = ViaCOM.GetProperty(prjs, "Count");
+                for(int i = 1; i <= (int)count; ++i)
+                {
+                    object[] prjItemArgs = { (object)i };
+                    object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
+                    string name = (string)ViaCOM.GetProperty(prj, "Name");
+                    if (0 == string.Compare(name, project_name, ignore_case))
+                    {
+                        Console.WriteLine("Found project: {0}", project_name);
+                        Console.WriteLine("Setting working directory");
+
+                        string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
+                        Console.WriteLine(full_project_name);
+
+                        // *NOTE:Mani Thanks to incompatibilities between different versions of the 
+                        // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
+                        // the VCProjectEngine types from a different version than the one built 
+                        // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built 
+                        // in VS 8.0. To avoid this problem, we can use the com object interfaces directly, 
+                        // without the type casting. Its tedious code, but it seems to work.
+
+                        // oCfgs should be assigned to a 'Project.Configurations' collection.
+                        object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
+
+                        // oCount will be assigned to the number of configs present in oCfgs.
+                        object oCount = ViaCOM.GetProperty(oCfgs, "Count");
+
+                        for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
+                        {
+                            object[] itemArgs = {(object)cfgIndex};
+                            object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
+                            object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
+                            ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
+                        }
+
+                        break;
+                    }
+                }
+                made_change = true;
+            }
+            catch( Exception e )
+            {
+                Console.WriteLine(e.Message);
+                Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
+            }
+
+            return made_change;
+        }
+
+        public static bool SetStartupProject(string startup_project)
+        {
+            bool result = false;
+            try
+            {
+                // You need the 'unique name of the project to set StartupProjects.
+                // find the project by generic name.
+                Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
+                object prjs = ViaCOM.GetProperty(solution, "Projects");
+                object count = ViaCOM.GetProperty(prjs, "Count");
+                for (int i = 1; i <= (int)count; ++i)
+                {
+                    object[] itemArgs = { (object)i };
+                    object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
+                    object prjName = ViaCOM.GetProperty(prj, "Name");
+                    if (0 == string.Compare((string)prjName, startup_project, ignore_case))
+                    {
+                        object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+                        ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
+                        Console.WriteLine("  Success!");
+                        result = true;
+                        break;
+                    }
+                }
+
+                if (result == false)
+                {
+                    Console.WriteLine("  Could not find project \"{0}\" in the solution.", startup_project);
+                }
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("  Failed to set the startup project!");
+                Console.WriteLine(e.Message);
+            }
+            return result;
+        }
+
+        public static bool SetActiveConfig(string config)
+        {
+            bool result = false;
+            try
+            {
+                Console.WriteLine("Trying to set active config to \"{0}\"", config);
+                object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
+                object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
+                object[] itemArgs = { (object)config };
+                object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
+                ViaCOM.CallMethod(solCfg, "Activate", null);
+                Console.WriteLine("  Success!");
+                result = true;
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("  Failed to set \"{0}\" as the active config.", config);
+                Console.WriteLine(e.Message);
+            }
+            return result;
+        }
+    }
+}
-- 
cgit v1.2.3


From b0c434fadfb7085fa93d13b3f61f29d48c610834 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 15 Aug 2016 17:15:31 -0400
Subject: Set CMake UNATTENDED variable to suppress VSTool in TC builds.

---
 build.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/build.sh b/build.sh
index cd2a9ebf5e..ab7a1faa37 100755
--- a/build.sh
+++ b/build.sh
@@ -97,6 +97,7 @@ pre_build()
 
     "$autobuild" configure --quiet -c $variant -- \
      -DPACKAGE:BOOL=ON \
+     -DUNATTENDED:BOOL=ON \
      -DRELEASE_CRASH_REPORTING:BOOL=ON \
      -DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
      -DGRID:STRING="\"$viewer_grid\"" \
-- 
cgit v1.2.3


From b240c494c43912b4b57e0efc0867997faa18b327 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Tue, 16 Aug 2016 11:03:03 -0400
Subject: Re-delete VSTool.exe invocations from autobuild.xml.

The CMake invocations are controlled by UNATTENDED -- these were not. Let
CMake do it if it must be done.
---
 autobuild.xml | 34 ----------------------------------
 1 file changed, 34 deletions(-)
 mode change 100755 => 100644 autobuild.xml

diff --git a/autobuild.xml b/autobuild.xml
old mode 100755
new mode 100644
index 072dfa678a..5a91ba15f5
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2617,14 +2617,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2663,20 +2655,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>RelWithDebInfo</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
@@ -2705,14 +2688,6 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
@@ -2749,20 +2724,11 @@
                 <key>arguments</key>
                 <array>
                   <string>..\indra</string>
-                  <string>&amp;&amp;</string>
-                  <string>..\indra\tools\vstool\VSTool.exe</string>
-                  <string>--solution</string>
-                  <string>SecondLife.sln</string>
-                  <string>--config</string>
-                  <string>Release</string>
-                  <string>--startup</string>
-                  <string>secondlife-bin</string>
                 </array>
                 <key>options</key>
                 <array>
                   <string>-G</string>
                   <string>"Visual Studio 12"</string>
-                  <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
                 </array>
-- 
cgit v1.2.3


From 57060fa0ebfacf3705ec2d9770e83aab3c86b894 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 2 Aug 2016 21:57:04 +0300
Subject: MAINT-4124 Warning user about render-heavy set of HUDs

---
 indra/newview/app_settings/settings.xml            |  55 +++++++++
 indra/newview/llavatarrendernotifier.cpp           | 130 +++++++++++++++++++++
 indra/newview/llavatarrendernotifier.h             |  36 ++++++
 indra/newview/llvoavatar.cpp                       |  65 ++++++++++-
 .../newview/skins/default/xui/en/notifications.xml |  14 +++
 indra/newview/skins/default/xui/en/strings.xml     |   7 ++
 6 files changed, 302 insertions(+), 5 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ca81696a50..00c769607f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10092,6 +10092,17 @@
     <key>Value</key>
     <integer>10</integer>
   </map>
+  <key>ComplexityChangesPopUpDelay</key>
+  <map>
+    <key>Comment</key>
+    <string>Delay before viewer will show avatar complexity notice again</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>300</integer>
+  </map>
   <key>RenderAvatarMaxComplexity</key>
   <map>
     <key>Comment</key>
@@ -10104,6 +10115,50 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+  <key>RenderHUDObjectsWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD containing to many objects if objects count is above this value</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>1000</integer>
+  </map>
+  <key>RenderHUDTexturesWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD containing to many textures if texture count is above this value</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>200</integer>
+  </map>
+  <key>RenderHUDOversizedTexturesWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>6</integer>
+  </map>
+  <key>RenderHUDTexturesVirtualMemoryWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD textures using memory above this value (Virtual memory, in pixels)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>10000000</integer>
+  </map>
   <key>RenderAutoMuteSurfaceAreaLimit</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index 24934fdb73..f7a1ef1621 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -51,6 +51,11 @@ static const F32 RENDER_ALLOWED_CHANGE_PCT = 0.1;
 // wait seconds before processing over limit updates after last complexity change
 static const U32 OVER_LIMIT_UPDATE_DELAY = 70;
 
+static const U32 WARN_HUD_OBJECTS_LIMIT = 1000;
+static const U32 WARN_HUD_TEXTURES_LIMIT = 200;
+static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6;
+static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 10000000; // in pixels
+
 
 LLAvatarRenderNotifier::LLAvatarRenderNotifier() :
 mAgentsCount(0),
@@ -264,3 +269,128 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)
     }
 }
 
+// LLHUDRenderNotifier
+
+LLHUDRenderNotifier::LLHUDRenderNotifier()
+{
+}
+
+LLHUDRenderNotifier::~LLHUDRenderNotifier()
+{
+}
+
+void LLHUDRenderNotifier::updateNotificationHUD(LLHUDComplexity new_complexity)
+{
+    if (!isAgentAvatarValid())
+    {
+        // data not ready.
+        return;
+    }
+
+    static const char* hud_memory = "hud_render_memory_warning";
+    static const char* hud_cost = "hud_render_cost_warning";
+    static const char* hud_heavy = "hud_render_heavy_textures_warning";
+    static const char* hud_cramped = "hud_render_cramped_warning";
+    static const char* hud_textures = "hud_render_textures_warning";
+
+    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost
+    static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT);
+    static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT);
+    static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT);
+    static LLCachedControl<U32> max_texture_memory(gSavedSettings, "RenderHUDTexturesVirtualMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT);
+
+    if (mHUDPopUpDelayTimer.hasExpired())
+    {
+        // Show warning with highest importance (5m delay between warnings by default)
+        // TODO:
+        // Consider showing message with list of issues.
+        // For now shows one after another if update arrives and timer expired, so
+        // consider showing only one most important or consider triggering not
+        // only in case of update
+        if (mReportedHUDComplexity.texturesSizeTotal < new_complexity.texturesSizeTotal
+            && new_complexity.texturesSizeTotal > max_texture_memory)
+        {
+            displayHUDNotification(hud_memory);
+            LL_DEBUGS("HUDdetail") << "HUD memory usage over limit,"
+                                   << " was " << mReportedHUDComplexity.texturesSizeTotal
+                                   << " is " << new_complexity.texturesSizeTotal << LL_ENDL;
+            mReportedHUDComplexity.texturesSizeTotal = new_complexity.texturesSizeTotal;
+        }
+        else if ((mReportedHUDComplexity.objectsCost < new_complexity.objectsCost
+            || mReportedHUDComplexity.texturesCost < new_complexity.texturesCost)
+            && max_render_cost > 0
+            && new_complexity.objectsCost + new_complexity.texturesCost > max_render_cost)
+        {
+            LL_DEBUGS("HUDdetail") << "HUD complexity over limit,"
+                                   << " HUD textures cost: " << new_complexity.texturesCost
+                                   << " HUD objects cost: " << new_complexity.objectsCost << LL_ENDL;
+            displayHUDNotification(hud_cost);
+            mReportedHUDComplexity.objectsCost = new_complexity.objectsCost;
+            mReportedHUDComplexity.texturesCost = new_complexity.texturesCost;
+        }
+        else if (mReportedHUDComplexity.largeTexturesCount < new_complexity.largeTexturesCount
+            && new_complexity.largeTexturesCount > max_oversized_count)
+        {
+            LL_DEBUGS("HUDdetail") << "HUD contains to many large textures: "
+                                   << new_complexity.largeTexturesCount << LL_ENDL;
+            displayHUDNotification(hud_heavy);
+            mReportedHUDComplexity.largeTexturesCount = new_complexity.largeTexturesCount;
+        }
+        else if (mReportedHUDComplexity.texturesCount < new_complexity.texturesCount
+            && new_complexity.texturesCount > max_textures_count)
+        {
+            LL_DEBUGS("HUDdetail") << "HUD contains too many textures: "
+                                   << new_complexity.texturesCount << LL_ENDL;
+            displayHUDNotification(hud_cramped);
+            mReportedHUDComplexity.texturesCount = new_complexity.texturesCount;
+        }
+        else if (mReportedHUDComplexity.objectsCount < new_complexity.objectsCount
+            && new_complexity.objectsCount > max_objects_count)
+        {
+            LL_DEBUGS("HUDdetail") << "HUD contains too many objects: "
+                                   << new_complexity.objectsCount << LL_ENDL;
+            displayHUDNotification(hud_textures);
+            mReportedHUDComplexity.objectsCount = new_complexity.objectsCount;
+        }
+        else
+        {
+            // all warnings displayed, just store everything so that we will
+            // be able to reduce values and show warnings again later
+            mReportedHUDComplexity = new_complexity;
+        }
+    }
+
+    if (mLatestHUDComplexity.objectsCost != new_complexity.objectsCost
+        || mLatestHUDComplexity.objectsCount != new_complexity.objectsCount
+        || mLatestHUDComplexity.texturesCost != new_complexity.texturesCost
+        || mLatestHUDComplexity.texturesCount != new_complexity.texturesCount
+        || mLatestHUDComplexity.largeTexturesCount != new_complexity.largeTexturesCount
+        || mLatestHUDComplexity.texturesSizeTotal != new_complexity.texturesSizeTotal)
+    {
+        LL_INFOS("HUDdetail") << "HUD textures count: " << new_complexity.texturesCount
+            << " HUD textures cost: " << new_complexity.texturesCost
+            << " Large textures: " << new_complexity.largeTexturesCount
+            << " HUD objects cost: " << new_complexity.objectsCost
+            << " HUD objects count: " << new_complexity.objectsCount << LL_ENDL;
+
+        mLatestHUDComplexity = new_complexity;
+    }
+    
+}
+
+void LLHUDRenderNotifier::displayHUDNotification(const char* message)
+{
+    static LLCachedControl<U32> pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300);
+    static LLCachedControl<U32> expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20);
+    LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay);
+
+    LLSD args;
+    args["HUD_REASON"] = LLTrans::getString(message);
+
+    LLNotifications::instance().add(LLNotification::Params()
+        .name("HUDComplexityWarning")
+        .expiry(expire_date)
+        .substitutions(args));
+    mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay);
+}
+
diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h
index 2a2704de28..959bebef02 100644
--- a/indra/newview/llavatarrendernotifier.h
+++ b/indra/newview/llavatarrendernotifier.h
@@ -33,6 +33,25 @@
 
 class LLViewerRegion;
 
+struct LLHUDComplexity
+{
+    LLHUDComplexity()
+    {
+        objectsCost = 0;
+        objectsCount = 0;
+        texturesCost = 0;
+        texturesCount = 0;
+        largeTexturesCount = 0;
+        texturesSizeTotal = 0;
+    }
+    U32 objectsCost;
+    U32 objectsCount;
+    U32 texturesCost;
+    U32 texturesCount;
+    U32 largeTexturesCount;
+    F64 texturesSizeTotal;
+};
+
 // Class to notify user about drastic changes in agent's render weights or if other agents
 // reported that user's agent is too 'heavy' for their settings
 class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
@@ -81,4 +100,21 @@ private:
     S32 mLastOutfitRezStatus;
 };
 
+// Class to notify user about heavy set of HUD
+class LLHUDRenderNotifier : public LLSingleton<LLHUDRenderNotifier>
+{
+public:
+    LLHUDRenderNotifier();
+    ~LLHUDRenderNotifier();
+
+    void updateNotificationHUD(LLHUDComplexity new_complexity);
+
+private:
+    void displayHUDNotification(const char* message);
+
+    LLHUDComplexity mReportedHUDComplexity;
+    LLHUDComplexity mLatestHUDComplexity;
+    LLFrameTimer mHUDPopUpDelayTimer;
+};
+
 #endif /* ! defined(LL_llavatarrendernotifier_H) */
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index cdc7e20c2c..aebc066507 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -186,6 +186,7 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
 const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
 
 const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;
+const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;
 
 enum ERenderName
 {
@@ -8356,6 +8357,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 	{
 		U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
 		LLVOVolume::texture_cost_t textures;
+		LLHUDComplexity hud_complexity;
 
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
@@ -8432,6 +8434,55 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 						}
 					}
 				}
+                if (isSelf()
+                    && attached_object
+                    && attached_object->isHUDAttachment()
+                    && attached_object->mDrawable)
+                {
+                    textures.clear();
+
+                    const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
+                    if (volume)
+                    {
+                        // get cost and individual textures
+                        hud_complexity.objectsCost += volume->getRenderCost(textures);
+                        hud_complexity.objectsCount++;
+
+                        LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+                        for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+                            iter != child_list.end(); ++iter)
+                        {
+                            LLViewerObject* childp = *iter;
+                            const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
+                            if (chld_volume)
+                            {
+                                // get cost and individual textures
+                                hud_complexity.objectsCost += chld_volume->getRenderCost(textures);
+                                hud_complexity.objectsCount++;
+                            }
+                        }
+
+                        hud_complexity.texturesCount += textures.size();
+
+                        for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+                            volume_texture != textures.end();
+                            ++volume_texture)
+                        {
+                            // add the cost of each individual texture (ignores duplicates)
+                            hud_complexity.texturesCost += volume_texture->second;
+                            LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
+                            if (tex)
+                            {
+                                F64 size = tex->getMaxVirtualSize(); // in pixels
+                                hud_complexity.texturesSizeTotal += size;
+                                if (size >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
+                                {
+                                    hud_complexity.largeTexturesCount++;
+                                }
+                            }
+                        }
+                    }
+                }
 			}
 		}
 
@@ -8493,11 +8544,15 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 
         static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
 
-		if (isSelf() && show_my_complexity_changes)
-		{
-			LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
-		}
-	}
+        if (isSelf() && show_my_complexity_changes)
+        {
+            // Avatar complexity
+            LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
+
+            // HUD complexity
+            LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity);
+        }
+    }
 }
 
 void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6fdeedc8ae..102ce0ddc0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3319,6 +3319,20 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin
 Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY].
   </notification>
 
+  <notification
+   icon = "notifytip.tga"
+   name = "HUDComplexityWarning"
+   type = "notifytip"
+   log_to_chat = "false">
+    <unique combine = "cancel_old">
+      <context>HUDComplexityWarning</context>
+    </unique>
+    [HUD_REASON], it is likely to negatively affect your performance.
+    <usetemplate
+     ignoretext="Warn me when my HUD complexity is too high"
+     name="notifyignore"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="FirstRun"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 27c08f560f..22441f1278 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2499,6 +2499,13 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f
   <string name="av_render_most_of">You may not be rendered by most of those around you.</string>
   <string name="av_render_anyone">You may not be rendered by anyone around you.</string>
 
+  <!-- HUD complexity rendering messages, see llavatarrendernotifier. -->
+  <string name="hud_render_memory_warning">Your HUD uses a lot of texture memory</string>
+  <string name="hud_render_cost_warning">Your HUD contains a lot of expensive objects and textures</string>
+  <string name="hud_render_heavy_textures_warning">Your HUD contains a lot of large textures</string>
+  <string name="hud_render_cramped_warning">Your HUD contains too many objects</string>
+  <string name="hud_render_textures_warning">Your HUD contains too many textures</string>
+
   <!-- AgeYearsA = singular,
        AgeYearsB = plural,
        AgeYearsC = plural for non-English languages like Russian
-- 
cgit v1.2.3


From cc7dda96e7ab09ee221e741aac9813af815e0aed Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 4 Aug 2016 17:27:48 +0300
Subject: MAINT-6604 FIXED [VOB] Snapshot preview is corrupted

---
 indra/newview/llfloateroutfitsnapshot.cpp | 4 ++--
 indra/newview/llfloateroutfitsnapshot.h   | 2 +-
 indra/newview/llfloatersnapshot.cpp       | 7 +++----
 indra/newview/llfloatersnapshot.h         | 4 ++--
 4 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index d671c36a1c..093a2dad64 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -1,5 +1,5 @@
 /** 
- * @file llfloatersnapshot.cpp
+ * @file llfloateroutfitsnapshot.cpp
  * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
@@ -256,7 +256,7 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
     }
     childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this);
 
-    sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+    mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 
     // create preview window
     LLRect full_screen_rect = getRootView()->getRect();
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index c7b221937f..482080da7a 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -53,7 +53,7 @@ public:
     static LLFloaterOutfitSnapshot* getInstance();
     /*virtual*/ void saveTexture();
 
-    static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
+    const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
 
     void setOutfitID(LLUUID id) { mOutfitID = id; }
     LLUUID getOutfitID() { return mOutfitID; }
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 98d4034ccf..a0e54e47b6 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -50,7 +50,6 @@
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
-LLUICtrl* LLFloaterSnapshotBase::sThumbnailPlaceholder = NULL;
 LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
 
 const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
@@ -1011,7 +1010,7 @@ BOOL LLFloaterSnapshot::postBuild()
 	LLWebProfile::setImageUploadResultCallback(boost::bind(&Impl::onSnapshotUploadFinished, this, _1));
 	LLPostCard::setPostResultCallback(boost::bind(&Impl::onSendingPostcardFinished, this, _1));
 
-	sThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
+	mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
 
 	// create preview window
 	LLRect full_screen_rect = getRootView()->getRect();
@@ -1060,7 +1059,7 @@ void LLFloaterSnapshotBase::draw()
 
 	LLFloater::draw();
 
-	if (previewp && !isMinimized() && sThumbnailPlaceholder->getVisible())
+	if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible())
 	{		
 		if(previewp->getThumbnailImage())
 		{
@@ -1089,7 +1088,7 @@ void LLFloaterSnapshotBase::draw()
 
 			gGL.pushUIMatrix();
 			LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom);
-			sThumbnailPlaceholder->draw();
+			mThumbnailPlaceholder->draw();
 			gGL.popUIMatrix();
 		}
 	}
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 61639eebc5..4c65c8d06a 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -56,7 +56,7 @@ public:
 	LLSnapshotLivePreview* getPreviewView();
 	const LLVector3d& getPosTakenGlobal();
 
-	static const LLRect& getThumbnailPlaceholderRect() { return sThumbnailPlaceholder->getRect(); }
+	const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
 
 	void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); }
 	void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); }
@@ -67,7 +67,7 @@ public:
 	ImplBase* impl;
 
 protected:
-	static LLUICtrl* sThumbnailPlaceholder;
+	LLUICtrl* mThumbnailPlaceholder;
 	LLUICtrl *mRefreshBtn, *mRefreshLabel;
 	LLUICtrl *mSucceessLblPanel, *mFailureLblPanel;
 };
-- 
cgit v1.2.3


From 2ce38c3c9890f6cf65238e125a78cdc57841f3bd Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 4 Aug 2016 16:20:39 -0400
Subject: MAINT-6584: Comment out completely unused LLImageJ2CKDU code.

The only call to the findDiscardLevelsBoundaries() method was commented out
inside initDecode(), with a comment:
        // Merov : Test!! DO NOT COMMIT!!

This was the only caller of copy_tile(), which was the only caller of
copy_block(). Commented out all three of these (biggish!) functions, since I
have no idea what any of them were supposed to do or when it might be useful
to call them. In other words, I can't yet rule out the possibility that I
might have to uncomment them.
---
 indra/llkdu/llimagej2ckdu.cpp | 9 +++++++++
 indra/llkdu/llimagej2ckdu.h   | 7 ++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 0863240686..9347e51b85 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -713,6 +713,8 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
 /* STATIC                        copy_block                                  */
 /*****************************************************************************/
 
+/*==========================================================================*|
+// Only called by copy_tile(), which is itself commented out
 static void copy_block(kdu_block *in, kdu_block *out)
 {
 	if (in->K_max_prime != out->K_max_prime)
@@ -741,11 +743,14 @@ static void copy_block(kdu_block *in, kdu_block *out)
 		out->set_max_bytes(num_bytes,false);
 	memcpy(out->byte_buffer,in->byte_buffer,(size_t) num_bytes);
 }
+|*==========================================================================*/
 
 /*****************************************************************************/
 /* STATIC                        copy_tile                                   */
 /*****************************************************************************/
 
+/*==========================================================================*|
+// Only called by findDiscardLevelsBoundaries(), which is itself commented out
 static void
 copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
 		  kdu_params *siz_in, kdu_params *siz_out, int skip_components,
@@ -802,10 +807,13 @@ copy_tile(kdu_tile tile_in, kdu_tile tile_out, int tnum_in, int tnum_out,
         }
     }
 }
+|*==========================================================================*/
 
 // Find the block boundary for each discard level in the input image.
 // We parse the input blocks and copy them in a temporary output stream.
 // For the moment, we do nothing more that parsing the raw list of blocks and outputing result.
+/*==========================================================================*|
+// See comments in header file for why this is commented out.
 void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
 {
 	// We need the number of levels in that image before starting.
@@ -909,6 +917,7 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base)
 	}
 	return;
 }
+|*==========================================================================*/
 
 void set_default_colour_weights(kdu_params *siz)
 {
diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h
index 5fb093826e..7d234435a4 100644
--- a/indra/llkdu/llimagej2ckdu.h
+++ b/indra/llkdu/llimagej2ckdu.h
@@ -74,13 +74,18 @@ protected:
 	virtual bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL);
 	virtual bool initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1, int levels = 0);
 	virtual std::string getEngineInfo() const;
-	void findDiscardLevelsBoundaries(LLImageJ2C &base);
 
 private:
 	bool initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);
 	void setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode);
 	void cleanupCodeStream();
 
+	// This method was public, but the only call to it is commented out in our
+	// own initDecode() method. I (nat 2016-08-04) don't know what it does or
+	// why. Even if it should be uncommented, it should probably still be
+	// private.
+//	void findDiscardLevelsBoundaries(LLImageJ2C &base);
+
 	// Helper class to hold a kdu_codestream, which is a handle to the
 	// underlying implementation object. When CodeStreamHolder is reset() or
 	// destroyed, it calls kdu_codestream::destroy() -- which kdu_codestream
-- 
cgit v1.2.3


From f459c67faea4bfcbca8e88c6d8b66319b4b461aa Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Fri, 5 Aug 2016 00:58:09 +0300
Subject: Buildfix: brought back LINDEN_J2C_COMMENT_PREFIX

---
 indra/llimage/llimagej2c.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 44aff98494..e196f7479e 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -130,6 +130,8 @@ protected:
 	friend class LLImageJ2C;
 };
 
+#define LINDEN_J2C_COMMENT_PREFIX "LL_" // Used by LLAppearanceUtility
+
 //
 // This class is used for performance data gathering only.
 // Tracks the image compression / decompression data,
-- 
cgit v1.2.3


From 65d608cdac701ab10f84bd8dc4a6c0be7eef26f1 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Aug 2016 14:02:12 -0400
Subject: MAINT-6584: Clarify LLKDUMessageError::flush() throwing exception.

---
 indra/llkdu/llimagej2ckdu.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 9347e51b85..2adb90320c 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -165,6 +165,12 @@ struct LLKDUMessageError : public LLKDUMessage
 		// terminating handler→flush call."
 		// So throwing an exception here isn't arbitrary: we MUST throw an
 		// exception if we want to recover from a KDU error.
+		// Because this confused me: the above quote specifically refers to
+		// the kdu_error class, which is constructed internally within KDU at
+		// the point where a fatal error is discovered and reported. It is NOT
+		// talking about the kdu_message subclass passed to
+		// kdu_customize_errors(). Destroying this static object at program
+		// shutdown will NOT engage the behavior described above.
 		if (end_of_message) 
 		{
 			throw "KDU throwing an exception";
-- 
cgit v1.2.3


From a5ce63eb3c4a3f3ea57ca2a353954a2afd43fc72 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Aug 2016 17:44:13 -0400
Subject: MAINT-6584: Add explanatory comments to LLImageJ2CKDU implementation.

These comments are inherently fragile, in that they enumerate all present
callers of certain methods. Adding, removing or relocating calls would
invalidate these comments. However, the LLImageJ2CKDU implementation is
probably pretty stable by now.
---
 indra/llkdu/llimagej2ckdu.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 2adb90320c..1201170f6d 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -202,6 +202,10 @@ LLImageJ2CKDU::~LLImageJ2CKDU()
 // Stuff for new simple decode
 void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);
 
+// This is called by the real (private) initDecode() (keep_codestream true)
+// and getMetadata() methods (keep_codestream false). As far as nat can tell,
+// mode is always MODE_FAST. It was called by findDiscardLevelsBoundaries()
+// as well, when that still existed, with keep_codestream true and MODE_FAST.
 void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECodeStreamMode mode)
 {
 	S32 data_size = base.getDataSize();
@@ -212,6 +216,12 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
 	//
 	mCodeStreamp.reset();
 
+	// It's not clear to nat under what circumstances we would reuse a
+	// pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of
+	// two U32s and a pointer, so it's not as if it would be a huge overhead
+	// to allocate a new one every time.
+	// Also -- why is base.getData() tested specifically here? If that returns
+	// NULL, shouldn't we bail out of the whole method?
 	if (!mInputp && base.getData())
 	{
 		// The compressed data has been loaded
@@ -301,6 +311,9 @@ void LLImageJ2CKDU::cleanupCodeStream()
 	mTileIndicesp.reset();
 }
 
+// This is the protected virtual method called by LLImageJ2C::initDecode().
+// However, as far as nat can tell, LLImageJ2C::initDecode() is called only by
+// llimage_libtest.cpp's load_image() function. No detectable production use.
 bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region)
 {
 	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region);
@@ -333,6 +346,9 @@ bool LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int bloc
 	return true;
 }
 
+// This is the real (private) initDecode() called both by the protected
+// initDecode() method and by decodeImpl(). As far as nat can tell, only the
+// decodeImpl() usage matters for production.
 bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)
 {
 	base.resetLastError();
-- 
cgit v1.2.3


From 80adc9b6aa9814c74fd0c67c5de9d1765a089925 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Fri, 5 Aug 2016 17:57:24 -0400
Subject: MAINT-6584: Introduce KDUError exception from other viewer project.

Specifically, manually apply changesets b4db8a8 and b98371d from
nat_linden/viewer-mac-mainloop. We need to throw from a new place, but if we
threw const char* (current convention), the new throw wouldn't be patched when
we merge to new exception convention.
---
 indra/llkdu/llimagej2ckdu.cpp | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index 1201170f6d..ba1560ec56 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -34,6 +34,15 @@
 
 #include "kdu_block_coding.h"
 
+#include <stdexcept>
+
+namespace {
+struct KDUError: public std::runtime_error
+{
+    KDUError(const std::string& msg): std::runtime_error(msg) {}
+};
+} // anonymous namespace
+
 class kdc_flow_control {
 	
 public:
@@ -173,7 +182,7 @@ struct LLKDUMessageError : public LLKDUMessage
 		// shutdown will NOT engage the behavior described above.
 		if (end_of_message) 
 		{
-			throw "KDU throwing an exception";
+	 		throw KDUError("LLKDUMessageError::flush()");
 		}
 	}
 };
@@ -406,9 +415,9 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 			mTPosp->x = 0;
 		}
 	}
-	catch (const char* msg)
+	catch (const KDUError& msg)
 	{
-		base.setLastError(ll_safe_string(msg));
+		base.setLastError(msg.what());
 		return false;
 	}
 	catch (...)
@@ -502,9 +511,9 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco
 					return false;
 				}
 			}
-			catch (const char* msg)
+			catch (const KDUError& msg)
 			{
-				base.setLastError(ll_safe_string(msg));
+				base.setLastError(msg.what());
 				base.decodeFailed();
 				cleanupCodeStream();
 				return true; // done
@@ -695,9 +704,9 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
 		base.updateData(); // set width, height
 		delete[] output_buffer;
 	}
-	catch(const char* msg)
+	catch(const KDUError& msg)
 	{
-		base.setLastError(ll_safe_string(msg));
+		base.setLastError(msg.what());
 		return false;
 	}
 	catch( ... )
@@ -719,9 +728,9 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base)
 		setupCodeStream(base, false, MODE_FAST);
 		return true;
 	}
-	catch (const char* msg)
+	catch (const KDUError& msg)
 	{
-		base.setLastError(ll_safe_string(msg));
+		base.setLastError(msg.what());
 		return false;
 	}
 	catch (...)
-- 
cgit v1.2.3


From 1773f44b6d9fffa7f5d0b2449184b2998e99be5a Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 6 Aug 2016 11:39:11 -0400
Subject: MAINT-6584: Don't crash on inconsistent dims in a JPEG-2000 image.

Previous code would crump with LL_ERRS. But a bad image file should fail only
the image load -- not crash the viewer.

While at it, validate all components present, not just 0, 1, 2.

While at it, make the failure message report which component and what the
mismatched dimensions are, not just "Components don't have matching
dimensions!"
---
 indra/llkdu/llimagej2ckdu.cpp | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index ba1560ec56..025c77b85e 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -31,18 +31,31 @@
 #include "llpointer.h"
 #include "llmath.h"
 #include "llkdumem.h"
+#include "stringize.h"
 
 #include "kdu_block_coding.h"
 
 #include <stdexcept>
+#include <iostream>
 
 namespace {
+// exception used to keep KDU from terminating entire program -- see comments
+// in LLKDUMessageError::flush()
 struct KDUError: public std::runtime_error
 {
-    KDUError(const std::string& msg): std::runtime_error(msg) {}
+	KDUError(const std::string& msg): std::runtime_error(msg) {}
 };
 } // anonymous namespace
 
+// stream kdu_dims to std::ostream
+// Turns out this must NOT be in the anonymous namespace!
+inline
+std::ostream& operator<<(std::ostream& out, const kdu_dims& dims)
+{
+	return out << "(" << dims.pos.x << "," << dims.pos.y << "),"
+				  "[" << dims.size.x << "x" << dims.size.y << "]";
+}
+
 class kdc_flow_control {
 	
 public:
@@ -287,13 +300,19 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
 
 	S32 components = mCodeStreamp->get_num_components();
 
-	if (components >= 3)
-	{ // Check that components have consistent dimensions (for PPM file)
-		kdu_dims dims1; mCodeStreamp->get_dims(1,dims1);
-		kdu_dims dims2; mCodeStreamp->get_dims(2,dims2);
-		if ((dims1 != dims) || (dims2 != dims))
+	// Check that components have consistent dimensions (for PPM file)
+	for (int idx = 1; idx < components; ++idx)
+	{
+		kdu_dims other_dims;
+		mCodeStreamp->get_dims(idx, other_dims);
+		if (other_dims != dims)
 		{
-			LL_ERRS() << "Components don't have matching dimensions!" << LL_ENDL;
+			// This method is only called from methods that catch KDUError.
+			// We want to fail the image load, not crash the viewer.
+			throw KDUError(STRINGIZE("Component " << idx << " dimensions "
+									 << other_dims
+									 << " do not match component 0 dimensions "
+									 << dims << "!"));
 		}
 	}
 
-- 
cgit v1.2.3


From d4b1db277ca538781661bf474b733296156e5728 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Tue, 9 Aug 2016 05:07:39 +0300
Subject: MAINT-6618 Fixed the crash in LLImageRaw::scale() + some additional
 checks

---
 indra/llimage/llimage.cpp | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 91fa8c6ad1..c7f02a6b1a 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -942,6 +942,12 @@ void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
 {
 	llassert( getComponents() <= 4 );
 	// This is fairly bogus, but it'll do for now.
+	if (isBufferInvalid())
+	{
+		LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+		return;
+	}
+
 	U8 *pos = getData();
 	U32 x, y;
 	for (x = 0; x < getWidth(); x++)
@@ -1136,7 +1142,6 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
 	llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
 	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
 
-
 	U8* src_data = src->getData();
 	U8* dst_data = dst->getData();
 	S32 pixels = getWidth() * getHeight();
@@ -1193,6 +1198,12 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
 // Fill the buffer with a constant color
 void LLImageRaw::fill( const LLColor4U& color )
 {
+	if (isBufferInvalid())
+	{
+		LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+		return;
+	}
+
 	S32 pixels = getWidth() * getHeight();
 	if( 4 == getComponents() )
 	{
@@ -1403,6 +1414,12 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data )
 {
 	llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
 
+	if (isBufferInvalid())
+	{
+		LL_WARNS() << "Invalid image buffer" << LL_ENDL;
+		return false;
+	}
+
 	S32 old_width = getWidth();
 	S32 old_height = getHeight();
 	
-- 
cgit v1.2.3


From 471ff40c2c544158158abebcd88070c3c6aaf4c8 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Tue, 9 Aug 2016 17:37:48 +0300
Subject: Reverted change to lllayoutstack.cpp which could possibly cause
 memory leak

---
 indra/llui/lllayoutstack.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 11769760aa..69246a2f57 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -283,7 +283,7 @@ void LLLayoutStack::removeChild(LLView* view)
 	if (embedded_panelp)
 	{
 		mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
-		//delete embedded_panelp;
+		delete embedded_panelp;
 		updateFractionalSizes();
 		mNeedsLayout = true;
 	}
-- 
cgit v1.2.3


From 5e02d304f03dd6adcb99f422e3a9a67eb262b2a1 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Tue, 9 Aug 2016 19:26:30 +0300
Subject: MAINT-6618 More checks

---
 indra/llimage/llimage.cpp | 41 +++++++++++++++++++++++++++++++++++++----
 indra/llimage/llimage.h   |  3 +++
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index c7f02a6b1a..feb97ec2ab 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1075,6 +1075,11 @@ void LLImageRaw::composite( LLImageRaw* src )
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
+	if (!validateSrcAndDst("LLImageRaw::composite", src, dst))
+	{
+		return;
+	}
+
 	llassert(3 == src->getComponents());
 	llassert(3 == dst->getComponents());
 
@@ -1176,6 +1181,11 @@ void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
+	if (!validateSrcAndDst("LLImageRaw::copyUnscaledAlphaMask", src, dst))
+	{
+		return;
+	}
+
 	llassert( 1 == src->getComponents() );
 	llassert( 4 == dst->getComponents() );
 	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
@@ -1242,14 +1252,13 @@ LLPointer<LLImageRaw> LLImageRaw::duplicate()
 // Src and dst can be any size.  Src and dst can each have 3 or 4 components.
 void LLImageRaw::copy(LLImageRaw* src)
 {
-	if (!src)
+	LLImageRaw* dst = this;  // Just for clarity.
+
+	if (!validateSrcAndDst("LLImageRaw::copy", src, dst))
 	{
-		LL_WARNS() << "LLImageRaw::copy called with a null src pointer" << LL_ENDL;
 		return;
 	}
 
-	LLImageRaw* dst = this;  // Just for clarity.
-
 	if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
 	{
 		// No scaling needed
@@ -1376,6 +1385,11 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
 {
 	LLImageRaw* dst = this;  // Just for clarity.
 
+	if (!validateSrcAndDst("LLImageRaw::copyScaled", src, dst))
+	{
+		return;
+	}
+
 	llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
 	llassert_always( src->getComponents() == dst->getComponents() );
 
@@ -1709,6 +1723,25 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
 	}
 }
 
+bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
+{
+	if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
+	{
+		LL_WARNS() << func << ": Source: ";
+		if (!src) LL_CONT << "Null pointer";
+		else if (src->isBufferInvalid()) LL_CONT << "Invalid buffer";
+		else LL_CONT << "OK";
+
+		LL_CONT << "; Destination: ";
+		if (!dst) LL_CONT << "Null pointer";
+		else if (dst->isBufferInvalid()) LL_CONT << "Invalid buffer";
+		else LL_CONT << "OK";
+		LL_CONT << "." << LL_ENDL;
+
+		return false;
+	}
+	return true;
+}
 
 //----------------------------------------------------------------------------
 
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index adc650d360..9cc7431a9c 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -277,6 +277,9 @@ protected:
 public:
 	static S32 sGlobalRawMemory;
 	static S32 sRawImageCount;
+
+private:
+	bool validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst);
 };
 
 // Compressed representation of image.
-- 
cgit v1.2.3


From b496e4ff156ab2fb055e741b97ceda5751476e7f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 10 Aug 2016 16:32:35 +0300
Subject: MAINT-6616 new crash in VOB viewer in snapshot preview

---
 indra/newview/llfloateroutfitsnapshot.cpp | 9 ++++++++-
 indra/newview/llfloateroutfitsnapshot.h   | 1 +
 indra/newview/llfloatersnapshot.cpp       | 8 +++++++-
 indra/newview/llfloatersnapshot.h         | 1 +
 4 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index 093a2dad64..ca5a2fdad5 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -311,13 +311,20 @@ void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
 // static 
 void LLFloaterOutfitSnapshot::update()
 {
-    LLFloaterOutfitSnapshot* inst = getInstance();
+    LLFloaterOutfitSnapshot* inst = findInstance();
     if (inst != NULL)
     {
         inst->impl->updateLivePreview();
     }
 }
 
+
+// static
+LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance()
+{
+    return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot");
+}
+
 // static
 LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
 {
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 482080da7a..04623acf0f 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -51,6 +51,7 @@ public:
     static void update();
 
     static LLFloaterOutfitSnapshot* getInstance();
+    static LLFloaterOutfitSnapshot* findInstance();
     /*virtual*/ void saveTexture();
 
     const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); }
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index a0e54e47b6..48c44b88fc 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1255,13 +1255,19 @@ void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
 //static 
 void LLFloaterSnapshot::update()
 {
-	LLFloaterSnapshot* inst = getInstance();
+	LLFloaterSnapshot* inst = findInstance();
 	if (inst != NULL)
 	{
 		inst->impl->updateLivePreview();
 	}
 }
 
+// static
+LLFloaterSnapshot* LLFloaterSnapshot::findInstance()
+{
+	return LLFloaterReg::findTypedInstance<LLFloaterSnapshot>("snapshot");
+}
+
 // static
 LLFloaterSnapshot* LLFloaterSnapshot::getInstance()
 {
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 4c65c8d06a..44c6415326 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -146,6 +146,7 @@ public:
 	static void update();
 
 	static LLFloaterSnapshot* getInstance();
+	static LLFloaterSnapshot* findInstance();
 	/*virtual*/ void saveTexture();
 	BOOL saveLocal();
 	static void setAgentEmail(const std::string& email);
-- 
cgit v1.2.3


From e4a1b2c9408af860532e6bf7bb628a2bb32a82be Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 11 Aug 2016 15:31:41 -0400
Subject: Added tag 4.0.7-release for changeset 33981d8130f0

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index 0d06bfe598..cee1281f2b 100755
--- a/.hgtags
+++ b/.hgtags
@@ -517,3 +517,4 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
 0a5de9ec2cb868f367501024d8d6958c20869053 4.0.4-release
 450de775fff66a011be1a001acd117cc623c445d 4.0.5-release
 4070611edd95eb3a683d1cd97c4c07fe67793812 4.0.6-release
+33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release
-- 
cgit v1.2.3


From 4fb100ac7a33174883184f1320d0beac08ead3a7 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 11 Aug 2016 15:31:41 -0400
Subject: increment viewer version to 4.0.8

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 43beb4001b..a2cec7aff4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-4.0.7
+4.0.8
-- 
cgit v1.2.3


From 0f061689914d1d73272d373c877d1656933ae501 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Wed, 17 Aug 2016 20:35:00 +0300
Subject: MAINT-6655 Group inspector doesn't support default icon.

---
 indra/newview/llgroupiconctrl.cpp                    | 20 ++++++++++----------
 indra/newview/llgroupiconctrl.h                      |  8 +++++++-
 indra/newview/llinspectgroup.cpp                     |  3 ++-
 indra/newview/lltexturectrl.cpp                      |  2 +-
 indra/newview/skins/default/xui/en/inspect_group.xml |  2 +-
 5 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 271dd44c1f..7c2a3cad43 100644
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -74,9 +74,16 @@ LLGroupIconCtrl::~LLGroupIconCtrl()
 	LLGroupMgr::getInstance()->removeObserver(this);
 }
 
-void LLGroupIconCtrl::setIconId(const LLSD& value)
+void LLGroupIconCtrl::setIconId(const LLUUID& icon_id)
 {
-    LLIconCtrl::setValue(value);
+    if (icon_id.notNull())
+    {
+        LLIconCtrl::setValue(icon_id);
+    }
+    else
+    {
+        LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
+    }
 }
 
 void LLGroupIconCtrl::setValue(const LLSD& value)
@@ -122,14 +129,7 @@ bool LLGroupIconCtrl::updateFromCache()
 	LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId);
 	if (!group_data) return false;
 
-	if (group_data->mInsigniaID.notNull())
-	{
-		LLIconCtrl::setValue(group_data->mInsigniaID);
-	}
-	else
-	{
-		LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
-	}
+	setIconId(group_data->mInsigniaID);
 
 	if (mDrawTooltip && !group_data->mName.empty())
 	{
diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h
index f8b22cf581..43e384d3e2 100644
--- a/indra/newview/llgroupiconctrl.h
+++ b/indra/newview/llgroupiconctrl.h
@@ -66,7 +66,13 @@ public:
 	 */
 	virtual void setValue(const LLSD& value);
 
-	void setIconId(const LLSD& value);
+	/**
+	 * Sets icon_id as icon value directly. Avoids LLGroupMgr cache checks for group id
+	 * Uses default icon in case id is null.
+	 *
+	 * @params icon_id - it is processed as icon id, default image will be used in case id is null.
+	 */
+	void setIconId(const LLUUID& icon_id);
 
 	// LLGroupMgrObserver observer trigger
 	virtual void changed(LLGroupChange gc);
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index 8e91af321e..0c5a91e48a 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -233,7 +233,8 @@ void LLInspectGroup::processGroupData()
 
 		getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) );
 
-		getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) );
+		// LLGroupIconCtrl
+		getChild<LLUICtrl>("group_icon")->setValue(LLSD(mGroupID));
 
 		std::string cost;
 		bool is_member = LLGroupActions::isInGroup(mGroupID);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index e5aa740a33..980810835e 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1393,7 +1393,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
 
 void	LLTextureCtrl::setImageAssetName(const std::string& name)
 {
-	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW);
+	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
 	if(imagep)
 	{
 		LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml
index 324ff3eabd..a69585074c 100644
--- a/indra/newview/skins/default/xui/en/inspect_group.xml
+++ b/indra/newview/skins/default/xui/en/inspect_group.xml
@@ -66,7 +66,7 @@ Fear the moose!  Fear it!  And the mongoose too!
    width="220">
 L$123 to join
   </text>
-  <icon
+  <group_icon
      follows="all"
      height="38"
      right="-10"
-- 
cgit v1.2.3


From d85bc7de7f03a4629f0108c076cf3242466a8a3f Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 16 Aug 2016 17:48:52 +0300
Subject: MAINT-6637 DebugAvatarAppearanceMessage incorrectly reports all
 avatars received COF version as -1

---
 doc/contributions.txt        |  1 +
 indra/newview/llvoavatar.cpp | 17 +++++++----------
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index d968e80250..b3d1c2432d 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -199,6 +199,7 @@ Ansariel Hiller
 	STORM-2133
 	MAINT-6511
 	MAINT-6612
+	MAINT-6637
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index aebc066507..f79249d6fa 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7392,16 +7392,13 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 	// No backsies zone - if we get here, the message should be valid and usable, will be processed.
     LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
 
-    if (isSelf())
-    {
-        // Note:
-        // locally the COF is maintained via LLInventoryModel::accountForUpdate
-        // which is called from various places.  This should match the simhost's 
-        // idea of what the COF version is.  AIS however maintains its own version
-        // of the COF that should be considered canonical. 
-        mLastUpdateReceivedCOFVersion = thisAppearanceVersion;
-    }
-		
+    // Note:
+    // locally the COF is maintained via LLInventoryModel::accountForUpdate
+    // which is called from various places.  This should match the simhost's 
+    // idea of what the COF version is.  AIS however maintains its own version
+    // of the COF that should be considered canonical. 
+    mLastUpdateReceivedCOFVersion = thisAppearanceVersion;
+
     if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE))
     {
         updateVisualComplexity();
-- 
cgit v1.2.3


From e8b23bbfffd38dbdad0cd57b236fd4604232ff6c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 18 Aug 2016 19:30:36 +0300
Subject: MAINT-6644 Way for users to disable avatar complexity notifications.

---
 indra/newview/skins/default/xui/en/notifications.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 102ce0ddc0..8e51aca516 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3317,6 +3317,9 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin
      <context>AgentComplexityNotice</context>
    </unique>
 Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY].
+    <usetemplate
+     ignoretext="Warn me about my avatar complexity changes"
+     name="notifyignore"/>
   </notification>
 
   <notification
-- 
cgit v1.2.3


From 8db7540908abf1eb6baab0d5d9e8028f489f5927 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 19 Aug 2016 11:58:32 +0300
Subject: MAINT-6649 PRIM_TEXT/llSetText upper draw distance limit

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llhudtext.cpp             | 17 +++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 00c769607f..d3b9f0faf0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -7940,6 +7940,17 @@
       <key>Value</key>
       <integer>100000</integer>
     </map>
+    <key>PrimTextMaxDrawDistance</key>
+    <map>
+      <key>Comment</key>
+      <string>Maximum draw distance beyond which PRIM_TEXT won't be rendered</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>64.0</real>
+    </map>
     <key>ProbeHardwareOnStartup</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 52e83fe412..6b1e196182 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -53,7 +53,7 @@ const F32 VERTICAL_PADDING = 12.f;
 const F32 BUFFER_SIZE = 2.f;
 const F32 HUD_TEXT_MAX_WIDTH = 190.f;
 const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f;
-const F32 MAX_DRAW_DISTANCE = 64.f;
+const F32 MAX_DRAW_DISTANCE = 300.f;
 
 std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects;
 std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects;
@@ -394,7 +394,20 @@ void LLHUDText::updateVisibility()
 
 	LLVector3 pos_agent_center = gAgent.getPosAgentFromGlobal(mPositionGlobal) - dir_from_camera;
 	F32 last_distance_center = (pos_agent_center - LLViewerCamera::getInstance()->getOrigin()).magVec();
-	if(last_distance_center > MAX_DRAW_DISTANCE)
+	F32 max_draw_distance = gSavedSettings.getF32("PrimTextMaxDrawDistance");
+
+	if(max_draw_distance < 0)
+	{
+		max_draw_distance = 0;
+		gSavedSettings.setF32("PrimTextMaxDrawDistance", max_draw_distance);
+	}
+	else if(max_draw_distance > MAX_DRAW_DISTANCE)
+	{
+		max_draw_distance = MAX_DRAW_DISTANCE;
+		gSavedSettings.setF32("PrimTextMaxDrawDistance", MAX_DRAW_DISTANCE);
+	}
+
+	if(last_distance_center > max_draw_distance)
 	{
 		mVisible = FALSE;
 		return;
-- 
cgit v1.2.3


From cf93c1c81d35d79279bb9ddc7445afac09f3d57f Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 18 Aug 2016 19:43:48 +0300
Subject: MAINT-5992 Second Life unusable on Windows 10 with 4k monitor SL
 forcibly overrides DPI compatibility option

---
 indra/llwindow/llwindowcallbacks.cpp |   5 ++
 indra/llwindow/llwindowcallbacks.h   |   1 +
 indra/llwindow/llwindowwin32.cpp     | 103 ++++++++++++++++++++++++++++++-----
 indra/llwindow/llwindowwin32.h       |   2 +-
 indra/newview/llappviewerwin32.cpp   |   4 +-
 indra/newview/llviewerwindow.cpp     |   7 +++
 indra/newview/llviewerwindow.h       |   1 +
 7 files changed, 106 insertions(+), 17 deletions(-)

diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index d2afb3f91b..474953d3a4 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -175,6 +175,11 @@ BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
 	return FALSE;
 }
 
+void LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
+{
+
+}
+
 void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 6a7137e593..de789a71d9 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -65,6 +65,7 @@ public:
 	virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
 	virtual BOOL handleTimerEvent(LLWindow *window);
 	virtual BOOL handleDeviceChange(LLWindow *window);
+	virtual void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
 
 	enum DragNDropAction {
 		DNDA_START_TRACKING = 0,// Start tracking an incoming drag
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 2a39029eee..f14cf26ce9 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -71,6 +71,11 @@ const S32	MAX_MESSAGE_PER_UPDATE = 20;
 const S32	BITS_PER_PIXEL = 32;
 const S32	MAX_NUM_RESOLUTIONS = 32;
 const F32	ICON_FLASH_TIME = 0.5f;
+const F32	DEFAULT_DPI = 96.0f;
+
+#ifndef WM_DPICHANGED                   
+const S32	WM_DPICHANGED = 0x02E0;
+#endif
 
 extern BOOL gDebugWindowProc;
 
@@ -97,6 +102,10 @@ typedef enum MONITOR_DPI_TYPE {
 
 typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value);
 
+typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)(
+	_In_ HANDLE hprocess,
+	_Out_ PROCESS_DPI_AWARENESS *value);
+
 typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)(
 	_In_ HMONITOR hmonitor,
 	_In_ MONITOR_DPI_TYPE dpiType,
@@ -2618,6 +2627,24 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
 
 				return 0;
 			}
+        
+		case WM_DPICHANGED:
+			{
+				LPRECT lprc_new_scale;
+				F32 new_scale = LOWORD(w_param) / 96.0f;
+				lprc_new_scale = (LPRECT)l_param;
+				S32 new_width = lprc_new_scale->right - lprc_new_scale->left;
+				S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top;
+				window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height);
+				SetWindowPos(h_wnd,
+					HWND_TOP,
+					lprc_new_scale->left,
+					lprc_new_scale->top,
+					new_width,
+					new_height,
+					SWP_NOZORDER | SWP_NOACTIVATE);
+					return 0;
+			}
 
 		case WM_SETFOCUS:
 			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
@@ -3903,40 +3930,86 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
 	return FALSE;
 }
 
+//static
+void LLWindowWin32::setDPIAwareness()
+{
+	HMODULE hShcore = LoadLibrary(L"shcore.dll");
+	if (hShcore != NULL)
+	{
+		SetProcessDpiAwarenessType pSPDA;
+		pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness");
+		if (pSPDA)
+		{
+			
+			HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE);
+			if (hr != S_OK)
+			{
+				LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL;
+			}
+		}
+		FreeLibrary(hShcore);	
+	}
+	else
+	{
+		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL;
+	}
+}
+
 F32 LLWindowWin32::getSystemUISize()
 {
 	float scale_value = 0;
 	HWND hWnd = (HWND)getPlatformWindow();
 	HDC hdc = GetDC(hWnd);
 	HMONITOR hMonitor;
+	HANDLE hProcess = GetCurrentProcess();
+	PROCESS_DPI_AWARENESS dpi_awareness;
 
 	HMODULE hShcore = LoadLibrary(L"shcore.dll");
 
 	if (hShcore != NULL)
 	{
-		SetProcessDpiAwarenessType pSPDA;
-		pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness");
+		GetProcessDpiAwarenessType pGPDA;
+		pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness");
 		GetDpiForMonitorType pGDFM;
 		pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor");
-		if (pSPDA != NULL && pGDFM != NULL)
+		if (pGPDA != NULL && pGDFM != NULL)
 		{
-			pSPDA(PROCESS_PER_MONITOR_DPI_AWARE);
-			POINT    pt;
-			UINT     dpix = 0, dpiy = 0;
-			HRESULT  hr = E_FAIL;
-
-			// Get the DPI for the main monitor, and set the scaling factor
-			pt.x = 1;
-			pt.y = 1;
-			hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
-			hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
-			scale_value = dpix / 96.0f;
+			pGPDA(hProcess, &dpi_awareness);
+			if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE)
+			{
+				POINT    pt;
+				UINT     dpix = 0, dpiy = 0;
+				HRESULT  hr = E_FAIL;
+				RECT     rect;
+
+				GetWindowRect(hWnd, &rect);
+				// Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor
+				pt.x = (rect.left + rect.right) / 2;
+				pt.y = (rect.top + rect.bottom) / 2;
+				hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
+				hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
+				if (hr == S_OK)
+				{
+					scale_value = dpix / DEFAULT_DPI;
+				}
+				else
+				{
+					LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL;
+					scale_value = 1.0f;
+				}
+			}
+			else
+			{
+				LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL;
+				scale_value = 1.0f;
+			}
 		}
+		FreeLibrary(hShcore);
 	}
 	else
 	{
 		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL;
-		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f;
+		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / DEFAULT_DPI;
 	}
 
 	ReleaseDC(hWnd, hdc);
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 1386321912..39ef9b31a4 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -115,7 +115,7 @@ public:
 	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
 
 	static std::vector<std::string> getDynamicFallbackFontList();
-
+	static void setDPIAwareness();
 protected:
 	LLWindowWin32(LLWindowCallbacks* callbacks,
 		const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, 
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 4786f83bfd..febcfe1f61 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -231,6 +231,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
 	DWORD heap_enable_lfh_error[MAX_HEAPS];
 	S32 num_heaps = 0;
 	
+	LLWindowWin32::setDPIAwareness();
+
 #if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD
 	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit
 #elif 0
@@ -569,7 +571,7 @@ bool LLAppViewerWin32::initHardwareTest()
 	// Do driver verification and initialization based on DirectX
 	// hardware polling and driver versions
 	//
-	if (FALSE == gSavedSettings.getBOOL("NoHardwareProbe"))
+	if (TRUE == gSavedSettings.getBOOL("ProbeHardwareOnStartup") && FALSE == gSavedSettings.getBOOL("NoHardwareProbe"))
 	{
 		// per DEV-11631 - disable hardware probing for everything
 		// but vram.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f47a37fcda..ff7722b90e 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1593,6 +1593,13 @@ BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
 	return FALSE;
 }
 
+void LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
+{
+    gSavedSettings.setF32("UIScaleFactor", ui_scale_factor);
+    LLViewerWindow::reshape(window_width, window_height);
+    mResDirty = true;
+}
+
 void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 	LLAppViewer::instance()->pingMainloopTimeout(msg);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index afe80358ca..87ba568d43 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -210,6 +210,7 @@ public:
 	/*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
 	/*virtual*/ BOOL handleTimerEvent(LLWindow *window);
 	/*virtual*/ BOOL handleDeviceChange(LLWindow *window);
+	/*virtual*/ void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
 
 	/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
 	/*virtual*/ void handlePauseWatchdog(LLWindow *window);
-- 
cgit v1.2.3


From ea4b5e60d92b0b1349115e2722f028cd0cf2da18 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 20 Aug 2016 14:28:03 +0300
Subject: Fixed line endings in llwindowwin32.cpp

---
 indra/llwindow/llwindowwin32.cpp | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index f14cf26ce9..26bc819aab 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3976,7 +3976,7 @@ F32 LLWindowWin32::getSystemUISize()
 		{
 			pGPDA(hProcess, &dpi_awareness);
 			if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE)
-			{
+			{
 				POINT    pt;
 				UINT     dpix = 0, dpiy = 0;
 				HRESULT  hr = E_FAIL;
@@ -3988,19 +3988,19 @@ F32 LLWindowWin32::getSystemUISize()
 				pt.y = (rect.top + rect.bottom) / 2;
 				hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
 				hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
-				if (hr == S_OK)
-				{
-					scale_value = dpix / DEFAULT_DPI;
-				}
-				else
-				{
-					LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL;
-					scale_value = 1.0f;
+				if (hr == S_OK)
+				{
+					scale_value = dpix / DEFAULT_DPI;
+				}
+				else
+				{
+					LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL;
+					scale_value = 1.0f;
 				}
 			}
 			else
 			{
-				LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL;
+				LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL;
 				scale_value = 1.0f;
 			}
 		}
-- 
cgit v1.2.3


From 6c280f9d2bbc8f6f7727bfc7b6792b33eb8ffafd Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Sat, 20 Aug 2016 14:36:04 +0300
Subject: MAINT-6662 Don't show release notes on first login

---
 indra/newview/llappviewer.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 64bc7fb2c4..3c81e81a6d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -5819,7 +5819,9 @@ void LLAppViewer::launchUpdater()
 */
 void LLAppViewer::showReleaseNotesIfRequired()
 {
-	if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion && gSavedSettings.getBOOL("UpdaterShowReleaseNotes"))
+	if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion
+		&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
+		&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
 	{
 		LLSD info(getViewerInfo());
 		LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
-- 
cgit v1.2.3


From f69e82b584eb69ef5cde751e2ad36f995b7bc9ea Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 22 Aug 2016 20:57:22 +0300
Subject: Backed out changeset: 6d631b9d02a0 for maint-6242

---
 indra/newview/llagent.cpp    | 18 ++----------------
 indra/newview/llagent.h      |  8 +++-----
 indra/newview/lltool.cpp     | 21 +++------------------
 indra/newview/lltoolcomp.cpp | 26 ++++++++++++--------------
 indra/newview/lltoolgrab.cpp |  2 +-
 5 files changed, 21 insertions(+), 54 deletions(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d8b0787852..6a1215c3af 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3191,7 +3191,7 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
 }
 
 BOOL LLAgent::leftButtonGrabbed() const	
-{
+{ 
 	const BOOL camera_mouse_look = gAgentCamera.cameraMouselook();
 	return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) 
 		|| (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
@@ -3199,13 +3199,6 @@ BOOL LLAgent::leftButtonGrabbed() const
 		|| (camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
 }
 
-BOOL LLAgent::leftButtonBlocked() const
-{
-    const BOOL camera_mouse_look = gAgentCamera.cameraMouselook();
-    return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
-        || (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
-}
-
 BOOL LLAgent::rotateGrabbed() const		
 { 
 	return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0)
@@ -3663,14 +3656,7 @@ BOOL LLAgent::anyControlGrabbed() const
 
 BOOL LLAgent::isControlGrabbed(S32 control_index) const
 {
-    if (gAgent.mControlsTakenCount[control_index] > 0)
-        return TRUE;
-    return gAgent.mControlsTakenPassedOnCount[control_index] > 0;
-}
-
-BOOL LLAgent::isControlBlocked(S32 control_index) const
-{
-    return mControlsTakenCount[control_index] > 0;
+	return mControlsTakenCount[control_index] > 0;
 }
 
 void LLAgent::forceReleaseControls()
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index d82ff7a67f..b5da5e9062 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -444,8 +444,7 @@ private:
 	// Grab
 	//--------------------------------------------------------------------
 public:
-    BOOL 			leftButtonGrabbed() const;
-    BOOL 			leftButtonBlocked() const;
+	BOOL 			leftButtonGrabbed() const;
 	BOOL 			rotateGrabbed() const;
 	BOOL 			forwardGrabbed() const;
 	BOOL 			backwardGrabbed() const;
@@ -462,9 +461,8 @@ public:
 	BOOL			controlFlagsDirty() const;
 	void			enableControlFlagReset();
 	void 			resetControlFlags();
-	BOOL			anyControlGrabbed() const; 		// True if a script has taken over any control
-    BOOL			isControlGrabbed(S32 control_index) const; // True if a script has taken over a control
-    BOOL			isControlBlocked(S32 control_index) const; // Control should be ignored or won't be passed
+	BOOL			anyControlGrabbed() const; 		// True iff a script has taken over a control
+	BOOL			isControlGrabbed(S32 control_index) const;
 	// Send message to simulator to force grabbed controls to be
 	// released, in case of a poorly written script.
 	void			forceReleaseControls();
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 5e703933ca..4aad650b68 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -38,7 +38,6 @@
 #include "lltoolfocus.h"
 #include "llfocusmgr.h"
 #include "llagent.h"
-#include "llagentcamera.h"
 #include "llviewerjoystick.h"
 
 extern BOOL gDebugClicks;
@@ -85,14 +84,7 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
 	}
 	// by default, didn't handle it
 	// LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL;
-    if (gAgentCamera.cameraMouselook())
-    {
-        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
-    }
-    else
-    {
-        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
-    }
+	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
 	return TRUE;
 }
 
@@ -103,15 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
 		LL_INFOS() << "LLTool left mouse up" << LL_ENDL;
 	}
 	// by default, didn't handle it
-    // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL;
-    if (gAgentCamera.cameraMouselook())
-    {
-        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_UP);
-    }
-    else
-    {
-        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
-    }
+	// LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL;
+	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
 	return TRUE;
 }
 
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 2b4fa757f6..76a791c6e9 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -742,13 +742,12 @@ BOOL LLToolCompGun::handleHover(S32 x, S32 y, MASK mask)
 
 BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
 { 
-    // if the left button is blocked, don't put up the pie menu
-    if (gAgent.leftButtonBlocked())
-    {
-        // in case of "grabbed" control flag will be set later
-        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
-        return FALSE;
-    }
+	// if the left button is grabbed, don't put up the pie menu
+	if (gAgent.leftButtonGrabbed())
+	{
+		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
+		return FALSE;
+	}
 
 	// On mousedown, start grabbing
 	gGrabTransientTool = this;
@@ -760,13 +759,12 @@ BOOL LLToolCompGun::handleMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLToolCompGun::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
-    // if the left button is blocked, don't put up the pie menu
-    if (gAgent.leftButtonBlocked())
-    {
-        // in case of "grabbed" control flag will be set later
-        gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
-        return FALSE;
-    }
+	// if the left button is grabbed, don't put up the pie menu
+	if (gAgent.leftButtonGrabbed())
+	{
+		gAgent.setControlFlags(AGENT_CONTROL_ML_LBUTTON_DOWN);
+		return FALSE;
+	}
 
 	// On mousedown, start grabbing
 	gGrabTransientTool = this;
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index c0ca4d7a9a..92e8af985b 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -143,7 +143,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
 	// call the base class to propogate info to sim
 	LLTool::handleMouseDown(x, y, mask);
 	
-	if (!gAgent.leftButtonBlocked())
+	if (!gAgent.leftButtonGrabbed())
 	{
 		// can grab transparent objects (how touch event propagates, scripters rely on this)
 		gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE);
-- 
cgit v1.2.3


From 377683a8ed85a0f6dcf78ba0d3c78f2fd9fff5d7 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 23 Aug 2016 13:01:19 +0300
Subject: MAINT-6648 FIXED [SECURITY] Link tags do not filter unicode and allow
 for easy URL spoofing.

---
 indra/llui/llurlentry.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 797fae81c4..27a2456deb 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -183,8 +183,9 @@ bool LLUrlEntryBase::isLinkDisabled() const
 
 bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
 {
-	std::string label = getLabelFromWikiLink(url);
-	return (LLUrlRegistry::instance().hasUrl(label)) ? false : true;
+	LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url));
+	label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end());
+	return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true;
 }
 
 std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
-- 
cgit v1.2.3


From b4ee80b91bfa1bdc427aaf5f5821e2a5590e21f4 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Tue, 23 Aug 2016 17:58:36 +0300
Subject: MAINT-6511 Crash in LLFloaterView::restoreAll - exception handling

---
 indra/llui/llfloater.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 1f9869fadc..b3048a9b16 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2320,7 +2320,17 @@ void LLFloaterView::restoreAll()
 	// make sure all subwindows aren't minimized
 	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
 	{
-		LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
+		LLFloater* floaterp = nullptr;
+		try
+		{
+			floaterp = dynamic_cast<LLFloater*>(*child_it);
+		}
+		catch (std::exception e) // See MAINT-6511
+		{
+			LL_WARNS() << "Caught exception: " << e.what() << LL_ENDL;
+			continue;
+		}
+
 		if (floaterp)
 		{
 			floaterp->setMinimized(FALSE);
-- 
cgit v1.2.3


From c37b822abff1a77150a334711d8484025e8c1436 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 23 Aug 2016 18:53:27 +0300
Subject: MAINT-6616 new crash in VOB viewer in snapshot preview

---
 indra/newview/lltexturectrl.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index fd13f60606..ad4f903dff 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -306,7 +306,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 
 void LLFloaterTexturePicker::onClose(bool app_quitting)
 {
-	if (mOnFloaterCloseCallback)
+	if (mOwner && mOnFloaterCloseCallback)
 	{
 		mOnFloaterCloseCallback();
 	}
-- 
cgit v1.2.3


From b22fc7f470398817056abd3c0ada256f8039c708 Mon Sep 17 00:00:00 2001
From: pavelkproductengine <pavelkproductengine@lindenlab.com>
Date: Thu, 25 Aug 2016 17:48:27 +0300
Subject: MAINT-6476 VOB - User can add any size image to an Outfit Gallery
 outfit folders

---
 indra/llimage/llimagedimensionsinfo.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
index 5bf3f29b3c..a5e546e977 100644
--- a/indra/llimage/llimagedimensionsinfo.cpp
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -201,7 +201,7 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
 	cinfo.out_color_space = JCS_RGB;
 	jpeg_start_decompress	(&cinfo);
 
-	mHeight = cinfo.output_width;
+	mWidth = cinfo.output_width;
 	mHeight = cinfo.output_height;
 
 	jpeg_destroy_decompress(&cinfo);
-- 
cgit v1.2.3


From 534bffb257044c407b8d3d8384ed0223fa9cb709 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Tue, 23 Aug 2016 17:58:36 +0300
Subject: MAINT-6511 Crash in LLFloaterView::restoreAll - exception handling

---
 indra/llui/llfloater.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 1f9869fadc..93ee1ceee3 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2320,7 +2320,17 @@ void LLFloaterView::restoreAll()
 	// make sure all subwindows aren't minimized
 	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
 	{
-		LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
+		LLFloater* floaterp = NULL;
+		try
+		{
+			floaterp = dynamic_cast<LLFloater*>(*child_it);
+		}
+		catch (std::exception e) // See MAINT-6511
+		{
+			LL_WARNS() << "Caught exception: " << e.what() << LL_ENDL;
+			continue;
+		}
+
 		if (floaterp)
 		{
 			floaterp->setMinimized(FALSE);
-- 
cgit v1.2.3


From 0279d5d98678702631dea48d00153dca83853412 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 23 Aug 2016 20:06:45 +0300
Subject: MAINT-6671 Fixed crash in LLFloaterPay::give()

---
 indra/newview/llfloaterpay.cpp | 141 ++++++++++++++++++++++-------------------
 1 file changed, 77 insertions(+), 64 deletions(-)

diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 31245db344..dfe462c8d1 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,6 +72,8 @@ struct LLGiveMoneyInfo
 		mFloater(floater), mAmount(amount){}
 };
 
+typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+
 ///----------------------------------------------------------------------------
 /// Class LLFloaterPay
 ///----------------------------------------------------------------------------
@@ -94,18 +96,18 @@ public:
 							bool is_group);
 	static bool payConfirmationCallback(const LLSD& notification,
 										const LLSD& response,
-										LLGiveMoneyInfo* info);
+										give_money_ptr info);
 
 private:
 	static void onCancel(void* data);
 	static void onKeystroke(LLLineEditor* editor, void* data);
-	static void onGive(void* data);
+	static void onGive(give_money_ptr info);
 	void give(S32 amount);
 	static void processPayPriceReply(LLMessageSystem* msg, void **userdata);
 	void finishPayUI(const LLUUID& target_id, BOOL is_group);
 
 protected:
-	std::vector<LLGiveMoneyInfo*> mCallbackData;
+	std::vector<give_money_ptr> mCallbackData;
 	money_callback mCallback;
 	LLTextBox* mObjectNameText;
 	LLUUID mTargetUUID;
@@ -113,7 +115,7 @@ protected:
 	BOOL mHaveName;
 
 	LLButton* mQuickPayButton[MAX_PAY_BUTTONS];
-	LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS];
+	give_money_ptr mQuickPayInfo[MAX_PAY_BUTTONS];
 
 	LLSafeHandle<LLObjectSelection> mObjectSelection;
 };
@@ -136,7 +138,11 @@ LLFloaterPay::LLFloaterPay(const LLSD& key)
 // Destroys the object
 LLFloaterPay::~LLFloaterPay()
 {
-	std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
+    std::vector<give_money_ptr>::iterator iter;
+    for (iter = mCallbackData.begin(); iter != mCallbackData.end(); ++iter)
+    {
+        (*iter)->mFloater = NULL;
+    }
 	mCallbackData.clear();
 	// Name callbacks will be automatically disconnected since LLFloater is trackable
 	
@@ -148,40 +154,40 @@ BOOL LLFloaterPay::postBuild()
 {
 	S32 i = 0;
 	
-	LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0);
+	give_money_ptr info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 1",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 1", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 1")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 1");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 5",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 5", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 5")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 5");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 10",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 10", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 10")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 10");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 20",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 20", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 20")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 20");
@@ -195,10 +201,10 @@ BOOL LLFloaterPay::postBuild()
 	getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this);
 	getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 
-	info = new LLGiveMoneyInfo(this, 0);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, 0));
 	mCallbackData.push_back(info);
 
-	childSetAction("pay btn",&LLFloaterPay::onGive,info);
+	childSetAction("pay btn", boost::bind(LLFloaterPay::onGive, info));
 	setDefaultBtn("pay btn");
 	getChildView("pay btn")->setVisible(FALSE);
 	getChildView("pay btn")->setEnabled(FALSE);
@@ -415,9 +421,9 @@ void LLFloaterPay::payDirectly(money_callback callback,
 	floater->finishPayUI(target_id, is_group);
 }
 
-bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, LLGiveMoneyInfo* info)
+bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, give_money_ptr info)
 {
-	if (!info || !info->mFloater)
+	if (!info.get() || !info->mFloater)
 	{
 		return false;
 	}
@@ -479,54 +485,61 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
 }
 
 // static
-void LLFloaterPay::onGive(void* data)
+void LLFloaterPay::onGive(give_money_ptr info)
 {
-	LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
-	LLFloaterPay* floater = info->mFloater;
-	if(info && floater)
-	{
-		S32 amount = info->mAmount;
-		if(amount == 0)
-		{
-			amount = atoi(floater->getChild<LLUICtrl>("amount")->getValue().asString().c_str());
-		}
-		if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
-		{
-			LLUUID payee_id = LLUUID::null;
-			BOOL is_group = false;
-			if (floater->mObjectSelection.notNull())
-			{
-				LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
-				if (node)
-				{
-					node->mPermissions->getOwnership(payee_id, is_group);
-				}
-				else
-				{
-					// object no longer exists
-					LLNotificationsUtil::add("PayObjectFailed");
-					floater->closeFloater();
-					return;
-				}
-			}
-			else
-			{
-				is_group = floater->mTargetIsGroup;
-				payee_id = floater->mTargetUUID;
-			}
-
-			LLSD args;
-			args["TARGET"] = LLSLURL( is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
-			args["AMOUNT"] = amount;
-
-			LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
-		}
-		else
-		{
-			floater->give(amount);
-			floater->closeFloater();
-		}
-	}
+    if (!info.get() || !info->mFloater)
+    {
+        return;
+    }
+
+    LLFloaterPay* floater = info->mFloater;
+    S32 amount = info->mAmount;
+    if (amount == 0)
+    {
+        LLUICtrl* text_field = floater->getChild<LLUICtrl>("amount");
+        if (!text_field)
+        {
+            return;
+        }
+        amount = atoi(text_field->getValue().asString().c_str());
+    }
+
+    if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
+    {
+        LLUUID payee_id = LLUUID::null;
+        BOOL is_group = false;
+        if (floater->mObjectSelection.notNull())
+        {
+            LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
+            if (node)
+            {
+                node->mPermissions->getOwnership(payee_id, is_group);
+            }
+            else
+            {
+                // object no longer exists
+                LLNotificationsUtil::add("PayObjectFailed");
+                floater->closeFloater();
+                return;
+            }
+        }
+        else
+        {
+            is_group = floater->mTargetIsGroup;
+            payee_id = floater->mTargetUUID;
+        }
+
+        LLSD args;
+        args["TARGET"] = LLSLURL(is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
+        args["AMOUNT"] = amount;
+
+        LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
+    }
+    else
+    {
+        floater->give(amount);
+        floater->closeFloater();
+    }
 }
 
 void LLFloaterPay::give(S32 amount)
-- 
cgit v1.2.3


From c4e9fe9fe5e19e6862909a0bb3c086e210871a21 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 25 Aug 2016 15:40:33 +0300
Subject: MAINT-6636 Mesh upload was failing from a folder with a diacritic
 character in the name

---
 doc/contributions.txt             | 1 +
 indra/llprimitive/lldaeloader.cpp | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index b3d1c2432d..917fcf14f6 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -200,6 +200,7 @@ Ansariel Hiller
 	MAINT-6511
 	MAINT-6612
 	MAINT-6637
+	MAINT-6636
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 00bde8dbc3..8071d716da 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1071,7 +1071,7 @@ bool LLDAELoader::OpenFile(const std::string& filename)
 std::string LLDAELoader::preprocessDAE(std::string filename)
 {
 	// Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678
-	std::ifstream inFile;
+	llifstream inFile;
 	inFile.open(filename.c_str(), std::ios_base::in);
 	std::stringstream strStream;
 	strStream << inFile.rdbuf();
-- 
cgit v1.2.3


From 1b8f2f1db9c86516f7c149031f9b67764868d100 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 25 Aug 2016 17:12:05 +0300
Subject: MAINT-6657 Media navigation bar beyond the window border

---
 indra/newview/skins/default/xui/de/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/es/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/fr/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/it/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/ja/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/pt/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/ru/panel_status_bar.xml | 2 +-
 indra/newview/skins/default/xui/tr/panel_status_bar.xml | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index d3d85de3c3..b0cb1e0592 100644
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-415" name="balance_bg" width="205">
+	<panel left="-436" name="balance_bg" width="205">
 		<text name="balance" tool_tip="Klicken, um L$-Guthaben zu aktualisieren" value="L$ ??"/>
 		<button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/>
 		<button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen" width="85"/>
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index 8ea56c5262..8aaa236475 100644
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-410" name="balance_bg" width="200">
+	<panel left="-431" name="balance_bg" width="200">
 		<text name="balance" tool_tip="Haz clic para actualizar tu saldo en L$" value="L$??"/>
 		<button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/>
 		<button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index e2f05a525e..fef0379c2c 100644
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt] [sday, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-405" name="balance_bg" width="195">
+	<panel left="-426" name="balance_bg" width="195">
 		<text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="L$ ??"/>
 		<button label="Acheter L$" name="buyL" tool_tip="Cliquer pour acheter plus de L$."/>
 		<button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life." width="75"/>
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index 83d2ae5bab..295ca8d9f2 100644
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-405" name="balance_bg" width="195">
+	<panel left="-426" name="balance_bg" width="195">
 		<text name="balance" tool_tip="Clicca per aggiornare il tuo saldo in L$" value="L$ ??"/>
 		<button label="Acquista L$" name="buyL" tool_tip="Clicca per acquistare più L$"/>
 		<button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life" width="75"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 2e1446d450..3f3845e491 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[year, datetime, slt] [month, datetime, slt] [day, datetime, slt] ([weekday, datetime, slt])</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-370" name="balance_bg" width="160">
+	<panel left="-391" name="balance_bg" width="160">
 		<text name="balance" tool_tip="クリックして L$ 残高を更新" value="L$??"/>
 		<button label="L$ の購入" name="buyL" tool_tip="クリックして L$ を購入します"/>
 		<button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開く" width="40"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index cfe52ff404..c35863734f 100644
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-410" name="balance_bg" width="200">
+	<panel left="-431" name="balance_bg" width="200">
 		<text name="balance" tool_tip="Atualizar saldo de L$" value="L$??"/>
 		<button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/>
 		<button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
index 630925fa60..49c48ae654 100644
--- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour, datetime, slt]:[min, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-450" name="balance_bg" width="240">
+	<panel left="-471" name="balance_bg" width="240">
 		<text name="balance" tool_tip="Щелкните для обновления вашего баланса L$" value="L$??"/>
 		<button label="Купить L$" name="buyL" tool_tip="Щелкните для покупки L$"/>
 		<button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life" width="121"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
index 9e2669ec2b..7c7bfc7e14 100644
--- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-425" name="balance_bg" width="215">
+	<panel left="-446" name="balance_bg" width="215">
 		<text name="balance" tool_tip="L$ bakiyenizi yenilemek için buraya tıklayın" value="L$??"/>
 		<button label="L$ Satın Al" name="buyL" tool_tip="Daha fazla L$ satın almak için tıklayın"/>
 		<button label="Alışveriş yap" name="goShop" tool_tip="Second Life Pazaryeri Aç" width="95"/>
-- 
cgit v1.2.3


From 7ea2f091a69794ce4aa121968175f69d88f0e644 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Thu, 25 Aug 2016 17:33:54 +0300
Subject: MAINT-6511 Buildfix

---
 indra/llui/llfloater.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index b3048a9b16..93ee1ceee3 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2320,7 +2320,7 @@ void LLFloaterView::restoreAll()
 	// make sure all subwindows aren't minimized
 	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
 	{
-		LLFloater* floaterp = nullptr;
+		LLFloater* floaterp = NULL;
 		try
 		{
 			floaterp = dynamic_cast<LLFloater*>(*child_it);
-- 
cgit v1.2.3


From 93617deff787be7a34a3ecd5a06a8aa95ed19b1b Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 26 Aug 2016 11:35:47 +0300
Subject: MAINT-6676 FIXED Viewer crashes when clicking "Default creation
 permissions" before logging in.

---
 indra/newview/llfloaterpreference.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 20d8119606..75f5e87a2b 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1232,6 +1232,9 @@ void LLFloaterPreference::refreshEnabledState()
 						(ctrl_wind_light->get()) ? TRUE : FALSE;
 
 	ctrl_deferred->setEnabled(enabled);
+
+	// Cannot have floater active until caps have been received
+	getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
 }
 
 void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
@@ -1369,9 +1372,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 	disableUnavailableSettings();
 
 	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
-
-	// Cannot have floater active until caps have been received
-	getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
 }
 
 // static
-- 
cgit v1.2.3


From d6b0db5118788106087ec2e5743fd10110fdb470 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 26 Aug 2016 17:02:32 +0300
Subject: MAINT-6665 [Contribution] Viewer crashes when setting a local texture
 from a path containing non-standard characters

---
 doc/contributions.txt            | 1 +
 indra/newview/lllocalbitmaps.cpp | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 917fcf14f6..05fb19aaf0 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1030,6 +1030,7 @@ Nicky Dasmijn
 	OPEN-187
     STORM-2010
 	STORM-2082
+	MAINT-6665
 Nicky Perian
 	OPEN-1
 	STORM-1087
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index aa934f95a1..a55938f334 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -181,7 +181,12 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
 		if (gDirUtilp->fileExists(mFilename))
 		{
 			// verifying that the file has indeed been modified
+
+#ifndef LL_WINDOWS
 			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+#else
+			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename)));
+#endif
 			LLSD new_last_modified = asctime(localtime(&temp_time));
 
 			if (mLastModified.asString() != new_last_modified.asString())
-- 
cgit v1.2.3


From db230ec3ac9761600e83322fb890342de3e38981 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 29 Aug 2016 11:15:54 +0300
Subject: MAINT-1768 Previous changes are reverted. Sharing items from trash is
 disabled now.

---
 indra/newview/llavataractions.cpp   | 11 +++++++++--
 indra/newview/llgiveinventory.cpp   |  4 ++--
 indra/newview/llinventorybridge.cpp |  6 ++++++
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index a6e745448a..7b8c630837 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -950,15 +950,22 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
 	if (inventory_selected.empty()) return false; // nothing selected
 
+	const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 	bool can_share = true;
 	std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
 	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
-		// any category can be offered.
+		LLUUID cat_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(cat_id);
+		// any category can be offered if it's not in trash.
 		if (inv_cat)
 		{
+			if ((cat_id == trash_id) || gInventory.isObjectDescendentOf(cat_id, trash_id))
+			{
+				can_share = false;
+				break;
+			}
 			continue;
 		}
 
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 97cc7684e4..a9bf8a9a50 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -248,7 +248,7 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
 	gInventory.collectDescendentsIf (cat->getUUID(),
 		cats,
 		items,
-		LLInventoryModel::INCLUDE_TRASH,
+		LLInventoryModel::EXCLUDE_TRASH,
 		giveable);
 	S32 count = cats.size();
 	bool complete = true;
@@ -499,7 +499,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 	gInventory.collectDescendentsIf (cat->getUUID(),
 		cats,
 		items,
-		LLInventoryModel::INCLUDE_TRASH,
+		LLInventoryModel::EXCLUDE_TRASH,
 		giveable);
 
 	bool give_successful = true;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 8d130c08e5..50fcf372a9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1398,6 +1398,12 @@ bool LLInvFVBridge::canShare() const
 				// Categories can be given.
 				can_share = (model->getCategory(mUUID) != NULL);
 			}
+
+			const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+			if ((mUUID == trash_id) || gInventory.isObjectDescendentOf(mUUID, trash_id))
+			{
+				can_share = false;
+			}
 		}
 	}
 
-- 
cgit v1.2.3


From f73b0ecd106c86eb71d27003f5b7e69322214f0a Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 26 Aug 2016 17:56:59 +0300
Subject: MAINT-6658 Profile was opening app url in browser.

---
 indra/newview/llmediactrl.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 9cf3249983..00043d1e72 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1007,7 +1007,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			std::string uuid = self->getClickUUID();
 			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL;
 
-			LLWeb::loadURL(url, target, std::string());
+			// try as slurl first
+			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
+			{
+				LLWeb::loadURL(url, target, std::string());
+			}
 
 			// CP: removing this code because we no longer support popups so this breaks the flow.
 			//     replaced with a bare call to LLWeb::LoadURL(...)
-- 
cgit v1.2.3


From d53ec6c2df414565284c5236c7ff4aee62f9a266 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 30 Aug 2016 16:41:28 +0300
Subject: MAINT-6682 Viewer crashes when deleting notecards one by one

---
 indra/newview/skins/default/xui/en/notifications.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 8e51aca516..864832062a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1483,6 +1483,7 @@ Save Changes?
    icon="alertmodal.tga"
    name="DeleteNotecard"
    type="alertmodal">
+   <unique/>
 Delete Notecard?
     <tag>confirm</tag>
     <usetemplate
-- 
cgit v1.2.3


From a00165aad438f69062c3f6e4533c1f16bf8ecf3c Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 30 Aug 2016 20:13:45 +0300
Subject: MAINT-6683 fixed wrapping issues of notecard embedded items

---
 indra/llrender/llfontgl.cpp | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 0e2946632a..cf0a117567 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -364,12 +364,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
 
 	if (right_x)
 	{
-        F32 cr_x = (cur_x - origin.mV[VX]) / sScaleX;
-        if (*right_x < cr_x)
-        {
-            // rightmost edge of previously drawn text, don't draw over previous text
-            *right_x = cr_x;
-        }
+		*right_x = (cur_x - origin.mV[VX]) / sScaleX;
 	}
 
 	//FIXME: add underline as glyph?
-- 
cgit v1.2.3


From ac1f29a73c8cdaa5bd7bdc47fd4d2157a879f304 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 31 Aug 2016 23:42:24 +0300
Subject: MAINT-6386 Update first-time Viewer Login screen with new LISI
 screenshots

---
 .../textures/windows/first_login_image_left.png    | Bin 311306 -> 384997 bytes
 .../textures/windows/first_login_image_right.png   | Bin 329170 -> 340188 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png
index b405a88245..1fa10fde53 100644
Binary files a/indra/newview/skins/default/textures/windows/first_login_image_left.png and b/indra/newview/skins/default/textures/windows/first_login_image_left.png differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png
index 22a6dd8a53..d764d846b7 100644
Binary files a/indra/newview/skins/default/textures/windows/first_login_image_right.png and b/indra/newview/skins/default/textures/windows/first_login_image_right.png differ
-- 
cgit v1.2.3


From 81b683f83b759e78d1e0b598e412d86991791d39 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 1 Sep 2016 16:40:41 +0300
Subject: MAINT-6686 FIXED [VOB] Outfit Snapshot floater should be resized
 independently of general Snapshot floater

---
 indra/newview/app_settings/settings.xml             | 11 +++++++++++
 indra/newview/llfloateroutfitsnapshot.cpp           |  9 +++++++++
 indra/newview/llfloateroutfitsnapshot.h             |  2 ++
 indra/newview/llfloatersnapshot.cpp                 | 21 ++++++++++++++-------
 indra/newview/llfloatersnapshot.h                   |  5 +++++
 .../default/xui/en/floater_outfit_snapshot.xml      |  8 ++++----
 6 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 64e4bd2074..2d3c885522 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -137,6 +137,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>AdvanceOutfitSnapshot</key>
+    <map>
+      <key>Comment</key>
+      <string>Display advanced parameter settings in outfit snaphot interface</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>AgentPause</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index ca5a2fdad5..d80793f9e4 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -246,6 +246,8 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
     getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
     childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
 
+    getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
+    getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
 
     // Filters
     LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
@@ -277,6 +279,7 @@ BOOL LLFloaterOutfitSnapshot::postBuild()
     impl->mPreviewHandle = previewp->getHandle();
     previewp->setContainer(this);
     impl->updateControls(this);
+    impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
     impl->updateLayout(this);
 
     previewp->mKeepAspectRatio = FALSE;
@@ -300,6 +303,7 @@ void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
     gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
 
     impl->updateControls(this);
+    impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
     impl->updateLayout(this);
 
     LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory");
@@ -308,6 +312,11 @@ void LLFloaterOutfitSnapshot::onOpen(const LLSD& key)
 
 }
 
+void LLFloaterOutfitSnapshot::onExtendFloater()
+{
+	impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot"));
+}
+
 // static 
 void LLFloaterOutfitSnapshot::update()
 {
diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h
index 04623acf0f..bee386ec63 100644
--- a/indra/newview/llfloateroutfitsnapshot.h
+++ b/indra/newview/llfloateroutfitsnapshot.h
@@ -50,6 +50,8 @@ public:
 
     static void update();
 
+    void onExtendFloater();
+
     static LLFloaterOutfitSnapshot* getInstance();
     static LLFloaterOutfitSnapshot* findInstance();
     /*virtual*/ void saveTexture();
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index f6d20c84d0..664668f2f7 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -158,8 +158,6 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
 {
 	LLSnapshotLivePreview* previewp = getPreviewView();
 
-	BOOL advanced = gSavedSettings.getBOOL("AdvanceSnapshot");
-
 	//BD - Automatically calculate the size of our snapshot window to enlarge
 	//     the snapshot preview to its maximum size, this is especially helpfull
 	//     for pretty much every aspect ratio other than 1:1.
@@ -175,16 +173,16 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
 	}
 
 	S32 floater_width = 224.f;
-	if(advanced)
+	if(mAdvanced)
 	{
 		floater_width = floater_width + panel_width;
 	}
 
 	LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder");
-	thumbnail_placeholder->setVisible(advanced);
+	thumbnail_placeholder->setVisible(mAdvanced);
 	thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
-	floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(advanced);
-	floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(advanced);
+	floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced);
+	floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced);
 	if(!floaterp->isMinimized())
 	{
 		floaterp->reshape(floater_width, floaterp->getRect().getHeight());
@@ -996,7 +994,9 @@ BOOL LLFloaterSnapshot::postBuild()
 
 	getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
 	childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
-    
+
+    getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
+    getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterSnapshot::onExtendFloater, this));
 
 	// Filters
 	LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
@@ -1038,6 +1038,7 @@ BOOL LLFloaterSnapshot::postBuild()
 	impl->mPreviewHandle = previewp->getHandle();
     previewp->setContainer(this);
 	impl->updateControls(this);
+	impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot"));
 	impl->updateLayout(this);
 	
 
@@ -1110,12 +1111,18 @@ void LLFloaterSnapshot::onOpen(const LLSD& key)
 	gSnapshotFloaterView->adjustToFitScreen(this, FALSE);
 
 	impl->updateControls(this);
+	impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot"));
 	impl->updateLayout(this);
 
 	// Initialize default tab.
 	getChild<LLSideTrayPanelContainer>("panel_container")->getCurrentPanel()->onOpen(LLSD());
 }
 
+void LLFloaterSnapshot::onExtendFloater()
+{
+	impl->setAdvanced(gSavedSettings.getBOOL("AdvanceSnapshot"));
+}
+
 //virtual
 void LLFloaterSnapshotBase::onClose(bool app_quitting)
 {
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 44f77a92ec..4bcfa674fa 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -116,6 +116,8 @@ public:
 	virtual EStatus getStatus() const { return mStatus; }
 	virtual void setNeedRefresh(bool need);
 
+	void setAdvanced(bool advanced) { mAdvanced = advanced; }
+
 	virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
 	virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
 	void setWorking(bool working);
@@ -129,6 +131,7 @@ public:
 	LLHandle<LLView> mPreviewHandle;
 	bool mAspectRatioCheckOff;
 	bool mNeedRefresh;
+	bool mAdvanced;
 	EStatus mStatus;
 };
 
@@ -146,6 +149,8 @@ public:
 	
 	static void update();
 
+	void onExtendFloater();
+
 	static LLFloaterSnapshot* getInstance();
 	static LLFloaterSnapshot* findInstance();
 	/*virtual*/ void saveTexture();
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
index 5941471907..15c480f144 100644
--- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
+++ b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml
@@ -50,8 +50,8 @@
      width="167" />
 	<button
        follows="left|top"
-	   control_name="AdvanceSnapshot"
-	   invisibility_control="AdvanceSnapshot"
+	   control_name="AdvanceOutfitSnapshot"
+	   invisibility_control="AdvanceOutfitSnapshot"
        height="25"
 	   is_toggle="true"
        layout="topleft"
@@ -65,8 +65,8 @@
        width="31" />
    <button
        follows="left|top"
-	   control_name="AdvanceSnapshot"
-	   visibility_control="AdvanceSnapshot"
+	   control_name="AdvanceOutfitSnapshot"
+	   visibility_control="AdvanceOutfitSnapshot"
        height="25"
 	   is_toggle="true"
        layout="topleft"
-- 
cgit v1.2.3


From 9acf7f5733063ff735ad37d456e740211c191cc9 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 1 Sep 2016 19:11:44 +0300
Subject: MAINT-6221 If two animations have the same priority, it's arbitrary
 which one will take precedence

---
 indra/llcharacter/llpose.cpp | 13 ++++++++-----
 indra/llcharacter/llpose.h   |  3 ++-
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index b1a7ebb159..c430a73f6b 100644
--- a/indra/llcharacter/llpose.cpp
+++ b/indra/llcharacter/llpose.cpp
@@ -195,7 +195,7 @@ LLJointStateBlender::~LLJointStateBlender()
 //-----------------------------------------------------------------------------
 // addJointState()
 //-----------------------------------------------------------------------------
-BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend)
+BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, LLUUID source_id, S32 priority, BOOL additive_blend)
 {
 	llassert(joint_state);
 
@@ -210,23 +210,26 @@ BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_sta
 			mJointStates[i] = joint_state;
 			mPriorities[i] = priority;
 			mAdditiveBlends[i] = additive_blend;
+			mMoutionIds[i] = source_id;
 			return TRUE;
 		} 
-		else if (priority > mPriorities[i])
+		else if (priority > mPriorities[i] || (priority == mPriorities[i] && source_id > mMoutionIds[i]))
 		{
 			// we're at a higher priority than the current joint state in this slot
 			// so shift everyone over
-			// previous joint states (newer motions) with same priority should stay in place
+			// previous joint states (newer motions) with same priority and source motion should stay in place
 			for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--)
 			{
 				mJointStates[j] = mJointStates[j - 1];
 				mPriorities[j] = mPriorities[j - 1];
 				mAdditiveBlends[j] = mAdditiveBlends[j - 1];
+				mMoutionIds[j] = mMoutionIds[j - 1];
 			}
 			// now store ourselves in this slot
 			mJointStates[i] = joint_state;
 			mPriorities[i] = priority;
 			mAdditiveBlends[i] = additive_blend;
+			mMoutionIds[i] = source_id;
 			return TRUE;
 		}
 	}
@@ -489,11 +492,11 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion)
 
 		if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY)
 		{
-			joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
+			joint_blender->addJointState(jsp, motion->getID(), motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
 		}
 		else
 		{
-			joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
+			joint_blender->addJointState(jsp, motion->getID(), jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
 		}
 
 		// add it to our list of active blenders
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index c004a0f3b7..28f560ed9f 100644
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
@@ -85,12 +85,13 @@ class LLJointStateBlender
 protected:
 	LLPointer<LLJointState>	mJointStates[JSB_NUM_JOINT_STATES];
 	S32				mPriorities[JSB_NUM_JOINT_STATES];
+	LLUUID			mMoutionIds[JSB_NUM_JOINT_STATES];
 	BOOL			mAdditiveBlends[JSB_NUM_JOINT_STATES];
 public:
 	LLJointStateBlender();
 	~LLJointStateBlender();
 	void blendJointStates(BOOL apply_now = TRUE);
-	BOOL addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend);
+	BOOL addJointState(const LLPointer<LLJointState>& joint_state, LLUUID source_id, S32 priority, BOOL additive_blend);
 	void interpolate(F32 u);
 	void clear();
 	void resetCachedJoint();
-- 
cgit v1.2.3


From 9e73d04811f65006198297f527d38f1c6262bdce Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 2 Sep 2016 19:20:31 +0300
Subject: MAINT-6461 crash due to invalid menu pointer during visibility change

---
 indra/llui/llfloater.cpp               | 15 +++----------
 indra/newview/llpanelmaininventory.cpp | 39 +++++++++++++++++++++++-----------
 indra/newview/llpanelmaininventory.h   |  2 +-
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 93ee1ceee3..4f664a1ccc 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2318,19 +2318,10 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
 void LLFloaterView::restoreAll()
 {
 	// make sure all subwindows aren't minimized
-	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+	child_list_t child_list = *(getChildList());
+	for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it)
 	{
-		LLFloater* floaterp = NULL;
-		try
-		{
-			floaterp = dynamic_cast<LLFloater*>(*child_it);
-		}
-		catch (std::exception e) // See MAINT-6511
-		{
-			LL_WARNS() << "Caught exception: " << e.what() << LL_ENDL;
-			continue;
-		}
-
+		LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
 		if (floaterp)
 		{
 			floaterp->setMinimized(FALSE);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c779ba5cdd..eb40616a9c 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -106,7 +106,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
 	  mSavedFolderState(NULL),
 	  mFilterText(""),
 	  mMenuGearDefault(NULL),
-	  mMenuAdd(NULL),
+	  mMenuAddHandle(),
 	  mNeedUploadCost(true)
 {
 	// Menu Callbacks (non contex menus)
@@ -200,10 +200,15 @@ BOOL LLPanelMainInventory::postBuild()
 
 	// *TODO:Get the cost info from the server
 	const std::string upload_cost("10");
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
+
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if (menu)
+	{
+		menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
+	}
 
 	// Trigger callback for focus received so we can deselect items in inbox/outbox
 	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
@@ -983,7 +988,8 @@ void LLPanelMainInventory::initListCommandsHandlers()
 	mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
 	mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	mGearMenuButton->setMenu(mMenuGearDefault);
-	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	mMenuAddHandle = menu->getHandle();
 
 	// Update the trash button when selected item(s) get worn or taken off.
 	LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
@@ -1001,11 +1007,15 @@ void LLPanelMainInventory::onAddButtonClick()
 // Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
 // unless "Always show folders" is checked in the filter options.
 	bool recent_active = ("Recent Items" == mActivePanel->getName());
-	mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if (menu)
+	{
+		menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
 
-	setUploadCostIfNeeded();
+		setUploadCostIfNeeded();
 
-	showActionMenu(mMenuAdd,"add_btn");
+		showActionMenu(menu,"add_btn");
+	}
 }
 
 void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
@@ -1156,7 +1166,11 @@ void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
 {
 	if(!new_visibility)
 	{
-		mMenuAdd->setVisible(FALSE);
+		LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+		if (menu)
+		{
+			menu->setVisible(FALSE);
+		}
 		getActivePanel()->getRootFolder()->finishRenamingItem();
 	}
 }
@@ -1289,9 +1303,10 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
 	// have two instances of Inventory panel at the moment(and two instances of context menu),
 	// call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances.
 
-	if(mNeedUploadCost && mMenuAdd)
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if(mNeedUploadCost && menu)
 	{
-		LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild<LLMenuItemBranchGL>("upload");
+		LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload");
 		if(upload_menu)
 		{
 			S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 290e2e5f47..efa18b42c1 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -156,8 +156,8 @@ protected:
 private:
 	LLDragAndDropButton*		mTrashButton;
 	LLToggleableMenu*			mMenuGearDefault;
-	LLMenuGL*					mMenuAdd;
 	LLMenuButton*				mGearMenuButton;
+	LLHandle<LLView>			mMenuAddHandle;
 
 	bool						mNeedUploadCost;
 	// List Commands                                                              //
-- 
cgit v1.2.3


From 74ec1116a22f325d0c726c109e0664fda566a7a6 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 2 Sep 2016 19:20:31 +0300
Subject: MAINT-6461 crash due to invalid menu pointer during visibility change

---
 indra/llui/llfloater.cpp               | 15 +++----------
 indra/newview/llpanelmaininventory.cpp | 39 +++++++++++++++++++++++-----------
 indra/newview/llpanelmaininventory.h   |  2 +-
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 93ee1ceee3..4f664a1ccc 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2318,19 +2318,10 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
 void LLFloaterView::restoreAll()
 {
 	// make sure all subwindows aren't minimized
-	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+	child_list_t child_list = *(getChildList());
+	for (child_list_const_iter_t child_it = child_list.begin(); child_it != child_list.end(); ++child_it)
 	{
-		LLFloater* floaterp = NULL;
-		try
-		{
-			floaterp = dynamic_cast<LLFloater*>(*child_it);
-		}
-		catch (std::exception e) // See MAINT-6511
-		{
-			LL_WARNS() << "Caught exception: " << e.what() << LL_ENDL;
-			continue;
-		}
-
+		LLFloater* floaterp = dynamic_cast<LLFloater*>(*child_it);
 		if (floaterp)
 		{
 			floaterp->setMinimized(FALSE);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c779ba5cdd..eb40616a9c 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -106,7 +106,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
 	  mSavedFolderState(NULL),
 	  mFilterText(""),
 	  mMenuGearDefault(NULL),
-	  mMenuAdd(NULL),
+	  mMenuAddHandle(),
 	  mNeedUploadCost(true)
 {
 	// Menu Callbacks (non contex menus)
@@ -200,10 +200,15 @@ BOOL LLPanelMainInventory::postBuild()
 
 	// *TODO:Get the cost info from the server
 	const std::string upload_cost("10");
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
-	mMenuAdd->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
+
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if (menu)
+	{
+		menu->getChild<LLMenuItemGL>("Upload Image")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Upload Sound")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Upload Animation")->setLabelArg("[COST]", upload_cost);
+		menu->getChild<LLMenuItemGL>("Bulk Upload")->setLabelArg("[COST]", upload_cost);
+	}
 
 	// Trigger callback for focus received so we can deselect items in inbox/outbox
 	LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLPanelMainInventory::onFocusReceived, this));
@@ -983,7 +988,8 @@ void LLPanelMainInventory::initListCommandsHandlers()
 	mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
 	mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	mGearMenuButton->setMenu(mMenuGearDefault);
-	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	mMenuAddHandle = menu->getHandle();
 
 	// Update the trash button when selected item(s) get worn or taken off.
 	LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
@@ -1001,11 +1007,15 @@ void LLPanelMainInventory::onAddButtonClick()
 // Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed
 // unless "Always show folders" is checked in the filter options.
 	bool recent_active = ("Recent Items" == mActivePanel->getName());
-	mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if (menu)
+	{
+		menu->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active);
 
-	setUploadCostIfNeeded();
+		setUploadCostIfNeeded();
 
-	showActionMenu(mMenuAdd,"add_btn");
+		showActionMenu(menu,"add_btn");
+	}
 }
 
 void LLPanelMainInventory::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
@@ -1156,7 +1166,11 @@ void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
 {
 	if(!new_visibility)
 	{
-		mMenuAdd->setVisible(FALSE);
+		LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+		if (menu)
+		{
+			menu->setVisible(FALSE);
+		}
 		getActivePanel()->getRootFolder()->finishRenamingItem();
 	}
 }
@@ -1289,9 +1303,10 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
 	// have two instances of Inventory panel at the moment(and two instances of context menu),
 	// call to gMenuHolder->childSetLabelArg() sets upload cost only for one of the instances.
 
-	if(mNeedUploadCost && mMenuAdd)
+	LLMenuGL* menu = (LLMenuGL*)mMenuAddHandle.get();
+	if(mNeedUploadCost && menu)
 	{
-		LLMenuItemBranchGL* upload_menu = mMenuAdd->findChild<LLMenuItemBranchGL>("upload");
+		LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload");
 		if(upload_menu)
 		{
 			S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 290e2e5f47..efa18b42c1 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -156,8 +156,8 @@ protected:
 private:
 	LLDragAndDropButton*		mTrashButton;
 	LLToggleableMenu*			mMenuGearDefault;
-	LLMenuGL*					mMenuAdd;
 	LLMenuButton*				mGearMenuButton;
+	LLHandle<LLView>			mMenuAddHandle;
 
 	bool						mNeedUploadCost;
 	// List Commands                                                              //
-- 
cgit v1.2.3


From ecd11724ca97a385bb04d2eb71eaf06c556791fa Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 5 Sep 2016 15:43:31 +0300
Subject: Backed out changeset: d3ffc46e9e92

---
 indra/llcharacter/llpose.cpp | 13 +++++--------
 indra/llcharacter/llpose.h   |  3 +--
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index c430a73f6b..b1a7ebb159 100644
--- a/indra/llcharacter/llpose.cpp
+++ b/indra/llcharacter/llpose.cpp
@@ -195,7 +195,7 @@ LLJointStateBlender::~LLJointStateBlender()
 //-----------------------------------------------------------------------------
 // addJointState()
 //-----------------------------------------------------------------------------
-BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, LLUUID source_id, S32 priority, BOOL additive_blend)
+BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend)
 {
 	llassert(joint_state);
 
@@ -210,26 +210,23 @@ BOOL LLJointStateBlender::addJointState(const LLPointer<LLJointState>& joint_sta
 			mJointStates[i] = joint_state;
 			mPriorities[i] = priority;
 			mAdditiveBlends[i] = additive_blend;
-			mMoutionIds[i] = source_id;
 			return TRUE;
 		} 
-		else if (priority > mPriorities[i] || (priority == mPriorities[i] && source_id > mMoutionIds[i]))
+		else if (priority > mPriorities[i])
 		{
 			// we're at a higher priority than the current joint state in this slot
 			// so shift everyone over
-			// previous joint states (newer motions) with same priority and source motion should stay in place
+			// previous joint states (newer motions) with same priority should stay in place
 			for (S32 j = JSB_NUM_JOINT_STATES - 1; j > i; j--)
 			{
 				mJointStates[j] = mJointStates[j - 1];
 				mPriorities[j] = mPriorities[j - 1];
 				mAdditiveBlends[j] = mAdditiveBlends[j - 1];
-				mMoutionIds[j] = mMoutionIds[j - 1];
 			}
 			// now store ourselves in this slot
 			mJointStates[i] = joint_state;
 			mPriorities[i] = priority;
 			mAdditiveBlends[i] = additive_blend;
-			mMoutionIds[i] = source_id;
 			return TRUE;
 		}
 	}
@@ -492,11 +489,11 @@ BOOL LLPoseBlender::addMotion(LLMotion* motion)
 
 		if (jsp->getPriority() == LLJoint::USE_MOTION_PRIORITY)
 		{
-			joint_blender->addJointState(jsp, motion->getID(), motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
+			joint_blender->addJointState(jsp, motion->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
 		}
 		else
 		{
-			joint_blender->addJointState(jsp, motion->getID(), jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
+			joint_blender->addJointState(jsp, jsp->getPriority(), motion->getBlendType() == LLMotion::ADDITIVE_BLEND);
 		}
 
 		// add it to our list of active blenders
diff --git a/indra/llcharacter/llpose.h b/indra/llcharacter/llpose.h
index 28f560ed9f..c004a0f3b7 100644
--- a/indra/llcharacter/llpose.h
+++ b/indra/llcharacter/llpose.h
@@ -85,13 +85,12 @@ class LLJointStateBlender
 protected:
 	LLPointer<LLJointState>	mJointStates[JSB_NUM_JOINT_STATES];
 	S32				mPriorities[JSB_NUM_JOINT_STATES];
-	LLUUID			mMoutionIds[JSB_NUM_JOINT_STATES];
 	BOOL			mAdditiveBlends[JSB_NUM_JOINT_STATES];
 public:
 	LLJointStateBlender();
 	~LLJointStateBlender();
 	void blendJointStates(BOOL apply_now = TRUE);
-	BOOL addJointState(const LLPointer<LLJointState>& joint_state, LLUUID source_id, S32 priority, BOOL additive_blend);
+	BOOL addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend);
 	void interpolate(F32 u);
 	void clear();
 	void resetCachedJoint();
-- 
cgit v1.2.3


From fc17f62335d728e79bf9f18f76482fa3bf45b34e Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 5 Sep 2016 17:32:50 +0300
Subject: MAINT-6685 [VOB] Outfit Image from an Outfit Gallery disappears after
 editing outfit

---
 indra/newview/llappearancemgr.cpp | 24 +++++++++++++++++++++++-
 indra/newview/llappearancemgr.h   |  5 +++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0ea206186c..1f8adbcb95 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3113,6 +3113,14 @@ void appearance_mgr_update_dirty_state()
 {
 	if (LLAppearanceMgr::instanceExists())
 	{
+		LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
+		LLUUID image_id = app_mgr.getOutfitImage();
+		if(image_id.notNull())
+		{
+			LLPointer<LLInventoryCallback> cb = NULL;
+			link_inventory_object(app_mgr.getBaseOutfitUUID(), image_id, cb);
+		}
+
 		LLAppearanceMgr::getInstance()->updateIsDirty();
 		LLAppearanceMgr::getInstance()->setOutfitLocked(false);
 		gAgentWearables.notifyLoadingFinished();
@@ -3122,7 +3130,21 @@ void appearance_mgr_update_dirty_state()
 void update_base_outfit_after_ordering()
 {
 	LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
-	
+	LLInventoryModel::cat_array_t sub_cat_array;
+	LLInventoryModel::item_array_t outfit_item_array;
+	gInventory.collectDescendents(app_mgr.getBaseOutfitUUID(),
+								sub_cat_array,
+								outfit_item_array,
+								LLInventoryModel::EXCLUDE_TRASH);
+	BOOST_FOREACH(LLViewerInventoryItem* outfit_item, outfit_item_array)
+	{
+		LLViewerInventoryItem* linked_item = outfit_item->getLinkedItem();
+		if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+		{
+			app_mgr.setOutfitImage(linked_item->getLinkedUUID());
+		}
+	}
+
 	LLPointer<LLInventoryCallback> dirty_state_updater =
 		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
 
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 7dbb86d7f2..2e570b9188 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -185,6 +185,9 @@ public:
 	
 	void wearBaseOutfit();
 
+	void setOutfitImage(const LLUUID& image_id) {mCOFImageID = image_id;}
+	LLUUID getOutfitImage() {return mCOFImageID;}
+
 	// Overrides the base outfit with the content from COF
 	// @return false if there is no base outfit
 	bool updateBaseOutfit();
@@ -269,6 +272,8 @@ private:
 	LLTimer mInFlightTimer;
 	static bool mActive;
 
+	LLUUID mCOFImageID;
+
 	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
 
 	// Set of temp attachment UUIDs that should be removed
-- 
cgit v1.2.3


From 4a9d6cd69f6e9291c26a389e6a2eeeb140835007 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 5 Sep 2016 19:31:42 +0300
Subject: MAINT-6697 make sure we have data to process

---
 indra/newview/llmeshrepository.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9577b3ab50..f9461e3132 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1753,6 +1753,11 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
 
 bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
 {
+	if (data == NULL || data_size == 0)
+	{
+		return false;
+	}
+
 	LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
 	std::string mesh_string((char*) data, data_size);
 	std::istringstream stream(mesh_string);
-- 
cgit v1.2.3


From ec9b92d274b6fb0d8d14ed88010835a5feab2a07 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 6 Sep 2016 14:07:20 +0300
Subject: MAINT-6698 [VOB] "Save" button is always enabled for outfit with
 non-default image even if there were no changes

---
 indra/newview/llappearancemgr.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 1f8adbcb95..ff5439d610 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2966,6 +2966,16 @@ void LLAppearanceMgr::updateIsDirty()
 		gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items,
 									  LLInventoryModel::EXCLUDE_TRASH, collector);
 
+		for (U32 i = 0; i < outfit_items.size(); ++i)
+		{
+			LLViewerInventoryItem* linked_item = outfit_items.at(i)->getLinkedItem();
+			if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE)
+			{
+				outfit_items.erase(outfit_items.begin() + i);
+				break;
+			}
+		}
+
 		if(outfit_items.size() != cof_items.size())
 		{
 			LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL;
-- 
cgit v1.2.3


From 464d70c54699315a7c616c9e535dbcfd461167c5 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Wed, 7 Sep 2016 08:08:19 +0300
Subject: Dummy commit to fix the teamcity builds

---
 BuildParams | 1 -
 1 file changed, 1 deletion(-)

diff --git a/BuildParams b/BuildParams
index 264f6f8a53..09cc06e83a 100755
--- a/BuildParams
+++ b/BuildParams
@@ -90,4 +90,3 @@ EDU_viewer_channel_suffix = "edu"
 # environment variable 'email' to a space-separated list of email addresses
 
 
-
-- 
cgit v1.2.3


From 1de6e0830c9cb500239256e9cab9cb565f8c098a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 7 Sep 2016 17:26:07 +0300
Subject: MAINT-6699 FIXED [VOB] Crash in
 LLSnapshotLivePreview::getBigThumbnailImage()

---
 indra/newview/llfloatersnapshot.cpp | 17 +++++++++++++----
 indra/newview/llfloatersnapshot.h   |  2 ++
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 664668f2f7..ff7594a531 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1235,14 +1235,14 @@ S32 LLFloaterSnapshot::notify(const LLSD& info)
 	return 0;
 }
 
-void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
+BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
 {
 	LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook");
 	LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
 	LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
 
-	if (!mFloater && !floater_facebook && !floater_flickr && !floater_twitter)
-		return;
+	if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter)
+		return FALSE;
 
 	BOOL changed = FALSE;
 	LL_DEBUGS() << "npreviews: " << LLSnapshotLivePreview::sList.size() << LL_ENDL;
@@ -1251,8 +1251,13 @@ void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
 	{
 		changed |= LLSnapshotLivePreview::onIdle(*iter);
 	}
+	return changed;
+}
+
 
-	if (mFloater && changed)
+void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
+{
+	if (ImplBase::updatePreviewList(true) && mFloater)
 	{
 		LL_DEBUGS() << "changed" << LL_ENDL;
 		updateControls(mFloater);
@@ -1267,6 +1272,10 @@ void LLFloaterSnapshot::update()
 	{
 		inst->impl->updateLivePreview();
 	}
+	else
+	{
+		ImplBase::updatePreviewList(false);
+	}
 }
 
 // static
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 4bcfa674fa..1f303ea4d6 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -116,6 +116,8 @@ public:
 	virtual EStatus getStatus() const { return mStatus; }
 	virtual void setNeedRefresh(bool need);
 
+	static BOOL updatePreviewList(bool initialized);
+
 	void setAdvanced(bool advanced) { mAdvanced = advanced; }
 
 	virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0;
-- 
cgit v1.2.3


From 8bb95eb8f80bd1c19fc24741cb612ff89ed8ed43 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 9 Sep 2016 16:17:43 +0300
Subject: MAINT-6711 "Object view" rotates around the avatar

---
 indra/newview/lltoolfocus.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index c4696c3a01..caa055e5e0 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -223,6 +223,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 		}
 
 		if (!(pick_info.mKeyMask & MASK_ALT) &&
+			!LLFloaterCamera::inFreeCameraMode() &&
 			gAgentCamera.cameraThirdPerson() &&
 			gViewerWindow->getLeftMouseDown() && 
 			!gSavedSettings.getBOOL("FreezeTime") &&
-- 
cgit v1.2.3


From 94f65c53a1f7db6c01fa19fe3ca7cf1fc4351b0e Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 12 Sep 2016 12:04:05 +0300
Subject: SL-444 Add Abuse Report Submision Confirmation Pop up

---
 indra/newview/llfloaterreporter.cpp                  |  2 ++
 indra/newview/skins/default/xui/en/notifications.xml | 15 ++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 5d77972180..a6ce0ba678 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -444,6 +444,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
 		if(!url.empty() || !sshot_url.empty())
 		{
 			self->sendReportViaCaps(url, sshot_url, self->gatherReport());
+			LLNotificationsUtil::add("HelpReportAbuseConfirm");
 			self->closeFloater();
 		}
 		else
@@ -869,6 +870,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 		self->mScreenID = uuid;
 		LL_INFOS() << "Got screen shot " << uuid << LL_ENDL;
 		self->sendReportViaLegacy(self->gatherReport());
+		LLNotificationsUtil::add("HelpReportAbuseConfirm");
 		self->closeFloater();
 	}
 }
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 864832062a..66a08da8c4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5876,7 +5876,20 @@ You cannot undo this action.
      notext="Cancel"
      yestext="Unlink"/>
   </notification>
-
+  
+  <notification
+   icon="alertmodal.tga"
+   name="HelpReportAbuseConfirm"
+   type="alertmodal">
+   <unique/>
+Thank you for taking the time to inform us of this issue. 
+We will review your report for possible violations and take
+the appropriate action.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+  
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseSelectCategory"
-- 
cgit v1.2.3


From 50ed0db1ff05c806b2a28ab0368a492c98762419 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 12 Sep 2016 17:45:12 +0300
Subject: MAINT-6720 Fixed onVisibilityChange() crash in LLTextBase

---
 indra/llui/lltextbase.cpp | 76 ++++++++++++++++++++++++++---------------------
 indra/llui/lltextbase.h   |  2 +-
 2 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c7d7535f87..7061d16dd4 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -181,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mMaxTextByteLength( p.max_text_length ),
 	mFont(p.font),
 	mFontShadow(p.font_shadow),
-	mPopupMenu(NULL),
+	mPopupMenuHandle(),
 	mReadOnly(p.read_only),
 	mSpellCheck(p.spellcheck),
 	mSpellCheckStart(-1),
@@ -1263,9 +1263,10 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)
 //virtual
 void LLTextBase::onVisibilityChange( BOOL new_visibility )
 {
-	if(!new_visibility && mPopupMenu)
+	LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+	if(!new_visibility && menu)
 	{
-		mPopupMenu->hide();
+		menu->hide();
 	}
 	LLUICtrl::onVisibilityChange(new_visibility);
 }
@@ -1956,41 +1957,48 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
 
 	// create and return the context menu from the XUI file
-	delete mPopupMenu;
+
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+    if (menu)
+    {
+        menu->updateParent(NULL);
+        mPopupMenuHandle.markDead();
+    }
 	llassert(LLMenuGL::sMenuContainer != NULL);
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
-																		 LLMenuHolderGL::child_registry_t::instance());	
-	if (mIsFriendSignal)
-	{
-		bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
-		LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
-		LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+    menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
+																		 LLMenuHolderGL::child_registry_t::instance());
+    if (menu)
+    {
+        mPopupMenuHandle = menu->getHandle();
 
-		if (addFriendButton && removeFriendButton)
-		{
-			addFriendButton->setEnabled(!isFriend);
-			removeFriendButton->setEnabled(isFriend);
-		}
-	}
+        if (mIsFriendSignal)
+        {
+            bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+            LLView* addFriendButton = menu->getChild<LLView>("add_friend");
+            LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
 
-	if (mIsObjectBlockedSignal)
-	{
-		bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
-		LLView* blockButton = mPopupMenu->getChild<LLView>("block_object");
-		LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object");
+            if (addFriendButton && removeFriendButton)
+            {
+                addFriendButton->setEnabled(!isFriend);
+                removeFriendButton->setEnabled(isFriend);
+            }
+        }
 
-		if (blockButton && unblockButton)
-		{
-			blockButton->setVisible(!is_blocked);
-			unblockButton->setVisible(is_blocked);
-		}
-	}
-	
-	if (mPopupMenu)
-	{
-		mPopupMenu->show(x, y);
-		LLMenuGL::showPopup(this, mPopupMenu, x, y);
-	}
+        if (mIsObjectBlockedSignal)
+        {
+            bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
+            LLView* blockButton = menu->getChild<LLView>("block_object");
+            LLView* unblockButton = menu->getChild<LLView>("unblock_object");
+
+            if (blockButton && unblockButton)
+            {
+                blockButton->setVisible(!is_blocked);
+                unblockButton->setVisible(is_blocked);
+            }
+        }
+        menu->show(x, y);
+        LLMenuGL::showPopup(this, menu, x, y);
+    }
 }
 
 void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 85641fd899..3d3a6ca869 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -673,7 +673,7 @@ protected:
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
-	LLContextMenu*				mPopupMenu;
+	LLHandle<LLContextMenu>		mPopupMenuHandle;
 	LLView*						mDocumentView;
 	LLScrollContainer*			mScroller;
 
-- 
cgit v1.2.3


From ff118b7d21633cc020b2fb4c833684b4f98b4e5e Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Mon, 12 Sep 2016 17:45:12 +0300
Subject: MAINT-6720 Fixed onVisibilityChange() crash in LLTextBase

---
 indra/llui/lltextbase.cpp | 76 ++++++++++++++++++++++++++---------------------
 indra/llui/lltextbase.h   |  2 +-
 2 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c7d7535f87..7061d16dd4 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -181,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mMaxTextByteLength( p.max_text_length ),
 	mFont(p.font),
 	mFontShadow(p.font_shadow),
-	mPopupMenu(NULL),
+	mPopupMenuHandle(),
 	mReadOnly(p.read_only),
 	mSpellCheck(p.spellcheck),
 	mSpellCheckStart(-1),
@@ -1263,9 +1263,10 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)
 //virtual
 void LLTextBase::onVisibilityChange( BOOL new_visibility )
 {
-	if(!new_visibility && mPopupMenu)
+	LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+	if(!new_visibility && menu)
 	{
-		mPopupMenu->hide();
+		menu->hide();
 	}
 	LLUICtrl::onVisibilityChange(new_visibility);
 }
@@ -1956,41 +1957,48 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
 
 	// create and return the context menu from the XUI file
-	delete mPopupMenu;
+
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+    if (menu)
+    {
+        menu->updateParent(NULL);
+        mPopupMenuHandle.markDead();
+    }
 	llassert(LLMenuGL::sMenuContainer != NULL);
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
-																		 LLMenuHolderGL::child_registry_t::instance());	
-	if (mIsFriendSignal)
-	{
-		bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
-		LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
-		LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+    menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
+																		 LLMenuHolderGL::child_registry_t::instance());
+    if (menu)
+    {
+        mPopupMenuHandle = menu->getHandle();
 
-		if (addFriendButton && removeFriendButton)
-		{
-			addFriendButton->setEnabled(!isFriend);
-			removeFriendButton->setEnabled(isFriend);
-		}
-	}
+        if (mIsFriendSignal)
+        {
+            bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+            LLView* addFriendButton = menu->getChild<LLView>("add_friend");
+            LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
 
-	if (mIsObjectBlockedSignal)
-	{
-		bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
-		LLView* blockButton = mPopupMenu->getChild<LLView>("block_object");
-		LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object");
+            if (addFriendButton && removeFriendButton)
+            {
+                addFriendButton->setEnabled(!isFriend);
+                removeFriendButton->setEnabled(isFriend);
+            }
+        }
 
-		if (blockButton && unblockButton)
-		{
-			blockButton->setVisible(!is_blocked);
-			unblockButton->setVisible(is_blocked);
-		}
-	}
-	
-	if (mPopupMenu)
-	{
-		mPopupMenu->show(x, y);
-		LLMenuGL::showPopup(this, mPopupMenu, x, y);
-	}
+        if (mIsObjectBlockedSignal)
+        {
+            bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
+            LLView* blockButton = menu->getChild<LLView>("block_object");
+            LLView* unblockButton = menu->getChild<LLView>("unblock_object");
+
+            if (blockButton && unblockButton)
+            {
+                blockButton->setVisible(!is_blocked);
+                unblockButton->setVisible(is_blocked);
+            }
+        }
+        menu->show(x, y);
+        LLMenuGL::showPopup(this, menu, x, y);
+    }
 }
 
 void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 85641fd899..3d3a6ca869 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -673,7 +673,7 @@ protected:
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
-	LLContextMenu*				mPopupMenu;
+	LLHandle<LLContextMenu>		mPopupMenuHandle;
 	LLView*						mDocumentView;
 	LLScrollContainer*			mScroller;
 
-- 
cgit v1.2.3


From 07cc376831b38334d9bcadf52b030073ced571da Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 13 Sep 2016 13:02:20 +0300
Subject: MAINT-6718 Can't Wear - Replace current outfits.

---
 indra/newview/llappearancemgr.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index ff5439d610..937ee86450 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1875,15 +1875,15 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 		return false;
 	}
 
-	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
+	// Check whether the outfit contains any wearables
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
+	LLFindWearables is_wearable;
 	gInventory.collectDescendentsIf(outfit_cat_id,
 		cats,
 		items,
 		LLInventoryModel::EXCLUDE_TRASH,
-		is_worn);
+		is_wearable);
 
 	return items.size() > 0;
 }
-- 
cgit v1.2.3


From a195406e484047cefc699a03c769816c4a8dc0f0 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 13 Sep 2016 20:32:34 +0300
Subject: MAINT-6726 Fixed LLLineEditor menus staying in memory forever

---
 indra/llui/lllineeditor.cpp           | 15 +++++++++++----
 indra/llui/lllineeditor.h             |  4 +++-
 indra/llui/lltextbase.cpp             |  2 +-
 indra/newview/lllocationinputctrl.cpp |  2 +-
 4 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 492c9315d1..c89e1dac1d 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2636,10 +2636,17 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
 
 void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
 {
-	if (new_context_menu)
-		mContextMenuHandle = new_context_menu->getHandle();
-	else
-		mContextMenuHandle.markDead();
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+    if (menu)
+    {
+        menu->die();
+        mContextMenuHandle.markDead();
+    }
+
+    if (new_context_menu)
+    {
+        mContextMenuHandle = new_context_menu->getHandle();
+    }
 }
 
 void LLLineEditor::setFont(const LLFontGL* font)
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index c6d472f59b..ccbd305a16 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -272,7 +272,7 @@ public:
 
 	void			setReplaceNewlinesWithSpaces(BOOL replace);
 
-	void			setContextMenu(LLContextMenu* new_context_menu);
+	void			resetContextMenu() { setContextMenu(NULL); };
 
 private:
 	// private helper methods
@@ -308,6 +308,8 @@ private:
 	virtual S32		getPreeditFontSize() const;
 	virtual LLWString getPreeditString() const { return getWText(); }
 
+	void			setContextMenu(LLContextMenu* new_context_menu);
+
 protected:
 	LLUIString		mText;					// The string being edited.
 	std::string		mPrevText;				// Saved string for 'ESC' revert
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7061d16dd4..20be739286 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1961,7 +1961,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
     LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
     if (menu)
     {
-        menu->updateParent(NULL);
+        menu->die();
         mPopupMenuHandle.markDead();
     }
 	llassert(LLMenuGL::sMenuContainer != NULL);
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 53b2ca2b74..11bc1425f9 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -243,7 +243,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
 	params.commit_on_focus_lost(false);
 	params.follows.flags(FOLLOWS_ALL);
 	mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
-	mTextEntry->setContextMenu(NULL);
+	mTextEntry->resetContextMenu();
 	addChild(mTextEntry);
 	// LLLineEditor is replaced with LLLocationLineEditor
 
-- 
cgit v1.2.3


From da23e0f925742045013fc09e75b962c65e1cda88 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Tue, 13 Sep 2016 20:32:34 +0300
Subject: MAINT-6726 Fixed LLLineEditor menus staying in memory forever

---
 indra/llui/lllineeditor.cpp           | 15 +++++++++++----
 indra/llui/lllineeditor.h             |  4 +++-
 indra/llui/lltextbase.cpp             |  2 +-
 indra/newview/lllocationinputctrl.cpp |  2 +-
 4 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 492c9315d1..c89e1dac1d 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2636,10 +2636,17 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
 
 void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
 {
-	if (new_context_menu)
-		mContextMenuHandle = new_context_menu->getHandle();
-	else
-		mContextMenuHandle.markDead();
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+    if (menu)
+    {
+        menu->die();
+        mContextMenuHandle.markDead();
+    }
+
+    if (new_context_menu)
+    {
+        mContextMenuHandle = new_context_menu->getHandle();
+    }
 }
 
 void LLLineEditor::setFont(const LLFontGL* font)
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index c6d472f59b..ccbd305a16 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -272,7 +272,7 @@ public:
 
 	void			setReplaceNewlinesWithSpaces(BOOL replace);
 
-	void			setContextMenu(LLContextMenu* new_context_menu);
+	void			resetContextMenu() { setContextMenu(NULL); };
 
 private:
 	// private helper methods
@@ -308,6 +308,8 @@ private:
 	virtual S32		getPreeditFontSize() const;
 	virtual LLWString getPreeditString() const { return getWText(); }
 
+	void			setContextMenu(LLContextMenu* new_context_menu);
+
 protected:
 	LLUIString		mText;					// The string being edited.
 	std::string		mPrevText;				// Saved string for 'ESC' revert
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7061d16dd4..20be739286 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1961,7 +1961,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
     LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
     if (menu)
     {
-        menu->updateParent(NULL);
+        menu->die();
         mPopupMenuHandle.markDead();
     }
 	llassert(LLMenuGL::sMenuContainer != NULL);
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 53b2ca2b74..11bc1425f9 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -243,7 +243,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
 	params.commit_on_focus_lost(false);
 	params.follows.flags(FOLLOWS_ALL);
 	mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
-	mTextEntry->setContextMenu(NULL);
+	mTextEntry->resetContextMenu();
 	addChild(mTextEntry);
 	// LLLineEditor is replaced with LLLocationLineEditor
 
-- 
cgit v1.2.3


From 3c8cc4d2ac4dbcbae6bc56ccb222a043d6616341 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 14 Sep 2016 18:27:54 +0300
Subject: MAINT-6723 FIXED [VOB] Crash in LLOutfitGallery::buildItemPanel(int)

---
 indra/newview/lloutfitgallery.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 65fd3f95ab..de6a36ce2f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -999,7 +999,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
         }
     }
     
-    if (mGalleryCreated)
+    if (mGalleryCreated && !LLApp::isQuitting())
     {
         reArrangeRows();
     }
-- 
cgit v1.2.3


From 98cb9251853a594a51bdc8c70a00c6ecc50bb412 Mon Sep 17 00:00:00 2001
From: Natty Linden <natty@lindenlab.com>
Date: Wed, 14 Sep 2016 15:53:58 -0700
Subject: MAINT-6731 Use web profile URLs from the grid configuration

---
 indra/newview/app_settings/settings.xml      | 22 --------------------
 indra/newview/llpanelprofile.cpp             | 14 +++----------
 indra/newview/llviewernetwork.cpp            | 30 +++++++++++++++++++++++++++-
 indra/newview/llviewernetwork.h              |  8 ++++++++
 indra/newview/tests/lllogininstance_test.cpp |  1 +
 5 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4498798ce9..674923e88d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4515,28 +4515,6 @@
       <key>Value</key>
       <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
-    <key>WebProfileURL</key>
-    <map>
-      <key>Comment</key>
-      <string>URL for Web Profiles</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>https://my.secondlife.com/[AGENT_NAME]</string>
-    </map>
-	<key>WebProfileNonProductionURL</key>
-	<map>
-		<key>Comment</key>
-		<string>URL for Web Profiles on Non-Production grids</string>
-		<key>Persist</key>
-		<integer>0</integer>
-		<key>Type</key>
-		<string>String</string>
-		<key>Value</key>
-		<string>https://my-demo.secondlife.com/[AGENT_NAME]</string>
-	</map>
     <key>HighResSnapshot</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 184238c40c..8afa35efa0 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -44,19 +44,11 @@ static const std::string PANEL_PICKS = "panel_picks";
 
 std::string getProfileURL(const std::string& agent_name)
 {
-	std::string url;
-
-	if (LLGridManager::getInstance()->isInProductionGrid())
-	{
-		url = gSavedSettings.getString("WebProfileURL");
-	}
-	else
-	{
-		url = gSavedSettings.getString("WebProfileNonProductionURL");
-	}
+	std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
 	LLSD subs;
+	subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
 	subs["AGENT_NAME"] = agent_name;
-	url = LLWeb::expandURLSubstitutions(url,subs);
+	url = LLWeb::expandURLSubstitutions(url, subs);
 	LLStringUtil::toLower(url);
 	return url;
 }
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 6666aecca2..2525886222 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -49,6 +49,8 @@ const std::string  GRID_UPDATE_SERVICE_URL = "update_query_url_base";
 const std::string  GRID_HELPER_URI_VALUE = "helper_uri";
 /// the splash page url
 const std::string  GRID_LOGIN_PAGE_VALUE = "login_page";
+/// url for the web profile site
+const std::string  GRID_WEB_PROFILE_VALUE = "web_profile_url";
 /// internal data on system grids
 const std::string  GRID_IS_SYSTEM_GRID_VALUE = "system_grid";
 /// whether this is single or double names
@@ -70,6 +72,8 @@ const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update";
 const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
 const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 
+const std::string MAIN_GRID_WEB_PROFILE_URL = "https://my.secondlife.com/";
+
 const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
 const char* DEFAULT_SLURL_BASE = "https://%s/region/";
 const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
@@ -125,6 +129,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "https://secondlife.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
+				  MAIN_GRID_WEB_PROFILE_URL,
 				  "Agni");
 	addSystemGrid(LLTrans::getString("AditiGridLabel"),
 				  "util.aditi.lindenlab.com",
@@ -132,6 +137,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
+				  "https://my.aditi.lindenlab.com/",
 				  "Aditi");
 
 	LLSD other_grids;
@@ -288,6 +294,10 @@ bool LLGridManager::addGrid(LLSD& grid_data)
 				{
 					grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
 				}
+				if (!grid_data.has(GRID_WEB_PROFILE_VALUE))
+				{
+					grid_data[GRID_WEB_PROFILE_VALUE] = std::string("https://") + grid + "/";
+				}
 
 				if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
 				{
@@ -302,7 +312,8 @@ bool LLGridManager::addGrid(LLSD& grid_data)
 										 <<"  id:          "<<grid_data[GRID_ID_VALUE].asString()<<"\n"
 										 <<"  label:       "<<grid_data[GRID_LABEL_VALUE].asString()<<"\n"
 										 <<"  login page:  "<<grid_data[GRID_LOGIN_PAGE_VALUE].asString()<<"\n"
-										 <<"  helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n";
+										 <<"  helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n"
+										 <<"  web profile: "<<grid_data[GRID_WEB_PROFILE_VALUE].asString()<<"\n";
 				/* still in LL_DEBUGS */ 
 				for (LLSD::array_const_iterator login_uris = grid_data[GRID_LOGIN_URI_VALUE].beginArray();
 					 login_uris != grid_data[GRID_LOGIN_URI_VALUE].endArray();
@@ -339,6 +350,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& helper,
 								  const std::string& login_page,
 								  const std::string& update_url_base,
+								  const std::string& web_profile_url,
 								  const std::string& login_id)
 {
 	LLSD grid = LLSD::emptyMap();
@@ -349,6 +361,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 	grid[GRID_LOGIN_URI_VALUE].append(login_uri);
 	grid[GRID_LOGIN_PAGE_VALUE] = login_page;
 	grid[GRID_UPDATE_SERVICE_URL] = update_url_base;
+	grid[GRID_WEB_PROFILE_VALUE] = web_profile_url;
 	grid[GRID_IS_SYSTEM_GRID_VALUE] = true;
 	grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
 	grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
@@ -535,6 +548,21 @@ std::string LLGridManager::getLoginPage()
 	return login_page;
 }
 
+std::string LLGridManager::getWebProfileURL(const std::string& grid)
+{
+	std::string web_profile_url;
+	std::string grid_name = getGrid(grid);
+	if (!grid_name.empty())
+	{
+		web_profile_url = mGridList[grid_name][GRID_WEB_PROFILE_VALUE].asString();
+	}
+	else
+	{
+		LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+	}
+	return web_profile_url;
+}
+
 void LLGridManager::getLoginIdentifierTypes(LLSD& idTypes)
 {
 	idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES];
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 8526c0ba7f..228303d8e2 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -166,6 +166,13 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	/// Return the application URL prefix for the selected grid
 	std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); }	
 
+	/// Return the url of the resident profile web site for the given grid
+	std::string getWebProfileURL(const std::string& grid);
+
+	/// Return the url of the resident profile web site for the selected grid
+	std::string getWebProfileURL() { return getWebProfileURL(mGrid); }
+
+
 	//@}
 
 	/* ================================================================
@@ -216,6 +223,7 @@ class LLGridManager : public LLSingleton<LLGridManager>
 					   const std::string& helper,
 					   const std::string& login_page,
 					   const std::string& update_url_base,
+					   const std::string& web_profile_url,
 					   const std::string& login_id = "");	
 	
 	
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 1b0334498e..b603157ca7 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -136,6 +136,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& helper,
 								  const std::string& login_page,
 								  const std::string& update_url_base,
+								  const std::string& web_profile_url,
 								  const std::string& login_id)
 {
 }
-- 
cgit v1.2.3


From 7d20fbdb6608b65414c4a5ccad26944f6334403c Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 15 Sep 2016 15:31:31 -0400
Subject: Added tag 4.0.8-release for changeset 45eaee56883d

---
 .hgtags | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.hgtags b/.hgtags
index cee1281f2b..0aa708c977 100755
--- a/.hgtags
+++ b/.hgtags
@@ -518,3 +518,4 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
 450de775fff66a011be1a001acd117cc623c445d 4.0.5-release
 4070611edd95eb3a683d1cd97c4c07fe67793812 4.0.6-release
 33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release
+45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release
-- 
cgit v1.2.3


From 51bb369a39142ff5049f753099f9638ce68b95dc Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Thu, 15 Sep 2016 15:31:31 -0400
Subject: increment viewer version to 4.0.9

---
 indra/newview/VIEWER_VERSION.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index a2cec7aff4..7919852fe1 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-4.0.8
+4.0.9
-- 
cgit v1.2.3


From f0c469b649feb2f94b07377faeb87e27fa3041a4 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Thu, 15 Sep 2016 19:22:10 +0300
Subject: MAINT-6734 Fixed processData() crash in LLMeshHeaderHandler

---
 indra/newview/llmeshrepository.cpp | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f9461e3132..e42647739f 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3015,12 +3015,23 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 	}
 	else if (data && data_size > 0)
 	{
-		// header was successfully retrieved from sim, cache in vfs
-		LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id];
+		// header was successfully retrieved from sim and parsed, cache in vfs
+		S32 header_bytes = 0;
+		LLSD header;
 
-		S32 version = header["version"].asInteger();
+		gMeshRepo.mThread->mHeaderMutex->lock();
+		LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
+		if (iter != gMeshRepo.mThread->mMeshHeader.end())
+		{
+			header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+			header = iter->second;
+		}
+		gMeshRepo.mThread->mHeaderMutex->unlock();
 
-		if (version <= MAX_MESH_VERSION)
+		if (header_bytes > 0
+			&& !header.has("404")
+			&& header.has("version")
+			&& header["version"].asInteger() <= MAX_MESH_VERSION)
 		{
 			std::stringstream str;
 
@@ -3069,6 +3080,17 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 				}
 			}
 		}
+		else
+		{
+			LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
+
+			// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
+			LLMutexLock lock(gMeshRepo.mThread->mMutex);
+			for (int i(0); i < 4; ++i)
+			{
+				gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));
+			}
+		}
 	}
 }
 
-- 
cgit v1.2.3


From c94496db9ea8ae872dd3d40b53a6329571322629 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 16 Sep 2016 16:34:47 +0300
Subject: MAINT-6694 Console overflow crash in gestures.

---
 indra/newview/llfloatergesture.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index d842106146..b840d37c4d 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -328,7 +328,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
 		element["columns"][0]["font"]["name"] = "SANSSERIF";
 		element["columns"][0]["font"]["style"] = font_style;
 
-		std::string key_string = LLKeyboard::stringFromKey(gesture->mKey);
+		std::string key_string;
 		std::string buffer;
 
 		if (gesture->mKey == KEY_NONE)
@@ -338,6 +338,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
 		}
 		else
 		{
+			key_string = LLKeyboard::stringFromKey(gesture->mKey);
 			buffer = LLKeyboard::stringFromAccelerator(gesture->mMask,
 					gesture->mKey);
 		}
-- 
cgit v1.2.3


From 56060218c3f542b28eaf305b42ecdd52e282cb59 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 19 Sep 2016 12:11:39 +0300
Subject: MAINT-6733 FIXED On build disabled land, the build button is enabled
 when left clicking any touchable object.

---
 indra/newview/lltoolmgr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index b0e3b5bf89..f6eb290bc3 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -267,7 +267,7 @@ bool LLToolMgr::canEdit()
 
 bool LLToolMgr::buildEnabledOrActive()
 {
-	return inEdit() || canEdit();
+	return LLFloaterReg::instanceVisible("build") || canEdit();
 }
 
 void LLToolMgr::toggleBuildMode(const LLSD& sdname)
-- 
cgit v1.2.3


From e638f635c81d2b380840e33acdc33ee692422153 Mon Sep 17 00:00:00 2001
From: andreykproductengine <none@none>
Date: Tue, 20 Sep 2016 16:45:42 +0300
Subject: MAINT-6735 Teleport offer sound does not play when the the
 destination region's maturity exceeds the current maturity settings

---
 indra/newview/llnotificationofferhandler.cpp       | 26 +++++++++++++---------
 .../newview/skins/default/xui/en/notifications.xml |  6 +++--
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 2657b84ef3..c29fdecefa 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -96,17 +96,21 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 
 			LLUUID from_id = notification->getPayload()["from_id"];
 
-			//Will not play a notification sound for inventory and teleport offer based upon chat preference
-			bool playSound = (!notification->isDND()
-							  && ((notification->getName() == "UserGiveItem"
-			                  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
-			                  || (notification->getName() == "TeleportOffered"
-			                  && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
-
-			            if(playSound)
-			            {
-			                notification->playSound();
-			            }
+			if (!notification->isDND())
+			{
+				//Will not play a notification sound for inventory and teleport offer based upon chat preference
+				bool playSound = (notification->getName() == "UserGiveItem"
+								  && gSavedSettings.getBOOL("PlaySoundInventoryOffer")
+								 || ((notification->getName() == "TeleportOffered"
+								     || notification->getName() == "TeleportOffered_MaturityExceeded"
+								     || notification->getName() == "TeleportOffered_MaturityBlocked")
+								    && gSavedSettings.getBOOL("PlaySoundTeleportOffer")));
+
+				if (playSound)
+				{
+					notification->playSound();
+				}
+			}
 
 			LLHandlerUtil::spawnIMSession(name, from_id);
 			LLHandlerUtil::addNotifPanelToIM(notification);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3fe21a261c..79ee35fe3e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7407,7 +7407,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    name="TeleportOffered_MaturityExceeded"
    log_to_im="true"
    log_to_chat="false"
-   type="offer">
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
@@ -7432,7 +7433,8 @@ This region contains [REGION_CONTENT_MATURITY] content, but your current prefere
    name="TeleportOffered_MaturityBlocked"
    log_to_im="true"
    log_to_chat="false"
-   type="notifytip">
+   type="notifytip"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
-- 
cgit v1.2.3


From c9cfa897d9a781b6781915d250bb8886c206cd3f Mon Sep 17 00:00:00 2001
From: andreykproductengine <none@none>
Date: Tue, 20 Sep 2016 17:47:30 +0300
Subject: MAINT-6655 fixed group list and inspector not always switching to
 default icon

---
 indra/newview/llgrouplist.cpp    | 5 +----
 indra/newview/llinspectgroup.cpp | 4 ++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 6126db2988..62414d3bbb 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -379,10 +379,7 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
 
 void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
 {
-	if (group_icon_id.notNull())
-	{
-		mGroupIcon->setIconId(group_icon_id);
-	}
+	mGroupIcon->setIconId(group_icon_id);
 }
 
 void LLGroupListItem::setGroupIconVisible(bool visible)
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index 0c5a91e48a..a4fce36783 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -41,6 +41,7 @@
 #include "lltooltip.h"	// positionViewNearMouse()
 #include "lltrans.h"
 #include "lluictrl.h"
+#include "llgroupiconctrl.h"
 
 //////////////////////////////////////////////////////////////////////////////
 // LLInspectGroup
@@ -233,8 +234,7 @@ void LLInspectGroup::processGroupData()
 
 		getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) );
 
-		// LLGroupIconCtrl
-		getChild<LLUICtrl>("group_icon")->setValue(LLSD(mGroupID));
+		getChild<LLGroupIconCtrl>("group_icon")->setIconId(data->mInsigniaID);
 
 		std::string cost;
 		bool is_member = LLGroupActions::isInGroup(mGroupID);
-- 
cgit v1.2.3


From 6e3acac4f0b47ee721f2e577484906de0240d76d Mon Sep 17 00:00:00 2001
From: andreykproductengine <none@none>
Date: Tue, 20 Sep 2016 20:42:57 +0300
Subject: MAINT-6735 brackets fix

---
 indra/newview/llnotificationofferhandler.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index c29fdecefa..63ab88da42 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -100,11 +100,11 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			{
 				//Will not play a notification sound for inventory and teleport offer based upon chat preference
 				bool playSound = (notification->getName() == "UserGiveItem"
-								  && gSavedSettings.getBOOL("PlaySoundInventoryOffer")
+								  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
 								 || ((notification->getName() == "TeleportOffered"
 								     || notification->getName() == "TeleportOffered_MaturityExceeded"
 								     || notification->getName() == "TeleportOffered_MaturityBlocked")
-								    && gSavedSettings.getBOOL("PlaySoundTeleportOffer")));
+								    && gSavedSettings.getBOOL("PlaySoundTeleportOffer"));
 
 				if (playSound)
 				{
-- 
cgit v1.2.3


From bb7cbe7cff43bec7061a7a0ccabaf2755e7376ee Mon Sep 17 00:00:00 2001
From: Ansariel <none@none>
Date: Tue, 20 Sep 2016 21:16:39 +0200
Subject: Small improvements to UI DPI scaling on Windows: * Use
 USER_DEFAULT_SCREEN_DPI define from WinUser.h * Change Win32 SDK target
 version to Windows Vista or greater * Define WM_DPICHANGED as preprocessor
 definition as in WinUser.h * Cull manual definitions of WM_MOUSEWHEEL and
 WHEEL_DELTA which are part of the Win32 SDK since Windows NT 4.0

---
 indra/cmake/00-Common.cmake      |  4 ++--
 indra/llwindow/llwindowwin32.cpp | 18 +++++-------------
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 86fc2dfff5..adc134c48c 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -83,8 +83,8 @@ if (WINDOWS)
     add_definitions(/WX)
   endif (NOT VS_DISABLE_FATAL_WARNINGS)
 
-  # configure win32 API for windows XP+ compatibility
-  set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
+  # configure Win32 API for Windows Vista+ compatibility
+  set(WINVER "0x0600" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
   add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
 endif (WINDOWS)
 
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 26bc819aab..4086db8e52 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -60,21 +60,13 @@
 #include <dinput.h>
 #include <Dbt.h.>
 
-// culled from winuser.h
-#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
-const S32	WM_MOUSEWHEEL = 0x020A;
-#endif
-#ifndef WHEEL_DELTA /* Added to be compatible with later SDK's */
-const S32	WHEEL_DELTA = 120;     /* Value for rolling one detent */
-#endif
 const S32	MAX_MESSAGE_PER_UPDATE = 20;
 const S32	BITS_PER_PIXEL = 32;
 const S32	MAX_NUM_RESOLUTIONS = 32;
 const F32	ICON_FLASH_TIME = 0.5f;
-const F32	DEFAULT_DPI = 96.0f;
 
-#ifndef WM_DPICHANGED                   
-const S32	WM_DPICHANGED = 0x02E0;
+#ifndef WM_DPICHANGED
+#define WM_DPICHANGED 0x02E0
 #endif
 
 extern BOOL gDebugWindowProc;
@@ -2631,7 +2623,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
 		case WM_DPICHANGED:
 			{
 				LPRECT lprc_new_scale;
-				F32 new_scale = LOWORD(w_param) / 96.0f;
+				F32 new_scale = LOWORD(w_param) / USER_DEFAULT_SCREEN_DPI;
 				lprc_new_scale = (LPRECT)l_param;
 				S32 new_width = lprc_new_scale->right - lprc_new_scale->left;
 				S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top;
@@ -3990,7 +3982,7 @@ F32 LLWindowWin32::getSystemUISize()
 				hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
 				if (hr == S_OK)
 				{
-					scale_value = dpix / DEFAULT_DPI;
+					scale_value = dpix / USER_DEFAULT_SCREEN_DPI;
 				}
 				else
 				{
@@ -4009,7 +4001,7 @@ F32 LLWindowWin32::getSystemUISize()
 	else
 	{
 		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL;
-		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / DEFAULT_DPI;
+		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / USER_DEFAULT_SCREEN_DPI;
 	}
 
 	ReleaseDC(hWnd, hdc);
-- 
cgit v1.2.3


From 5b61515ca34dfb6bc84fea019f48a47be76c1b5f Mon Sep 17 00:00:00 2001
From: andreykproductengine <none@none>
Date: Thu, 22 Sep 2016 12:34:52 +0300
Subject: MAINT-6694 Gesture floater crash

---
 indra/llcharacter/llkeyframemotion.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index cd201a65b4..e786dfff86 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2149,7 +2149,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
 	LLCharacter* character = *char_iter;
 
 	// look for an existing instance of this motion
-	LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid);
+	LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid));
 	if (motionp)
 	{
 		if (0 == status)
-- 
cgit v1.2.3


From 741194085a70c3b6b004ad18b5bf9eb59a81b9c0 Mon Sep 17 00:00:00 2001
From: AndreyL ProductEngine <alihatskiy@productengine.com>
Date: Fri, 23 Sep 2016 00:50:16 +0300
Subject: MAINT-6752 Updated contributions.txt

---
 doc/contributions.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 05fb19aaf0..9f6b701000 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -201,6 +201,7 @@ Ansariel Hiller
 	MAINT-6612
 	MAINT-6637
 	MAINT-6636
+	MAINT-6752
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
-- 
cgit v1.2.3


From 21fdf0485fc4198ef6b159afb6577cbd31687fc4 Mon Sep 17 00:00:00 2001
From: andreykproductengine <akleshchev@productengine.com>
Date: Fri, 23 Sep 2016 19:45:58 +0300
Subject: MAINT-6747 eliminating convertion error

---
 indra/llmath/llmath.h     | 5 +++++
 indra/llui/llspinctrl.cpp | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 93b9f22b25..692284e04b 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -254,6 +254,11 @@ inline int round_int(double x)
 }
 #endif // BOGUS_ROUND
 
+inline F64 ll_round(const F64 val)
+{
+	return F64(floor(val + 0.5f));
+}
+
 inline F32 ll_round( F32 val, F32 nearest )
 {
 	return F32(floor(val * (1.0f / nearest) + 0.5f)) * nearest;
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 8b1ba406c8..d49e216898 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -153,7 +153,7 @@ F32 clamp_precision(F32 value, S32 decimal_precision)
 	for (S32 i = 0; i < decimal_precision; i++)
 		clamped_value *= 10.0;
 
-	clamped_value = ll_round((F32)clamped_value);
+	clamped_value = ll_round(clamped_value);
 
 	for (S32 i = 0; i < decimal_precision; i++)
 		clamped_value /= 10.0;
-- 
cgit v1.2.3


From fa4376b457b887130e98bd96e6bccb231e8947d2 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 27 Sep 2016 15:16:18 +0300
Subject: MAINT-6737 [VOB] Show confirmation floater when dnd an image to an
 Outfit folder

---
 indra/newview/CMakeLists.txt                       |   6 +-
 indra/newview/llfloateroutfitphotopreview.cpp      | 289 +++++++++++++++++++++
 indra/newview/llfloateroutfitphotopreview.h        |  77 ++++++
 indra/newview/llinventorybridge.cpp                |  15 +-
 indra/newview/llviewerfloaterreg.cpp               |   2 +
 .../xui/en/floater_outfit_photo_preview.xml        |  65 +++++
 6 files changed, 448 insertions(+), 6 deletions(-)
 create mode 100644 indra/newview/llfloateroutfitphotopreview.cpp
 create mode 100644 indra/newview/llfloateroutfitphotopreview.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 195363fb75..d1924126ec 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -262,7 +262,8 @@ set(viewer_SOURCE_FILES
     llfloatermodeluploadbase.cpp
     llfloaternamedesc.cpp
     llfloaternotificationsconsole.cpp
-    llfloaternotificationstabbed.cpp 
+    llfloaternotificationstabbed.cpp
+    llfloateroutfitphotopreview.cpp 
     llfloateroutfitsnapshot.cpp
     llfloaterobjectweights.cpp
     llfloateropenobject.cpp
@@ -880,7 +881,8 @@ set(viewer_HEADER_FILES
     llfloatermodeluploadbase.h
     llfloaternamedesc.h
     llfloaternotificationsconsole.h
-    llfloaternotificationstabbed.h 
+    llfloaternotificationstabbed.h
+    llfloateroutfitphotopreview.h
     llfloateroutfitsnapshot.h
     llfloaterobjectweights.h
     llfloateropenobject.h
diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp
new file mode 100644
index 0000000000..6c39db730c
--- /dev/null
+++ b/indra/newview/llfloateroutfitphotopreview.cpp
@@ -0,0 +1,289 @@
+/** 
+ * @file llfloateroutfitphotopreview.cpp
+ * @brief LLFloaterOutfitPhotoPreview class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llwindow.h"
+
+#include "llfloateroutfitphotopreview.h"
+
+#include "llagent.h"
+#include "llappearancemgr.h"
+#include "llbutton.h"
+#include "llcombobox.h"
+#include "llfilepicker.h"
+#include "llfloaterreg.h"
+#include "llimagetga.h"
+#include "llimagepng.h"
+#include "llinventory.h"
+#include "llinventorymodel.h"
+#include "llnotificationsutil.h"
+#include "llresmgr.h"
+#include "lltrans.h"
+#include "lltextbox.h"
+#include "lltextureview.h"
+#include "llui.h"
+#include "llviewerinventory.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+#include "lluictrlfactory.h"
+#include "llviewerwindow.h"
+#include "lllineeditor.h"
+
+const S32 MAX_OUTFIT_PHOTO_WIDTH = 256;
+const S32 MAX_OUTFIT_PHOTO_HEIGHT = 256;
+
+const S32 CLIENT_RECT_VPAD = 4;
+
+LLFloaterOutfitPhotoPreview::LLFloaterOutfitPhotoPreview(const LLSD& key)
+	: LLPreview(key),
+	  mUpdateDimensions(TRUE),
+	  mImage(NULL),
+	  mOutfitID(LLUUID()),
+	  mImageOldBoostLevel(LLGLTexture::BOOST_NONE),
+	  mExceedLimits(FALSE)
+{
+	updateImageID();
+}
+
+LLFloaterOutfitPhotoPreview::~LLFloaterOutfitPhotoPreview()
+{
+	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
+
+	if (mImage.notNull())
+	{
+		mImage->setBoostLevel(mImageOldBoostLevel);
+		mImage = NULL;
+	}
+}
+
+// virtual
+BOOL LLFloaterOutfitPhotoPreview::postBuild()
+{
+	getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onOkBtn, this));
+	getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterOutfitPhotoPreview::onCancelBtn, this));
+
+	return LLPreview::postBuild();
+}
+
+void LLFloaterOutfitPhotoPreview::draw()
+{
+	updateDimensions();
+	
+	LLPreview::draw();
+
+	if (!isMinimized())
+	{
+		LLGLSUIDefault gls_ui;
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		
+		const LLRect& border = mClientRect;
+		LLRect interior = mClientRect;
+		interior.stretch( -PREVIEW_BORDER_WIDTH );
+
+		// ...border
+		gl_rect_2d( border, LLColor4(0.f, 0.f, 0.f, 1.f));
+		gl_rect_2d_checkerboard( interior );
+
+		if ( mImage.notNull() )
+		{
+			// Draw the texture
+			gGL.diffuseColor3f( 1.f, 1.f, 1.f );
+			gl_draw_scaled_image(interior.mLeft,
+								interior.mBottom,
+								interior.getWidth(),
+								interior.getHeight(),
+								mImage);
+
+			// Pump the texture priority
+			F32 pixel_area = (F32)(interior.getWidth() * interior.getHeight() );
+			mImage->addTextureStats( pixel_area );
+
+			S32 int_width = interior.getWidth();
+			S32 int_height = interior.getHeight();
+			mImage->setKnownDrawSize(int_width, int_height);
+		}
+	} 
+
+}
+
+// virtual
+void LLFloaterOutfitPhotoPreview::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+	LLPreview::reshape(width, height, called_from_parent);
+
+	LLRect dim_rect(getChildView("dimensions")->getRect());
+
+	S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
+
+	S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
+
+	LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
+	client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
+	client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
+
+	S32 client_width = client_rect.getWidth();
+	S32 client_height = client_width;
+
+	if(client_height > client_rect.getHeight())
+	{
+		client_height = client_rect.getHeight();
+		client_width = client_height;
+	}
+	mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() +  (client_height / 2), client_width, client_height);
+
+}
+
+
+void LLFloaterOutfitPhotoPreview::updateDimensions()
+{
+	if (!mImage)
+	{
+		return;
+	}
+	if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+	{
+		return;
+	}
+
+	if (mAssetStatus != PREVIEW_ASSET_LOADED)
+	{
+		mAssetStatus = PREVIEW_ASSET_LOADED;
+		mUpdateDimensions = TRUE;
+	}
+	
+	getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]",  llformat("%d", mImage->getFullWidth()));
+	getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight()));
+
+	if ((mImage->getFullWidth() <= MAX_OUTFIT_PHOTO_WIDTH) && (mImage->getFullHeight() <= MAX_OUTFIT_PHOTO_HEIGHT))
+	{
+		getChild<LLButton>("ok_btn")->setEnabled(TRUE);
+		mExceedLimits = FALSE;
+	}
+	else
+	{
+		mExceedLimits = TRUE;
+		LLStringUtil::format_map_t args;
+		args["MAX_WIDTH"] = llformat("%d", MAX_OUTFIT_PHOTO_WIDTH);
+		args["MAX_HEIGHT"] = llformat("%d", MAX_OUTFIT_PHOTO_HEIGHT);
+		std::string label = getString("exceed_limits", args);
+		getChild<LLUICtrl>("notification")->setValue(label);
+		getChild<LLUICtrl>("notification")->setColor(LLColor4::yellow);
+		getChild<LLButton>("ok_btn")->setEnabled(FALSE);
+	}
+
+	if (mUpdateDimensions)
+	{
+		mUpdateDimensions = FALSE;
+
+		reshape(getRect().getWidth(), getRect().getHeight());
+		gFloaterView->adjustToFitScreen(this, FALSE);
+	}
+}
+
+void LLFloaterOutfitPhotoPreview::loadAsset()
+{
+	if (mImage.notNull())
+	{
+		mImage->setBoostLevel(mImageOldBoostLevel);
+	}
+	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mImageOldBoostLevel = mImage->getBoostLevel();
+	mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+	mImage->forceToSaveRawImage(0) ;
+	mAssetStatus = PREVIEW_ASSET_LOADING;
+	mUpdateDimensions = TRUE;
+	updateDimensions();
+}
+
+LLPreview::EAssetStatus LLFloaterOutfitPhotoPreview::getAssetStatus()
+{
+	if (mImage.notNull() && (mImage->getFullWidth() * mImage->getFullHeight() > 0))
+	{
+		mAssetStatus = PREVIEW_ASSET_LOADED;
+	}
+	return mAssetStatus;
+}
+
+void LLFloaterOutfitPhotoPreview::updateImageID()
+{
+	const LLViewerInventoryItem *item = static_cast<const LLViewerInventoryItem*>(getItem());
+	if(item)
+	{
+		mImageID = item->getAssetUUID();
+		LLPermissions perm(item->getPermissions());
+	}
+	else
+	{
+		mImageID = mItemUUID;
+	}
+
+}
+
+/* virtual */
+void LLFloaterOutfitPhotoPreview::setObjectID(const LLUUID& object_id)
+{
+	mObjectUUID = object_id;
+
+	const LLUUID old_image_id = mImageID;
+
+	updateImageID();
+	if (mImageID != old_image_id)
+	{
+		mAssetStatus = PREVIEW_ASSET_UNLOADED;
+		loadAsset();
+	}
+	refreshFromItem();
+}
+
+void LLFloaterOutfitPhotoPreview::setOutfitID(const LLUUID& outfit_id)
+{
+	mOutfitID = outfit_id;
+	LLViewerInventoryCategory* outfit_folder = gInventory.getCategory(mOutfitID);
+	if(outfit_folder && !mExceedLimits)
+	{
+		getChild<LLUICtrl>("notification")->setValue( getString("photo_confirmation"));
+		getChild<LLUICtrl>("notification")->setTextArg("[OUTFIT]", outfit_folder->getName());
+		getChild<LLUICtrl>("notification")->setColor(LLColor4::white);
+	}
+
+}
+
+void LLFloaterOutfitPhotoPreview::onOkBtn()
+{
+	if(mOutfitID.notNull() && getItem())
+	{
+		LLAppearanceMgr::instance().removeOutfitPhoto(mOutfitID);
+		LLPointer<LLInventoryCallback> cb = NULL;
+		link_inventory_object(mOutfitID, LLConstPointer<LLInventoryObject>(getItem()), cb);
+	}
+	closeFloater();
+}
+
+void LLFloaterOutfitPhotoPreview::onCancelBtn()
+{
+	closeFloater();
+}
diff --git a/indra/newview/llfloateroutfitphotopreview.h b/indra/newview/llfloateroutfitphotopreview.h
new file mode 100644
index 0000000000..a1e7b58abe
--- /dev/null
+++ b/indra/newview/llfloateroutfitphotopreview.h
@@ -0,0 +1,77 @@
+/** 
+ * @file llfloateroutfitphotopreview.h
+ * @brief LLFloaterOutfitPhotoPreview class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATEROUTFITPHOTOPREVIEW_H
+#define LL_LLFLOATEROUTFITPHOTOPREVIEW_H
+
+#include "llpreview.h"
+#include "llbutton.h"
+#include "llframetimer.h"
+#include "llviewertexture.h"
+
+class LLComboBox;
+class LLImageRaw;
+
+class LLFloaterOutfitPhotoPreview : public LLPreview
+{
+public:
+	LLFloaterOutfitPhotoPreview(const LLSD& key);
+	~LLFloaterOutfitPhotoPreview();
+
+	virtual void		draw();
+
+	virtual void		loadAsset();
+	virtual EAssetStatus	getAssetStatus();
+	
+	virtual void		reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
+	/*virtual*/ void setObjectID(const LLUUID& object_id);
+
+	void setOutfitID(const LLUUID& outfit_id);
+	void onOkBtn();
+	void onCancelBtn();
+
+protected:
+	void				init();
+	/* virtual */ BOOL	postBuild();
+	
+private:
+	void				updateImageID(); // set what image is being uploaded.
+	void				updateDimensions();
+	LLUUID				mImageID;
+	LLUUID				mOutfitID;
+	LLPointer<LLViewerFetchedTexture>		mImage;
+	S32                 mImageOldBoostLevel;
+
+	// This is stored off in a member variable, because the save-as
+	// button and drag and drop functionality need to know.
+	BOOL mUpdateDimensions;
+
+	BOOL mExceedLimits;
+
+	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ;
+};
+#endif  // LL_LLFLOATEROUTFITPHOTOPREVIEW_H
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index eebb6a0384..02fa81d5be 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -41,6 +41,7 @@
 #include "llfloateropenobject.h"
 #include "llfloaterreg.h"
 #include "llfloatermarketplacelistings.h"
+#include "llfloateroutfitphotopreview.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterworldmap.h"
 #include "llfolderview.h"
@@ -4393,7 +4394,7 @@ static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_curr
 
 	if((inv_type == LLInventoryType::IT_TEXTURE) || (inv_type == LLInventoryType::IT_SNAPSHOT))
 	{
-		return TRUE;
+		return !move_is_into_current_outfit;
 	}
 
 	if (move_is_into_current_outfit && get_is_item_worn(inv_item->getUUID()))
@@ -4448,9 +4449,15 @@ void LLFolderBridge::dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_c
 {
 	if((inv_item->getInventoryType() == LLInventoryType::IT_TEXTURE) || (inv_item->getInventoryType() == LLInventoryType::IT_SNAPSHOT))
 	{
-		LLAppearanceMgr::instance().removeOutfitPhoto(mUUID);
-		LLPointer<LLInventoryCallback> cb = NULL;
-		link_inventory_object(mUUID, LLConstPointer<LLInventoryObject>(inv_item), cb);
+		const LLUUID &my_outifts_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+		if(mUUID != my_outifts_id)
+		{
+			LLFloaterOutfitPhotoPreview* photo_preview  = LLFloaterReg::showTypedInstance<LLFloaterOutfitPhotoPreview>("outfit_photo_preview", inv_item->getUUID());
+			if(photo_preview)
+			{
+				photo_preview->setOutfitID(mUUID);
+			}
+		}
 		return;
 	}
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 6d13d28e18..0a78686cd4 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -93,6 +93,7 @@
 #include "llfloaternotificationstabbed.h"
 #include "llfloaterobjectweights.h"
 #include "llfloateropenobject.h"
+#include "llfloateroutfitphotopreview.h"
 #include "llfloateroutfitsnapshot.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindingconsole.h"
@@ -277,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("object_weights", "floater_object_weights.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterObjectWeights>);
 	LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
 	LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
+	LLFloaterReg::add("outfit_photo_preview", "floater_outfit_photo_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitPhotoPreview>);
 	LLFloaterPayUtil::registerFloater();
 
 	LLFloaterReg::add("pathfinding_characters", "floater_pathfinding_characters.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingCharacters>);
diff --git a/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml b/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml
new file mode 100644
index 0000000000..bfc1c39e9d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_outfit_photo_preview.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="false"
+ height="325"
+ layout="topleft"
+ name="outfit_photo_preview"
+ help_topic="preview_texture"
+ width="410">
+   <floater.string
+     name="Title">
+        Texture: [NAME]
+    </floater.string>
+    <floater.string
+     name="exceed_limits">
+        Max outfit photo size is [MAX_WIDTH]*[MAX_HEIGHT]. Please select another texture.
+    </floater.string>
+    <floater.string
+     name="photo_confirmation">
+         Set this as Outfit Photo for [OUTFIT]?
+    </floater.string>
+    <text
+     type="string"
+     halign="right"
+     length="1"
+     follows="right|bottom"
+     height="16"
+     layout="topleft"
+     left="110"
+     name="dimensions"
+     top="255"
+     width="200">
+        [WIDTH]px x [HEIGHT]px
+    </text>
+    <text
+     type="string"
+     follows="left|top"
+     height="16"
+     layout="topleft"
+     name="notification"
+     left="25"
+     halign="center"
+     top_pad="5"
+     width="360">
+    </text>
+    <button
+     follows="right|bottom"
+     height="22"
+     label="OK"
+     layout="topleft"
+     name="ok_btn"
+     top_pad="5"
+     right="-115"
+     top_delta="0"
+     width="90" />
+    <button
+     follows="right|bottom"
+     height="22"
+     label="Cancel"
+     layout="topleft"
+     name="cancel_btn"
+     right="-20"
+     top_delta="0"
+     width="90" />
+</floater>
-- 
cgit v1.2.3