From 3ee20531c96c05452a4b832634df000cf5d0dc08 Mon Sep 17 00:00:00 2001
From: Kadah_Coba <kadah.coba@gmail.com>
Date: Mon, 8 Apr 2019 03:05:03 -0700
Subject: [PATCH] Added Copy/Paste to object properties in Build Tools

---
 indra/newview/llpanelobject.cpp               | 116 +++++++++++++++-
 indra/newview/llpanelobject.h                 |  24 +++-
 .../skins/default/textures/icons/Paste.png    | Bin 0 -> 530 bytes
 .../skins/default/textures/textures.xml       |   1 +
 .../skins/default/xui/en/floater_tools.xml    | 126 +++++++++++++++---
 5 files changed, 247 insertions(+), 20 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/icons/Paste.png

diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 3665910c633..56a19d75515 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -150,6 +150,24 @@ BOOL	LLPanelObject::postBuild()
 	mCtrlRotZ = getChild<LLSpinCtrl>("Rot Z");
 	childSetCommitCallback("Rot Z",onCommitRotation,this);
 
+    // Copy/paste pos
+    mBtnCopyPos = getChild<LLButton>("copy_pos_btn");
+    mBtnCopyPos->setCommitCallback( boost::bind(&LLPanelObject::onCopyPos, this, _2 ));
+    mBtnPastePos = getChild<LLButton>("paste_pos_btn");
+    mBtnPastePos->setCommitCallback( boost::bind(&LLPanelObject::onPastePos, this, _2 ));
+	
+    // Copy/paste size
+    mBtnCopySize = getChild<LLButton>("copy_size_btn");
+    mBtnCopySize->setCommitCallback( boost::bind(&LLPanelObject::onCopySize, this, _2 ));
+    mBtnPasteSize = getChild<LLButton>("paste_size_btn");
+    mBtnPasteSize->setCommitCallback( boost::bind(&LLPanelObject::onPasteSize, this, _2 ));
+	
+    // Copy/paste rot
+    mBtnCopyRot = getChild<LLButton>("copy_rot_btn");
+    mBtnCopyRot->setCommitCallback( boost::bind(&LLPanelObject::onCopyRot, this, _2 ));
+    mBtnPasteRot = getChild<LLButton>("paste_rot_btn");
+    mBtnPasteRot->setCommitCallback( boost::bind(&LLPanelObject::onPasteRot, this, _2 ));;
+
 	//--------------------------------------------------------
 		
 	// Base Type
@@ -286,7 +304,10 @@ LLPanelObject::LLPanelObject()
 	mSelectedType(MI_BOX),
 	mSculptTextureRevert(LLUUID::null),
 	mSculptTypeRevert(0),
-	mSizeChanged(FALSE)
+	mSizeChanged(FALSE),
+    mHasPosClipboard(FALSE),
+    mHasSizeClipboard(FALSE),
+    mHasRotClipboard(FALSE)
 {
 }
 
@@ -379,6 +400,8 @@ void LLPanelObject::getState( )
 	mCtrlPosX->setEnabled(enable_move);
 	mCtrlPosY->setEnabled(enable_move);
 	mCtrlPosZ->setEnabled(enable_move);
+    mBtnCopyPos->setEnabled(enable_move);
+    mBtnPastePos->setEnabled(enable_move && mHasPosClipboard);
 
 	if (enable_scale)
 	{
@@ -404,6 +427,8 @@ void LLPanelObject::getState( )
 	mCtrlScaleX->setEnabled( enable_scale );
 	mCtrlScaleY->setEnabled( enable_scale );
 	mCtrlScaleZ->setEnabled( enable_scale );
+    mBtnCopySize->setEnabled( enable_scale );
+    mBtnPasteSize->setEnabled( enable_scale && mHasSizeClipboard );
 
 	LLQuaternion object_rot = objectp->getRotationEdit();
 	object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ]));
@@ -435,6 +460,8 @@ void LLPanelObject::getState( )
 	mCtrlRotX->setEnabled( enable_rotate );
 	mCtrlRotY->setEnabled( enable_rotate );
 	mCtrlRotZ->setEnabled( enable_rotate );
+    mBtnCopyRot->setEnabled( enable_rotate );
+    mBtnPasteRot->setEnabled( enable_rotate && mHasRotClipboard );
 
 	LLUUID owner_id;
 	std::string owner_name;
