diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b5a39aae34..1d3003df35 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -11582,6 +11582,17 @@ Change of this parameter will affect the layout of buttons in notification toast
Value
5748decc-f629-461c-9a36-a35a221fe21f
+ UIImgInvisibleUUID
+
+ Comment
+
+ Persist
+ 0
+ Type
+ String
+ Value
+ f54a0c32-3cd1-d49a-5b4f-7b792bebc204
+
UILineEditorCursorThickness
Comment
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 6e19c34241..3c09663c54 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -47,6 +47,8 @@
#include "llcolorswatch.h"
#include "llcombobox.h"
#include "llfocusmgr.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h"
#include "llmanipscale.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
@@ -67,6 +69,7 @@
#include "pipeline.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
+#include "llwindow.h" // for clipboad operations -KC
//#include "llfirstuse.h"
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
#include "rlvhandler.h"
@@ -167,6 +170,36 @@ BOOL LLPanelObject::postBuild()
mCtrlRotZ = getChild("Rot Z");
childSetCommitCallback("Rot Z",onCommitRotation,this);
+ // Copy/paste pos
+ mBtnCopyPos = getChild("copypos");
+ mBtnCopyPos->setCommitCallback( boost::bind(&LLPanelObject::onCopyPos, this, _2 ));
+ mBtnPastePos = getChild("pastepos");
+ mBtnPastePos->setCommitCallback( boost::bind(&LLPanelObject::onPastePos, this, _2 ));
+ mBtnPastePosClip = getChild("pasteposclip");
+ mBtnPastePosClip->setCommitCallback( boost::bind(&LLPanelObject::onPastePosClip, this, _2 ));
+
+ // Copy/paste size
+ mBtnCopySize = getChild("copysize");
+ mBtnCopySize->setCommitCallback( boost::bind(&LLPanelObject::onCopySize, this, _2 ));
+ mBtnPasteSize = getChild("pastesize");
+ mBtnPasteSize->setCommitCallback( boost::bind(&LLPanelObject::onPasteSize, this, _2 ));
+ mBtnPasteSizeClip = getChild("pastesizeclip");
+ mBtnPasteSizeClip->setCommitCallback( boost::bind(&LLPanelObject::onPasteSizeClip, this, _2 ));
+
+ // Copy/paste rot
+ mBtnCopyRot = getChild("copyrot");
+ mBtnCopyRot->setCommitCallback( boost::bind(&LLPanelObject::onCopyRot, this, _2 ));
+ mBtnPasteRot = getChild("pasterot");
+ mBtnPasteRot->setCommitCallback( boost::bind(&LLPanelObject::onPasteRot, this, _2 ));
+ mBtnPasteRotClip = getChild("pasterotclip");
+ mBtnPasteRotClip->setCommitCallback( boost::bind(&LLPanelObject::onPasteRotClip, this, _2 ));
+
+ // Copy/paste obj prams
+ mBtnCopyParams = getChild("copyparams");
+ mBtnCopyParams->setCommitCallback( boost::bind(&LLPanelObject::onCopyParams, this, _2 ));
+ mBtnPasteParams = getChild("pasteparams");
+ mBtnPasteParams->setCommitCallback( boost::bind(&LLPanelObject::onPasteParams, this, _2 ));
+
//--------------------------------------------------------
// material type popup
@@ -319,7 +352,11 @@ LLPanelObject::LLPanelObject()
mCastShadows(TRUE),
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
- mSculptTypeRevert(0)
+ mSculptTypeRevert(0),
+ mHasParamClipboard(FALSE),
+ mHasFlexiParam(FALSE),
+ mHasSculptParam(FALSE),
+ mHasLightParam(FALSE)
{
}
@@ -460,6 +497,18 @@ void LLPanelObject::getState( )
mCtrlRotY->setEnabled( enable_rotate );
mCtrlRotZ->setEnabled( enable_rotate );
+ mBtnCopyPos->setEnabled(enable_move);
+ mBtnPastePos->setEnabled(enable_move);
+ mBtnPastePosClip->setEnabled(enable_move);
+ mBtnCopySize->setEnabled( enable_scale );
+ mBtnPasteSize->setEnabled( enable_scale );
+ mBtnPasteSizeClip->setEnabled( enable_scale );
+ mBtnCopyRot->setEnabled( enable_rotate );
+ mBtnPasteRot->setEnabled( enable_rotate );
+ mBtnPasteRotClip->setEnabled( enable_rotate );
+ mBtnCopyParams->setEnabled( single_volume && objectp->permModify() );
+ mBtnPasteParams->setEnabled( single_volume && objectp->permModify() );
+
BOOL owners_identical;
LLUUID owner_id;
std::string owner_name;
@@ -2058,3 +2107,293 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
self->sendSculpt();
}
+
+
+void copy_vector_to_clipboard(const LLVector3& vec)
+{
+ std::string stringVec = llformat("<%g, %g, %g>", vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+}
+
+void LLPanelObject::onCopyPos(const LLSD& data)
+{
+ mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
+ copy_vector_to_clipboard(mClipboardPos);
+ mBtnPastePos->setToolTip(llformat("Paste Position\n<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]));
+}
+
+void LLPanelObject::onCopySize(const LLSD& data)
+{
+ mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
+ copy_vector_to_clipboard(mClipboardSize);
+ mBtnPasteSize->setToolTip(llformat("Paste Size\n<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]));
+}
+
+void LLPanelObject::onCopyRot(const LLSD& data)
+{
+ mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
+ copy_vector_to_clipboard(mClipboardRot);
+ mBtnPasteRot->setToolTip(llformat("Paste Rotation\n<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]));
+}
+
+
+void LLPanelObject::onPastePos(const LLSD& data)
+{
+ if(mClipboardPos.isNull()) return;
+
+ //clamp pos on non-attachments, just keep the prims on the sim
+ if (!mObject->isAttachment())
+ {
+ mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], 0.f, 256.f);
+ mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], 0.f, 256.f);
+ //height will get properly clammed by sendPosition
+ }
+
+ mCtrlPosX->set( mClipboardPos.mV[VX] );
+ mCtrlPosY->set( mClipboardPos.mV[VY] );
+ mCtrlPosZ->set( mClipboardPos.mV[VZ] );
+
+ sendPosition(FALSE);
+}
+
+void LLPanelObject::onPasteSize(const LLSD& data)
+{
+ if(mClipboardSize.isNull()) return;
+
+ mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+
+ mCtrlScaleX->set( mClipboardSize.mV[VX] );
+ mCtrlScaleY->set( mClipboardSize.mV[VY] );
+ mCtrlScaleZ->set( mClipboardSize.mV[VZ] );
+
+ sendScale(FALSE);
+}
+
+void LLPanelObject::onPasteRot(const LLSD& data)
+{
+ if(mClipboardRot.isNull()) return;
+
+ mCtrlRotX->set( mClipboardRot.mV[VX] );
+ mCtrlRotY->set( mClipboardRot.mV[VY] );
+ mCtrlRotZ->set( mClipboardRot.mV[VZ] );
+
+ sendRotation(FALSE);
+}
+
+//Paste from clip board
+BOOL get_vector_from_clipboard(LLVector3* value)
+{
+ LLWString temp_string;
+ LLView::getWindow()->pasteTextFromClipboard(temp_string);
+ const std::string stringVec = wstring_to_utf8str(temp_string);
+
+ if(stringVec.empty() || value == NULL) return FALSE;
+
+ LLVector3 vec;
+ S32 count = sscanf( stringVec.c_str(), "<%f, %f, %f>", vec.mV + 0, vec.mV + 1, vec.mV + 2 );
+ if( 3 == count )
+ {
+ value->setVec( vec );
+ return TRUE;
+ }
+
+ return FALSE;
+}
+void LLPanelObject::onPastePosClip(const LLSD& data)
+{
+ if(get_vector_from_clipboard(&mClipboardPos))
+ onPastePos(data);
+}
+void LLPanelObject::onPasteSizeClip(const LLSD& data)
+{
+ if(get_vector_from_clipboard(&mClipboardSize))
+ onPasteSize(data);
+}
+void LLPanelObject::onPasteRotClip(const LLSD& data)
+{
+ if(get_vector_from_clipboard(&mClipboardRot))
+ onPasteRot(data);
+}
+
+
+void LLPanelObject::onCopyParams(const LLSD& data)
+{
+ getVolumeParams(mClipboardVolumeParams);
+ mHasParamClipboard = TRUE;
+
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ return;
+
+ LLVOVolume *volobjp = NULL;
+ if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ volobjp = (LLVOVolume *)objectp;
+
+ mHasFlexiParam = FALSE;
+ if(volobjp && volobjp->isFlexible())
+ {
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ mPramsClipboard["lod"] = attributes->getSimulateLOD();
+ mPramsClipboard["gav"] = attributes->getGravity();
+ mPramsClipboard["ten"] = attributes->getTension();
+ mPramsClipboard["fri"] = attributes->getAirFriction();
+ mPramsClipboard["sen"] = attributes->getWindSensitivity();
+ LLVector3 force = attributes->getUserForce();
+ mPramsClipboard["forx"] = force.mV[0];
+ mPramsClipboard["fory"] = force.mV[1];
+ mPramsClipboard["forz"] = force.mV[2];
+ mHasFlexiParam = TRUE;
+ }
+ }
+
+ 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)
+ )
+ allow_texture = TRUE;
+ 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.count())
+ {
+ // search for copyable version first
+ for (S32 i = 0; i < items.count(); 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)
+ mPramsClipboard["sculptid"] = image_id;
+ else
+ mPramsClipboard["sculptid"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+
+ mPramsClipboard["sculpt_type"] = sculpt_params->getSculptType();
+ mHasSculptParam = TRUE;
+ }
+ else
+ {
+ mHasSculptParam = FALSE;
+ }
+
+ if (volobjp && volobjp->getIsLight())
+ {
+ mPramsClipboard["Light Intensity"] = volobjp->getLightIntensity();
+ mPramsClipboard["Light Radius"] = volobjp->getLightRadius();
+ mPramsClipboard["Light Falloff"] = volobjp->getLightFalloff();
+ LLColor3 color = volobjp->getLightColor();
+ mPramsClipboard["r"] = color.mV[0];
+ mPramsClipboard["g"] = color.mV[1];
+ mPramsClipboard["b"] = color.mV[2];
+ mHasLightParam = TRUE;
+ }
+ else
+ {
+ mHasLightParam = FALSE;
+ }
+
+}
+
+void LLPanelObject::onPasteParams(const LLSD& data)
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ return;
+
+ if (mHasFlexiParam && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ LLFlexibleObjectData new_attributes;
+ new_attributes = *attributes;
+
+ new_attributes.setSimulateLOD(mPramsClipboard["lod"].asInteger());
+ new_attributes.setGravity(mPramsClipboard["gav"].asReal());
+ new_attributes.setTension(mPramsClipboard["ten"].asReal());
+ new_attributes.setAirFriction(mPramsClipboard["fri"].asReal());
+ new_attributes.setWindSensitivity(mPramsClipboard["sen"].asReal());
+ F32 fx = (F32)mPramsClipboard["forx"].asReal();
+ F32 fy = (F32)mPramsClipboard["fory"].asReal();
+ F32 fz = (F32)mPramsClipboard["forz"].asReal();
+ LLVector3 force(fx,fy,fz);
+ new_attributes.setUserForce(force);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
+ }
+ }
+
+ if (mHasSculptParam)
+ {
+ LLSculptParams sculpt_params;
+
+ if (mPramsClipboard.has("sculptid"))
+ sculpt_params.setSculptTexture(mPramsClipboard["sculptid"].asUUID());
+
+ if (mPramsClipboard.has("sculptid"))
+ sculpt_params.setSculptType((U8)mPramsClipboard["sculpt_type"].asInteger());
+
+ objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+ }
+ else
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+ }
+
+ LLVOVolume *volobjp = NULL;
+ if ( objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ volobjp = (LLVOVolume *)objectp;
+
+ if (volobjp && mHasLightParam)
+ {
+ volobjp->setIsLight(TRUE);
+ volobjp->setLightIntensity((F32)mPramsClipboard["Light Intensity"].asReal());
+ volobjp->setLightRadius((F32)mPramsClipboard["Light Radius"].asReal());
+ volobjp->setLightFalloff((F32)mPramsClipboard["Light Falloff"].asReal());
+ F32 r = (F32)mPramsClipboard["r"].asReal();
+ F32 g = (F32)mPramsClipboard["g"].asReal();
+ F32 b = (F32)mPramsClipboard["b"].asReal();
+ volobjp->setLightColor(LLColor3(r,g,b));
+ }
+
+ if(mHasParamClipboard)
+ objectp->updateVolume(mClipboardVolumeParams);
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index e07bf007ec..771500f6c3 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -67,6 +67,18 @@ public:
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata);
+ void onCopyPos( const LLSD& data);
+ void onPastePos( const LLSD& data);
+ void onPastePosClip( const LLSD& data);
+ void onCopySize( const LLSD& data);
+ void onPasteSize( const LLSD& data);
+ void onPasteSizeClip( const LLSD& data);
+ void onCopyRot( const LLSD& data);
+ void onPasteRot( const LLSD& data);
+ void onPasteRotClip( const LLSD& data);
+ void onCopyParams( const LLSD& data);
+ void onPasteParams( const LLSD& data);
+
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
static void onCommitMaterial( LLUICtrl* ctrl, void* userdata);
@@ -93,6 +105,17 @@ protected:
void getVolumeParams(LLVolumeParams& volume_params);
protected:
+
+ LLVector3 mClipboardPos;
+ LLVector3 mClipboardSize;
+ LLVector3 mClipboardRot;
+ LLSD mPramsClipboard;
+ LLVolumeParams mClipboardVolumeParams;
+ BOOL mHasParamClipboard;
+ BOOL mHasFlexiParam;
+ BOOL mHasSculptParam;
+ BOOL mHasLightParam;
+
S32 mComboMaterialItemCount;
LLComboBox* mComboMaterial;
@@ -153,6 +176,21 @@ protected:
LLSpinCtrl* mCtrlRotY;
LLSpinCtrl* mCtrlRotZ;
+ LLButton *mBtnCopyPos;
+ LLButton *mBtnPastePos;
+ LLButton *mBtnPastePosClip;
+
+ LLButton *mBtnCopySize;
+ LLButton *mBtnPasteSize;
+ LLButton *mBtnPasteSizeClip;
+
+ LLButton *mBtnCopyRot;
+ LLButton *mBtnPasteRot;
+ LLButton *mBtnPasteRotClip;
+
+ LLButton* mBtnCopyParams;
+ LLButton* mBtnPasteParams;
+
LLCheckBoxCtrl *mCheckLock;
LLCheckBoxCtrl *mCheckPhysics;
LLCheckBoxCtrl *mCheckTemporary;
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 5420828427..6c4e8cc7a0 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1361,6 +1361,15 @@ even though the user gets a free copy.
text_enabled_color="Red"
top_pad="5"
width="87" />
+
+
+
@@ -1417,6 +1444,15 @@ even though the user gets a free copy.
text_enabled_color="White"
top_pad="5"
width="87" />
+
+
+
@@ -1475,6 +1529,15 @@ even though the user gets a free copy.
text_enabled_color="White"
top_pad="5"
width="87" />
+
+
+
+
+ Object Parameters:
+
+
+
+
+