From 7980dedc3205d2c1a7596d4cad3fa3f7fff383a5 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 30 Mar 2017 20:11:28 +0300 Subject: MAINT-728 Allows multiple dialogs per script --- indra/newview/app_settings/settings.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'indra/newview/app_settings') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 097a9ac7b9..db2d48bd12 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10734,6 +10734,17 @@ Value 1 + ScriptDialogLimitations + + Comment + Limits amount of dialogs per script (0 - per object, 1 - per channel, 2 - per channel for attachments, 3 - per channel for HUDs, 4 -unconstrained for HUDs) + Persist + 1 + Type + U32 + Value + 0 + SecondLifeEnterprise Comment -- cgit v1.3 From 26809498db128f2f69da3d04ae2b736f78f6e13a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 5 Apr 2017 14:29:35 +0300 Subject: MAINT-3595 Add the ability to turn off auto-complete of gestures in local chat --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llfloaterimnearbychat.cpp | 3 ++- .../newview/skins/default/xui/en/panel_preferences_chat.xml | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'indra/newview/app_settings') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index db2d48bd12..c086e71fae 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1619,6 +1619,17 @@ Value default + ChatAutocompleteGestures + + Comment + Auto-complete gestures in nearby chat + Persist + 1 + Type + Boolean + Value + 1 + ChatBarStealsFocus Comment diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 40ae22bb4e..7895a5ff48 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -485,7 +485,8 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke() KEY key = gKeyboard->currentKey(); // Ignore "special" keys, like backspace, arrows, etc. - if (length > 1 + if (gSavedSettings.getBOOL("ChatAutocompleteGestures") + && length > 1 && raw_text[0] == '/' && key < KEY_SPECIAL) { diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 440c6613d5..78f771cd51 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -9,6 +9,18 @@ name="chat" top="1" width="517"> + + + Date: Thu, 13 Apr 2017 18:25:31 +0300 Subject: MAINT-7313 Connect the recent per attachment reported render weight cap to a debug setting. --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llvoavatar.cpp | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'indra/newview/app_settings') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c086e71fae..f0a91fd407 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10179,6 +10179,17 @@ Value 10 + MaxAttachmentComplexity + + Comment + Attachment's render weight limit + Persist + 1 + Type + F32 + Value + 1.0E6 + ComplexityChangesPopUpDelay Comment diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f6a16f7da1..571dc73013 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -119,7 +119,6 @@ const F32 MAX_HOVER_Z = 2.0; const F32 MIN_HOVER_Z = -2.0; const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f; -const F32 MAX_ATTACHMENT_COMPLEXITY = 1.0e6f; using namespace LLAvatarAppearanceDefines; @@ -9018,7 +9017,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity() * the official viewer for consideration. *****************************************************************/ static const U32 COMPLEXITY_BODY_PART_COST = 200; - + static LLCachedControl max_complexity(gSavedSettings,"MaxAttachmentComplexity"); + F32 MAX_ATTACHMENT_COMPLEXITY = max_complexity; // Diagnostic list of all textures on our avatar static std::set all_textures; -- cgit v1.3 From 69db7cd947a6b272004f7a02a0f45527dba0fdbd Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 27 Apr 2017 17:26:32 +0300 Subject: MAINT-3223 Texture repeats synch feature --- indra/newview/app_settings/settings.xml | 11 + indra/newview/llpanelface.cpp | 326 ++++++++++++++++++--- indra/newview/llpanelface.h | 13 +- .../skins/default/xui/en/panel_tools_texture.xml | 14 +- 4 files changed, 317 insertions(+), 47 deletions(-) (limited to 'indra/newview/app_settings') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f0a91fd407..89f5d7a24f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11878,6 +11878,17 @@ Value 0 + SyncMaterialSettings + + Comment + SyncMaterialSettings + Persist + 1 + Type + Boolean + Value + 0 + SnapshotQuality Comment diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ad600358dd..a16259886d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -131,13 +131,13 @@ BOOL LLPanelFace::postBuild() childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this); childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this); childSetCommitCallback("combobox alphamode",&LLPanelFace::onCommitAlphaMode,this); - childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureScaleX, this); + childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureScaleY, this); + childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureRot, this); childSetCommitCallback("rptctrl",&LLPanelFace::onCommitRepeatsPerMeter, this); childSetCommitCallback("checkbox planar align",&LLPanelFace::onCommitPlanarAlign, this); - childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this); - childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this); + childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureOffsetX, this); + childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureOffsetY, this); childSetCommitCallback("bumpyScaleU",&LLPanelFace::onCommitMaterialBumpyScaleX, this); childSetCommitCallback("bumpyScaleV",&LLPanelFace::onCommitMaterialBumpyScaleY, this); @@ -691,6 +691,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } getChildView("radio_material_type")->setEnabled(editable); + getChildView("checkbox_sync_settings")->setEnabled(editable); + childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings")); updateVisibility(); bool identical = true; // true because it is anded below @@ -1862,12 +1864,39 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } +//static +void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU) +{ + LLSelectedTEMaterial::setNormalOffsetX(self,offsetU); + LLSelectedTEMaterial::setSpecularOffsetX(self,offsetU); + self->getChild("TexOffsetU")->forceSetValue(offsetU); + self->sendTextureInfo(); +} + +//static +void LLPanelFace::syncOffsetY(LLPanelFace* self, F32 offsetV) +{ + LLSelectedTEMaterial::setNormalOffsetY(self,offsetV); + LLSelectedTEMaterial::setSpecularOffsetY(self,offsetV); + self->getChild("TexOffsetV")->forceSetValue(offsetV); + self->sendTextureInfo(); +} + //static void LLPanelFace::onCommitMaterialBumpyOffsetX(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self,self->getCurrentBumpyOffsetU()); + } + else + { + LLSelectedTEMaterial::setNormalOffsetX(self,self->getCurrentBumpyOffsetU()); + } + } //static @@ -1875,7 +1904,15 @@ void LLPanelFace::onCommitMaterialBumpyOffsetY(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self,self->getCurrentBumpyOffsetV()); + } + else + { + LLSelectedTEMaterial::setNormalOffsetY(self,self->getCurrentBumpyOffsetV()); + } } //static @@ -1883,7 +1920,15 @@ void LLPanelFace::onCommitMaterialShinyOffsetX(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self, self->getCurrentShinyOffsetU()); + } + else + { + LLSelectedTEMaterial::setSpecularOffsetX(self,self->getCurrentShinyOffsetU()); + } } //static @@ -1891,7 +1936,31 @@ void LLPanelFace::onCommitMaterialShinyOffsetY(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self,self->getCurrentShinyOffsetV()); + } + else + { + LLSelectedTEMaterial::setSpecularOffsetY(self,self->getCurrentShinyOffsetV()); + } +} + +//static +void LLPanelFace::syncRepeatX(LLPanelFace* self, F32 scaleU) +{ + LLSelectedTEMaterial::setNormalRepeatX(self,scaleU); + LLSelectedTEMaterial::setSpecularRepeatX(self,scaleU); + self->sendTextureInfo(); +} + +//static +void LLPanelFace::syncRepeatY(LLPanelFace* self, F32 scaleV) +{ + LLSelectedTEMaterial::setNormalRepeatY(self,scaleV); + LLSelectedTEMaterial::setSpecularRepeatY(self,scaleV); + self->sendTextureInfo(); } //static @@ -1904,7 +1973,16 @@ void LLPanelFace::onCommitMaterialBumpyScaleX(LLUICtrl* ctrl, void* userdata) { bumpy_scale_u *= 0.5f; } - LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleU")->forceSetValue(self->getCurrentBumpyScaleU()); + syncRepeatX(self, bumpy_scale_u); + } + else + { + LLSelectedTEMaterial::setNormalRepeatX(self,bumpy_scale_u); + } } //static @@ -1917,7 +1995,17 @@ void LLPanelFace::onCommitMaterialBumpyScaleY(LLUICtrl* ctrl, void* userdata) { bumpy_scale_v *= 0.5f; } - LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); + + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleV")->forceSetValue(self->getCurrentBumpyScaleV()); + syncRepeatY(self, bumpy_scale_v); + } + else + { + LLSelectedTEMaterial::setNormalRepeatY(self,bumpy_scale_v); + } } //static @@ -1930,7 +2018,16 @@ void LLPanelFace::onCommitMaterialShinyScaleX(LLUICtrl* ctrl, void* userdata) { shiny_scale_u *= 0.5f; } - LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleU")->forceSetValue(self->getCurrentShinyScaleU()); + syncRepeatX(self, shiny_scale_u); + } + else + { + LLSelectedTEMaterial::setSpecularRepeatX(self,shiny_scale_u); + } } //static @@ -1943,7 +2040,24 @@ void LLPanelFace::onCommitMaterialShinyScaleY(LLUICtrl* ctrl, void* userdata) { shiny_scale_v *= 0.5f; } - LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexScaleV")->forceSetValue(self->getCurrentShinyScaleV()); + syncRepeatY(self, shiny_scale_v); + } + else + { + LLSelectedTEMaterial::setSpecularRepeatY(self,shiny_scale_v); + } +} + +//static +void LLPanelFace::syncMaterialRot(LLPanelFace* self, F32 rot) +{ + LLSelectedTEMaterial::setNormalRotation(self,rot * DEG_TO_RAD); + LLSelectedTEMaterial::setSpecularRotation(self,rot * DEG_TO_RAD); + self->sendTextureInfo(); } //static @@ -1951,7 +2065,16 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexRot")->forceSetValue(self->getCurrentBumpyRot()); + syncMaterialRot(self, self->getCurrentBumpyRot()); + } + else + { + LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); + } } //static @@ -1959,7 +2082,16 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) { LLPanelFace* self = (LLPanelFace*) userdata; llassert_always(self); - LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + self->getChild("TexRot")->forceSetValue(self->getCurrentShinyRot()); + syncMaterialRot(self, self->getCurrentShinyRot()); + } + else + { + LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); + } } //static @@ -1994,6 +2126,92 @@ void LLPanelFace::onCommitTextureInfo( LLUICtrl* ctrl, void* userdata ) self->updateUI(true); } +// static +void LLPanelFace::onCommitTextureScaleX( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + F32 bumpy_scale_u = self->getChild("TexScaleU")->getValue().asReal(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_u *= 0.5f; + } + syncRepeatX(self, bumpy_scale_u); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); +} + +// static +void LLPanelFace::onCommitTextureScaleY( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + F32 bumpy_scale_v = self->getChild("TexScaleV")->getValue().asReal(); + if (self->isIdenticalPlanarTexgen()) + { + bumpy_scale_v *= 0.5f; + } + syncRepeatY(self, bumpy_scale_v); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); +} + +// static +void LLPanelFace::onCommitTextureRot( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncMaterialRot(self, self->getChild("TexRot")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); +} + +// static +void LLPanelFace::onCommitTextureOffsetX( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetX(self, self->getChild("TexOffsetU")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); +} + +// static +void LLPanelFace::onCommitTextureOffsetY( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelFace* self = (LLPanelFace*) userdata; + if (gSavedSettings.getBOOL("SyncMaterialSettings")) + { + syncOffsetY(self, self->getChild("TexOffsetV")->getValue().asReal()); + } + else + { + self->sendTextureInfo(); + } + self->updateUI(true); +} + // Commit the number of repeats per meter // static void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) @@ -2017,44 +2235,62 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); + + LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); + LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); + LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); + LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); - switch (material_type) + if (gSavedSettings.getBOOL("SyncMaterialSettings")) { - case MATTYPE_DIFFUSE: - { - LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); -} - break; + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); - case MATTYPE_NORMAL: - { - LLUICtrl* bumpy_scale_u = self->getChild("bumpyScaleU"); - LLUICtrl* bumpy_scale_v = self->getChild("bumpyScaleV"); - - bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); - bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); - } - break; + LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); - case MATTYPE_SPECULAR: + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + } + else + { + switch (material_type) { - LLUICtrl* shiny_scale_u = self->getChild("shinyScaleU"); - LLUICtrl* shiny_scale_v = self->getChild("shinyScaleV"); - - shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); - shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + case MATTYPE_DIFFUSE: + { + LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter ); + } + break; - LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); - } - break; + case MATTYPE_NORMAL: + { + bumpy_scale_u->setValue(obj_scale_s * repeats_per_meter); + bumpy_scale_v->setValue(obj_scale_t * repeats_per_meter); - default: - llassert(false); - break; + LLSelectedTEMaterial::setNormalRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setNormalRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + case MATTYPE_SPECULAR: + { + shiny_scale_u->setValue(obj_scale_s * repeats_per_meter); + shiny_scale_v->setValue(obj_scale_t * repeats_per_meter); + + LLSelectedTEMaterial::setSpecularRepeatX(self,obj_scale_s * repeats_per_meter); + LLSelectedTEMaterial::setSpecularRepeatY(self,obj_scale_t * repeats_per_meter); + } + break; + + default: + llassert(false); + break; + } } // vertical scale and repeats per meter depends on each other, so force set on changes self->updateUI(true); diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 078995e787..7c084cb0ab 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -162,7 +162,12 @@ protected: // Callback funcs for individual controls // - static void onCommitTextureInfo( LLUICtrl* ctrl, void* userdata); + static void onCommitTextureInfo(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureScaleY(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureRot(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetX(LLUICtrl* ctrl, void* userdata); + static void onCommitTextureOffsetY(LLUICtrl* ctrl, void* userdata); static void onCommitMaterialBumpyScaleX( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialBumpyScaleY( LLUICtrl* ctrl, void* userdata); @@ -170,6 +175,12 @@ protected: static void onCommitMaterialBumpyOffsetX( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialBumpyOffsetY( LLUICtrl* ctrl, void* userdata); + static void syncRepeatX(LLPanelFace* self, F32 scaleU); + static void syncRepeatY(LLPanelFace* self, F32 scaleV); + static void syncOffsetX(LLPanelFace* self, F32 offsetU); + static void syncOffsetY(LLPanelFace* self, F32 offsetV); + static void syncMaterialRot(LLPanelFace* self, F32 rot); + static void onCommitMaterialShinyScaleX( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialShinyScaleY( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialShinyRot( LLUICtrl* ctrl, void* userdata); 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 b7b67147eb..ffdbc5d227 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -148,6 +148,18 @@ top_pad="1" value="2"/> + Date: Tue, 2 May 2017 19:55:24 +0300 Subject: MAINT-7351 New Default volume for Streaming Music & Media --- indra/newview/app_settings/settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/app_settings') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 89f5d7a24f..962537bc12 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -333,7 +333,7 @@ Type F32 Value - 0.5 + 0.3 AudioLevelMic @@ -355,7 +355,7 @@ Type F32 Value - 0.5 + 0.3 AudioLevelRolloff -- cgit v1.3 From b59ac959fcf2f1f0435f965d2c7279f529f1ce5c Mon Sep 17 00:00:00 2001 From: Ansariel Date: Thu, 27 Apr 2017 19:19:11 +0200 Subject: MAINT-6519 Contribution, adds feature to replace inventory links --- doc/contributions.txt | 1 + indra/newview/CMakeLists.txt | 2 + indra/newview/app_settings/settings.xml | 22 ++ indra/newview/llfloaterlinkreplace.cpp | 396 +++++++++++++++++++++ indra/newview/llfloaterlinkreplace.h | 127 +++++++ indra/newview/llinventorybridge.cpp | 25 ++ indra/newview/llinventorybridge.h | 3 + indra/newview/llinventoryfunctions.cpp | 20 ++ indra/newview/llpanelmaininventory.cpp | 20 ++ indra/newview/llviewerfloaterreg.cpp | 2 + .../skins/default/xui/en/floater_linkreplace.xml | 106 ++++++ .../skins/default/xui/en/menu_inventory.xml | 8 + .../default/xui/en/menu_inventory_gear_default.xml | 8 + 13 files changed, 740 insertions(+) create mode 100644 indra/newview/llfloaterlinkreplace.cpp create mode 100644 indra/newview/llfloaterlinkreplace.h create mode 100644 indra/newview/skins/default/xui/en/floater_linkreplace.xml (limited to 'indra/newview/app_settings') diff --git a/doc/contributions.txt b/doc/contributions.txt index 0fb6110adb..2272ec7922 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -214,6 +214,7 @@ Ansariel Hiller MAINT-6953 MAINT-7028 MAINT-7059 + MAINT-6519 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 4241ede365..b4e930d062 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -254,6 +254,7 @@ set(viewer_SOURCE_FILES llfloaterlagmeter.cpp llfloaterland.cpp llfloaterlandholdings.cpp + llfloaterlinkreplace.cpp llfloaterloadprefpreset.cpp llfloatermarketplacelistings.cpp llfloatermap.cpp @@ -876,6 +877,7 @@ set(viewer_HEADER_FILES llfloaterlagmeter.h llfloaterland.h llfloaterlandholdings.h + llfloaterlinkreplace.h llfloaterloadprefpreset.h llfloatermap.h llfloatermarketplacelistings.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 962537bc12..f490551406 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5450,6 +5450,28 @@ Value 1 + LinkReplaceBatchSize + + Comment + The maximum size of a batch in a link replace operation + Persist + 1 + Type + U32 + Value + 25 + + LinkReplaceBatchPauseTime + + Comment + The time in seconds between two batches in a link replace operation + Persist + 1 + Type + F32 + Value + 1.0 + LipSyncAah Comment diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp new file mode 100644 index 0000000000..6576af2ea3 --- /dev/null +++ b/indra/newview/llfloaterlinkreplace.cpp @@ -0,0 +1,396 @@ +/** + * @file llfloaterlinkreplace.cpp + * @brief Allows replacing link targets in inventory links + * @author Ansariel Hiller + * + * $LicenseInfo:firstyear=2017&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloaterlinkreplace.h" + +#include "llagent.h" +#include "llappearancemgr.h" +#include "lllineeditor.h" +#include "lltextbox.h" +#include "llviewercontrol.h" + +LLFloaterLinkReplace::LLFloaterLinkReplace(const LLSD& key) + : LLFloater(key), + LLEventTimer(gSavedSettings.getF32("LinkReplaceBatchPauseTime")), + mRemainingItems(0), + mSourceUUID(LLUUID::null), + mTargetUUID(LLUUID::null), + mInstance(NULL), + mBatchSize(gSavedSettings.getU32("LinkReplaceBatchSize")) +{ + mEventTimer.stop(); + mInstance = this; +} + +LLFloaterLinkReplace::~LLFloaterLinkReplace() +{ + mInstance = NULL; +} + +BOOL LLFloaterLinkReplace::postBuild() +{ + mStartBtn = getChild("btn_start"); + mStartBtn->setCommitCallback(boost::bind(&LLFloaterLinkReplace::onStartClicked, this)); + + mRefreshBtn = getChild("btn_refresh"); + mRefreshBtn->setCommitCallback(boost::bind(&LLFloaterLinkReplace::checkEnableStart, this)); + + mSourceEditor = getChild("source_uuid_editor"); + mTargetEditor = getChild("target_uuid_editor"); + + mSourceEditor->setDADCallback(boost::bind(&LLFloaterLinkReplace::onSourceItemDrop, this, _1)); + mTargetEditor->setDADCallback(boost::bind(&LLFloaterLinkReplace::onTargetItemDrop, this, _1)); + + mStatusText = getChild("status_text"); + + return TRUE; +} + +void LLFloaterLinkReplace::onOpen(const LLSD& key) +{ + if (key.asUUID().notNull()) + { + LLUUID item_id = key.asUUID(); + LLViewerInventoryItem* item = gInventory.getItem(item_id); + mSourceEditor->setItem(item); + onSourceItemDrop(item->getLinkedUUID()); + } + else + { + checkEnableStart(); + } +} + +void LLFloaterLinkReplace::onSourceItemDrop(const LLUUID& source_item_id) +{ + mSourceUUID = source_item_id; + checkEnableStart(); +} + +void LLFloaterLinkReplace::onTargetItemDrop(const LLUUID& target_item_id) +{ + mTargetUUID = target_item_id; + checkEnableStart(); +} + +void LLFloaterLinkReplace::updateFoundLinks() +{ + LLInventoryModel::item_array_t items; + LLInventoryModel::cat_array_t cat_array; + LLLinkedItemIDMatches is_linked_item_match(mSourceUUID); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + items, + LLInventoryModel::INCLUDE_TRASH, + is_linked_item_match); + mRemainingItems = (U32)items.size(); + + LLStringUtil::format_map_t args; + args["NUM"] = llformat("%d", mRemainingItems); + mStatusText->setText(getString("ItemsFound", args)); +} + +void LLFloaterLinkReplace::checkEnableStart() +{ + if (mSourceUUID.notNull() && mTargetUUID.notNull() && mSourceUUID == mTargetUUID) + { + mStatusText->setText(getString("ItemsIdentical")); + } + else if (mSourceUUID.notNull()) + { + updateFoundLinks(); + } + + mStartBtn->setEnabled(mRemainingItems > 0 && mSourceUUID.notNull() && mTargetUUID.notNull() && mSourceUUID != mTargetUUID); +} + +void LLFloaterLinkReplace::onStartClicked() +{ + LL_INFOS() << "Starting inventory link replace" << LL_ENDL; + + if (mSourceUUID.isNull() || mTargetUUID.isNull()) + { + LL_WARNS() << "Cannot replace. Either source or target UUID is null." << LL_ENDL; + return; + } + + if (mSourceUUID == mTargetUUID) + { + LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL; + return; + } + + LLInventoryModel::cat_array_t cat_array; + LLLinkedItemIDMatches is_linked_item_match(mSourceUUID); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + mRemainingInventoryItems, + LLInventoryModel::INCLUDE_TRASH, + is_linked_item_match); + LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL; + + if (mRemainingInventoryItems.size() > 0) + { + LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID); + if (target_item) + { + mRemainingItems = (U32)mRemainingInventoryItems.size(); + + LLStringUtil::format_map_t args; + args["NUM"] = llformat("%d", mRemainingItems); + mStatusText->setText(getString("ItemsRemaining", args)); + + mStartBtn->setEnabled(FALSE); + mRefreshBtn->setEnabled(FALSE); + + mEventTimer.start(); + tick(); + } + else + { + mStatusText->setText(getString("TargetNotFound")); + LL_WARNS() << "Link replace target not found." << LL_ENDL; + } + } +} + +void LLFloaterLinkReplace::linkCreatedCallback(const LLUUID& old_item_id, + const LLUUID& target_item_id, + bool needs_wearable_ordering_update, + bool needs_description_update, + const LLUUID& outfit_folder_id) +{ + LL_DEBUGS() << "Inventory link replace:" << LL_NEWLINE + << " - old_item_id = " << old_item_id.asString() << LL_NEWLINE + << " - target_item_id = " << target_item_id.asString() << LL_NEWLINE + << " - order update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE + << " - description update = " << (needs_description_update ? "true" : "false") << LL_NEWLINE + << " - outfit_folder_id = " << outfit_folder_id.asString() << LL_ENDL; + + // If we are replacing an object, bodypart or gesture link within an outfit folder, + // we need to change the actual description of the link itself. LLAppearanceMgr *should* + // have created COF links that will be used to save the outfit with an empty description. + // Since link_inventory_array() will set the description of the linked item for the link + // itself, this will lead to a dirty outfit state when the outfit with the replaced + // link is worn. So we have to correct this. + if (needs_description_update && outfit_folder_id.notNull()) + { + LLInventoryModel::item_array_t items; + LLInventoryModel::cat_array_t cats; + LLLinkedItemIDMatches is_target_link(target_item_id); + gInventory.collectDescendentsIf(outfit_folder_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + is_target_link); + + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + { + LLPointer item = *it; + + if ((item->getType() == LLAssetType::AT_BODYPART || + item->getType() == LLAssetType::AT_OBJECT || + item->getType() == LLAssetType::AT_GESTURE) + && !item->getActualDescription().empty()) + { + LL_DEBUGS() << "Updating description for " << item->getName() << LL_ENDL; + + LLSD updates; + updates["desc"] = ""; + update_inventory_item(item->getUUID(), updates, LLPointer(NULL)); + } + } + } + + LLUUID outfit_update_folder = LLUUID::null; + if (needs_wearable_ordering_update && outfit_folder_id.notNull()) + { + // If a wearable item was involved in the link replace operation and replaced + // a link in an outfit folder, we need to update the clothing ordering information + // *after* the original link has been removed. LLAppearanceMgr abuses the actual link + // description to store the clothing ordering information it. We will have to update + // the clothing ordering information or the outfit will be in dirty state when worn. + outfit_update_folder = outfit_folder_id; + } + + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::itemRemovedCallback, this, outfit_update_folder)); + remove_inventory_object(old_item_id, cb); +} + +void LLFloaterLinkReplace::itemRemovedCallback(const LLUUID& outfit_folder_id) +{ + if (outfit_folder_id.notNull()) + { + LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(outfit_folder_id); + } + + if (mInstance) + { + decreaseOpenItemCount(); + } +} + +void LLFloaterLinkReplace::decreaseOpenItemCount() +{ + mRemainingItems--; + + if (mRemainingItems == 0) + { + mStatusText->setText(getString("ReplaceFinished")); + mStartBtn->setEnabled(TRUE); + mRefreshBtn->setEnabled(TRUE); + mEventTimer.stop(); + LL_INFOS() << "Inventory link replace finished." << LL_ENDL; + } + else + { + LLStringUtil::format_map_t args; + args["NUM"] = llformat("%d", mRemainingItems); + mStatusText->setText(getString("ItemsRemaining", args)); + LL_DEBUGS() << "Inventory link replace: " << mRemainingItems << " links remaining..." << LL_ENDL; + } +} + +BOOL LLFloaterLinkReplace::tick() +{ + LL_DEBUGS() << "Calling tick - remaining items = " << mRemainingInventoryItems.size() << LL_ENDL; + + LLInventoryModel::item_array_t current_batch; + + for (U32 i = 0; i < mBatchSize; ++i) + { + if (!mRemainingInventoryItems.size()) + { + mEventTimer.stop(); + break; + } + + current_batch.push_back(mRemainingInventoryItems.back()); + mRemainingInventoryItems.pop_back(); + } + processBatch(current_batch); + + return FALSE; +} + +void LLFloaterLinkReplace::processBatch(LLInventoryModel::item_array_t items) +{ + const LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID); + const LLUUID cof_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false); + const LLUUID outfit_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + { + LLPointer source_item = *it; + + if (source_item->getParentUUID() != cof_folder_id) + { + bool is_outfit_folder = gInventory.isObjectDescendentOf(source_item->getParentUUID(), outfit_folder_id); + // If either the new or old item in the COF is a wearable, we need to update wearable ordering after the link has been replaced + bool needs_wearable_ordering_update = is_outfit_folder && source_item->getType() == LLAssetType::AT_CLOTHING || target_item->getType() == LLAssetType::AT_CLOTHING; + // Other items in the COF need a description update (description of the actual link item must be empty) + bool needs_description_update = is_outfit_folder && target_item->getType() != LLAssetType::AT_CLOTHING; + + LL_DEBUGS() << "is_outfit_folder = " << (is_outfit_folder ? "true" : "false") << LL_NEWLINE + << "needs_wearable_ordering_update = " << (needs_wearable_ordering_update ? "true" : "false") << LL_NEWLINE + << "needs_description_update = " << (needs_description_update ? "true" : "false") << LL_ENDL; + + LLInventoryObject::const_object_list_t obj_array; + obj_array.push_back(LLConstPointer(target_item)); + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(&LLFloaterLinkReplace::linkCreatedCallback, + this, + source_item->getUUID(), + target_item->getUUID(), + needs_wearable_ordering_update, + needs_description_update, + (is_outfit_folder ? source_item->getParentUUID() : LLUUID::null) )); + link_inventory_array(source_item->getParentUUID(), obj_array, cb); + } + else + { + decreaseOpenItemCount(); + } + } +} + + +////////////////////////////////////////////////////////////////////////////// +// LLInventoryLinkReplaceDropTarget + +static LLDefaultChildRegistry::Register r("inventory_link_replace_drop_target"); + +BOOL LLInventoryLinkReplaceDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) +{ + LLInventoryItem* item = (LLInventoryItem*)cargo_data; + + if (cargo_type >= DAD_TEXTURE && cargo_type <= DAD_LINK && + item && item->getActualType() != LLAssetType::AT_LINK_FOLDER && item->getType() != LLAssetType::AT_CATEGORY && + ( + LLAssetType::lookupCanLink(item->getType()) || + (item->getType() == LLAssetType::AT_LINK && !gInventory.getObject(item->getLinkedUUID())) // Broken Link! + )) + { + if (drop) + { + setItem(item); + if (!mDADSignal.empty()) + { + mDADSignal(mItemID); + } + } + else + { + *accept = ACCEPT_YES_SINGLE; + } + } + else + { + *accept = ACCEPT_NO; + } + + return TRUE; +} + +void LLInventoryLinkReplaceDropTarget::setItem(LLInventoryItem* item) +{ + if (item) + { + mItemID = item->getLinkedUUID(); + setText(item->getName()); + } + else + { + mItemID.setNull(); + setText(LLStringExplicit("")); + } +} diff --git a/indra/newview/llfloaterlinkreplace.h b/indra/newview/llfloaterlinkreplace.h new file mode 100644 index 0000000000..377dd1d450 --- /dev/null +++ b/indra/newview/llfloaterlinkreplace.h @@ -0,0 +1,127 @@ +/** + * @file llfloaterlinkreplace.h + * @brief Allows replacing link targets in inventory links + * @author Ansariel Hiller + * + * $LicenseInfo:firstyear=2017&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2017, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATERLINKREPLACE_H +#define LL_FLOATERLINKREPLACE_H + +#include "llfloater.h" +#include "lleventtimer.h" +#include "lllineeditor.h" +#include "llinventoryfunctions.h" +#include "llviewerinventory.h" + +class LLButton; +class LLTextBox; + +class LLInventoryLinkReplaceDropTarget : public LLLineEditor +{ +public: + struct Params : public LLInitParam::Block + { + Params() + {} + }; + + LLInventoryLinkReplaceDropTarget(const Params& p) + : LLLineEditor(p) {} + ~LLInventoryLinkReplaceDropTarget() {} + + typedef boost::signals2::signal item_dad_callback_t; + boost::signals2::connection setDADCallback(const item_dad_callback_t::slot_type& cb) + { + return mDADSignal.connect(cb); + } + + virtual BOOL postBuild() + { + setEnabled(FALSE); + return LLLineEditor::postBuild(); + } + + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg); + + LLUUID getItemID() const { return mItemID; } + void setItem(LLInventoryItem* item); + +private: + LLUUID mItemID; + + item_dad_callback_t mDADSignal; +}; + + +class LLFloaterLinkReplace : public LLFloater, LLEventTimer +{ + LOG_CLASS(LLFloaterLinkReplace); + +public: + LLFloaterLinkReplace(const LLSD& key); + virtual ~LLFloaterLinkReplace(); + + BOOL postBuild(); + virtual void onOpen(const LLSD& key); + + virtual BOOL tick(); + +private: + void checkEnableStart(); + void onStartClicked(); + void decreaseOpenItemCount(); + void updateFoundLinks(); + void processBatch(LLInventoryModel::item_array_t items); + + void linkCreatedCallback(const LLUUID& old_item_id, + const LLUUID& target_item_id, + bool needs_wearable_ordering_update, + bool needs_description_update, + const LLUUID& outfit_folder_id); + void itemRemovedCallback(const LLUUID& outfit_folder_id); + + void onSourceItemDrop(const LLUUID& source_item_id); + void onTargetItemDrop(const LLUUID& target_item_id); + + LLInventoryLinkReplaceDropTarget* mSourceEditor; + LLInventoryLinkReplaceDropTarget* mTargetEditor; + LLButton* mStartBtn; + LLButton* mRefreshBtn; + LLTextBox* mStatusText; + + LLUUID mSourceUUID; + LLUUID mTargetUUID; + U32 mRemainingItems; + U32 mBatchSize; + + LLInventoryModel::item_array_t mRemainingInventoryItems; + + LLFloaterLinkReplace* mInstance; +}; + +#endif // LL_FLOATERLINKREPLACE_H diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 555c19baac..bf4a2301ae 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -851,6 +851,7 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -1051,6 +1052,20 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, items.push_back(std::string("Marketplace Listings Separator")); } +void LLInvFVBridge::addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_vec_t& disabled_items) +{ + const LLInventoryObject* obj = getInventoryObject(); + + if (isAgentInventory() && obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getType() != LLAssetType::AT_LINK_FOLDER) + { + items.push_back(std::string("Replace Links")); + + if (mRoot->getSelectedCount() != 1) + { + disabled_items.push_back(std::string("Replace Links")); + } + } +} // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const @@ -5179,6 +5194,7 @@ void LLTextureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("Save As")); } } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -5251,6 +5267,7 @@ void LLSoundBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Sound Play")); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -5339,6 +5356,7 @@ void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("About Landmark")); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -5641,6 +5659,7 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) disabled_items.push_back(std::string("Conference Chat")); } } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -5910,6 +5929,7 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Activate")); } } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -5967,6 +5987,7 @@ void LLAnimationBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Animation Audition")); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -6283,6 +6304,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } } } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -6511,6 +6533,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } } } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -6682,6 +6705,7 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Properties")); addDeleteContextMenuOptions(items, disabled_items); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } @@ -6733,6 +6757,7 @@ void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) getClipboardEntries(true, items, disabled_items, flags); } + addLinkReplaceMenuOption(items, disabled_items); hide_context_entries(menu, items, disabled_items); } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index b7d8c9d034..e6fcb6be96 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -148,6 +148,9 @@ protected: virtual void addMarketplaceContextMenuOptions(U32 flags, menuentry_vec_t &items, menuentry_vec_t &disabled_items); + virtual void addLinkReplaceMenuOption(menuentry_vec_t& items, + menuentry_vec_t& disabled_items); + protected: LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid); diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index f04d6cc753..bccc654fbf 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -2306,6 +2306,26 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root // Clear the clipboard before we start adding things on it LLClipboard::instance().reset(); } + if ("replace_links" == action) + { + LLSD params; + if (root->getSelectedCount() == 1) + { + LLFolderViewItem* folder_item = root->getSelectedItems().front(); + LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem(); + + if (bridge) + { + LLInventoryObject* obj = bridge->getInventoryObject(); + if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER) + { + params = LLSD(obj->getUUID()); + } + } + } + LLFloaterReg::showInstance("linkreplace", params); + return; + } static const std::string change_folder_string = "change_folder_type_"; if (action.length() > change_folder_string.length() && diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index adbcf377c0..ff54f83016 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1159,6 +1159,26 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata) mFilterEditor->setText(item_name); mFilterEditor->setFocus(TRUE); } + + if (command_name == "replace_links") + { + LLSD params; + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (current_item) + { + LLInvFVBridge* bridge = (LLInvFVBridge*)current_item->getViewModelItem(); + + if (bridge) + { + LLInventoryObject* obj = bridge->getInventoryObject(); + if (obj && obj->getType() != LLAssetType::AT_CATEGORY && obj->getActualType() != LLAssetType::AT_LINK_FOLDER) + { + params = LLSD(obj->getUUID()); + } + } + } + LLFloaterReg::showInstance("linkreplace", params); + } } void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility ) diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 4c146679db..0ebacddd9b 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -83,6 +83,7 @@ #include "llfloaterlagmeter.h" #include "llfloaterland.h" #include "llfloaterlandholdings.h" +#include "llfloaterlinkreplace.h" #include "llfloaterloadprefpreset.h" #include "llfloatermap.h" #include "llfloatermarketplacelistings.h" @@ -258,6 +259,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("linkreplace", "floater_linkreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("load_pref_preset", "floater_load_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/skins/default/xui/en/floater_linkreplace.xml b/indra/newview/skins/default/xui/en/floater_linkreplace.xml new file mode 100644 index 0000000000..ece75e2576 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_linkreplace.xml @@ -0,0 +1,106 @@ + + + + Ready... + + + Target item not found. + + + Source and target are identical. + + + Found [NUM] inventory links. + + + Links remaining: [NUM] + + + Finished replacing inventory links. + + + Old: + + + + New: + + + + Ready... + +