@@ -2001,3 +2028,90 @@ 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]));
+    mBtnPastePos->setEnabled(TRUE);
+
+    mHasPosClipboard = TRUE;
+}
+
+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]));
+    mBtnPasteSize->setEnabled(TRUE);
+
+    mHasSizeClipboard = TRUE;
+}
+
+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]));
+    mBtnPasteSize->setEnabled(TRUE);
+
+    mHasRotClipboard = TRUE;
+}
+
+void LLPanelObject::onPastePos(const LLSD& data)
+{
+    if(!mHasPosClipboard) return;
+
+    // Clamp pos on non-attachments, just keep the prims within the region
+    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(!mHasSizeClipboard) 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(!mHasRotClipboard) return;
+
+    mCtrlRotX->set( mClipboardRot.mV[VX] );
+    mCtrlRotY->set( mClipboardRot.mV[VY] );
+    mCtrlRotZ->set( mClipboardRot.mV[VZ] );
+
+    sendRotation(FALSE);
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 8829f493fa7..c1e0367b53a 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -66,6 +66,13 @@ class LLPanelObject : public LLPanel
 	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);
+
 	static void 	onCommitParametric(LLUICtrl* ctrl, void* userdata);
 
 
@@ -157,7 +164,18 @@ class LLPanelObject : public LLPanel
 	LLComboBox      *mCtrlSculptType;
 	LLCheckBoxCtrl  *mCtrlSculptMirror;
 	LLCheckBoxCtrl  *mCtrlSculptInvert;
-	
+
+    LLButton        *mBtnCopyPos;
+    LLButton        *mBtnPastePos;
+    LLButton        *mBtnCopySize;
+    LLButton        *mBtnPasteSize;
+    LLButton        *mBtnCopyRot;
+    LLButton        *mBtnPasteRot;
+
+    LLVector3       mClipboardPos;
+    LLVector3       mClipboardSize;
+    LLVector3       mClipboardRot;
+
 	LLVector3		mCurEulerDegrees;		// to avoid sending rotation when not changed
 	BOOL			mIsPhysical;			// to avoid sending "physical" when not changed
 	BOOL			mIsTemporary;			// to avoid sending "temporary" when not changed
@@ -167,6 +185,10 @@ class LLPanelObject : public LLPanel
 	LLUUID          mSculptTextureRevert;   // so we can revert the sculpt texture on cancel
 	U8              mSculptTypeRevert;      // so we can revert the sculpt type on cancel
 
+    BOOL            mHasPosClipboard;
+    BOOL            mHasSizeClipboard;
+    BOOL            mHasRotClipboard;
+
 	LLPointer<LLViewerObject> mObject;
 	LLPointer<LLViewerObject> mRootObject;
 };
