diff options
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) { |