diff options
| -rw-r--r-- | indra/newview/llpanelface.cpp | 482 | ||||
| -rw-r--r-- | indra/newview/llpanelface.h | 27 | ||||
| -rw-r--r-- | indra/newview/llpanelobject.cpp | 474 | ||||
| -rw-r--r-- | indra/newview/llpanelobject.h | 30 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_tools.xml | 37 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_build_paste.xml | 30 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/menu_texture_paste.xml | 70 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/panel_tools_texture.xml | 55 | 
8 files changed, 972 insertions, 233 deletions
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index c686aab821..1e0b1874f7 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@  #include "llfontgl.h"  // project includes +#include "llagent.h" // gAgent  #include "llagentdata.h"  #include "llbutton.h"  #include "llcheckboxctrl.h" @@ -45,10 +46,14 @@  #include "llcombobox.h"  #include "lldrawpoolbump.h"  #include "llface.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" // gInventory  #include "lllineeditor.h"  #include "llmaterialmgr.h"  #include "llmediaentry.h" +#include "llmenubutton.h"  #include "llnotificationsutil.h" +#include "llpanelobject.h" // LLPanelObject::canCopyTexture  #include "llradiogroup.h"  #include "llresmgr.h"  #include "llselectmgr.h" @@ -298,7 +303,18 @@ BOOL	LLPanelFace::postBuild()  	{  		mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);  	} -	 + +    mBtnCopyFaces = getChild<LLButton>("copy_face_btn"); +    if(mBtnCopyFaces) +    { +        BtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this)); +    } +    mBtnPasteFaces = getChild<LLButton>("paste_face_btn"); +    if (mBtnPasteFaces) +    { +        mBtnPasteFaces->setCommitCallback(boost::bind(&LLPanelFace::onPasteFaces, this)); +    } +    mBtnPasteMenu = getChild<LLMenuButton>("paste_face_gear_btn");  	clearCtrls(); @@ -307,9 +323,21 @@ BOOL	LLPanelFace::postBuild()  LLPanelFace::LLPanelFace()  :	LLPanel(), -	mIsAlpha(false) +    mIsAlpha(false), +    mPasteColor(TRUE), +    mPasteAlpha(TRUE), +    mPasteGlow(TRUE), +    mPasteDiffuse(TRUE), +    mPasteNormal(TRUE), +    mPasteSpecular(TRUE), +    mPasteMapping(TRUE), +    mPasteMedia(TRUE)  {  	USE_TEXTURE = LLTrans::getString("use_texture"); + +    mEnableCallbackRegistrar.add("BuildFace.PasteCheckItem", boost::bind(&LLPanelFace::pasteCheckMenuItem, this, _2)); +    mCommitCallbackRegistrar.add("BuildFace.PasteDoToSelected", boost::bind(&LLPanelFace::pasteDoMenuItem, this, _2)); +    mEnableCallbackRegistrar.add("BuildFace.PasteEnable", boost::bind(&LLPanelFace::pasteEnabletMenuItem, this, _2));  } @@ -1535,6 +1563,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)  			}  		} +        S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); +        BOOL single_volume = (selected_count == 1); +        mBtnCopyFaces->setEnabled(editable && single_volume); +        mBtnPasteFaces->setEnabled(editable && (mClipboard.size() > 0)); +        mBtnPasteMenu->setEnabled(editable); +  		// Set variable values for numeric expressions  		LLCalc* calcp = LLCalc::getInstance();  		calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); @@ -1735,8 +1769,6 @@ void LLPanelFace::updateVisibility()  	getChildView("bumpyRot")->setVisible(show_bumpiness);  	getChildView("bumpyOffsetU")->setVisible(show_bumpiness);  	getChildView("bumpyOffsetV")->setVisible(show_bumpiness); - -  }  // static @@ -2850,3 +2882,445 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic  	} max_diff_repeats_func;  	identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );  } + +static LLSD texture_clipboard; + +void LLPanelFace::onCopyFaces() +{ +    LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); +    LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); +    S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); +    if( !objectp || !node +        || objectp->getPCode() != LL_PCODE_VOLUME +        || !objectp->permModify() +        || objectp->isPermanentEnforced() +        || selected_count > 1) +    { +        return; +    } + +    mClipboard.clear(); + +    S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); +    for (S32 te = 0; te < num_tes; ++te) +    { +        if (node->isTESelected(te)) +        { +            LLTextureEntry* tep = objectp->getTE(te); +            if (tep) +            { +                LLSD te_data; + +                te_data["te"] = tep->asLLSD(); +                te_data["te"]["glow"] = tep->getGlow(); +                te_data["te"]["shiny"] = tep->getShiny(); + +                if (te_data["te"].has("imageid")) +                { +                    LLUUID id = te_data["te"]["imageid"].asUUID(); +                    if (id.isNull() || !LLPanelObject::canCopyTexture(id)) +                    { +                        te_data["te"].erase("imageid"); +                        te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); +                    } +                    // else +                    // { +                        // te_data["te"]["imageid"] = canCopyTexture(te_data["te"]["imageid"].asUUID()); +                    // } +                } + +                LLMaterialPtr material_ptr = tep->getMaterialParams(); +                if (!material_ptr.isNull()) +                { +                    LLSD mat_data; + +                    mat_data["NormMap"] = material_ptr->getNormalID(); +                    mat_data["SpecMap"] = material_ptr->getSpecularID(); + +                    mat_data["NormRepX"] = material_ptr->getNormalRepeatX(); +                    mat_data["NormRepY"] = material_ptr->getNormalRepeatY(); +                    mat_data["NormOffX"] = material_ptr->getNormalOffsetX(); +                    mat_data["NormOffY"] = material_ptr->getNormalOffsetY(); +                    mat_data["NormRot"] = material_ptr->getNormalRotation(); + +                    mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX(); +                    mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY(); +                    mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX(); +                    mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY(); +                    mat_data["SpecRot"] = material_ptr->getSpecularRotation(); + +                    mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue(); +                    mat_data["SpecExp"] = material_ptr->getSpecularLightExponent(); +                    mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity(); +                    mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff(); +                    mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode(); + +                    // Replace no-copy textures, destination texture will get used instead if available +                    if (mat_data.has("NormMap")) +                    { +                        LLUUID id = te_data["material"]["NormMap"].asUUID(); +                        if (id.notNull() && !LLPanelObject::canCopyTexture(id)) +                        { +                            mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); +                            mat_data["NormMapNoCopy"] = true; +                        } +                         +                    } +                    if (mat_data.has("SpecMap")) +                    { +                        LLUUID id = te_data["material"]["SpecMap"].asUUID(); +                        if (id.notNull() && !LLPanelObject::canCopyTexture(id)) +                        { +                            mat_data["SpecMap"]  = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); +                            mat_data["SpecMapNoCopy"] = true; +                        } +                         +                    } + +                    te_data["material"] = mat_data; +                } + +                //*TODO: Media + +                mClipboard.append(te_data); +            } +        } +    } +} + +void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) +{ +    LLSD te_data; +    if (mClipboard.size() == 1) +    { +        te_data = *(mClipboard.beginArray()); +    } +    else if (mClipboard[te]) +    { +        te_data = mClipboard[te]; +    } +    else +    { +        return; +    } + +    LLTextureEntry* tep = objectp->getTE(te); +    if (tep) +    { +        if (te_data.has("te")) +        { +            // Texture +            if (mPasteDiffuse) +            { +                // Replace no-copy texture with target's +                if (!te_data["te"].has("imageid")) +                { +                    te_data["te"]["imageid"] = tep->getID(); +                } +                const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); +                LLViewerInventoryItem* item = gInventory.getItem(imageid); +                if (item) +                { +                    if (te == -1) // all faces +                    { +                        LLToolDragAndDrop::dropTextureAllFaces(objectp, +                                                               item, +                                                               LLToolDragAndDrop::SOURCE_AGENT, +                                                               LLUUID::null); +                    } +                    else // one face +                    { +                        LLToolDragAndDrop::dropTextureOneFace(objectp, +                                                              te, +                                                              item, +                                                              LLToolDragAndDrop::SOURCE_AGENT, +                                                              LLUUID::null); +                    } +                } +                else // not an inventory item +                { +                    LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +                    objectp->setTEImage(U8(te), image); +                } +            } + +            // Color / Alpha +            if ((mPasteColor || mPasteAlpha) && te_data.has("colors")) +            { +                LLColor4 color = objectp->getTE(te)->getColor(); + +                LLColor4 clip_color; +                clip_color.setValue(te_data["colors"]); + +                // Color +                if (mPasteColor) +                { +                    color.mV[VRED] = clip_color.mV[VRED]; +                    color.mV[VGREEN] = clip_color.mV[VGREEN]; +                    color.mV[VBLUE] = clip_color.mV[VBLUE]; +                } + +                // Alpha +                if (mPasteAlpha) +                { +                    color.mV[VALPHA] = clip_color.mV[VALPHA]; +                } + +                objectp->setTEColor(te, color); +            } +             +            // Glow +            if (mPasteGlow && te_data.has("glow")) +            { +                objectp->setTEGlow(te, (F32)te_data["glow"].asReal()); +            } + +            // Texture map +            if (mPasteMapping) +            { +                if (te_data.has("scales") && te_data.has("scalet")) +                { +                    objectp->setTEScale(te, (F32)te_data["scales"].asReal(), (F32)te_data["scalet"].asReal()); +                } +                if (te_data.has("offsets") && te_data.has("offsett")) +                { +                    objectp->setTEOffset(te, (F32)te_data["offsets"].asReal(), (F32)te_data["offsett"].asReal()); +                } +                if (te_data.has("imagerot")) +                { +                    objectp->setTERotation(te, (F32)te_data["imagerot"].asReal()); +                } +            } + +           // Media +            if (mPasteMedia && te_data.has("media")) +            { +                //*TODO +            } +            else +            { +                // // Keep media flags on destination unchanged +                // // Media is handled later +                // if (te_data["te"].has("media_flags")) +                // { +                    // te_data["te"]["media_flags"] = tep->getMediaTexGen(); +                // } +            } +        } + +        if (te_data.has("material")) +        { +            LLUUID object_id = objectp->getID(); + +            LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + +            if (mPasteNormal) +            { +                // Replace placeholders with target's +                if (te_data["material"].has("NormMapNoCopy")) +                { +                    LLMaterialPtr material = tep->getMaterialParams(); +                    if (material.notNull()) +                    { +                        LLUUID id = material->getNormalID(); +                        if (id.notNull()) +                        { +                            te_data["material"]["NormMap"] = id; +                        } +                    } +                } +                LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id); +                LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id); +                LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id); +                LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id); +                LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id); +                LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id); +            } + +            if (mPasteSpecular) +            { +                // Replace placeholders with target's +                if (te_data["material"].has("SpecMapNoCopy")) +                { +                    LLMaterialPtr material = tep->getMaterialParams(); +                    if (material.notNull()) +                    { +                        LLUUID id = material->getSpecularID(); +                        if (id.notNull()) +                        { +                            te_data["material"]["SpecMap"] = id; +                        } +                    } +                } +                LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id); +                LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id); +                LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id); +                LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id); +                LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id); +                LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id); +                LLColor4 spec_color(te_data["material"]["SpecColor"]); +                LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); +                LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); +                LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te), object_id; +                LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); +                if (te_data.has("shiny")) +                { +                    objectp->setTEShiny(te, (U8)te_data["shiny"].asInteger()); +                } +            } +        } +    } +} + +struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor +{ +    LLPanelFacePasteTexFunctor(LLPanelFace* panel) : +        mPanelFace(panel){} + +    virtual bool apply(LLViewerObject* objectp, S32 te) +    { +        mPanelFace->pasteFace(objectp, te); +        return true; +    } +private: +    LLPanelFace *mPanelFace; +}; + +void LLPanelFace::onPasteFaces() +{ +    LLPanelFacePasteTexFunctor paste_func(this); +    LLSelectMgr::getInstance()->getSelection()->applyToTEs(&paste_func); + +    LLPanelFaceSendFunctor sendfunc; +    LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); +} + +bool LLPanelFace::pasteCheckMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    if ("Color" == command) +    { +        return mPasteColor; +    } +    if ("Transparency" == command) +    { +        return mPasteAlpha; +    } +    if ("Glow" == command) +    { +        return mPasteGlow; +    } +    if ("Diffuse" == command) +    { +        return mPasteDiffuse; +    } +    if ("Normal" == command) +    { +        return mPasteNormal; +    } +    if ("Specular" == command) +    { +        return mPasteSpecular; +    } +    if ("Mapping" == command) +    { +        return mPasteMapping; +    } +    if ("Media" == command) +    { +        return mPasteMedia; +    } + +    return false; +} + +void LLPanelFace::pasteDoMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    if ("Color" == command) +    { +        mPasteColor = !mPasteColor; +    } +    if ("Transparency" == command) +    { +        mPasteAlpha = !mPasteAlpha; +    } +    if ("Glow" == command) +    { +        mPasteGlow = !mPasteGlow; +    } +    if ("Diffuse" == command) +    { +        mPasteDiffuse = !mPasteDiffuse; +    } +    if ("Normal" == command) +    { +        mPasteNormal = !mPasteNormal; +    } +    if ("Specular" == command) +    { +        mPasteSpecular = !mPasteSpecular; +    } +    if ("Mapping" == command) +    { +        mPasteMapping = !mPasteMapping; +    } +    if ("Media" == command) +    { +        mPasteMedia = !mPasteMedia; +    } +} + +bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    // Keep at least one option enabled +    S32 num_enabled = mPasteColor +                    + mPasteAlpha +                    + mPasteGlow +                    + mPasteDiffuse +                    + mPasteNormal +                    + mPasteSpecular +                    + mPasteMapping +                    + mPasteMedia; +    if ( num_enabled == 1) +    { +        if ("Color" == command && mPasteColor) +        { +            return false; +        } +        if ("Transparency" == command && mPasteAlpha) +        { +            return false; +        } +        if ("Glow" == command && mPasteGlow) +        { +            return false; +        } +        if ("Diffuse" == command && mPasteDiffuse) +        { +            return false; +        } +        if ("Normal" == command && mPasteNormal) +        { +            return false; +        } +        if ("Specular" == command && mPasteSpecular) +        { +            return false; +        } +        if ("Mapping" == command && mPasteMapping) +        { +            return false; +        } +        if ("Media" == command && mPasteMedia) +        { +            return false; +        } +    } + +    return true; +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 2d57d89a44..76673c6444 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -47,6 +47,7 @@ class LLUICtrl;  class LLViewerObject;  class LLFloater;  class LLMaterialID; +class LLMenuButton;  // Represents an edit for use in replicating the op across one or more materials in the selection set.  // @@ -113,6 +114,8 @@ public:  	LLRender::eTexIndex getTextureChannelToEdit(); +    void            pasteFace(LLViewerObject* object, S32 te); +  protected:  	void			getState(); @@ -205,9 +208,13 @@ protected:  	static void		onClickAutoFix(void*);      static void		onAlignTexture(void*); -	static F32     valueGlow(LLViewerObject* object, S32 face); +    void            onCopyFaces(); +    void            onPasteFaces(); +    bool            pasteCheckMenuItem(const LLSD& userdata); +    void            pasteDoMenuItem(const LLSD& userdata); +    bool            pasteEnabletMenuItem(const LLSD& userdata); -	 +	static F32     valueGlow(LLViewerObject* object, S32 face);  private: @@ -234,6 +241,20 @@ private:  	F32		getCurrentShinyOffsetU();  	F32		getCurrentShinyOffsetV(); +    LLButton        *mBtnCopyFaces; +    LLButton        *mBtnPasteFaces; +    LLMenuButton    *mBtnPasteMenu; + +    LLSD            mClipboard; +    BOOL            mPasteColor; +    BOOL            mPasteAlpha; +    BOOL            mPasteGlow; +    BOOL            mPasteDiffuse; +    BOOL            mPasteNormal; +    BOOL            mPasteSpecular; +    BOOL            mPasteMapping; +    BOOL            mPasteMedia; +  	// Update visibility of controls to match current UI mode  	// (e.g. materials vs media editing)  	// @@ -497,6 +518,8 @@ public:  		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID);  		DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID);  		DEF_EDIT_MAT_STATE(LLColor4U,	const LLColor4U&,setSpecularLightColor); + +		DEF_EDIT_MAT_STATE(LLSD, const LLSD&, fromLLSD);  	};  	class LLSelectedTE diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 3c41a4bce4..a382813de6 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -50,6 +50,7 @@  #include "llinventoryfunctions.h"  #include "llinventorymodel.h"  #include "llmanipscale.h" +#include "llmenubutton.h"  #include "llpreviewscript.h"  #include "llresmgr.h"  #include "llselectmgr.h" @@ -155,27 +156,28 @@ BOOL	LLPanelObject::postBuild()      // Copy/paste pos      mBtnCopyPos = getChild<LLButton>("copy_pos_btn"); -    mBtnCopyPos->setCommitCallback( boost::bind(&LLPanelObject::onCopyPos, this, _2 )); +    mBtnCopyPos->setCommitCallback(boost::bind(&LLPanelObject::onCopyPos, this));      mBtnPastePos = getChild<LLButton>("paste_pos_btn"); -    mBtnPastePos->setCommitCallback( boost::bind(&LLPanelObject::onPastePos, this, _2 )); -	 +    mBtnPastePos->setCommitCallback(boost::bind(&LLPanelObject::onPastePos, this)); +      // Copy/paste size      mBtnCopySize = getChild<LLButton>("copy_size_btn"); -    mBtnCopySize->setCommitCallback( boost::bind(&LLPanelObject::onCopySize, this, _2 )); +    mBtnCopySize->setCommitCallback(boost::bind(&LLPanelObject::onCopySize, this));      mBtnPasteSize = getChild<LLButton>("paste_size_btn"); -    mBtnPasteSize->setCommitCallback( boost::bind(&LLPanelObject::onPasteSize, this, _2 )); -	 +    mBtnPasteSize->setCommitCallback(boost::bind(&LLPanelObject::onPasteSize, this)); +      // Copy/paste rot      mBtnCopyRot = getChild<LLButton>("copy_rot_btn"); -    mBtnCopyRot->setCommitCallback( boost::bind(&LLPanelObject::onCopyRot, this, _2 )); +    mBtnCopyRot->setCommitCallback(boost::bind(&LLPanelObject::onCopyRot, this));      mBtnPasteRot = getChild<LLButton>("paste_rot_btn"); -    mBtnPasteRot->setCommitCallback( boost::bind(&LLPanelObject::onPasteRot, this, _2 ));; +    mBtnPasteRot->setCommitCallback(boost::bind(&LLPanelObject::onPasteRot, this));;      // Copy/paste obj prams      mBtnCopyParams = getChild<LLButton>("copy_params_btn"); -    mBtnCopyParams->setCommitCallback( boost::bind(&LLPanelObject::onCopyParams, this, _2 )); +    mBtnCopyParams->setCommitCallback(boost::bind(&LLPanelObject::onCopyParams, this));      mBtnPasteParams = getChild<LLButton>("paste_params_btn"); -    mBtnPasteParams->setCommitCallback( boost::bind(&LLPanelObject::onPasteParams, this, _2 )); +    mBtnPasteParams->setCommitCallback(boost::bind(&LLPanelObject::onPasteParams, this)); +    mBtnPasteMenu = getChild<LLMenuButton>("paste_gear_btn");  	//-------------------------------------------------------- @@ -317,8 +319,14 @@ LLPanelObject::LLPanelObject()      mHasParamsClipboard(FALSE),      mHasPosClipboard(FALSE),      mHasSizeClipboard(FALSE), -    mHasRotClipboard(FALSE) +    mHasRotClipboard(FALSE), +    mPasteParametric(TRUE), +    mPastePhysics(TRUE), +    mPasteLight(TRUE)  { +    mEnableCallbackRegistrar.add("BuildObject.PasteCheckItem", boost::bind(&LLPanelObject::pasteCheckMenuItem, this, _2)); +    mCommitCallbackRegistrar.add("BuildObject.PasteDoToSelected", boost::bind(&LLPanelObject::pasteDoMenuItem, this, _2)); +    mEnableCallbackRegistrar.add("BuildObject.PasteEnable", boost::bind(&LLPanelObject::pasteEnabletMenuItem, this, _2));  } @@ -475,6 +483,7 @@ void LLPanelObject::getState( )      mBtnCopyParams->setEnabled( single_volume && enable_modify );      mBtnPasteParams->setEnabled( single_volume && enable_modify && mHasParamsClipboard ); +    mBtnPasteMenu->setEnabled( single_volume && enable_modify );  	LLUUID owner_id;  	std::string owner_name; @@ -2042,49 +2051,55 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)  	self->sendSculpt();  } -void copy_vector_to_clipboard(const LLVector3& vec) +void LLPanelObject::onCopyPos()  { -    std::string stringVec = llformat("<%g, %g, %g>", vec.mV[VX], vec.mV[VY], vec.mV[VZ]); -	LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); -} +    mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get()); -void LLPanelObject::onCopyPos(const LLSD& data) -{ -	mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get()); +    std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]); +    LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); -    copy_vector_to_clipboard(mClipboardPos); +    LLStringUtil::format_map_t args; +    args["VALUE"] = stringVec; +    mBtnPastePos->setToolTip(getString("paste_position", args)); -    mBtnPastePos->setToolTip(llformat("Paste Position\n<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]));      mBtnPastePos->setEnabled(TRUE);      mHasPosClipboard = TRUE;  } -void LLPanelObject::onCopySize(const LLSD& data) +void LLPanelObject::onCopySize()  { -	mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get()); +    mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get()); + +    std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]); +    LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); -    copy_vector_to_clipboard(mClipboardSize); +    LLStringUtil::format_map_t args; +    args["VALUE"] = stringVec; +    mBtnPasteSize->setToolTip(getString("paste_size", args)); -    mBtnPasteSize->setToolTip(llformat("Paste Size\n<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]));      mBtnPasteSize->setEnabled(TRUE);      mHasSizeClipboard = TRUE;  } -void LLPanelObject::onCopyRot(const LLSD& data) +void LLPanelObject::onCopyRot()  { -	mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get()); +    mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get()); -    copy_vector_to_clipboard(mClipboardRot); +    std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]); +    LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); + +    LLStringUtil::format_map_t args; +    args["VALUE"] = stringVec; +    mBtnPasteRot->setToolTip(getString("paste_rotation", args)); -    mBtnPasteRot->setToolTip(llformat("Paste Rotation\n<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]));      mBtnPasteRot->setEnabled(TRUE);      mHasRotClipboard = TRUE;  } -void LLPanelObject::onPastePos(const LLSD& data) +void LLPanelObject::onPastePos()  {      if(!mHasPosClipboard) return; @@ -2103,7 +2118,7 @@ void LLPanelObject::onPastePos(const LLSD& data)      sendPosition(FALSE);  } -void LLPanelObject::onPasteSize(const LLSD& data) +void LLPanelObject::onPasteSize()  {      if(!mHasSizeClipboard) return; @@ -2118,7 +2133,7 @@ void LLPanelObject::onPasteSize(const LLSD& data)      sendScale(FALSE);  } -void LLPanelObject::onPasteRot(const LLSD& data) +void LLPanelObject::onPasteRot()  {      if(!mHasRotClipboard) return; @@ -2129,7 +2144,7 @@ void LLPanelObject::onPasteRot(const LLSD& data)      sendRotation(FALSE);  } -void LLPanelObject::onCopyParams(const LLSD& data) +void LLPanelObject::onCopyParams()  {      LLViewerObject* objectp = mObject;      if (!objectp) @@ -2137,9 +2152,13 @@ void LLPanelObject::onCopyParams(const LLSD& data)          return;      } +    mParamsClipboard.clear(); + +    mParamsClipboard["is_phantom"] = objectp->flagPhantom(); +    mParamsClipboard["is_physical"] = objectp->flagUsePhysics(); +      // Parametrics      getVolumeParams(mClipboardVolumeParams); -    mHasParamsClipboard = TRUE;      LLVOVolume *volobjp = NULL;      if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) @@ -2153,122 +2172,70 @@ void LLPanelObject::onCopyParams(const LLSD& data)          LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);          if (attributes)          { -            mParamsClipboard["lod"] = attributes->getSimulateLOD(); -            mParamsClipboard["gav"] = attributes->getGravity(); -            mParamsClipboard["ten"] = attributes->getTension(); -            mParamsClipboard["fri"] = attributes->getAirFriction(); -            mParamsClipboard["sen"] = attributes->getWindSensitivity(); +            mParamsClipboard["flex"]["lod"] = attributes->getSimulateLOD(); +            mParamsClipboard["flex"]["gav"] = attributes->getGravity(); +            mParamsClipboard["flex"]["ten"] = attributes->getTension(); +            mParamsClipboard["flex"]["fri"] = attributes->getAirFriction(); +            mParamsClipboard["flex"]["sen"] = attributes->getWindSensitivity();              LLVector3 force = attributes->getUserForce(); -            mParamsClipboard["forx"] = force.mV[0]; -            mParamsClipboard["fory"] = force.mV[1]; -            mParamsClipboard["forz"] = force.mV[2]; -            mHasFlexiParam = TRUE; +            mParamsClipboard["flex"]["forx"] = force.mV[0]; +            mParamsClipboard["flex"]["fory"] = force.mV[1]; +            mParamsClipboard["flex"]["forz"] = force.mV[2];          }      } -    else -    { -        mHasFlexiParam = FALSE; -    }      // Sculpted Prim -    // User is allowed to copy if they could otherwise recreate it manually -    // ie. User has full perm copy of the sculpted texture in their inventory, -    // or is a default texture or library asset.      if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))      {          LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); -        LLUUID image_id = sculpt_params->getSculptTexture(); -        BOOL allow_texture = FALSE; -        if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) -            || image_id == LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )) -            || image_id == LLUUID(gSavedSettings.getString( "UIImgWhiteUUID" )) -            || image_id == LLUUID(gSavedSettings.getString( "UIImgInvisibleUUID" )) -            || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) +        LLUUID texture_id = sculpt_params->getSculptTexture(); +        if (canCopyTexture(texture_id))          { -            allow_texture = TRUE; +            LL_INFOS() << "copu texture " << LL_ENDL; +            mParamsClipboard["sculpt"]["id"] = texture_id;          }          else          { -            LLUUID inventory_item_id; -            LLViewerInventoryCategory::cat_array_t cats; -            LLViewerInventoryItem::item_array_t items; -            LLAssetIDMatches asset_id_matches(image_id); -            gInventory.collectDescendentsIf(LLUUID::null, -                                    cats, -                                    items, -                                    LLInventoryModel::INCLUDE_TRASH, -                                    asset_id_matches); - -            if (items.size()) -            { -                // search for copyable version first -                for (S32 i = 0; i < items.size(); i++) -                { -                    LLInventoryItem* itemp = items[i]; -                    LLPermissions item_permissions = itemp->getPermissions(); -                    if (item_permissions.allowCopyBy(gAgent.getID(), gAgent.getGroupID())) -                    { -                        inventory_item_id = itemp->getUUID(); -                        break; -                    } -                } -            } -            if (inventory_item_id.notNull()) -            { -                LLInventoryItem* itemp = gInventory.getItem(inventory_item_id); -                if (itemp) -                { -                    LLPermissions perm = itemp->getPermissions(); -                    if ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) -                    { -                        allow_texture = TRUE; -                    } -                } -            } -        } -        if (allow_texture) -        { -            mParamsClipboard["sculptid"] = image_id; -        } -        else -        { -            mParamsClipboard["sculptid"] = LLUUID(SCULPT_DEFAULT_TEXTURE); +            mParamsClipboard["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);          } -        mParamsClipboard["sculpt_type"] = sculpt_params->getSculptType(); -        mHasSculptParam = TRUE; -    } -    else -    { -        mHasSculptParam = FALSE; +        mParamsClipboard["sculpt"]["type"] = sculpt_params->getSculptType();      }      // Light Source -    // only captures basic settings      if (volobjp && volobjp->getIsLight())      { -        mParamsClipboard["Light Intensity"] = volobjp->getLightIntensity(); -        mParamsClipboard["Light Radius"] = volobjp->getLightRadius(); -        mParamsClipboard["Light Falloff"] = volobjp->getLightFalloff(); +        mParamsClipboard["light"]["intensity"] = volobjp->getLightIntensity(); +        mParamsClipboard["light"]["radius"] = volobjp->getLightRadius(); +        mParamsClipboard["light"]["falloff"] = volobjp->getLightFalloff();          LLColor3 color = volobjp->getLightColor(); -        mParamsClipboard["r"] = color.mV[0]; -        mParamsClipboard["g"] = color.mV[1]; -        mParamsClipboard["b"] = color.mV[2]; -        mHasLightParam = TRUE; -    } -    else -    { -        mHasLightParam = FALSE; +        mParamsClipboard["light"]["r"] = color.mV[0]; +        mParamsClipboard["light"]["g"] = color.mV[1]; +        mParamsClipboard["light"]["b"] = color.mV[2]; + +        // Spotlight +        if (volobjp->isLightSpotlight()) +        { +            LLUUID id = volobjp->getLightTextureID(); +            if (id.notNull() && canCopyTexture(id)) +            { +                mParamsClipboard["spot"]["id"] = id; +                LLVector3 spot_params = volobjp->getSpotLightParams(); +                mParamsClipboard["spot"]["fov"] = spot_params.mV[0]; +                mParamsClipboard["spot"]["focus"] = spot_params.mV[1]; +                mParamsClipboard["spot"]["ambiance"] = spot_params.mV[2]; +            } +        }      }      // Physics      { -        mParamsClipboard["physics_shape"] = objectp->getPhysicsShapeType(); -        mParamsClipboard["physics_gravity"] = objectp->getPhysicsGravity(); -        mParamsClipboard["physics_friction"] = objectp->getPhysicsFriction(); -        mParamsClipboard["physics_density"] = objectp->getPhysicsDensity(); -        mParamsClipboard["physics_restitution"] = objectp->getPhysicsRestitution(); +        mParamsClipboard["physics"]["shape"] = objectp->getPhysicsShapeType(); +        mParamsClipboard["physics"]["gravity"] = objectp->getPhysicsGravity(); +        mParamsClipboard["physics"]["friction"] = objectp->getPhysicsFriction(); +        mParamsClipboard["physics"]["density"] = objectp->getPhysicsDensity(); +        mParamsClipboard["physics"]["restitution"] = objectp->getPhysicsRestitution();          U8 material_code = 0;          struct f : public LLSelectedTEGetFunctor<U8> @@ -2282,13 +2249,14 @@ void LLPanelObject::onCopyParams(const LLSD& data)          // This should always be true since material should be per object.          if (material_same)          { -            mParamsClipboard["physics_material"] = material_code; +            mParamsClipboard["physics"]["material"] = material_code;          }      } -    mBtnPasteParams->setEnabled(TRUE); + +    mHasParamsClipboard = TRUE;  } -void LLPanelObject::onPasteParams(const LLSD& data) +void LLPanelObject::onPasteParams()  {      LLViewerObject* objectp = mObject;      if (!objectp || !mHasParamsClipboard) @@ -2296,111 +2264,217 @@ void LLPanelObject::onPasteParams(const LLSD& data)          return;      } -    // Flexi Prim -    if (mHasFlexiParam && (objectp->getPCode() == LL_PCODE_VOLUME)) +    LLVOVolume *volobjp = NULL; +    if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))      { -        LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); -        if (attributes) -        { -            LLFlexibleObjectData new_attributes; -            new_attributes = *attributes; - -            new_attributes.setSimulateLOD(mParamsClipboard["lod"].asInteger()); -            new_attributes.setGravity(mParamsClipboard["gav"].asReal()); -            new_attributes.setTension(mParamsClipboard["ten"].asReal()); -            new_attributes.setAirFriction(mParamsClipboard["fri"].asReal()); -            new_attributes.setWindSensitivity(mParamsClipboard["sen"].asReal()); -            F32 fx = (F32)mParamsClipboard["forx"].asReal(); -            F32 fy = (F32)mParamsClipboard["fory"].asReal(); -            F32 fz = (F32)mParamsClipboard["forz"].asReal(); -            LLVector3 force(fx,fy,fz); -            new_attributes.setUserForce(force); -            objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); -        } +        volobjp = (LLVOVolume *)objectp;      } -    // Sculpted Prim -    if (mHasSculptParam) +    // Light Source +    if (mPasteLight && volobjp)      { -        LLSculptParams sculpt_params; - -        if (mParamsClipboard.has("sculptid")) +        if (mParamsClipboard.has("light"))          { -            sculpt_params.setSculptTexture(mParamsClipboard["sculptid"].asUUID(), (U8)mParamsClipboard["sculpt_type"].asInteger()); +            volobjp->setIsLight(TRUE); +            volobjp->setLightIntensity((F32)mParamsClipboard["light"]["intensity"].asReal()); +            volobjp->setLightRadius((F32)mParamsClipboard["light"]["radius"].asReal()); +            volobjp->setLightFalloff((F32)mParamsClipboard["light"]["falloff"].asReal()); +            F32 r = (F32)mParamsClipboard["light"]["r"].asReal(); +            F32 g = (F32)mParamsClipboard["light"]["g"].asReal(); +            F32 b = (F32)mParamsClipboard["light"]["b"].asReal(); +            volobjp->setLightColor(LLColor3(r,g,b));          } -        objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); -    } -    else -    { -        LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); -        if (sculpt_params) +        if (mParamsClipboard.has("spot"))          { -            objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); +            volobjp->setLightTextureID(mParamsClipboard["spot"]["id"].asUUID()); +            LLVector3 spot_params; +            spot_params.mV[0] = (F32)mParamsClipboard["spot"]["fov"].asReal(); +            spot_params.mV[1] = (F32)mParamsClipboard["spot"]["focus"].asReal(); +            spot_params.mV[2] = (F32)mParamsClipboard["spot"]["ambiance"].asReal(); +            volobjp->setSpotLightParams(spot_params);          }      } -    // Light Source -    if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) +    // Physics +    if (mPastePhysics)      { -        LLVOVolume *volobjp = (LLVOVolume *)objectp; +        bool is_root = objectp->isRoot(); -        if (volobjp && mHasLightParam) -        { -            volobjp->setIsLight(TRUE); -            volobjp->setLightIntensity((F32)mParamsClipboard["Light Intensity"].asReal()); -            volobjp->setLightRadius((F32)mParamsClipboard["Light Radius"].asReal()); -            volobjp->setLightFalloff((F32)mParamsClipboard["Light Falloff"].asReal()); -            F32 r = (F32)mParamsClipboard["r"].asReal(); -            F32 g = (F32)mParamsClipboard["g"].asReal(); -            F32 b = (F32)mParamsClipboard["b"].asReal(); -            volobjp->setLightColor(LLColor3(r,g,b)); -        } -    } +        // Not sure if phantom should go under physics, but doesn't fit elsewhere +        BOOL is_phantom = mParamsClipboard["is_phantom"].asBoolean() && is_root; +        LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom); -    // Physics -    { -        if (mParamsClipboard.has("physics_shape")) -        { -            objectp->setPhysicsShapeType((U8)mParamsClipboard["physics_shape"].asInteger()); -        } -        if (mParamsClipboard.has("physics_material")) +        BOOL is_physical = mParamsClipboard["is_physical"].asBoolean() && is_root; +        LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical); + +        if (mParamsClipboard.has("physics"))          { +            objectp->setPhysicsShapeType((U8)mParamsClipboard["physics"]["shape"].asInteger());              U8 cur_material = objectp->getMaterial();              U8 material = (U8)mParamsClipboard["physics_material"].asInteger() | (cur_material & ~LL_MCODE_MASK); +              objectp->setMaterial(material);              objectp->sendMaterialUpdate(); +            objectp->setPhysicsGravity(mParamsClipboard["physics"]["gravity"].asReal()); +            objectp->setPhysicsFriction(mParamsClipboard["physics"]["friction"].asReal()); +            objectp->setPhysicsDensity(mParamsClipboard["physics"]["density"].asReal()); +            objectp->setPhysicsRestitution(mParamsClipboard["physics"]["restitution"].asReal()); +            objectp->updateFlags(TRUE);          } -        bool phys_update_flags = false; -        if (mParamsClipboard.has("physics_gravity")) +    } + +    // Parametrics +    if(mPasteParametric) +    { +        // Sculpted Prim +        if (mParamsClipboard.has("sculpt"))          { -            objectp->setPhysicsGravity(mParamsClipboard["physics_gravity"].asReal()); -            phys_update_flags = true; +            LLSculptParams sculpt_params; +            LLUUID sculpt_id = mParamsClipboard["sculpt"]["id"].asUUID(); +            U8 sculpt_type = (U8)mParamsClipboard["sculpt"]["type"].asInteger(); +            sculpt_params.setSculptTexture(sculpt_id, sculpt_type); +            objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);          } -        if (mParamsClipboard.has("physics_friction")) +        else          { -            objectp->setPhysicsFriction(mParamsClipboard["physics_friction"].asReal()); -            phys_update_flags = true; +            LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); +            if (sculpt_params) +            { +                objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); +            }          } -        if (mParamsClipboard.has("physics_density")) + +        // Flexi Params +        if (mParamsClipboard.has("flex"))          { -            objectp->setPhysicsDensity(mParamsClipboard["physics_density"].asReal()); -            phys_update_flags = true; +            if (objectp->getClickAction() == CLICK_ACTION_SIT) +            { +                objectp->setClickAction(CLICK_ACTION_NONE); +            } + +            LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); +            if (attributes) +            { +                LLFlexibleObjectData new_attributes; +                new_attributes = *attributes; +                new_attributes.setSimulateLOD(mParamsClipboard["flex"]["lod"].asInteger()); +                new_attributes.setGravity(mParamsClipboard["flex"]["gav"].asReal()); +                new_attributes.setTension(mParamsClipboard["flex"]["ten"].asReal()); +                new_attributes.setAirFriction(mParamsClipboard["flex"]["fri"].asReal()); +                new_attributes.setWindSensitivity(mParamsClipboard["flex"]["sen"].asReal()); +                F32 fx = (F32)mParamsClipboard["flex"]["forx"].asReal(); +                F32 fy = (F32)mParamsClipboard["flex"]["fory"].asReal(); +                F32 fz = (F32)mParamsClipboard["flex"]["forz"].asReal(); +                LLVector3 force(fx,fy,fz); +                new_attributes.setUserForce(force); +                objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); +            }          } -        if (mParamsClipboard.has("physics_restitution")) + +        objectp->updateVolume(mClipboardVolumeParams); +    } +} + +bool LLPanelObject::pasteCheckMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    if ("Parametric" == command) +    { +        return mPasteParametric; +    } +    if ("Physics" == command) +    { +        return mPastePhysics; +    } +    if ("Light" == command) +    { +        return mPasteLight; +    } + +    return false; +} + +void LLPanelObject::pasteDoMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    if ("Parametric" == command) +    { +        mPasteParametric = !mPasteParametric; +    } +    if ("Physics" == command) +    { +        mPastePhysics = !mPastePhysics; +    } +    if ("Light" == command) +    { +        mPasteLight = !mPasteLight; +    } +} + +bool LLPanelObject::pasteEnabletMenuItem(const LLSD& userdata) +{ +    std::string command = userdata.asString(); + +    // Keep at least one option enabled +    if (mPasteParametric + mPastePhysics + mPasteLight == 1) +    { +        if ("Parametric" == command && mPasteParametric)          { -            objectp->setPhysicsRestitution(mParamsClipboard["physics_restitution"].asReal()); -            phys_update_flags = true; +            return false;          } -        if (phys_update_flags) +        if ("Physics" == command && mPastePhysics)          { -            objectp->updateFlags(TRUE); +            return false; +        } +        if ("Light" == command && mPasteLight) +        { +            return false;          }      } -    // Parametrics -    if(mHasParamsClipboard) +    return true; +} + +// Static +bool LLPanelObject::canCopyTexture(LLUUID image_id) +{ +    // User is allowed to copy a texture if: +    // library asset or default texture, +    // or full perm asset exists in user's inventory + +    // Library asset or default texture +    if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) +        || image_id == LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )) +        || image_id == LLUUID(gSavedSettings.getString( "UIImgWhiteUUID" )) +        || image_id == LLUUID(gSavedSettings.getString( "UIImgInvisibleUUID" )) +        || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE))      { -        objectp->updateVolume(mClipboardVolumeParams); +        return true; +    } + +    // Search for a full perm asset +    LLViewerInventoryCategory::cat_array_t cats; +    LLViewerInventoryItem::item_array_t items; +    LLAssetIDMatches asset_id_matches(image_id); +    gInventory.collectDescendentsIf(LLUUID::null, +                                    cats, +                                    items, +                                    LLInventoryModel::INCLUDE_TRASH, +                                    asset_id_matches); +    if (items.size()) +    { +        for (S32 i = 0; i < items.size(); i++) +        { +            LLViewerInventoryItem* itemp = items[i]; +            if (itemp->getIsFullPerm()) +            { +                return true; +            } +        }      } + +    return false;  } diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 46725a80e4..7161f51c73 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -37,6 +37,7 @@ class LLCheckBoxCtrl;  class LLTextBox;  class LLUICtrl;  class LLButton; +class LLMenuButton;  class LLViewerObject;  class LLComboBox;  class LLColorSwatchCtrl; @@ -66,14 +67,14 @@ public:  	static void 	onCommitPhantom(		LLUICtrl* ctrl, void* userdata);  	static void 	onCommitPhysics(		LLUICtrl* ctrl, void* userdata); -    void            onCopyPos(const LLSD& data); -    void            onPastePos(const LLSD& data); -    void            onCopySize(const LLSD& data); -    void            onPasteSize(const LLSD& data); -    void            onCopyRot(const LLSD& data); -    void            onPasteRot(const LLSD& data); -    void            onCopyParams(const LLSD& data); -    void            onPasteParams(const LLSD& data); +    void            onCopyPos(); +    void            onPastePos(); +    void            onCopySize(); +    void            onPasteSize(); +    void            onCopyRot(); +    void            onPasteRot(); +    void            onCopyParams(); +    void            onPasteParams();  	static void 	onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -84,6 +85,11 @@ public:  	BOOL     		onDropSculpt(LLInventoryItem* item);  	static void     onCommitSculptType(    LLUICtrl *ctrl, void* userdata); +    bool            pasteCheckMenuItem(const LLSD& userdata); +    void            pasteDoMenuItem(const LLSD& userdata); +    bool            pasteEnabletMenuItem(const LLSD& userdata); +    static bool     canCopyTexture(LLUUID image_id); +  protected:  	void			getState(); @@ -164,6 +170,7 @@ protected:      LLButton        *mBtnPasteRot;      LLButton        *mBtnCopyParams;      LLButton        *mBtnPasteParams; +    LLMenuButton    *mBtnPasteMenu;  	LLCheckBoxCtrl	*mCheckLock;  	LLCheckBoxCtrl	*mCheckPhysics; @@ -196,9 +203,10 @@ protected:      LLSD            mParamsClipboard;      LLVolumeParams  mClipboardVolumeParams;      BOOL            mHasParamsClipboard; -    BOOL            mHasFlexiParam; -    BOOL            mHasSculptParam; -    BOOL            mHasLightParam; +     +    BOOL            mPasteParametric; +    BOOL            mPastePhysics; +    BOOL            mPasteLight;  	LLPointer<LLViewerObject> mObject;  	LLPointer<LLViewerObject> mRootObject; diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index bbb978a631..425af16261 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1397,6 +1397,18 @@ even though the user gets a free copy.           name="Object"           top="16"           width="295"> +            <panel.string name="paste_position"> +Paste Position +[VALUE] +            </panel.string> +            <panel.string name="paste_size"> +Paste Size +[VALUE] +            </panel.string> +            <panel.string name="paste_rotation"> +Paste Rotation +[VALUE] +            </panel.string>              <check_box               height="19"               label="Locked" @@ -1706,25 +1718,38 @@ even though the user gets a free copy.              </text>-->      		<button      		 follows="top|right" -    		 height="16" +    		 height="23"      		 label="Copy"      		 layout="topleft"      		 left="135"      		 name="copy_params_btn"      		 tool_tip="Copy Parameters to Clipboard"               top="6" -    		 width="65"> +    		 width="53">      		</button>      		<button      		 follows="top|right" -    		 height="16" +    		 height="23"      		 label="Paste"      		 layout="topleft" -    		 left_pad="10" +    		 left_pad="5"      		 name="paste_params_btn"      		 tool_tip="Paste Parameters from Clipboard" -    		 width="65"> +    		 width="53">      		</button> +            <menu_button +             menu_filename="menu_build_paste.xml" +             follows="top|left" +             height="23" +             image_hover_unselected="Toolbar_Middle_Over" +             image_overlay="OptionsMenu_Off" +             image_selected="Toolbar_Middle_Selected" +             image_unselected="Toolbar_Middle_Off" +             layout="topleft" +             left_pad="5" +             name="paste_gear_btn" +             tool_tip="Paste options" +             width="31"/>              <combo_box               height="19"               layout="topleft" @@ -2646,7 +2671,7 @@ even though the user gets a free copy.               top_pad="8"               width="132" />          </panel> -         <panel +        <panel           label="Texture"           help_topic="toolbox_texture_tab"           name="Texture" diff --git a/indra/newview/skins/default/xui/en/menu_build_paste.xml b/indra/newview/skins/default/xui/en/menu_build_paste.xml new file mode 100644 index 0000000000..f63362dabf --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_build_paste.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Conversation Gear Menu"> +    <menu_item_check +     label="Prim Parameters" +     layout="topleft" +     name="Parametric"> +        <on_check function="BuildObject.PasteCheckItem" parameter="Parametric" /> +        <on_click function="BuildObject.PasteDoToSelected" parameter="Parametric" /> +        <on_enable function="BuildObject.PasteEnable" parameter="Parametric" /> +    </menu_item_check> +    <menu_item_check +     label="Physics" +     layout="topleft" +     name="Physics"> +        <on_check function="BuildObject.PasteCheckItem" parameter="Physics" /> +        <on_click function="BuildObject.PasteDoToSelected" parameter="Physics" /> +        <on_enable function="BuildObject.PasteEnable" parameter="Physics" /> +    </menu_item_check> +    <menu_item_check +     label="Light" +     layout="topleft" +     name="Light"> +        <on_check function="BuildObject.PasteCheckItem" parameter="Light" /> +        <on_click function="BuildObject.PasteDoToSelected" parameter="Light" /> +        <on_enable function="BuildObject.PasteEnable" parameter="Light" /> +    </menu_item_check> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/menu_texture_paste.xml b/indra/newview/skins/default/xui/en/menu_texture_paste.xml new file mode 100644 index 0000000000..be6535b989 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_texture_paste.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + name="Conversation Gear Menu"> +    <menu_item_check +     label="Color" +     layout="topleft" +     name="Color"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Color" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Color" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Color" /> +    </menu_item_check> +    <menu_item_check +     label="Transparency" +     layout="topleft" +     name="Transparency"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Transparency" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Transparency" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Transparency" /> +    </menu_item_check> +    <menu_item_check +     label="Glow" +     layout="topleft" +     name="Glow"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Glow" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Glow" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Glow" /> +    </menu_item_check> +    <menu_item_check +     label="Texture" +     layout="topleft" +     name="Diffuse"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Diffuse" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Diffuse" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Diffuse" /> +    </menu_item_check> +    <menu_item_check +     label="Bumpiness" +     layout="topleft" +     name="Normal"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Normal" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Normal" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Normal" /> +    </menu_item_check> +    <menu_item_check +     label="Shininess" +     layout="topleft" +     name="Specular"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Specular" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Specular" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Specular" /> +    </menu_item_check> +    <menu_item_check +     label="Mapping" +     layout="topleft" +     name="Mapping"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Mapping" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Mapping" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Mapping" /> +    </menu_item_check> +    <menu_item_check +     label="Media" +     layout="topleft" +     name="Media"> +        <on_check function="BuildFace.PasteCheckItem" parameter="Media" /> +        <on_click function="BuildFace.PasteDoToSelected" parameter="Media" /> +        <on_enable function="BuildFace.PasteEnable" parameter="Media" /> +    </menu_item_check> +</toggleable_menu> + diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 90f32ae452..ec610758cc 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -43,7 +43,7 @@               follows="left|top"               height="10"               layout="topleft" -             left_pad="15" +             left_pad="10"               name="color trans"               text_readonly_color="LabelDisabledColor"               top="6" @@ -68,7 +68,7 @@               follows="left|top"               height="10"               layout="topleft" -             left_pad="15" +             left_pad="13"               name="glow label"               text_readonly_color="LabelDisabledColor"               top="6" @@ -84,7 +84,7 @@               left_delta="0"               name="glow"               top_pad="4" -             width="80" /> +             width="50" />              <check_box               height="19"               label="Full Bright" @@ -93,12 +93,47 @@               name="checkbox fullbright"               top_pad="4"               width="81" /> +            <button +             follows="top|right" +             height="23" +             label="Copy" +             layout="topleft" +             left="240" +             name="copy_face_btn" +             tool_tip="Copy Parameters to Clipboard" +             top="6" +             width="53"> +            </button> +            <button +             follows="top|right" +             height="23" +             label="Paste" +             layout="topleft" +             name="paste_face_btn" +             tool_tip="Paste Parameters from Clipboard" +             top_pad="5" +             width="53"> +            </button> +            <menu_button +             menu_filename="menu_texture_paste.xml" +             follows="top|left" +             height="23" +             image_hover_unselected="Toolbar_Middle_Over" +             image_overlay="OptionsMenu_Off" +             image_selected="Toolbar_Middle_Selected" +             image_unselected="Toolbar_Middle_Off" +             layout="topleft" +             left_delta="20" +             name="paste_face_gear_btn" +             tool_tip="Paste options" +             top_pad="5" +             width="31"/>              <combo_box               height="23"               layout="topleft"               left="10"               name="combobox matmedia" -             top_pad="5" +             top="70"               width="100">                  <combo_box.item                   label="Materials" @@ -113,10 +148,10 @@              control_name="ComboMaterialType"              height="50"              layout="topleft" -            left_pad="20" +            left_pad="5"              top_delta="-10"              width="150" -            visible = "false" +            visible = "true"              name="radio_material_type">                  <radio_item                  label="Texture (diffuse)" @@ -139,7 +174,7 @@                  layout="topleft"                  top_pad="1"                  value="2"/> -            </radio_group>  +            </radio_group>              <check_box               control_name="SyncMaterialSettings"               follows="top|left" @@ -158,7 +193,7 @@               fallback_image="materials_ui_x_24.png"               follows="left|top"               height="80" -             label="Texture       " +             label="Texture"               layout="topleft"               left="10"               name="texture control" @@ -235,7 +270,7 @@               fallback_image="materials_ui_x_24.png"               follows="left|top"               height="80" -             label="Texture       " +             label="Texture"               layout="topleft"               left="10"               name="bumpytexture control" @@ -349,7 +384,7 @@               fallback_image="materials_ui_x_24.png"               follows="left|top"               height="80" -             label="Texture       " +             label="Texture"               layout="topleft"               left="10"               name="shinytexture control"  | 