diff --git a/indra/newview/skins/default/textures/icons/Paste.png b/indra/newview/skins/default/textures/icons/Paste.png
new file mode 100644
index 0000000000000000000000000000000000000000..10211df427113fa93c2bfb435ad0dce52ce22bc2
GIT binary patch
literal 530
zcmV+t0`2{YP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9
za%BK;VQFr3E^cLXAT%y9E;jv63FrU-0fR|IK~y+Tt&%~C!axv3Gu~rl?jV|#XAlWl
z%Pew`47dm)5=4Ro2_hkc;2GSx7m+9)V-8SLzmg7ZkGc?r*J+Yp&+h8Bi0Ca;gJrdu
zF4KDezO~I_ooe9VZnvZTeovFhgoeYRfcg1+ro-WYP}eNhsRsVn<MBvkSrVSp=~Phf
zuGcF<J+oM+8aQ;hT%_o9I*9;aj(7Nm4AWvhz(bKLK(WH}JlW!CG(zZyv5~F$Vp<PH
zYGuH6UD;w7hO}5LD2gIlE|>DOZ9CLuHzE@y0<+mno<R`MYPAwszuy<xQxUf2IF6hg
z1oQb^z#JlwBngV;5E_x*8-Qk`KjZOO3gS3!wuP-?g-=E5#Bg^Y@_nC*qM$TQr4TED
z5ItM3*Z)OIpo<2B0d2Qi5oK8>vdv~AGOX~P2;Eo5s=!fyD^Z^3jSK>;4pL+rQ7w~;
zrh&_6Lt=^`0GM;;R%BAkdZtLp6fcQP8L#S>GabpB0v-O{>zz)A`IM|#{2FBa0TGr1
UP&YJ-SpWb407*qoM6N<$f)6^{=Kufz

literal 0
HcmV?d00001

diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 2540ee148dd..c3cc4e83d03 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -187,6 +187,7 @@ with the same filename but different name
   <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
 
   <texture name="Copy" file_name="icons/Copy.png" preload="false" />
+  <texture name="Paste" file_name="icons/Paste.png" preload="false" />
   
   <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
 
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index d9a15fed9e3..81a207c0233 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1446,6 +1446,21 @@ even though the user gets a free copy.
              text_enabled_color="1 0 0.3 .7"
              top_pad="5"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Copy"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="copy_pos_btn"
+             tool_tip="Copy Position" />
             <spinner
              follows="left|top"
              height="19"
@@ -1454,13 +1469,28 @@ even though the user gets a free copy.
              label="Y"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="512"
              min_val="-256"
              name="Pos Y"
              text_enabled_color="EmphasisColor"
              top_pad="3"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Paste"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="paste_pos_btn"
+             tool_tip="Paste Position" />
             <spinner
              follows="left|top"
              height="19"
@@ -1469,7 +1499,7 @@ even though the user gets a free copy.
              label="Z"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="4096"
              name="Pos Z"
              text_enabled_color="0 0.8 1 .65"
@@ -1502,6 +1532,21 @@ even though the user gets a free copy.
              text_enabled_color="1 1 1 1"
              top_pad="5"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Copy"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="copy_size_btn"
+             tool_tip="Copy Size" />
             <spinner
              follows="left|top"
              height="19"
@@ -1510,13 +1555,28 @@ even though the user gets a free copy.
              label="Y"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="64"
              min_val="0.01"
              name="Scale Y"
              text_enabled_color="1 1 1 1"
              top_pad="3"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Paste"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="paste_size_btn"
+             tool_tip="Paste Size" />
             <spinner
              follows="left|top"
              height="19"
@@ -1525,7 +1585,7 @@ even though the user gets a free copy.
              label="Z"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="64"
              min_val="0.01"
              name="Scale Z"
@@ -1560,6 +1620,21 @@ even though the user gets a free copy.
              text_enabled_color="1 1 1 1"
              top_pad="5"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Copy"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="copy_rot_btn"
+             tool_tip="Copy Rotation" />
             <spinner
              decimal_digits="2"
              follows="left|top"
@@ -1569,13 +1644,28 @@ even though the user gets a free copy.
              label="Y"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="9999"
              min_val="-9999"
              name="Rot Y"
              text_enabled_color="1 1 1 1"
              top_pad="3"
              width="87" />
+            <button
+             top_delta="0"
+             left_pad="5"
+             height="19"
+             width="20"
+             follows="top|right"
+             layout="topleft"
+             tab_stop="false"
+             image_bottom_pad="1"
+             image_overlay="Paste"
+             image_hover_unselected="Toolbar_Middle_Over"
+             image_selected="Toolbar_Middle_Selected"
+             image_unselected="Toolbar_Middle_Off"
+             name="paste_rot_btn"
+             tool_tip="Paste Rotation" />
             <spinner
              decimal_digits="2"
              follows="left|top"
@@ -1585,7 +1675,7 @@ even though the user gets a free copy.
              label="Z"
              label_width="10"
              layout="topleft"
-             left_delta="0"
+             left="10"
              max_val="9999"
              min_val="-9999"
              name="Rot Z"
@@ -1598,7 +1688,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="label basetype"
              top="5"
              width="150">
@@ -1609,7 +1699,7 @@ even though the user gets a free copy.
              layout="topleft"
              name="comboBaseType"
              top="6"
-             left="125"
+             left="135"
              width="150">
                 <combo_box.item
                  label="Box"
@@ -1688,7 +1778,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="text hollow"
              top_pad="6"
              width="68">
@@ -1712,7 +1802,7 @@ even though the user gets a free copy.
              increment="5"
              initial_value="0"
              layout="topleft"
-             left="125"
+             left="135"
              max_val="95"
              name="Scale 1"
              top_pad="4"
@@ -1736,7 +1826,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="15"
              layout="topleft"
-             left="125"
+             left="135"
              name="Hollow Shape"
              top_pad="4"
              width="150">
@@ -1814,7 +1904,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="scale_taper"
              top_pad="3"
              width="150">
@@ -1867,7 +1957,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="text topshear"
              top_pad="3"
              width="141">
@@ -1910,7 +2000,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="advanced_cut"
              top_pad="3"
              width="150">
@@ -1974,7 +2064,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="text taper2"
              top_pad="3"
              width="150">
@@ -2017,7 +2107,7 @@ even though the user gets a free copy.
              follows="left|top"
              height="10"
              layout="topleft"
-             left="125"
+             left="135"
              name="text radius delta"
              top_pad="2"
              width="78">
@@ -2042,7 +2132,7 @@ even though the user gets a free copy.
              increment="0.05"
              initial_value="0"
              layout="topleft"
-             left="125"
+             left="135"
              min_val="-1"
              name="Radius Offset"
              top_pad="4"
@@ -2067,7 +2157,7 @@ even though the user gets a free copy.
              height="141"
              label="Sculpt Texture"
              layout="topleft"
-             left="125"
+             left="135"
              name="sculpt texture control"
              tool_tip="Click to choose a picture"
              top="70"
-- 
GitLab