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" /> + +