summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llstring.cpp15
-rw-r--r--indra/llui/llaccordionctrl.cpp11
-rw-r--r--indra/llui/llaccordionctrltab.cpp15
-rw-r--r--indra/llui/llaccordionctrltab.h1
-rw-r--r--indra/llui/llmenugl.cpp6
-rw-r--r--indra/llui/llmenugl.h1
-rw-r--r--indra/newview/llappearancemgr.cpp15
-rw-r--r--indra/newview/llappearancemgr.h5
-rw-r--r--indra/newview/llfloaterworldmap.cpp68
-rw-r--r--indra/newview/llfloaterworldmap.h7
-rw-r--r--indra/newview/llfolderview.h1
-rw-r--r--indra/newview/llgroupmgr.cpp10
-rw-r--r--indra/newview/llinventoryicon.cpp1
-rw-r--r--indra/newview/lloutfitslist.cpp39
-rw-r--r--indra/newview/lloutfitslist.h5
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp8
-rw-r--r--indra/newview/llpaneloutfitedit.cpp33
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp2
-rw-r--r--indra/newview/lltexturectrl.cpp30
-rw-r--r--indra/newview/llviewerinventory.cpp1
-rw-r--r--indra/newview/llviewermenu.cpp84
-rw-r--r--indra/newview/skins/default/xui/en/floater_buy_land.xml24
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml123
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml3
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp10
27 files changed, 398 insertions, 125 deletions
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index 804c00fd60..2693c0e22b 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -672,16 +672,23 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
{
- int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
+ // From review:
+ // We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
+ // plus one for a null terminator, and be guaranteed to not overflow.
+
+ // Normally, I'd call that sort of thing premature optimization,
+ // but we *are* seeing string operations taking a bunch of time, especially when constructing widgets.
+// int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
// reserve place to NULL terminator
+ int output_str_len = in.length();
wchar_t* w_out = new wchar_t[output_str_len + 1];
memset(w_out, 0, output_str_len + 1);
- MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
+ int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
- w_out[output_str_len] = 0;
+ w_out[real_output_str_len] = 0;
return w_out;
}
@@ -689,7 +696,7 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page
std::string ll_convert_string_to_utf8_string(const std::string& in)
{
wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP);
- std::string out_utf8 = ll_convert_wide_to_string(w_mesg, CP_UTF8);
+ std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8));
delete[] w_mesg;
return out_utf8;
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 2bc8ea054a..c3ef734823 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -765,6 +765,17 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
}
return 0;
}
+ else if(str_action == "deselect_current")
+ {
+ // Reset selection to the currently selected tab.
+ if (mSelectedTab)
+ {
+ mSelectedTab->setSelected(false);
+ mSelectedTab = NULL;
+ return 1;
+ }
+ return 0;
+ }
}
else if (info.has("scrollToShowRect"))
{
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 37fc571bbd..d8760d5cdb 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -371,9 +371,11 @@ LLAccordionCtrlTab::LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&p)
mHeader = LLUICtrlFactory::create<LLAccordionCtrlTabHeader>(headerParams);
addChild(mHeader, 1);
- if (p.selection_enabled)
+ LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this));
+
+ if (!p.selection_enabled)
{
- LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLAccordionCtrlTab::selectOnFocusReceived, this));
+ LLFocusableElement::setFocusLostCallback(boost::bind(&LLAccordionCtrlTab::deselectOnFocusLost, this));
}
reshape(100, 200,FALSE);
@@ -598,6 +600,15 @@ void LLAccordionCtrlTab::selectOnFocusReceived()
getParent()->notifyParent(LLSD().with("action", "select_current"));
}
+void LLAccordionCtrlTab::deselectOnFocusLost()
+{
+ if(getParent()) // A parent may not be set if tabs are added dynamically.
+ {
+ getParent()->notifyParent(LLSD().with("action", "deselect_current"));
+ }
+
+}
+
S32 LLAccordionCtrlTab::getHeaderHeight()
{
return mHeaderVisible?HEADER_HEIGHT:0;
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index 5646a355d0..0ef9c407f1 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -220,6 +220,7 @@ protected:
LLView* findContainerView ();
void selectOnFocusReceived();
+ void deselectOnFocusLost();
private:
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index b4a1bcb7c5..8610d79142 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -218,6 +218,12 @@ void LLMenuItemGL::setValue(const LLSD& value)
}
//virtual
+LLSD LLMenuItemGL::getValue() const
+{
+ return getLabel();
+}
+
+//virtual
BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
{
if( getEnabled() && (!gKeyboard->getKeyRepeated(key) || mAllowKeyRepeat) && (key == mAcceleratorKey) && (mask == (mAcceleratorMask & MASK_NORMALKEYS)) )
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 7668f301ea..a484405eaa 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -95,6 +95,7 @@ public:
// LLUICtrl overrides
/*virtual*/ void setValue(const LLSD& value);
+ /*virtual*/ LLSD getValue() const;
virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index c04c2e271f..b64007aa75 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2699,6 +2699,21 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
return gInventory.isObjectDescendentOf(obj_id, getCOF());
}
+// static
+bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLLinkedItemIDMatches find_links(gInventory.getLinkedItemID(obj_id));
+ gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
+ cats,
+ items,
+ LLInventoryModel::EXCLUDE_TRASH,
+ find_links);
+
+ return !items.empty();
+}
+
BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
if (!getIsInCOF(obj_id)) return FALSE;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index ca57d62446..9f554dbdef 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -223,6 +223,11 @@ public:
BOOL getIsInCOF(const LLUUID& obj_id) const;
// Is this in the COF and can the user delete it from the COF?
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
+
+ /**
+ * Checks if COF contains link to specified object.
+ */
+ static bool isLinkInCOF(const LLUUID& obj_id);
};
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 983fd97b0b..88f8545877 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -206,6 +206,7 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE);
+ mCommitCallbackRegistrar.add("WMap.Coordinates", boost::bind(&LLFloaterWorldMap::onCoordinatesCommit, this));
mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this));
mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this));
@@ -336,8 +337,6 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
}
}
-
-
// static
void LLFloaterWorldMap::reloadIcons(void*)
{
@@ -582,6 +581,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
S32 world_y = S32(pos_global.mdV[1] / 256);
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
setDefaultBtn("");
+
+ // clicked on a non-region - turn off coord display
+ enableTeleportCoordsDisplay( false );
+
return;
}
if (sim_info->isDown())
@@ -592,6 +595,10 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
LLWorldMap::getInstance()->setTrackingInvalid();
LLTracker::stopTracking(NULL);
setDefaultBtn("");
+
+ // clicked on a down region - turn off coord display
+ enableTeleportCoordsDisplay( false );
+
return;
}
@@ -609,9 +616,40 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
LLTracker::trackLocation(pos_global, full_name, tooltip);
LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking
+ LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
+ updateTeleportCoordsDisplay( coord_pos );
+
+ // we have a valid region - turn on coord display
+ enableTeleportCoordsDisplay( true );
+
setDefaultBtn("Teleport");
}
+// enable/disable teleport destination coordinates
+void LLFloaterWorldMap::enableTeleportCoordsDisplay( bool enabled )
+{
+ childSetEnabled("teleport_coordinate_x", enabled );
+ childSetEnabled("teleport_coordinate_y", enabled );
+ childSetEnabled("teleport_coordinate_z", enabled );
+}
+
+// update display of teleport destination coordinates - pos is in global coordinates
+void LLFloaterWorldMap::updateTeleportCoordsDisplay( const LLVector3d& pos )
+{
+ // if we're going to update their value, we should also enable them
+ enableTeleportCoordsDisplay( true );
+
+ // convert global specified position to a local one
+ F32 region_local_x = (F32)fmod( pos.mdV[VX], (F64)REGION_WIDTH_METERS );
+ F32 region_local_y = (F32)fmod( pos.mdV[VY], (F64)REGION_WIDTH_METERS );
+ F32 region_local_z = (F32)fmod( pos.mdV[VZ], (F64)REGION_WIDTH_METERS );
+
+ // write in the values
+ childSetValue("teleport_coordinate_x", region_local_x );
+ childSetValue("teleport_coordinate_y", region_local_y );
+ childSetValue("teleport_coordinate_z", region_local_z );
+}
+
void LLFloaterWorldMap::updateLocation()
{
bool gotSimName;
@@ -638,6 +676,9 @@ void LLFloaterWorldMap::updateLocation()
// Fill out the location field
childSetValue("location", agent_sim_name);
+ // update the coordinate display with location of avatar in region
+ updateTeleportCoordsDisplay( agentPos );
+
// Figure out where user is
// Set the current SLURL
mSLURL = LLSLURL(agent_sim_name, gAgent.getPositionGlobal());
@@ -668,6 +709,10 @@ void LLFloaterWorldMap::updateLocation()
childSetValue("location", sim_name);
+ // refresh coordinate display to reflect where user clicked.
+ LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal();
+ updateTeleportCoordsDisplay( coord_pos );
+
// simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
if ( gotSimName )
{
@@ -1139,6 +1184,22 @@ void LLFloaterWorldMap::onLocationCommit()
}
}
+void LLFloaterWorldMap::onCoordinatesCommit()
+{
+ if( mIsClosing )
+ {
+ return;
+ }
+
+ S32 x_coord = (S32)childGetValue("teleport_coordinate_x").asReal();
+ S32 y_coord = (S32)childGetValue("teleport_coordinate_y").asReal();
+ S32 z_coord = (S32)childGetValue("teleport_coordinate_z").asReal();
+
+ const std::string region_name = childGetValue("location").asString();
+
+ trackURL( region_name, x_coord, y_coord, z_coord );
+}
+
void LLFloaterWorldMap::onClearBtn()
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
@@ -1199,6 +1260,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
else if(LLWorldMap::getInstance()->isTracking())
{
pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();;
+
+
+
}
else
{
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 550b4ef689..e31bafaf9b 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -149,6 +149,7 @@ protected:
void updateSearchEnabled();
void onLocationFocusChanged( LLFocusableElement* ctrl );
void onLocationCommit();
+ void onCoordinatesCommit();
void onCommitSearchResult();
void cacheLandmarkPosition();
@@ -160,6 +161,12 @@ private:
F32 mCurZoomVal;
LLFrameTimer mZoomTimer;
+ // update display of teleport destination coordinates - pos is in global coordinates
+ void updateTeleportCoordsDisplay( const LLVector3d& pos );
+
+ // enable/disable teleport destination coordinates
+ void enableTeleportCoordsDisplay( bool enabled );
+
LLDynamicArray<LLUUID> mLandmarkAssetIDList;
LLDynamicArray<LLUUID> mLandmarkItemIDList;
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 4047e31c08..c69f08eb2d 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -263,6 +263,7 @@ public:
BOOL needsAutoRename() { return mNeedsAutoRename; }
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
+ void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 996553ccf7..d464b67105 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -903,7 +903,15 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
if (member_id.notNull())
{
- formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ if (online_status == "Online")
+ {
+ static std::string localized_online(LLTrans::getString("group_member_status_online"));
+ online_status = localized_online;
+ }
+ else
+ {
+ formatDateString(online_status); // reformat for sorting, e.g. 12/25/2008 -> 2008/12/25
+ }
//llinfos << "Member " << member_id << " has powers " << std::hex << agent_powers << std::dec << llendl;
LLGroupMemberData* newdata = new LLGroupMemberData(member_id,
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 3090371a73..2201481df3 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -117,6 +117,7 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
if (item_is_multi)
{
idx = ICONNAME_OBJECT_MULTI;
+ return getIconName(idx);
}
switch(asset_type)
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 63ffb80ff2..c3eee1d1ad 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -665,7 +665,18 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
}
if (command_name == "wear")
{
- return !gAgentWearables.isCOFChangeInProgress();
+ if (gAgentWearables.isCOFChangeInProgress())
+ {
+ return false;
+ }
+
+ if (hasItemSelected())
+ {
+ return canWearSelected();
+ }
+
+ // outfit selected
+ return LLAppearanceMgr::getCanAddToCOF(mSelectedOutfitUUID);
}
if (command_name == "take_off")
{
@@ -677,6 +688,7 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
if (command_name == "wear_add")
{
+ // *TODO: do we ever get here?
if (gAgentWearables.isCOFChangeInProgress())
{
return false;
@@ -984,6 +996,31 @@ bool LLOutfitsList::canTakeOffSelected()
return false;
}
+bool LLOutfitsList::canWearSelected()
+{
+ uuid_vec_t selected_items;
+ getSelectedItemsUUIDs(selected_items);
+
+ for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it)
+ {
+ const LLUUID& id = *it;
+
+ if (LLAppearanceMgr::isLinkInCOF(id))
+ {
+ return false;
+ }
+
+ // Check whether the item is worn.
+ if (!get_can_item_be_worn(id))
+ {
+ return false;
+ }
+ }
+
+ // All selected items can be worn.
+ return true;
+}
+
void LLOutfitsList::onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id)
{
LLAccordionCtrlTab* tab = dynamic_cast<LLAccordionCtrlTab*>(ctrl);
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index d7cf8a8c08..206854b232 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -183,6 +183,11 @@ private:
*/
bool canTakeOffSelected();
+ /**
+ * Returns true if all selected items can be worn.
+ */
+ bool canWearSelected();
+
void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);
void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
void onCOFChanged();
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 65fe7165c2..b7d6b65ce5 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1432,10 +1432,10 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits, (S32)floor((F32)total_debits/(F32)non_exempt_members)));
// text.append(llformat( "%-24s %6d %6d \n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits, (S32)floor((F32)(total_credits + total_debits)/(F32)non_exempt_members)));
- text.append( " Group\n");
- text.append(llformat( "%-24s %6d\n", "Credits", total_credits));
- text.append(llformat( "%-24s %6d\n", "Debits", total_debits));
- text.append(llformat( "%-24s %6d\n", "Total", total_credits + total_debits));
+ text.append(llformat( "%s\n", LLTrans::getString("GroupColumn").c_str()));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyCredits").c_str(), total_credits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyDebits").c_str(), total_debits));
+ text.append(llformat( "%-24s %6d\n", LLTrans::getString("GroupMoneyTotal").c_str(), total_credits + total_debits));
if ( mImplementationp->mTextEditorp )
{
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c09aff44da..58a5529505 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -779,7 +779,9 @@ void LLPanelOutfitEdit::updatePlusButton()
}
// If any of the selected items are not wearable (due to already being worn OR being of the wrong type), disable the add button.
- uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1));
+ uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1)
+ // since item can be not worn but in wearing process at that time - we need to check is link to item presents in COF
+ || boost::bind(&LLAppearanceMgr::isLinkInCOF, _1));
bool can_add = ( unwearable_item == selected_items.end() );
mPlusBtn->setEnabled(can_add);
@@ -839,15 +841,38 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
bool more_than_one_selected = ids.size() > 1;
bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()));
- //selected and expanded accordion tabs determine filtering when no item is selected
+ // selected, expanded accordion tabs and selection in flat list view determine filtering when no item is selected in COF
+ // selection in flat list view participates in determining filtering because of EXT-7963
+ // So the priority of criterions in is:
+ // 1. Selected accordion tab | IF (any accordion selected)
+ // | filter_type = selected_accordion_type
+ // 2. Selected item in flat list view | ELSEIF (any item in flat list view selected)
+ // | filter_type = selected_item_type
+ // 3. Expanded accordion tab | ELSEIF (any accordion expanded)
+ // | filter_type = expanded accordion_type
if (nothing_selected)
{
showWearablesListView();
- //selected accordion tab is more priority than expanded tab when determining filtering
+ //selected accordion tab is more priority than expanded tab
+ //and selected item in flat list view of 'Add more' panel when
+ //determining filtering
LLAssetType::EType type = mCOFWearables->getSelectedAccordionAssetType();
if (type == LLAssetType::AT_NONE)
- {
+ { //no accordion selected
+
+ // when no accordion selected then selected item from flat list view
+ // has more priority than expanded when determining filtering
+ LLUUID selected_item_id = mWearableItemsList->getSelectedUUID();
+ LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
+ if(item)
+ {
+ showFilteredWearablesListView(item->getWearableType());
+ return;
+ }
+
+ // when no accordion selected and no selected items in flat list view
+ // determine filtering according to expanded accordion
type = mCOFWearables->getExpandedAccordionAssetType();
}
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index ca5679d5b0..16ef7998b3 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -337,7 +337,7 @@ bool LLPanelOutfitsInventory::isCOFPanelActive() const
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
- mListCommands->childSetEnabled("wear_btn", !val);
+ updateVerbs();
}
void LLPanelOutfitsInventory::onWearablesLoaded()
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 0b02861b75..c0518b705b 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -175,6 +175,8 @@ protected:
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
LLSaveFolderState mSavedFolderState;
+
+ BOOL mSelectedItemPinned;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
@@ -197,7 +199,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
- mContextConeOpacity(0.f)
+ mContextConeOpacity(0.f),
+ mSelectedItemPinned( FALSE )
{
mCanApplyImmediately = can_apply_immediately;
LLUICtrlFactory::getInstance()->buildFloater(this,"floater_texture_ctrl.xml",NULL);
@@ -597,6 +600,31 @@ void LLFloaterTexturePicker::draw()
mTentativeLabel->setVisible( TRUE );
drawChild(mTentativeLabel);
}
+
+ if (mSelectedItemPinned) return;
+
+ LLFolderView* folder_view = mInventoryPanel->getRootFolder();
+ if (!folder_view) return;
+
+ LLInventoryFilter* filter = folder_view->getFilter();
+ if (!filter) return;
+
+ bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+ filter->isNotDefault();
+
+ // After inventory panel filter is applied we have to update
+ // constraint rect for the selected item because of folder view
+ // AutoSelectOverride set to TRUE. We force PinningSelectedItem
+ // flag to FALSE state and setting filter "dirty" to update
+ // scroll container to show selected item (see LLFolderView::doIdle()).
+ if (!is_filter_active && !mSelectedItemPinned)
+ {
+ folder_view->setPinningSelectedItem(mSelectedItemPinned);
+ folder_view->dirtyFilter();
+ folder_view->arrangeFromRoot();
+
+ mSelectedItemPinned = TRUE;
+ }
}
}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 3b56183dfe..9926c8d15f 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -96,6 +96,7 @@ public:
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
+ mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
mInventoryItemsDict["Contents"] = LLTrans::getString("Contents");
mInventoryItemsDict["Gesture"] = LLTrans::getString("Gesture");
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7cca118392..df8e127b1f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -108,9 +108,12 @@
#include "llappearancemgr.h"
#include "lltrans.h"
#include "lleconomy.h"
+#include "boost/unordered_map.hpp"
using namespace LLVOAvatarDefines;
+static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
+
BOOL enable_land_build(void*);
BOOL enable_object_build(void*);
@@ -2403,31 +2406,53 @@ void handle_object_touch()
msg->sendMessage(object->getRegion()->getHost());
}
-// One object must have touch sensor
-class LLObjectEnableTouch : public view_listener_t
+static void init_default_item_label(const std::string& item_name)
{
- bool handleEvent(const LLSD& userdata)
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it == sDefaultItemLabels.end())
{
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
-
- bool new_value = obj && obj->flagHandleTouch();
-
- // Update label based on the node touch name if available.
- std::string touch_text;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
- if (node && node->mValid && !node->mTouchName.empty())
- {
- touch_text = node->mTouchName;
- }
- else
+ LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString();
+ if (!default_label.empty())
{
- touch_text = userdata.asString();
+ sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
}
- gMenuHolder->childSetText("Object Touch", touch_text);
- gMenuHolder->childSetText("Attachment Object Touch", touch_text);
+ }
+}
- return new_value;
+static LLStringExplicit get_default_item_label(const std::string& item_name)
+{
+ LLStringExplicit res("");
+ boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
+ if (it != sDefaultItemLabels.end())
+ {
+ res = it->second;
+ }
+
+ return res;
+}
+
+
+bool enable_object_touch(LLUICtrl* ctrl)
+{
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+
+ bool new_value = obj && obj->flagHandleTouch();
+
+ std::string item_name = ctrl->getName();
+ init_default_item_label(item_name);
+
+ // Update label based on the node touch name if available.
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid && !node->mTouchName.empty())
+ {
+ gMenuHolder->childSetText(item_name, node->mTouchName);
+ }
+ else
+ {
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
+
+ return new_value;
};
//void label_touch(std::string& label, void*)
@@ -5519,27 +5544,27 @@ bool enable_object_stand_up()
return sitting_on_selection();
}
-bool enable_object_sit()
+bool enable_object_sit(LLUICtrl* ctrl)
{
// 'Object Sit' menu item is enabled when agent is not sitting on selection
bool sitting_on_sel = sitting_on_selection();
if (!sitting_on_sel)
{
- LLMenuItemGL* sit_menu_item = gMenuHolder->getChild<LLMenuItemGL>("Object Sit");
- // Init default 'Object Sit' menu item label
- static const LLStringExplicit sit_text(sit_menu_item->getLabel());
+ std::string item_name = ctrl->getName();
+
+ // init default labels
+ init_default_item_label(item_name);
+
// Update label
- std::string label;
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mSitName.empty())
{
- label.assign(node->mSitName);
+ gMenuHolder->childSetText(item_name, node->mSitName);
}
else
{
- label = sit_text;
+ gMenuHolder->childSetText(item_name, get_default_item_label(item_name));
}
- sit_menu_item->setLabel(label);
}
return !sitting_on_sel && is_object_sittable();
}
@@ -8048,7 +8073,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
- enable.add("Object.EnableGearSit", boost::bind(&is_object_sittable));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
@@ -8064,12 +8088,12 @@ void initialize_menus()
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
- view_listener_t::addMenu(new LLObjectEnableTouch(), "Object.EnableTouch");
+ enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid));
enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
- enable.add("Object.EnableSit", boost::bind(&enable_object_sit));
+ enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml
index 0ad4fbc967..c88de878f4 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml
@@ -529,13 +529,14 @@ sold with objects
length="1"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="account_action"
right="438"
top="200"
- width="218">
+ width="218"
+ wrap="true">
Upgrade you to premium membership.
</text>
<text
@@ -577,19 +578,21 @@ sold with objects
layout="topleft"
left="0"
name="step_2"
+ top_pad="-10"
width="64" />
<text
type="string"
length="1"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="land_use_action"
right="438"
top="284"
- width="218">
+ width="218"
+ wrap="true">
Increase your monthly land use fees to US$ 40/month.
</text>
<text
@@ -620,14 +623,15 @@ This parcel is 512 m² of land.
<text
type="string"
length="1"
- bottom_delta="-38"
+ bottom_delta="-22"
follows="top|left"
font="SansSerifBig"
- height="16"
+ height="32"
layout="topleft"
left="72"
name="purchase_action"
- right="438">
+ right="438"
+ wrap="true">
Pay Joe Resident L$ 4000 for the land
</text>
<text
@@ -665,7 +669,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="170"
name="currency_amt"
- top="408"
+ top="424"
width="80">
1000
</line_editor>
@@ -681,7 +685,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="260"
name="currency_est"
- top="409"
+ top="425"
width="178">
for approx. [LOCAL_AMOUNT]
</text>
@@ -713,7 +717,7 @@ This parcel is 512 m² of land.
layout="topleft"
left="70"
name="buy_btn"
- top="448"
+ top="460"
width="100" />
<button
follows="bottom|right"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index a59db1420f..20629018e2 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -395,7 +395,7 @@
<panel
follows="right|top|bottom"
- height="310"
+ height="330"
top_pad="0"
width="238"
name="layout_panel_4">
@@ -534,7 +534,66 @@
<scroll_list.commit_callback
function="WMap.SearchResult" />
</scroll_list>
- <button
+ <text
+ type="string"
+ length="1"
+ follows="right|bottom"
+ halign="right"
+ height="16"
+ layout="topleft"
+ left="25"
+ name="events_label"
+ top_pad="16"
+ width="70">
+ Location:
+ </text>
+ <spinner
+ control_name="Teleport_Coordinate_X"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="74"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_x"
+ width="44" >
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <spinner
+ control_name="Teleport_Coordinate_Y"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="47"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_y" >
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <spinner
+ control_name="Teleport_Coordinate_Z"
+ decimal_digits="0"
+ follows="right|bottom"
+ height="23"
+ increment="1"
+ initial_value="128"
+ layout="topleft"
+ left_delta="47"
+ max_val="255"
+ min_val="0"
+ name="teleport_coordinate_z">
+ <spinner.commit_callback
+ function="WMap.Coordinates" />
+ </spinner>
+ <button
follows="right|bottom"
height="23"
image_unselected="PushButton_On"
@@ -574,66 +633,6 @@
<button.commit_callback
function="WMap.ShowTarget" />
</button>
-
-<!-- <text
- type="string"
- length="1"
- follows="bottom|right"
- halign="left"
- height="16"
- top_pad="4"
- left="25"
- layout="topleft"
- name="land_sale_label"
- width="250">
- Location:
- </text>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- increment="1"
- initial_value="128"
- layout="topleft"
- top_pad="0"
- left="25"
- max_val="255"
- name="spin x"
- tool_tip="X coordinate of location to show on map"
- width="48">
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- height="16"
- increment="1"
- initial_value="128"
- layout="topleft"
- left_pad="2"
- max_val="255"
- name="spin y"
- tool_tip="Y coordinate of location to show on map"
- top_delta="0"
- width="48" >
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>
- <spinner
- decimal_digits="0"
- follows="bottom|right"
- increment="1"
- initial_value="0"
- layout="topleft"
- left_pad="2"
- max_val="4096"
- name="spin z"
- tool_tip="Z coordinate of location to show on map"
- top_delta="0"
- width="48">
- <spinner.commit_callback
- function="WMap.CommitLocation" />
- </spinner>-->
</panel>
<panel
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 7239b13466..e2348375d5 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -11,8 +11,7 @@
function="Object.Touch" />
<menu_item_call.on_enable
function="Object.EnableTouch"
- name="EnableTouch"
- parameter="Touch" />
+ name="EnableTouch"/>
</menu_item_call>
<!--menu_item_call
label="Stand Up"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index b6f00ef6d1..8ec7689819 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
@@ -22,7 +22,7 @@
<menu_item_call.on_click
function="InspectObject.Sit"/>
<menu_item_call.on_visible
- function="Object.EnableGearSit" />
+ function="Object.EnableSit"/>
</menu_item_call>
<menu_item_call
label="Pay"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 3d8ceb9912..a0c67e3612 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2103,6 +2103,7 @@ Clears (deletes) the media and all params from the given face.
<string name="SummaryForTheWeek" value="Summary for this week, beginning on " />
<string name="NextStipendDay" value="The next stipend day is " />
<string name="GroupIndividualShare" value=" Group Individual Share" />
+ <string name="GroupColumn" value=" Group" />
<string name="Balance">Balance</string>
<string name="Credits">Credits</string>
<string name="Debits">Debits</string>
@@ -3142,6 +3143,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="group_role_everyone">Everyone</string>
<string name="group_role_officers">Officers</string>
<string name="group_role_owners">Owners</string>
+ <string name="group_member_status_online">Online</string>
<string name="uploading_abuse_report">Uploading...
@@ -3166,6 +3168,7 @@ Abuse Report</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
<string name="New Script">New Script</string>
+ <string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
<string name="Contents">Contents</string>
<string name="Gesture">Gesture</string>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 1c29feec5f..347a5e8ab8 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -226,6 +226,16 @@ S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& resp
return response.asInteger();
}
+//-----------------------------------------------------------------------------
+#include "../llmachineid.h"
+unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {77,21,46,31,89,2};
+
+S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len)
+{
+ memcpy(unique_id, gMACAddress, len);
+ return 1;
+}
+//-----------------------------------------------------------------------------
// misc
std::string xml_escape_string(const std::string& in)
{