summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloatermodelpreview.cpp1
-rw-r--r--indra/newview/llpanelface.cpp64
-rw-r--r--indra/newview/llpanelface.h7
-rw-r--r--indra/newview/llpanelobject.cpp219
-rw-r--r--indra/newview/llpanelobject.h11
-rw-r--r--indra/newview/lltexturectrl.cpp55
-rw-r--r--indra/newview/lltexturectrl.h10
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Off.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Press.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml31
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml26
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml26
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_size.xml26
16 files changed, 382 insertions, 118 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index bc44e37c5a..f44dd92ddb 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -4379,6 +4379,7 @@ void LLModelPreview::textureLoadedCallback(
if(final && preview->mModelLoader)
{
+ // for areTexturesReady()
if(preview->mModelLoader->mNumOfFetchingTextures > 0)
{
preview->mModelLoader->mNumOfFetchingTextures-- ;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 369861fa25..6e99a10b98 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -54,7 +54,6 @@
#include "llmediaentry.h"
#include "llmenubutton.h"
#include "llnotificationsutil.h"
-#include "llpanelobject.h" // LLPanelObject::canCopyTexture
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -2929,7 +2928,7 @@ void LLPanelFace::onCopyFaces()
{
LLUUID item_id;
LLUUID id = te_data["te"]["imageid"].asUUID();
- bool full_perm = LLPanelFace::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify());
+ bool full_perm = get_is_library_texture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify());
if (id.notNull() && !full_perm)
{
@@ -2944,7 +2943,7 @@ void LLPanelFace::onCopyFaces()
// as result it is Hightly unreliable, leaves little control to user, borderline hack
// but there are little options to preserve permissions - multiple inventory
// items might reference same asset and inventory search is expensive.
- item_id = LLPanelFace::getCopyPermInventoryTextureId(id);
+ item_id = get_copy_free_item_by_asset_id(id);
// record value to avoid repeating inventory search when possible
asset_item_map[id] = item_id;
}
@@ -3022,7 +3021,7 @@ void LLPanelFace::onCopyFaces()
if (mat_data.has("NormMap"))
{
LLUUID id = mat_data["NormMap"].asUUID();
- if (id.notNull() && !LLPanelFace::canCopyTexture(id))
+ if (id.notNull() && !get_can_copy_texture(id))
{
mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ));
mat_data["NormMapNoCopy"] = true;
@@ -3032,7 +3031,7 @@ void LLPanelFace::onCopyFaces()
if (mat_data.has("SpecMap"))
{
LLUUID id = mat_data["SpecMap"].asUUID();
- if (id.notNull() && !LLPanelFace::canCopyTexture(id))
+ if (id.notNull() && !get_can_copy_texture(id))
{
mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" ));
mat_data["SpecMapNoCopy"] = true;
@@ -3504,58 +3503,3 @@ bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata)
return true;
}
-
-//static
-bool LLPanelFace::isLibraryTexture(LLUUID image_id)
-{
- 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))
- {
- return true;
- }
- return false;
-}
-
-//static
-LLUUID LLPanelFace::getCopyPermInventoryTextureId(LLUUID image_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())
- {
- for (S32 i = 0; i < items.size(); i++)
- {
- LLViewerInventoryItem* itemp = items[i];
- if (itemp)
- {
- LLPermissions item_permissions = itemp->getPermissions();
- if (item_permissions.allowOperationBy(PERM_COPY,
- gAgent.getID(),
- gAgent.getGroupID()))
- {
- return itemp->getUUID();
- }
- }
- }
- }
- return LLUUID::null;
-}
-
-// Static
-bool LLPanelFace::canCopyTexture(LLUUID image_id)
-{
- // User is allowed to copy a texture if:
- // library asset or default texture,
- // or copy perm asset exists in user's inventory
-
- return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull();
-}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index dbf3531332..770f10e2ee 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -115,13 +115,6 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
void pasteFace(LLViewerObject* object, S32 te);
- static bool isLibraryTexture(LLUUID image_id);
-
- // Finds copy-enabled texture with specified asset from inventory
- // This can be performance unfriendly and doesn't warranty that
- // the texture is original source of asset
- static LLUUID getCopyPermInventoryTextureId(LLUUID image_id);
- static bool canCopyTexture(LLUUID image_id);
protected:
void getState();
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 6fa2da7bac..f1426ddf33 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -159,6 +159,8 @@ BOOL LLPanelObject::postBuild()
mComboBaseType = getChild<LLComboBox>("comboBaseType");
childSetCommitCallback("comboBaseType",onCommitParametric,this);
+ mMenuClipboardParams = getChild<LLMenuButton>("clipboard_params_btn");
+
// Cut
mLabelCut = getChild<LLTextBox>("text cut");
mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
@@ -289,9 +291,10 @@ LLPanelObject::LLPanelObject()
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
mSculptTypeRevert(0),
- mHasPosClipboard(FALSE),
- mHasSizeClipboard(FALSE),
- mHasRotClipboard(FALSE),
+ mHasClipboardPos(false),
+ mHasClipboardSize(false),
+ mHasClipboardRot(false),
+ mHasClipboardParams(false),
mSizeChanged(FALSE)
{
mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2));
@@ -618,7 +621,7 @@ void LLPanelObject::getState( )
}
else
{
- LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
selected_item = MI_BOX;
}
@@ -944,6 +947,7 @@ void LLPanelObject::getState( )
// Update field enablement
mComboBaseType ->setEnabled( enabled );
+ mMenuClipboardParams->setEnabled(enabled);
mLabelCut ->setEnabled( enabled );
mSpinCutBegin ->setEnabled( enabled );
@@ -1104,7 +1108,8 @@ void LLPanelObject::getState( )
}
mComboBaseType->setEnabled(!isMesh);
-
+ mMenuClipboardParams->setEnabled(!isMesh);
+
if (mCtrlSculptType)
{
if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
@@ -1168,11 +1173,11 @@ void LLPanelObject::sendIsPhysical()
LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
mIsPhysical = value;
- LL_INFOS() << "update physics sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update physics not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL;
}
}
@@ -1184,11 +1189,11 @@ void LLPanelObject::sendIsTemporary()
LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
mIsTemporary = value;
- LL_INFOS() << "update temporary sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update temporary not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL;
}
}
@@ -1201,11 +1206,11 @@ void LLPanelObject::sendIsPhantom()
LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
mIsPhantom = value;
- LL_INFOS() << "update phantom sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update phantom not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL;
}
}
@@ -1315,7 +1320,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
break;
default:
- LL_WARNS() << "Unknown base type " << selected_type
+ LL_WARNS("FloaterTools") << "Unknown base type " << selected_type
<< " in getVolumeParams()" << LL_ENDL;
// assume a box
selected_type = MI_BOX;
@@ -2019,7 +2024,13 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata)
std::string command = userdata.asString();
// paste
- if (command == "pos_paste")
+ if (command == "psr_paste")
+ {
+ onPastePos();
+ onPasteSize();
+ onPasteRot();
+ }
+ else if (command == "pos_paste")
{
onPastePos();
}
@@ -2031,7 +2042,17 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata)
{
onPasteRot();
}
+ else if (command == "params_paste")
+ {
+ onPasteParams();
+ }
// copy
+ else if (command == "psr_copy")
+ {
+ onCopyPos();
+ onCopySize();
+ onCopyRot();
+ }
else if (command == "pos_copy")
{
onCopyPos();
@@ -2044,23 +2065,71 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata)
{
onCopyRot();
}
+ else if (command == "params_copy")
+ {
+ onCopyParams();
+ }
}
bool LLPanelObject::menuEnableItem(const LLSD& userdata)
{
std::string command = userdata.asString();
- if (command == "pos_paste")
+ // paste options
+ if (command == "psr_paste")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot;
+ }
+ else if (command == "pos_paste")
{
- return mHasPosClipboard;
+ // assumes that menu won't be active if there is no move permission
+ return mHasClipboardPos;
}
else if (command == "size_paste")
{
- return mHasSizeClipboard;
+ return mHasClipboardSize;
}
else if (command == "rot_paste")
{
- return mHasRotClipboard;
+ return mHasClipboardRot;
+ }
+ else if (command == "params_paste")
+ {
+ return mHasClipboardParams;
+ }
+ // copy options
+ else if (command == "psr_copy")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ // since we forbid seeing values we also should forbid copying them
+ return enable_move && enable_modify;
}
return false;
}
@@ -2072,7 +2141,7 @@ void LLPanelObject::onCopyPos()
std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]);
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
- mHasPosClipboard = TRUE;
+ mHasClipboardPos = true;
}
void LLPanelObject::onCopySize()
@@ -2082,7 +2151,7 @@ void LLPanelObject::onCopySize()
std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]);
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
- mHasSizeClipboard = TRUE;
+ mHasClipboardSize = true;
}
void LLPanelObject::onCopyRot()
@@ -2092,12 +2161,12 @@ void LLPanelObject::onCopyRot()
std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]);
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
- mHasRotClipboard = TRUE;
+ mHasClipboardRot = true;
}
void LLPanelObject::onPastePos()
{
- if (!mHasPosClipboard) return;
+ if (!mHasClipboardPos) return;
if (mObject.isNull()) return;
LLViewerRegion* regionp = mObject->getRegion();
@@ -2122,26 +2191,118 @@ void LLPanelObject::onPastePos()
void LLPanelObject::onPasteSize()
{
- if (!mHasSizeClipboard) return;
+ if (!mHasClipboardSize) 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] );
+ mCtrlScaleX->set(mClipboardSize.mV[VX]);
+ mCtrlScaleY->set(mClipboardSize.mV[VY]);
+ mCtrlScaleZ->set(mClipboardSize.mV[VZ]);
sendScale(FALSE);
}
void LLPanelObject::onPasteRot()
{
- if (!mHasRotClipboard) return;
+ if (!mHasClipboardRot) return;
- mCtrlRotX->set( mClipboardRot.mV[VX] );
- mCtrlRotY->set( mClipboardRot.mV[VY] );
- mCtrlRotZ->set( mClipboardRot.mV[VZ] );
+ mCtrlRotX->set(mClipboardRot.mV[VX]);
+ mCtrlRotY->set(mClipboardRot.mV[VY]);
+ mCtrlRotZ->set(mClipboardRot.mV[VZ]);
sendRotation(FALSE);
}
+
+void LLPanelObject::onCopyParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ mClipboardParams.clear();
+
+ // Parametrics
+ if (!objectp->isMesh())
+ {
+ LLVolumeParams params;
+ getVolumeParams(params);
+ mClipboardParams["volume_params"] = params.asLLSD();
+ }
+
+ // Sculpted Prim
+ if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+ if (!objectp->isMesh())
+ {
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
+ {
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
+ }
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ }
+ }
+
+ mHasClipboardParams = TRUE;
+}
+
+void LLPanelObject::onPasteParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || !mHasClipboardParams)
+ {
+ return;
+ }
+
+ // Sculpted Prim
+ if (mClipboardParams.has("sculpt"))
+ {
+ LLSculptParams sculpt_params;
+ LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID();
+ U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger();
+ sculpt_params.setSculptTexture(sculpt_id, sculpt_type);
+ 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);
+ }
+ }
+
+ // volume params
+ // make sure updateVolume() won't affect flexible
+ if (mClipboardParams.has("volume_params"))
+ {
+ LLVolumeParams params;
+ params.fromLLSD(mClipboardParams["volume_params"]);
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->isFlexible())
+ {
+ if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE);
+ }
+ }
+ else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_LINE);
+ }
+
+ objectp->updateVolume(params);
+ }
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 764c0d8af4..5ea3d07699 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -73,6 +73,8 @@ public:
void onPasteSize();
void onCopyRot();
void onPasteRot();
+ void onCopyParams();
+ void onPasteParams();
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
@@ -102,6 +104,7 @@ protected:
protected:
// Per-object options
LLComboBox* mComboBaseType;
+ LLMenuButton* mMenuClipboardParams;
LLTextBox* mLabelCut;
LLSpinCtrl* mSpinCutBegin;
@@ -183,10 +186,12 @@ protected:
LLVector3 mClipboardPos;
LLVector3 mClipboardSize;
LLVector3 mClipboardRot;
+ LLSD mClipboardParams;
- BOOL mHasPosClipboard;
- BOOL mHasSizeClipboard;
- BOOL mHasRotClipboard;
+ bool mHasClipboardPos;
+ bool mHasClipboardSize;
+ bool mHasClipboardRot;
+ bool mHasClipboardParams;
LLPointer<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 6a0464c657..2f5be2b32e 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -79,6 +79,61 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
//static const char NO_IMAGE_NAME[] = "None";
+
+
+//static
+bool get_is_library_texture(LLUUID image_id)
+{
+ 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))
+ {
+ return true;
+ }
+ return false;
+}
+
+LLUUID get_copy_free_item_by_asset_id(LLUUID image_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())
+ {
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ return itemp->getUUID();
+ }
+ }
+ }
+ }
+ return LLUUID::null;
+}
+
+bool get_can_copy_texture(LLUUID image_id)
+{
+ // User is allowed to copy a texture if:
+ // library asset or default texture,
+ // or copy perm asset exists in user's inventory
+
+ return get_is_library_texture(image_id) || get_copy_free_item_by_asset_id(image_id).notNull();
+}
+
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
LLUUID image_asset_id,
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index b2a34a37c4..2b2c5fa237 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -53,6 +53,16 @@ class LLViewerFetchedTexture;
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
+// Helper functions for UI that work with picker
+bool get_is_library_texture(LLUUID image_id);
+
+// texture picker works by asset ids since objects normaly do
+// not retain inventory ids as result these functions are looking
+// for textures in inventory by asset ids
+// This search can be performance unfriendly and doesn't warranty
+// that the texture is original source of asset
+LLUUID get_copy_free_item_by_asset_id(LLUUID image_id);
+bool get_can_copy_texture(LLUUID image_id);
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
new file mode 100644
index 0000000000..9a81c5f94b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
new file mode 100644
index 0000000000..88012cf8d1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
new file mode 100644
index 0000000000..ab02e7d42d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b7fa1e72f8..473b074213 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -441,6 +441,9 @@ with the same filename but different name
<texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" />
<texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" />
<texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" />
+ <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" />
+ <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" />
<texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" />
<texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index afc6155585..0b2b1abeb9 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1436,7 +1436,7 @@ even though the user gets a free copy.
height="0"
layout="topleft"
left_delta="0"
- name="lod_tab_border"
+ name="object_horizontal"
top_pad="10"
width="95" />
<menu_button
@@ -1666,13 +1666,23 @@ even though the user gets a free copy.
width="150">
Prim Type
</text>-->
+
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ name="object_vertical"
+ left="117"
+ top="6"
+ height="500"
+ width="0"/>
<combo_box
height="19"
layout="topleft"
name="comboBaseType"
top="6"
left="125"
- width="150">
+ width="125">
<combo_box.item
label="Box"
name="Box"
@@ -1706,15 +1716,28 @@ even though the user gets a free copy.
name="Sculpted"
value="Sculpted" />
</combo_box>
+ <menu_button
+ menu_filename="menu_copy_paste_generic.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left_pad="8"
+ top_delta="2"
+ name="clipboard_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left="125"
name="text cut"
- top_pad="5"
+ top_pad="7"
width="150">
Path Cut (begin/end)
</text>
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml
new file mode 100644
index 0000000000..8e016e4a1c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Generic Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="params_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
index c2763af603..3ea95b281f 100644
--- a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
@@ -3,19 +3,35 @@
layout="topleft"
name="Copy Paste Position Menu">
<menu_item_call
- label="Copy Position"
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy position"
layout="topleft"
name="pos_copy"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
</menu_item_call>
<menu_item_call
- label="Paste Position"
+ label="Paste position"
layout="topleft"
name="pos_paste"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" />
- <on_enable function="PanelObject.menuEnable" parameter="pos_paste" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="pos_paste" />
</menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
index dcfb3faeca..06ce80f897 100644
--- a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
@@ -3,19 +3,35 @@
layout="topleft"
name="Copy Paste Rotation Menu">
<menu_item_call
- label="Copy Rotation"
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy rotation"
layout="topleft"
name="rot_copy"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
</menu_item_call>
<menu_item_call
- label="Paste Rotation"
+ label="Paste rotation"
layout="topleft"
name="rot_paste"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" />
- <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
</menu_item_call>
</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
index 58d71b12d5..7082a0e65b 100644
--- a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
@@ -3,19 +3,35 @@
layout="topleft"
name="Copy Paste Size Menu">
<menu_item_call
- label="Copy Size"
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy size"
layout="topleft"
name="size_copy"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
</menu_item_call>
<menu_item_call
- label="Paste Size"
+ label="Paste size"
layout="topleft"
name="size_paste"
visible="true">
- <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" />
- <on_enable function="PanelObject.menuEnable" parameter="size_paste" />
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="size_paste" />
</menu_item_call>
</toggleable_menu>